Reference documentation for deal.II version GIT 5743fb25e5 2023-09-22 04: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 - 2023 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 
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 
29 #include <fstream>
30 #include <map>
31 #include <ostream>
32 #include <string>
33 #include <variant>
34 #include <vector>
35 
36 
38 
39 // Forward declaration
40 #ifndef DOXYGEN
41 class TableHandler;
42 #endif
43 
44 namespace internal
45 {
54  struct TableEntry
55  {
56  public:
60  TableEntry() = default;
61 
66  template <typename T>
67  explicit TableEntry(const T &t);
68 
75  template <typename T>
76  T
77  get() const;
78 
85  double
86  get_numeric_value() const;
87 
95  void
96  cache_string(bool scientific, unsigned int precision) const;
97 
102  const std::string &
103  get_cached_string() const;
104 
105 
111  TableEntry
113 
119  template <class Archive>
120  void
121  save(Archive &ar, const unsigned int version) const;
122 
128  template <class Archive>
129  void
130  load(Archive &ar, const unsigned int version);
131 
132 #ifdef DOXYGEN
138  template <class Archive>
139  void
140  serialize(Archive &archive, const unsigned int version);
141 #else
142  // This macro defines the serialize() method that is compatible with
143  // the templated save() and load() method that have been implemented.
144  BOOST_SERIALIZATION_SPLIT_MEMBER()
145 #endif
146 
147  private:
151  using value_type =
152  std::variant<int, unsigned int, std::uint64_t, double, std::string>;
153 
158 
162  mutable std::string cached_value;
163 
164  friend class ::TableHandler;
165  };
166 } // namespace internal
167 
168 
294 {
295 public:
355  {
373  };
374 
378  TableHandler();
379 
380 
402  void
403  declare_column(const std::string &key);
404 
411  template <typename T>
412  void
413  add_value(const std::string &key, const T value);
414 
428  void
429  start_new_row();
430 
435  void
436  set_auto_fill_mode(const bool state);
437 
450  void
451  add_column_to_supercolumn(const std::string &key,
452  const std::string &superkey);
453 
470  void
471  set_column_order(const std::vector<std::string> &new_order);
472 
478  void
479  set_precision(const std::string &key, const unsigned int precision);
480 
485  void
486  set_scientific(const std::string &key, const bool scientific);
487 
493  void
494  set_tex_caption(const std::string &key, const std::string &tex_caption);
495 
499  void
500  set_tex_table_caption(const std::string &table_caption);
501 
505  void
506  set_tex_table_label(const std::string &table_label);
507 
513  void
514  set_tex_supercaption(const std::string &superkey,
515  const std::string &tex_supercaption);
516 
523  void
524  set_tex_format(const std::string &key, const std::string &format = "c");
525 
537  void
538  write_text(std::ostream &out,
539  const TextOutputFormat format = table_with_headers) const;
540 
548  void
549  write_tex(std::ostream &file, const bool with_header = true) const;
550 
555  void
556  clear();
557 
563  void
565 
571  template <class Archive>
572  void
573  serialize(Archive &ar, const unsigned int version);
574 
584  std::string,
585  << "Column <" << arg1 << "> does not exist.");
586 
591  std::string,
592  << "Supercolumn <" << arg1 << "> does not exist.");
593 
598  std::string,
599  << "Column or supercolumn <" << arg1 << "> does not exist.");
600 
605  std::string,
606  int,
607  std::string,
608  int,
609  << "Column <" << arg1 << "> has " << arg2
610  << " rows, but Column <" << arg3 << "> has " << arg4
611  << " rows.");
612 
617  std::string,
618  << '<' << arg1 << "> is not a tex column format. Use "
619  << "'l', 'c', or 'r' to indicate left, centered, or "
620  << "right aligned text.");
622 protected:
627  struct Column
628  {
632  Column();
633 
637  explicit Column(const std::string &tex_caption);
638 
643  void
644  pad_column_below(const unsigned int length);
645 
651  template <class Archive>
652  void
653  save(Archive &ar, const unsigned int version) const;
654 
660  template <class Archive>
661  void
662  load(Archive &ar, const unsigned int version);
663 
664 #ifdef DOXYGEN
670  template <class Archive>
671  void
672  serialize(Archive &archive, const unsigned int version);
673 #else
674  // This macro defines the serialize() method that is compatible with
675  // the templated save() and load() method that have been implemented.
676  BOOST_SERIALIZATION_SPLIT_MEMBER()
677 #endif
678 
679 
684  void
686 
691  std::vector<internal::TableEntry> entries;
692 
699  std::string tex_caption;
700 
708  std::string tex_format;
709 
714  unsigned int precision;
715 
720 
728  unsigned int flag;
729 
734  unsigned int max_length;
735  };
736 
745  void
746  get_selected_columns(std::vector<std::string> &sel_columns) const;
747 
753  unsigned int
754  n_rows() const;
755 
761  std::vector<std::string> column_order;
762 
770  mutable std::map<std::string, Column> columns;
771 
780  std::map<std::string, std::vector<std::string>> supercolumns;
781 
789  std::map<std::string, std::string> tex_supercaptions;
790 
794  std::string tex_table_caption;
798  std::string tex_table_label;
799 
804 };
805 
806 
807 namespace internal
808 {
809  template <typename T>
811  : value(t)
812  {}
813 
814 
815  template <typename T>
816  T
818  {
819  // we don't quite know the data type in 'value', but
820  // it must be one of the ones in the type list of the
821  // std::variant. so if T is not in the list, or if
822  // the data stored in the TableEntry is not of type
823  // T, then we will get an exception that we can
824  // catch and produce an error message
825  try
826  {
827  return std::get<T>(value);
828  }
829  catch (...)
830  {
831  Assert(false,
832  ExcMessage(
833  "This TableEntry object does not store a datum of type T"));
834  throw;
835  }
836  }
837 
838 
839 
840  template <class Archive>
841  void
842  TableEntry::save(Archive &ar, const unsigned int) const
843  {
844  // write first an identifier for the kind
845  // of data stored and then the actual
846  // data, in its correct data type
847  if (std::holds_alternative<int>(value))
848  {
849  const int p = std::get<int>(value);
850  char c = 'i';
851  ar &c &p;
852  }
853  else if (std::holds_alternative<unsigned int>(value))
854  {
855  const unsigned int p = std::get<unsigned int>(value);
856  char c = 'u';
857  ar &c &p;
858  }
859  else if (std::holds_alternative<double>(value))
860  {
861  const double p = std::get<double>(value);
862  char c = 'd';
863  ar &c &p;
864  }
865  else if (std::holds_alternative<std::string>(value))
866  {
867  const std::string p = std::get<std::string>(value);
868  char c = 's';
869  ar &c &p;
870  }
871  else if (std::holds_alternative<std::uint64_t>(value))
872  {
873  const std::uint64_t p = std::get<std::uint64_t>(value);
874  char c = 'l';
875  ar &c &p;
876  }
877  else
878  Assert(false, ExcInternalError());
879  }
880 
881 
882 
883  template <class Archive>
884  void
885  TableEntry::load(Archive &ar, const unsigned int)
886  {
887  // following what we do in the save()
888  // function, first read in the data type
889  // as a one-character id, and then read
890  // the data
891  char c;
892  ar &c;
893 
894  switch (c)
895  {
896  case 'i':
897  {
898  int val;
899  ar &val;
900  value = val;
901  break;
902  }
903 
904  case 'u':
905  {
906  unsigned int val;
907  ar &val;
908  value = val;
909  break;
910  }
911 
912  case 'd':
913  {
914  double val;
915  ar &val;
916  value = val;
917  break;
918  }
919 
920  case 's':
921  {
922  std::string val;
923  ar &val;
924  value = val;
925  break;
926  }
927 
928  case 'l':
929  {
930  std::uint64_t val;
931  ar &val;
932  value = val;
933  break;
934  }
935 
936  default:
937  Assert(false, ExcInternalError());
938  }
939  }
940 } // namespace internal
941 
942 
943 
944 template <typename T>
945 void
946 TableHandler::add_value(const std::string &key, const T value)
947 {
948  // see if the column already exists
949  if (columns.find(key) == columns.end())
950  declare_column(key);
951 
952  if (auto_fill_mode == true)
953  {
954  // follow the algorithm given in the introduction to this class
955  // of padding columns as necessary
956  unsigned int max_col_length = 0;
957  for (const auto &column : columns)
958  max_col_length =
959  std::max(max_col_length,
960  static_cast<unsigned int>(column.second.entries.size()));
961 
962  while (columns[key].entries.size() + 1 < max_col_length)
963  {
964  columns[key].entries.push_back(internal::TableEntry(T()));
965  internal::TableEntry &entry = columns[key].entries.back();
966  entry.cache_string(columns[key].scientific, columns[key].precision);
967  columns[key].max_length =
968  std::max(columns[key].max_length,
969  static_cast<unsigned int>(
970  entry.get_cached_string().size()));
971  }
972  }
973 
974  // now push the value given to this function
975  columns[key].entries.push_back(internal::TableEntry(value));
976  internal::TableEntry &entry = columns[key].entries.back();
977  entry.cache_string(columns[key].scientific, columns[key].precision);
978  columns[key].max_length =
979  std::max(columns[key].max_length,
980  static_cast<unsigned int>(entry.get_cached_string().size()));
981 }
982 
983 
984 
985 template <class Archive>
986 void
987 TableHandler::Column::save(Archive &ar, const unsigned int /*version*/) const
988 {
990 }
991 
992 
993 
994 template <class Archive>
995 void
996 TableHandler::Column::load(Archive &ar, const unsigned int /*version*/)
997 {
998  ar &entries &tex_caption &tex_format &precision &scientific &flag &max_length;
999  invalidate_cache();
1000 }
1001 
1002 
1003 template <class Archive>
1004 void
1005 TableHandler::serialize(Archive &ar, const unsigned int)
1006 {
1009 }
1010 
1011 
1013 
1014 #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)
unsigned int n_rows() const
void get_selected_columns(std::vector< std::string > &sel_columns) const
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
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)
std::vector< std::string > column_order
void set_tex_table_label(const std::string &table_label)
void set_precision(const std::string &key, const unsigned int precision)
std::map< std::string, Column > columns
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:477
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:478
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:581
static ::ExceptionBase & ExcColumnOrSuperColumnNotExistent(std::string arg1)
static ::ExceptionBase & ExcSuperColumnNotExistent(std::string arg1)
static ::ExceptionBase & ExcWrongNumberOfDataEntries(std::string arg1, int arg2, std::string arg3, int arg4)
#define Assert(cond, exc)
Definition: exceptions.h:1616
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:512
static ::ExceptionBase & ExcMessage(std::string arg1)
static const char T
void pad_column_below(const unsigned int length)
void serialize(Archive &archive, const unsigned int version)
void save(Archive &ar, const unsigned int version) const
unsigned int max_length
unsigned int precision
void load(Archive &ar, const unsigned int version)
std::string tex_format
std::vector< internal::TableEntry > entries
std::string tex_caption
void serialize(Archive &archive, const unsigned int version)
TableEntry get_default_constructed_copy() const
void load(Archive &ar, const unsigned int version)
void save(Archive &ar, const unsigned int version) const
std::string cached_value
const std::string & get_cached_string() const
double get_numeric_value() const
std::variant< int, unsigned int, std::uint64_t, double, std::string > value_type
void cache_string(bool scientific, unsigned int precision) const