Reference documentation for deal.II version 9.1.1
\(\newcommand{\dealcoloneq}{\mathrel{\vcenter{:}}=}\)
table_handler.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2019 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.md at
12 // the top level directory of deal.II.
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 
22 #include <deal.II/base/exceptions.h>
23 
24 #include <boost/serialization/map.hpp>
25 #include <boost/serialization/split_member.hpp>
26 #include <boost/serialization/string.hpp>
27 #include <boost/serialization/vector.hpp>
28 #include <boost/variant.hpp>
29 
30 #include <fstream>
31 #include <map>
32 #include <ostream>
33 #include <string>
34 #include <vector>
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
74  get() const;
75 
82  double
83  get_numeric_value() const;
84 
92  void
93  cache_string(bool scientific, unsigned int precision) const;
94 
99  const std::string &
100  get_cached_string() const;
101 
102 
108  TableEntry
110 
115  template <class Archive>
116  void
117  save(Archive &ar, const unsigned int version) const;
118 
123  template <class Archive>
124  void
125  load(Archive &ar, const unsigned int version);
126 
127  BOOST_SERIALIZATION_SPLIT_MEMBER()
128 
129  private:
133  using value_type = boost::
134  variant<int, unsigned int, unsigned long long int, double, std::string>;
135 
140 
144  mutable std::string cached_value;
145 
146  friend class ::TableHandler;
147  };
148 } // namespace internal
149 
150 
278 {
279 public:
339  {
357  };
358 
362  TableHandler();
363 
364 
386  void
387  declare_column(const std::string &key);
388 
395  template <typename T>
396  void
397  add_value(const std::string &key, const T value);
398 
412  void
413  start_new_row();
414 
419  void
420  set_auto_fill_mode(const bool state);
421 
434  void
435  add_column_to_supercolumn(const std::string &key,
436  const std::string &superkey);
437 
454  void
455  set_column_order(const std::vector<std::string> &new_order);
456 
462  void
463  set_precision(const std::string &key, const unsigned int precision);
464 
469  void
470  set_scientific(const std::string &key, const bool scientific);
471 
477  void
478  set_tex_caption(const std::string &key, const std::string &tex_caption);
479 
483  void
484  set_tex_table_caption(const std::string &table_caption);
485 
489  void
490  set_tex_table_label(const std::string &table_label);
491 
497  void
498  set_tex_supercaption(const std::string &superkey,
499  const std::string &tex_supercaption);
500 
507  void
508  set_tex_format(const std::string &key, const std::string &format = "c");
509 
521  void
522  write_text(std::ostream & out,
523  const TextOutputFormat format = table_with_headers) const;
524 
532  void
533  write_tex(std::ostream &file, const bool with_header = true) const;
534 
539  void
540  clear();
541 
547  void
549 
554  template <class Archive>
555  void
556  serialize(Archive &ar, const unsigned int version);
557 
567  std::string,
568  << "Column <" << arg1 << "> does not exist.");
569 
574  std::string,
575  << "Supercolumn <" << arg1 << "> does not exist.");
576 
581  std::string,
582  << "Column or supercolumn <" << arg1 << "> does not exist.");
583 
588  std::string,
589  int,
590  std::string,
591  int,
592  << "Column <" << arg1 << "> has " << arg2
593  << " rows, but Column <" << arg3 << "> has " << arg4
594  << " rows.");
595 
600  std::string,
601  << "<" << arg1 << "> is not a tex column format. Use "
602  << "'l', 'c', or 'r' to indicate left, centered, or "
603  << "right aligned text.");
605 protected:
610  struct Column
611  {
615  Column();
616 
620  Column(const std::string &tex_caption);
621 
626  void
627  pad_column_below(const unsigned int length);
628 
633  template <class Archive>
634  void
635  save(Archive &ar, const unsigned int version) const;
636  template <class Archive>
637  void
638  load(Archive &ar, const unsigned int version);
639  BOOST_SERIALIZATION_SPLIT_MEMBER()
640 
641 
642 
646  void
648 
653  std::vector<internal::TableEntry> entries;
654 
661  std::string tex_caption;
662 
670  std::string tex_format;
671 
676  unsigned int precision;
677 
682 
690  unsigned int flag;
691 
696  unsigned int max_length;
697  };
698 
707  void
708  get_selected_columns(std::vector<std::string> &sel_columns) const;
709 
715  unsigned int
716  n_rows() const;
717 
723  std::vector<std::string> column_order;
724 
732  mutable std::map<std::string, Column> columns;
733 
742  std::map<std::string, std::vector<std::string>> supercolumns;
743 
751  std::map<std::string, std::string> tex_supercaptions;
752 
756  std::string tex_table_caption;
760  std::string tex_table_label;
761 
766 };
767 
768 
769 namespace internal
770 {
771  template <typename T>
773  : value(t)
774  {}
775 
776 
777  template <typename T>
778  T
780  {
781  // we don't quite know the data type in 'value', but
782  // it must be one of the ones in the type list of the
783  // boost::variant. so if T is not in the list, or if
784  // the data stored in the TableEntry is not of type
785  // T, then we will get an exception that we can
786  // catch and produce an error message
787  try
788  {
789  return boost::get<T>(value);
790  }
791  catch (...)
792  {
793  Assert(false,
794  ExcMessage(
795  "This TableEntry object does not store a datum of type T"));
796  throw;
797  }
798  }
799 
800 
801 
802  template <class Archive>
803  void
804  TableEntry::save(Archive &ar, const unsigned int) const
805  {
806  // write first an identifier for the kind
807  // of data stored and then the actual
808  // data, in its correct data type
809  if (const int *p = boost::get<int>(&value))
810  {
811  char c = 'i';
812  ar &c &*p;
813  }
814  else if (const unsigned int *p = boost::get<unsigned int>(&value))
815  {
816  char c = 'u';
817  ar &c &*p;
818  }
819  else if (const double *p = boost::get<double>(&value))
820  {
821  char c = 'd';
822  ar &c &*p;
823  }
824  else if (const std::string *p = boost::get<std::string>(&value))
825  {
826  char c = 's';
827  ar &c &*p;
828  }
829  else if (const unsigned long long int *p =
830  boost::get<unsigned long long int>(&value))
831  {
832  char c = 'l';
833  ar &c &*p;
834  }
835  else
836  Assert(false, ExcInternalError());
837  }
838 
839 
840 
841  template <class Archive>
842  void
843  TableEntry::load(Archive &ar, const unsigned int)
844  {
845  // following what we do in the save()
846  // function, first read in the data type
847  // as a one-character id, and then read
848  // the data
849  char c;
850  ar & c;
851 
852  switch (c)
853  {
854  case 'i':
855  {
856  int val;
857  ar &val;
858  value = val;
859  break;
860  }
861 
862  case 'u':
863  {
864  unsigned int val;
865  ar & val;
866  value = val;
867  break;
868  }
869 
870  case 'd':
871  {
872  double val;
873  ar & val;
874  value = val;
875  break;
876  }
877 
878  case 's':
879  {
880  std::string val;
881  ar & val;
882  value = val;
883  break;
884  }
885 
886  case 'l':
887  {
888  unsigned long long int val;
889  ar & val;
890  value = val;
891  break;
892  }
893 
894  default:
895  Assert(false, ExcInternalError());
896  }
897  }
898 } // namespace internal
899 
900 
901 
902 template <typename T>
903 void
904 TableHandler::add_value(const std::string &key, const T value)
905 {
906  // see if the column already exists
907  if (columns.find(key) == columns.end())
908  declare_column(key);
909 
910  if (auto_fill_mode == true)
911  {
912  // follow the algorithm given in the introduction to this class
913  // of padding columns as necessary
914  unsigned int max_col_length = 0;
915  for (const auto &column : columns)
916  max_col_length =
917  std::max(max_col_length,
918  static_cast<unsigned int>(column.second.entries.size()));
919 
920  while (columns[key].entries.size() + 1 < max_col_length)
921  {
922  columns[key].entries.push_back(internal::TableEntry(T()));
923  internal::TableEntry &entry = columns[key].entries.back();
924  entry.cache_string(columns[key].scientific, columns[key].precision);
925  columns[key].max_length =
926  std::max(columns[key].max_length,
927  static_cast<unsigned int>(
928  entry.get_cached_string().length()));
929  }
930  }
931 
932  // now push the value given to this function
933  columns[key].entries.push_back(internal::TableEntry(value));
934  internal::TableEntry &entry = columns[key].entries.back();
935  entry.cache_string(columns[key].scientific, columns[key].precision);
936  columns[key].max_length =
937  std::max(columns[key].max_length,
938  static_cast<unsigned int>(entry.get_cached_string().length()));
939 }
940 
941 
942 
943 template <class Archive>
944 void
945 TableHandler::Column::save(Archive &ar, const unsigned int /*version*/) const
946 {
948 }
949 
950 
951 
952 template <class Archive>
953 void
954 TableHandler::Column::load(Archive &ar, const unsigned int /*version*/)
955 {
956  ar &entries &tex_caption &tex_format &precision &scientific &flag &max_length;
957  invalidate_cache();
958 }
959 
960 
961 template <class Archive>
962 void
963 TableHandler::serialize(Archive &ar, const unsigned int)
964 {
967 }
968 
969 
970 DEAL_II_NAMESPACE_CLOSE
971 
972 #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
boost::variant< int, unsigned int, unsigned long long int, double, std::string > value_type
void set_tex_supercaption(const std::string &superkey, const std::string &tex_supercaption)
std::map< std::string, Column > columns
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:518
void write_text(std::ostream &out, const TextOutputFormat format=table_with_headers) const
std::string cached_value
#define Assert(cond, exc)
Definition: exceptions.h:1407
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()
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:587
static ::ExceptionBase & ExcColumnNotExistent(std::string arg1)
void serialize(Archive &ar, const unsigned int version)
std::vector< internal::TableEntry > entries
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)