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