Reference documentation for deal.II version 9.0.0
table_handler.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2017 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_table_handler_h
17 #define dealii_table_handler_h
18 
19 
20 #include <deal.II/base/config.h>
21 #include <deal.II/base/exceptions.h>
22 
23 #include <map>
24 #include <vector>
25 #include <string>
26 #include <fstream>
27 
28 #include <ostream>
29 
30 #include <boost/variant.hpp>
31 #include <boost/serialization/map.hpp>
32 #include <boost/serialization/string.hpp>
33 #include <boost/serialization/vector.hpp>
34 #include <boost/serialization/split_member.hpp>
35 
36 
37 DEAL_II_NAMESPACE_OPEN
38 
39 class TableHandler;
40 
41 namespace internal
42 {
51  struct TableEntry
52  {
53  public:
57  TableEntry () = default;
58 
63  template <typename T>
64  TableEntry (const T &t);
65 
72  template <typename T>
73  T get () const;
74 
81  double get_numeric_value () const;
82 
90  void cache_string(bool scientific, unsigned int precision) const;
91 
96  const std::string &get_cached_string() const;
97 
98 
105 
110  template <class Archive>
111  void save (Archive &ar, const unsigned int version) const;
112 
117  template <class Archive>
118  void load (Archive &ar, const unsigned int version);
119 
120  BOOST_SERIALIZATION_SPLIT_MEMBER()
121 
122  private:
126  typedef boost::variant<int,unsigned int,unsigned long long int,double,std::string> value_type;
127 
132 
136  mutable std::string cached_value;
137 
138  friend class ::TableHandler;
139  };
140 }
141 
142 
263 {
264 public:
324  {
342  };
343 
347  TableHandler ();
348 
349 
371  void declare_column (const std::string &key);
372 
379  template <typename T>
380  void add_value (const std::string &key,
381  const T value);
382 
396  void start_new_row ();
397 
402  void set_auto_fill_mode (const bool state);
403 
416  void add_column_to_supercolumn (const std::string &key,
417  const std::string &superkey);
418 
435  void set_column_order (const std::vector<std::string> &new_order);
436 
442  void set_precision (const std::string &key,
443  const unsigned int precision);
444 
449  void set_scientific (const std::string &key,
450  const bool scientific);
451 
457  void set_tex_caption (const std::string &key,
458  const std::string &tex_caption);
459 
463  void set_tex_table_caption (const std::string &table_caption);
464 
468  void set_tex_table_label (const std::string &table_label);
469 
475  void set_tex_supercaption (const std::string &superkey,
476  const std::string &tex_supercaption);
477 
484  void set_tex_format (const std::string &key,
485  const std::string &format="c");
486 
498  void write_text (std::ostream &out,
499  const TextOutputFormat format = table_with_headers) const;
500 
508  void write_tex (std::ostream &file, const bool with_header=true) const;
509 
514  void clear ();
515 
521  void clear_current_row ();
522 
527  template <class Archive>
528  void serialize(Archive &ar, const unsigned int version);
529 
539  std::string,
540  << "Column <" << arg1 << "> does not exist.");
541 
546  std::string,
547  << "Supercolumn <" << arg1 << "> does not exist.");
548 
553  std::string,
554  << "Column or supercolumn <" << arg1 << "> does not exist.");
555 
560  std::string, int, std::string, int,
561  << "Column <" << arg1 << "> has " << arg2
562  << " rows, but Column <" << arg3 << "> has " << arg4 << " rows.");
563 
568  std::string,
569  << "<" << arg1 << "> is not a tex column format. Use "
570  << "'l', 'c', or 'r' to indicate left, centered, or "
571  << "right aligned text.");
573 protected:
574 
579  struct Column
580  {
584  Column ();
585 
589  Column (const std::string &tex_caption);
590 
595  void pad_column_below (const unsigned int length);
596 
601  template <class Archive>
602  void save(Archive &ar, const unsigned int version) const;
603  template <class Archive>
604  void load(Archive &ar, const unsigned int version);
605  BOOST_SERIALIZATION_SPLIT_MEMBER()
606 
607 
608 
612  void invalidate_cache();
613 
618  std::vector<internal::TableEntry> entries;
619 
626  std::string tex_caption;
627 
635  std::string tex_format;
636 
641  unsigned int precision;
642 
647 
655  unsigned int flag;
656 
661  unsigned int max_length;
662  };
663 
672  void get_selected_columns (std::vector<std::string> &sel_columns) const;
673 
679  unsigned int n_rows() const;
680 
686  std::vector<std::string> column_order;
687 
695  mutable std::map<std::string,Column> columns;
696 
705  std::map<std::string, std::vector<std::string> > supercolumns;
706 
714  std::map<std::string, std::string> tex_supercaptions;
715 
719  std::string tex_table_caption;
723  std::string tex_table_label;
724 
729 };
730 
731 
732 namespace internal
733 {
734  template <typename T>
736  :
737  value (t)
738  {}
739 
740 
741  template <typename T>
742  T TableEntry::get () const
743  {
744  // we don't quite know the data type in 'value', but
745  // it must be one of the ones in the type list of the
746  // boost::variant. so if T is not in the list, or if
747  // the data stored in the TableEntry is not of type
748  // T, then we will get an exception that we can
749  // catch and produce an error message
750  try
751  {
752  return boost::get<T>(value);
753  }
754  catch (...)
755  {
756  Assert(false, ExcMessage ("This TableEntry object does not store a datum of type T"));
757  throw;
758  }
759  }
760 
761 
762 
763  template <class Archive>
764  void TableEntry::save (Archive &ar,
765  const unsigned int) const
766  {
767  // write first an identifier for the kind
768  // of data stored and then the actual
769  // data, in its correct data type
770  if (const int *p = boost::get<int>(&value))
771  {
772  char c = 'i';
773  ar &c & *p;
774  }
775  else if (const unsigned int *p = boost::get<unsigned int>(&value))
776  {
777  char c = 'u';
778  ar &c & *p;
779  }
780  else if (const double *p = boost::get<double>(&value))
781  {
782  char c = 'd';
783  ar &c & *p;
784  }
785  else if (const std::string *p = boost::get<std::string>(&value))
786  {
787  char c = 's';
788  ar &c & *p;
789  }
790  else if (const unsigned long long int *p = boost::get<unsigned long long int>(&value))
791  {
792  char c = 'l';
793  ar &c & *p;
794  }
795  else
796  Assert (false, ExcInternalError());
797  }
798 
799 
800 
801  template <class Archive>
802  void TableEntry::load (Archive &ar,
803  const unsigned int)
804  {
805  // following what we do in the save()
806  // function, first read in the data type
807  // as a one-character id, and then read
808  // the data
809  char c;
810  ar &c;
811 
812  switch (c)
813  {
814  case 'i':
815  {
816  int val;
817  ar &val;
818  value = val;
819  break;
820  }
821 
822  case 'u':
823  {
824  unsigned int val;
825  ar &val;
826  value = val;
827  break;
828  }
829 
830  case 'd':
831  {
832  double val;
833  ar &val;
834  value = val;
835  break;
836  }
837 
838  case 's':
839  {
840  std::string val;
841  ar &val;
842  value = val;
843  break;
844  }
845 
846  case 'l':
847  {
848  unsigned long long int val;
849  ar &val;
850  value = val;
851  break;
852  }
853 
854  default:
855  Assert (false, ExcInternalError());
856  }
857  }
858 }
859 
860 
861 
862 template <typename T>
863 void TableHandler::add_value (const std::string &key,
864  const T value)
865 {
866  // see if the column already exists
867  if (columns.find(key) == columns.end())
868  declare_column (key);
869 
870  if (auto_fill_mode == true)
871  {
872  // follow the algorithm given in the introduction to this class
873  // of padding columns as necessary
874  unsigned int max_col_length = 0;
875  for (std::map< std::string, Column >::iterator p = columns.begin(); p != columns.end(); ++p)
876  max_col_length = std::max(max_col_length,
877  static_cast<unsigned int>(p->second.entries.size()));
878 
879  while (columns[key].entries.size()+1 < max_col_length)
880  {
881  columns[key].entries.push_back (internal::TableEntry(T()));
882  internal::TableEntry &entry = columns[key].entries.back();
883  entry.cache_string(columns[key].scientific, columns[key].precision);
884  columns[key].max_length = std::max(columns[key].max_length, static_cast<unsigned int>(entry.get_cached_string().length()));
885  }
886  }
887 
888  // now push the value given to this function
889  columns[key].entries.push_back (internal::TableEntry(value));
890  internal::TableEntry &entry = columns[key].entries.back();
891  entry.cache_string(columns[key].scientific, columns[key].precision);
892  columns[key].max_length = std::max(columns[key].max_length,
893  static_cast<unsigned int>(entry.get_cached_string().length()));
894 }
895 
896 
897 
898 template <class Archive>
899 void
900 TableHandler::Column::save(Archive &ar, const unsigned int /*version*/) const
901 {
902  ar &entries &tex_caption
904  & scientific
905  & flag
906  & max_length;
907 }
908 
909 
910 
911 template <class Archive>
912 void
913 TableHandler::Column::load(Archive &ar, const unsigned int /*version*/)
914 {
915  ar &entries &tex_caption
916  & tex_format &precision
917  & scientific
918  & flag
919  & max_length;
920  invalidate_cache();
921 }
922 
923 
924 template <class Archive>
925 void
927  const unsigned int)
928 {
929  ar &column_order &columns
933  & auto_fill_mode;
934 }
935 
936 
937 DEAL_II_NAMESPACE_CLOSE
938 
939 #endif
std::map< std::string, std::string > tex_supercaptions
void set_precision(const std::string &key, const unsigned int precision)
void declare_column(const std::string &key)
unsigned int max_length
void save(Archive &ar, const unsigned int version) const
void set_tex_supercaption(const std::string &superkey, const std::string &tex_supercaption)
static ::ExceptionBase & ExcColumnOrSuperColumnNotExistent(std::string arg1)
void add_value(const std::string &key, const T value)
const std::string & get_cached_string() const
void set_tex_caption(const std::string &key, const std::string &tex_caption)
void cache_string(bool scientific, unsigned int precision) const
void add_column_to_supercolumn(const std::string &key, const std::string &superkey)
void set_tex_format(const std::string &key, const std::string &format="c")
void get_selected_columns(std::vector< std::string > &sel_columns) const
static ::ExceptionBase & ExcSuperColumnNotExistent(std::string arg1)
static ::ExceptionBase & ExcWrongNumberOfDataEntries(std::string arg1, int arg2, std::string arg3, int arg4)
void load(Archive &ar, const unsigned int version)
std::vector< std::string > column_order
std::string tex_format
static ::ExceptionBase & ExcMessage(std::string arg1)
std::string tex_table_caption
double get_numeric_value() const
TableEntry get_default_constructed_copy() const
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:346
void write_text(std::ostream &out, const TextOutputFormat format=table_with_headers) const
std::string cached_value
#define Assert(cond, exc)
Definition: exceptions.h:1142
void save(Archive &ar, const unsigned int version) const
void set_tex_table_label(const std::string &table_label)
unsigned int precision
void write_tex(std::ostream &file, const bool with_header=true) const
void clear_current_row()
boost::variant< int, unsigned int, unsigned long long int, double, std::string > value_type
static ::ExceptionBase & ExcUndefinedTexFormat(std::string arg1)
void set_column_order(const std::vector< std::string > &new_order)
void set_scientific(const std::string &key, const bool scientific)
void pad_column_below(const unsigned int length)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:382
static ::ExceptionBase & ExcColumnNotExistent(std::string arg1)
void serialize(Archive &ar, const unsigned int version)
std::vector< internal::TableEntry > entries
std::map< std::string, Column > columns
unsigned int n_rows() const
void start_new_row()
std::string tex_caption
void set_tex_table_caption(const std::string &table_caption)
std::map< std::string, std::vector< std::string > > supercolumns
std::string tex_table_label
static ::ExceptionBase & ExcInternalError()
void set_auto_fill_mode(const bool state)