Psi4
TableSpecs.h
Go to the documentation of this file.
1 /*
2  * @BEGIN LICENSE
3  *
4  * Psi4: an open-source quantum chemistry software package
5  *
6  * Copyright (c) 2007-2017 The Psi4 Developers.
7  *
8  * The copyrights for code used from other parties are included in
9  * the corresponding files.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  *
25  * @END LICENSE
26  */
27 #ifndef TABLESPECS_H_
28 #define TABLESPECS_H_
29 #include<string>
30 #include<sstream>
31 #include<iomanip>
32 
33 namespace psi {
35 class Nothing {
36 };
37 
39 enum Align {
41 };
42 
186 template <typename T1=Nothing, typename T2=Nothing, typename T3=Nothing,
187  typename T4=Nothing, typename T5=Nothing, typename T6=Nothing>
189 
191 template <>
193  private:
194  std::string TokenSep_;
195  protected:
196 
198  virtual bool IsBase() const {
199  return true;
200  }
201 
203  int NRows_;
204  virtual int NRows() const {
205  return NRows_;
206  }
207 
209  std::vector<std::string> Title_;
210  virtual std::vector<std::string> Title() const {
211  return Title_;
212  }
213 
215  std::vector<Align> Alignments_;
216  virtual std::vector<Align> Alignments() const {
217  return Alignments_;
218  }
219 
221  char TitleSep_;
222  virtual char TitleSep() const {
223  return TitleSep_;
224  }
225 
227  char ColSep_;
228  virtual char ColSep() const {
229  return ColSep_;
230  }
231 
233  char RowSep_;
234  virtual char RowSep() const {
235  return RowSep_;
236  }
237 
239  int Width_;
240  virtual int Width() const {
241  return Width_;
242  }
243 
245  std::vector<int> ReqWidth_;
246  virtual std::vector<int> ReqWidth()const{
247  return ReqWidth_;
248  }
249  public:
251  void SetTitles(const std::vector<std::string>& Titles) {
252  Title_=Titles;
253  }
254 
256  void SetAlignments(const std::vector<Align>& Alignments) {
257  Alignments_=Alignments;
258  }
259 
261  void SetWidths(const std::vector<int>& Widths){
262  ReqWidth_=Widths;
263  }
265  virtual std::string GetData(int row) const {
266  return std::string(" "+TokenSep_+" ");
267  }
268 
270  virtual int NCols() const {
271  return 0;
272  }
273 
275  void Init(void* Data1=NULL, void* Data2=NULL, void* Data3=NULL,
276  void* Data4=NULL, void* Data5=NULL, void* Data6=NULL) const {
277  }
278 
280  const int NRows, const char TitleSep='-', const char ColSep=' ',
281  const char RowSep='\0', int Width=80) :
282  NRows_(NRows), TitleSep_(TitleSep), ColSep_(ColSep),
283  RowSep_(RowSep), Width_(Width), TokenSep_("RMRStringSepRMR") {
284  }
285 
288  }
289 };
290 
291 
292 
293 
294 
296 template <typename T1, typename T2, typename T3, typename T4, typename T5,
297  typename T6>
298 class TableSpecs:public TableSpecs<T2, T3, T4, T5, T6> {
299  private:
302  std::string TokenSep_;
303  protected:
305  T1* Data_;
306 
308  virtual bool IsBase() const {
309  return false;
310  }
311 
313  virtual int NCols() const {
314  int cols=BaseType::NCols();
315  return ++cols;
316  }
317 
319  virtual std::vector<std::string> Title() const {
320  return BaseType::Title();
321  }
322 
324  virtual std::vector<Align> Alignments() const {
325  return BaseType::Alignments();
326  }
327 
329  virtual int Width() const {
330  return BaseType::Width();
331  }
332 
334  virtual char RowSep() const {
335  return BaseType::RowSep();
336  }
337 
339  virtual char ColSep() const {
340  return BaseType::ColSep();
341  }
342 
344  virtual char TitleSep() const {
345  return BaseType::TitleSep();
346  }
347 
349  virtual int NRows() const {
350  return BaseType::NRows();
351  }
352 
354  virtual std::vector<int> ReqWidth()const{
355  return BaseType::ReqWidth();
356  }
357  public:
358 
360  virtual void SetTitles(const std::vector<std::string>& Titles) {
361  BaseType::SetTitles(Titles);
362  }
363 
365  virtual void SetWidths(const std::vector<int>& Widths){
366  BaseType::SetWidths(Widths);
367  }
368 
370  virtual void SetAlignments(const std::vector<Align>& Alignments) {
371  BaseType::SetAlignments(Alignments);
372  }
373 
374  virtual std::string Table()const;
375 
378  TitleSep='-', const char ColSep=' ', const char RowSep='\0',
379  int Width=80) :
380  Data_(NULL), TokenSep_("RMRStringSepRMR"),
382  Width) {}
383 
385  }
386 
388  void Init(T1* Data1, T2* Data2=NULL, T3* Data3=NULL, T4* Data4=NULL,
389  T5* Data5=NULL, T6* Data6=NULL) {
390  Data_=Data1;
391  if (Data2!=NULL) BaseType::Init(Data2, Data3, Data4, Data5, Data6);
392  }
393 
395  template<typename NotDouble>
396  std::string PrintData(const NotDouble Data)const{
397  std::stringstream RawData;
398  RawData<<Data<<" "<<TokenSep_<<" ";
399  return RawData.str();
400  }
401 
402 
403  std::string PrintData(const double Data)const{
404  std::stringstream RawData;
405  RawData<<std::fixed<<std::setprecision(16)<<Data<<" "<<TokenSep_<<" ";
406  return RawData.str();
407  }
408 
410  virtual std::string GetData(const int row) const {
411  std::stringstream RowData;
412  RowData<<PrintData(Data_[row]);
413  if (!BaseType::IsBase()) RowData<<BaseType::GetData(row);
414  return RowData.str();
415  }
416 
417 
418 };
419 
420 static inline std::string Alignment(const int Width, const std::string Text,
421  const Align& AlignType=CENTER) {
422  std::string ReturnString;
423  int TitleSize=Text.size();
424  if (TitleSize>Width) //Truncation of title, sorry
425  ReturnString=Text.substr(0, Width);
426  else {
427  int nspaces=Width-TitleSize;
428  int lspaces=0;
429  int rspaces=0;
430  if (AlignType==CENTER) {
431  lspaces=(nspaces-nspaces%2)/2+(nspaces%2);
432  rspaces=nspaces-lspaces;
433  }
434  else {
435  lspaces=(AlignType==LEFT ? 0 : nspaces);
436  rspaces=(AlignType==RIGHT ? 0 : nspaces);
437  }
438  std::string Lspaces(lspaces, ' ');
439  std::string Rspaces(rspaces, ' ');
440  ReturnString=Lspaces;
441  ReturnString+=Text;
442  ReturnString+=Rspaces;
443  }
444  return ReturnString;
445 }
446 
447 static inline std::string ParseSStream(std::stringstream& tokenizer,
448  const std::string& TokenSep) {
449  std::string line;
450  bool done=false;
451  int itr=0;
452  while (!done&&!tokenizer.eof()) {
453  std::string token;
454  tokenizer>>token;
455  if (token!=TokenSep){
456  if(itr++>=1)line+=" ";
457  line+=token;
458  }
459  else done=true;
460  }
461  return line;
462 
463 }
464 
465 static inline std::string MakeRow(const int ncols, std::stringstream& tokenizer,
466  const std::vector<Align>& Aligns, const std::vector<int>& ColspCell,
467  const char colsep, const std::string& TokenSep) {
468  std::stringstream DaTable;
469  for (int j=0; j<ncols-1; j++) {
470  std::string line=ParseSStream(tokenizer,TokenSep);
471  Align align=(Aligns.size()>0 ? Aligns[j] : CENTER);
472  DaTable<<Alignment(ColspCell[j], line, align)<<colsep;
473  }
474  std::string line=ParseSStream(tokenizer,TokenSep);
475  Align align=(Aligns.size()>0 ? Aligns.back() : CENTER);
476  DaTable<<Alignment(ColspCell.back(), line, align)<<std::endl;
477  return DaTable.str();
478 }
479 
480 
481 template <typename T1, typename T2, typename T3, typename T4, typename T5,
482  typename T6>
484  std::stringstream DaTable;//This will be the table
485 
487  int ncols=NCols();
489  std::vector<int> ColspCell=ReqWidth();
490  std::vector<bool> OrigSet(ncols,false);
491  int tempsize=ColspCell.size();
492  if(tempsize<ncols){
493  for(int i=0;i<(ncols-tempsize);i++)
494  ColspCell.push_back(0);
495  }
496  int nColsByUser=0;
497  int accountedforcolumns=0;
498  for(int i=0;i<ncols;i++){
499  if(ColspCell[i]!=0){
500  OrigSet[i]=true;
501  nColsByUser++;
502  accountedforcolumns+=ColspCell[i];
503  }
504  }
505  int width=Width();
506  int nseparators=ncols-1;
507  int EffWidth=width-nseparators-accountedforcolumns;
508  ncols-=nColsByUser;
509  if(ncols==0&&EffWidth!=0)throw
510  PSIEXCEPTION("You micro-managed the columns and didn't count"
511  "them out right, noob...");
512  int LeftOverCols=EffWidth%ncols;
513  int othercolumns=(EffWidth-LeftOverCols)/ncols;
514  ncols=NCols();
515  for(int i=0;i<ncols;i++){
516  if(!OrigSet[i])ColspCell[i]=othercolumns;
517  }
518  for (int i=0; i<LeftOverCols; i++)
519  if(!OrigSet[i])ColspCell[i]++;
520 
521  //Add the titles
522  std::vector<std::string>Titles=Title();
523  std::vector<Align>Aligns=Alignments();
524  int NTitleRows=Titles.size()/ncols;
525  char colsep=ColSep();
526  char rowsep='\0';
527  std::stringstream Buffer;
528  for (int i=0; i<Titles.size(); i++) {
529  Buffer<<Titles[i];
530  Buffer<<" "<<TokenSep_<<" ";
531  }
532 
533  //Titles
534  for (int i=0; i<NTitleRows; i++)
535  DaTable<<MakeRow(ncols, Buffer, Aligns, ColspCell, colsep, TokenSep_);
536 
537  //Title seperator
538  std::string FirstSep(width, TitleSep());
539  DaTable<<FirstSep<<std::endl;
540 
541  //Data
542  int nrows=NRows();
543  rowsep=RowSep();
544  for (int i=0; i<nrows; i++) {
545  std::stringstream tokenizer(GetData(i));
546  DaTable<<MakeRow(ncols, tokenizer, Aligns, ColspCell, colsep, TokenSep_);
547  if (rowsep!='\0') {
548  std::string RowSep(width, rowsep);
549  DaTable<<RowSep<<std::endl;
550  }
551  }
552  return DaTable.str();
553  }
554 
555 
556 } //End namespace psi
557 #endif /* TABLESPECS_H_ */
TableSpecs will hold all the data needed to print a table out.
Definition: TableSpecs.h:188
virtual void SetWidths(const std::vector< int > &Widths)
Sets the width of each column.
Definition: TableSpecs.h:365
void SetWidths(const std::vector< int > &Widths)
Sets the width of each column.
Definition: TableSpecs.h:261
virtual std::vector< Align > Alignments() const
Returns the Alignment vector.
Definition: TableSpecs.h:324
virtual std::string GetData(const int row) const
Returns the Data for row &quot;row&quot; as a string (non-EOL terminated)
Definition: TableSpecs.h:410
virtual std::string Table() const
Definition: TableSpecs.h:483
std::string TokenSep_
Definition: TableSpecs.h:302
T1 * Data_
This class does not take ownership of your data.
Definition: TableSpecs.h:305
virtual bool IsBase() const
Tells us we are no longer the base recursion class.
Definition: TableSpecs.h:308
virtual bool IsBase() const
Returns true because this is the base.
Definition: TableSpecs.h:198
Definition: liboptions.h:250
virtual void SetTitles(const std::vector< std::string > &Titles)
Sets the titles.
Definition: TableSpecs.h:360
Definition: pointgrp.h:105
virtual std::vector< std::string > Title() const
Definition: TableSpecs.h:210
int NRows_
The number of rows.
Definition: TableSpecs.h:203
std::vector< int > ReqWidth_
This is the user requested widths, value of 0 means calculate it.
Definition: TableSpecs.h:245
int Width_
This is the width (in columns) of the table, defaults to 80.
Definition: TableSpecs.h:239
static std::string ParseSStream(std::stringstream &tokenizer, const std::string &TokenSep)
Definition: TableSpecs.h:447
std::string PrintData(const double Data) const
Definition: TableSpecs.h:403
std::vector< Align > Alignments_
This is the alignment of each column.
Definition: TableSpecs.h:215
virtual char RowSep() const
Definition: TableSpecs.h:234
void SetAlignments(const std::vector< Align > &Alignments)
Sets the alignment of the columns.
Definition: TableSpecs.h:256
virtual int NRows() const
Returns the number of rows.
Definition: TableSpecs.h:349
std::vector< std::string > Title_
This is the title of the column, just stored in general class.
Definition: TableSpecs.h:209
virtual int Width() const
Definition: TableSpecs.h:240
Definition: TableSpecs.h:40
Definition: TableSpecs.h:40
char ColSep_
This is the column separator character, defaults to &quot; &quot;.
Definition: TableSpecs.h:227
std::string PrintData(const NotDouble Data) const
Overloaded function to catch doubles.
Definition: TableSpecs.h:396
virtual char TitleSep() const
Returns the Title separator.
Definition: TableSpecs.h:344
static std::string MakeRow(const int ncols, std::stringstream &tokenizer, const std::vector< Align > &Aligns, const std::vector< int > &ColspCell, const char colsep, const std::string &TokenSep)
Definition: TableSpecs.h:465
virtual char ColSep() const
Definition: TableSpecs.h:228
As the name implies this a NULL class.
Definition: TableSpecs.h:35
void SetTitles(const std::vector< std::string > &Titles)
Sets the titles.
Definition: TableSpecs.h:251
virtual std::vector< Align > Alignments() const
Definition: TableSpecs.h:216
virtual std::string GetData(int row) const
Returns a NULL string.
Definition: TableSpecs.h:265
static std::string Alignment(const int Width, const std::string Text, const Align &AlignType=CENTER)
Definition: TableSpecs.h:420
virtual int NRows() const
Definition: TableSpecs.h:204
virtual char TitleSep() const
Definition: TableSpecs.h:222
char TitleSep_
This is the Title separator character, defaults to &#39;-&#39;.
Definition: TableSpecs.h:221
TableSpecs< T2, T3, T4, T5, T6 > BaseType
Typedef of the base for compactness.
Definition: TableSpecs.h:301
virtual void SetAlignments(const std::vector< Align > &Alignments)
Sets the alignment of the columns.
Definition: TableSpecs.h:370
virtual char RowSep() const
Returns the RowSeparator.
Definition: TableSpecs.h:334
virtual std::vector< std::string > Title() const
Returns the title vector.
Definition: TableSpecs.h:319
void Init(void *Data1=NULL, void *Data2=NULL, void *Data3=NULL, void *Data4=NULL, void *Data5=NULL, void *Data6=NULL) const
This fxn should never be called, but is needed so that it compiles.
Definition: TableSpecs.h:275
virtual std::vector< int > ReqWidth() const
Returns the requested width of the column.
Definition: TableSpecs.h:354
virtual int NCols() const
Returns the number of columns.
Definition: TableSpecs.h:313
void Init(T1 *Data1, T2 *Data2=NULL, T3 *Data3=NULL, T4 *Data4=NULL, T5 *Data5=NULL, T6 *Data6=NULL)
The call that actually initializes this class.
Definition: TableSpecs.h:388
virtual int Width() const
Returns the width.
Definition: TableSpecs.h:329
char RowSep_
This is the separator between rows, defaults to null string.
Definition: TableSpecs.h:233
virtual char ColSep() const
Returns the Column separator.
Definition: TableSpecs.h:339
#define PSIEXCEPTION(message)
Definition: exception.h:47
virtual std::vector< int > ReqWidth() const
Definition: TableSpecs.h:246
virtual int NCols() const
Returns the number of columns.
Definition: TableSpecs.h:270
Definition: TableSpecs.h:40
Align
Enumerations of the possible alignments.
Definition: TableSpecs.h:39