Reference documentation for deal.II version GIT 2c37b3e359 2022-05-26 00:10:02+00:00
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
table_handler.h
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2022 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 
24 
26 #include <boost/serialization/map.hpp>
27 #include <boost/serialization/split_member.hpp>
28 #include <boost/serialization/string.hpp>
29 #include <boost/serialization/vector.hpp>
31 
32 #include <fstream>
33 #include <map>
34 #include <ostream>
35 #include <string>
36 #include <vector>
37 
38 
40 
41 // Forward declaration
42 #ifndef DOXYGEN
43 class TableHandler;
44 #endif
45 
46 namespace internal
47 {
56  struct TableEntry
57  {
58  public:
62  TableEntry() = default;
63 
68  template <typename T>
69  TableEntry(const T &t);
70 
77  template <typename T>
78  T
79  get() const;
80 
87  double
88  get_numeric_value() const;
89 
97  void
98  cache_string(bool scientific, unsigned int precision) const;
99 
104  const std::string &
105  get_cached_string() const;
106 
107 
113  TableEntry
115 
121  template <class Archive>
122  void
123  save(Archive &ar, const unsigned int version) const;
124 
130  template <class Archive>
131  void
132  load(Archive &ar, const unsigned int version);
133 
134 #ifdef DOXYGEN
140  template <class Archive>
141  void
142  serialize(Archive &archive, const unsigned int version);
143 #else
144  // This macro defines the serialize() method that is compatible with
145  // the templated save() and load() method that have been implemented.
146  BOOST_SERIALIZATION_SPLIT_MEMBER()
147 #endif
148 
149  private:
153  using value_type =
154  std_cxx17::variant<int, unsigned int, std::uint64_t, double, std::string>;
155 
160 
164  mutable std::string cached_value;
165 
166  friend class ::TableHandler;
167  };
168 } // namespace internal
169 
170 
296 {
297 public:
357  {
375  };
376 
380  TableHandler();
381 
382 
404  void
405  declare_column(const std::string &key);
406 
413  template <typename T>
414  void
415  add_value(const std::string &key, const T value);
416 
430  void
431  start_new_row();
432 
437  void
438  set_auto_fill_mode(const bool state);
439 
452  void
453  add_column_to_supercolumn(const std::string &key,
454  const std::string &superkey);
455 
472  void
473  set_column_order(const std::vector<std::string> &new_order);
474 
480  void
481  set_precision(const std::string &key, const unsigned int precision);
482 
487  void
488  set_scientific(const std::string &key, const bool scientific);
489 
495  void
496  set_tex_caption(const std::string &key, const std::string &tex_caption);
497 
501  void
502  set_tex_table_caption(const std::string &table_caption);
503 
507  void
508  set_tex_table_label(const std::string &table_label);
509 
515  void
516  set_tex_supercaption(const std::string &superkey,
517  const std::string &tex_supercaption);
518 
525  void
526  set_tex_format(const std::string &key, const std::string &format = "c");
527 
539  void
540  write_text(std::ostream & out,
541  const TextOutputFormat format = table_with_headers) const;
542 
550  void
551  write_tex(std::ostream &file, const bool with_header = true) const;
552 
557  void
558  clear();
559 
565  void
567 
573  template <class Archive>
574  void
575  serialize(Archive &ar, const unsigned int version);
576 
586  std::string,
587  << "Column <" << arg1 << "> does not exist.");
588 
593  std::string,
594  << "Supercolumn <" << arg1 << "> does not exist.");
595 
600  std::string,
601  << "Column or supercolumn <" << arg1 << "> does not exist.");
602 
607  std::string,
608  int,
609  std::string,
610  int,
611  << "Column <" << arg1 << "> has " << arg2
612  << " rows, but Column <" << arg3 << "> has " << arg4
613  << " rows.");
614 
619  std::string,
620  << '<' << arg1 << "> is not a tex column format. Use "
621  << "'l', 'c', or 'r' to indicate left, centered, or "
622  << "right aligned text.");
624 protected:
629  struct Column
630  {
634  Column();
635 
639  Column(const std::string &tex_caption);
640 
645  void
646  pad_column_below(const unsigned int length);
647 
653  template <class Archive>
654  void
655  save(Archive &ar, const unsigned int version) const;
656 
662  template <class Archive>
663  void
664  load(Archive &ar, const unsigned int version);
665 
666 #ifdef DOXYGEN
672  template <class Archive>
673  void
674  serialize(Archive &archive, const unsigned int version);
675 #else
676  // This macro defines the serialize() method that is compatible with
677  // the templated save() and load() method that have been implemented.
678  BOOST_SERIALIZATION_SPLIT_MEMBER()
679 #endif
680 
681 
686  void
688 
693  std::vector<internal::TableEntry> entries;
694 
701  std::string tex_caption;
702 
710  std::string tex_format;
711 
716  unsigned int precision;
717 
722 
730  unsigned int flag;
731 
736  unsigned int max_length;
737  };
738 
747  void
748  get_selected_columns(std::vector<std::string> &sel_columns) const;
749 
755  unsigned int
756  n_rows() const;
757 
763  std::vector<std::string> column_order;
764 
772  mutable std::map<std::string, Column> columns;
773 
782  std::map<std::string, std::vector<std::string>> supercolumns;
783 
791  std::map<std::string, std::string> tex_supercaptions;
792 
796  std::string tex_table_caption;
800  std::string tex_table_label;
801 
806 };
807 
808 
809 namespace internal
810 {
811  template <typename T>
813  : value(t)
814  {}
815 
816 
817  template <typename T>
818  T
820  {
821  // we don't quite know the data type in 'value', but
822  // it must be one of the ones in the type list of the
823  // std_cxx17::variant. so if T is not in the list, or if
824  // the data stored in the TableEntry is not of type
825  // T, then we will get an exception that we can
826  // catch and produce an error message
827  try
828  {
829  return std_cxx17::get<T>(value);
830  }
831  catch (...)
832  {
833  Assert(false,
834  ExcMessage(
835  "This TableEntry object does not store a datum of type T"));
836  throw;
837  }
838  }
839 
840 
841 
842  template <class Archive>
843  void
844  TableEntry::save(Archive &ar, const unsigned int) const
845  {
846  // write first an identifier for the kind
847  // of data stored and then the actual
848  // data, in its correct data type
849  if (std_cxx17::holds_alternative<int>(value))
850  {
851  const int p = std_cxx17::get<int>(value);
852  char c = 'i';
853  ar &c &p;
854  }
855  else if (std_cxx17::holds_alternative<unsigned int>(value))
856  {
857  const unsigned int p = std_cxx17::get<unsigned int>(value);
858  char c = 'u';
859  ar &c &p;
860  }
861  else if (std_cxx17::holds_alternative<double>(value))
862  {
863  const double p = std_cxx17::get<double>(value);
864  char c = 'd';
865  ar &c &p;
866  }
867  else if (std_cxx17::holds_alternative<std::string>(value))
868  {
869  const std::string p = std_cxx17::get<std::string>(value);
870  char c = 's';
871  ar &c &p;
872  }
873  else if (std_cxx17::holds_alternative<std::uint64_t>(value))
874  {
875  const std::uint64_t p = std_cxx17::get<std::uint64_t>(value);
876  char c = 'l';
877  ar &c &p;
878  }
879  else
880  Assert(false, ExcInternalError());
881  }
882 
883 
884 
885  template <class Archive>
886  void
887  TableEntry::load(Archive &ar, const unsigned int)
888  {
889  // following what we do in the save()
890  // function, first read in the data type
891  // as a one-character id, and then read
892  // the data
893  char c;
894  ar & c;
895 
896  switch (c)
897  {
898  case 'i':
899  {
900  int val;
901  ar &val;
902  value = val;
903  break;
904  }
905 
906  case 'u':
907  {
908  unsigned int val;
909  ar & val;
910  value = val;
911  break;
912  }
913 
914  case 'd':
915  {
916  double val;
917  ar & val;
918  value = val;
919  break;
920  }
921 
922  case 's':
923  {
924  std::string val;
925  ar & val;
926  value = val;
927  break;
928  }
929 
930  case 'l':
931  {
932  std::uint64_t val;
933  ar & val;
934  value = val;
935  break;
936  }
937 
938  default:
939  Assert(false, ExcInternalError());
940  }
941  }
942 } // namespace internal
943 
944 
945 
946 template <typename T>
947 void
948 TableHandler::add_value(const std::string &key, const T value)
949 {
950  // see if the column already exists
951  if (columns.find(key) == columns.end())
952  declare_column(key);
953 
954  if (auto_fill_mode == true)
955  {
956  // follow the algorithm given in the introduction to this class
957  // of padding columns as necessary
958  unsigned int max_col_length = 0;
959  for (const auto &column : columns)
960  max_col_length =
961  std::max(max_col_length,
962  static_cast<unsigned int>(column.second.entries.size()));
963 
964  while (columns[key].entries.size() + 1 < max_col_length)
965  {
966  columns[key].entries.push_back(internal::TableEntry(T()));
967  internal::TableEntry &entry = columns[key].entries.back();
968  entry.cache_string(columns[key].scientific, columns[key].precision);
969  columns[key].max_length =
970  std::max(columns[key].max_length,
971  static_cast<unsigned int>(
972  entry.get_cached_string().size()));
973  }
974  }
975 
976  // now push the value given to this function
977  columns[key].entries.push_back(internal::TableEntry(value));
978  internal::TableEntry &entry = columns[key].entries.back();
979  entry.cache_string(columns[key].scientific, columns[key].precision);
980  columns[key].max_length =
981  std::max(columns[key].max_length,
982  static_cast<unsigned int>(entry.get_cached_string().size()));
983 }
984 
985 
986 
987 template <class Archive>
988 void
989 TableHandler::Column::save(Archive &ar, const unsigned int /*version*/) const
990 {
992 }
993 
994 
995 
996 template <class Archive>
997 void
998 TableHandler::Column::load(Archive &ar, const unsigned int /*version*/)
999 {
1000  ar &entries &tex_caption &tex_format &precision &scientific &flag &max_length;
1001  invalidate_cache();
1002 }
1003 
1004 
1005 template <class Archive>
1006 void
1007 TableHandler::serialize(Archive &ar, const unsigned int)
1008 {
1011 }
1012 
1013 
1015 
1016 #endif
void set_tex_format(const std::string &key, const std::string &format="c")
void start_new_row()
void set_tex_table_caption(const std::string &table_caption)
void set_tex_supercaption(const std::string &superkey, const std::string &tex_supercaption)
void serialize(Archive &ar, const unsigned int version)
void declare_column(const std::string &key)
void write_text(std::ostream &out, const TextOutputFormat format=table_with_headers) const
void set_auto_fill_mode(const bool state)
void add_value(const std::string &key, const T value)
void write_tex(std::ostream &file, const bool with_header=true) const
void add_column_to_supercolumn(const std::string &key, const std::string &superkey)
void set_column_order(const std::vector< std::string > &new_order)
void set_tex_caption(const std::string &key, const std::string &tex_caption)
void clear_current_row()
void set_scientific(const std::string &key, const bool scientific)
void set_tex_table_label(const std::string &table_label)
void set_precision(const std::string &key, const unsigned int precision)
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:416
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
Definition: config.h:430
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:417
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
Definition: config.h:469
static ::ExceptionBase & ExcColumnNotExistent(std::string arg1)
static ::ExceptionBase & ExcUndefinedTexFormat(std::string arg1)
static ::ExceptionBase & ExcInternalError()
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:578
void load(Archive &ar, const unsigned int version)
void save(Archive &ar, const unsigned int version) const
void pad_column_below(const unsigned int length)
void serialize(Archive &archive, const unsigned int version)
static ::ExceptionBase & ExcColumnOrSuperColumnNotExistent(std::string arg1)
void save(Archive &ar, const unsigned int version) const
static ::ExceptionBase & ExcSuperColumnNotExistent(std::string arg1)
unsigned int n_rows() const
void get_selected_columns(std::vector< std::string > &sel_columns) const
static ::ExceptionBase & ExcWrongNumberOfDataEntries(std::string arg1, int arg2, std::string arg3, int arg4)
#define Assert(cond, exc)
Definition: exceptions.h:1473
std::map< std::string, std::vector< std::string > > supercolumns
@ simple_table_with_separate_column_description
@ table_with_separate_column_description
std::map< std::string, std::string > tex_supercaptions
std::string tex_table_label
std::string tex_table_caption
unsigned int max_length
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:509
unsigned int precision
void load(Archive &ar, const unsigned int version)
std::string tex_format
static ::ExceptionBase & ExcMessage(std::string arg1)
std::vector< std::string > column_order
std::vector< internal::TableEntry > entries
std::string tex_caption
std::map< std::string, Column > columns
static const char T
void serialize(Archive &archive, const unsigned int version)
TableEntry get_default_constructed_copy() const
std::string cached_value
const std::string & get_cached_string() const
double get_numeric_value() const
void cache_string(bool scientific, unsigned int precision) const
std_cxx17::variant< int, unsigned int, std::uint64_t, double, std::string > value_type