Reference documentation for deal.II version 9.3.0
\(\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 - 2021 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 
25 #include <boost/serialization/map.hpp>
26 #include <boost/serialization/split_member.hpp>
27 #include <boost/serialization/string.hpp>
28 #include <boost/serialization/vector.hpp>
29 #include <boost/variant.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
135 
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  boost::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  {
374  org_mode_table
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
566  clear_current_row();
567 
573  template <class Archive>
574  void
575  serialize(Archive &ar, const unsigned int version);
576 
585  DeclException1(ExcColumnNotExistent,
586  std::string,
587  << "Column <" << arg1 << "> does not exist.");
588 
592  DeclException1(ExcSuperColumnNotExistent,
593  std::string,
594  << "Supercolumn <" << arg1 << "> does not exist.");
595 
599  DeclException1(ExcColumnOrSuperColumnNotExistent,
600  std::string,
601  << "Column or supercolumn <" << arg1 << "> does not exist.");
602 
606  DeclException4(ExcWrongNumberOfDataEntries,
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 
618  DeclException1(ExcUndefinedTexFormat,
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
667 
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
687  invalidate_cache();
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  // boost::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 boost::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 (const int *p = boost::get<int>(&value))
850  {
851  char c = 'i';
852  ar &c &*p;
853  }
854  else if (const unsigned int *p = boost::get<unsigned int>(&value))
855  {
856  char c = 'u';
857  ar &c &*p;
858  }
859  else if (const double *p = boost::get<double>(&value))
860  {
861  char c = 'd';
862  ar &c &*p;
863  }
864  else if (const std::string *p = boost::get<std::string>(&value))
865  {
866  char c = 's';
867  ar &c &*p;
868  }
869  else if (const std::uint64_t *p = boost::get<std::uint64_t>(&value))
870  {
871  char c = 'l';
872  ar &c &*p;
873  }
874  else
875  Assert(false, ExcInternalError());
876  }
877 
878 
879 
880  template <class Archive>
881  void
882  TableEntry::load(Archive &ar, const unsigned int)
883  {
884  // following what we do in the save()
885  // function, first read in the data type
886  // as a one-character id, and then read
887  // the data
888  char c;
889  ar & c;
890 
891  switch (c)
892  {
893  case 'i':
894  {
895  int val;
896  ar &val;
897  value = val;
898  break;
899  }
900 
901  case 'u':
902  {
903  unsigned int val;
904  ar & val;
905  value = val;
906  break;
907  }
908 
909  case 'd':
910  {
911  double val;
912  ar & val;
913  value = val;
914  break;
915  }
916 
917  case 's':
918  {
919  std::string val;
920  ar & val;
921  value = val;
922  break;
923  }
924 
925  case 'l':
926  {
927  std::uint64_t val;
928  ar & val;
929  value = val;
930  break;
931  }
932 
933  default:
934  Assert(false, ExcInternalError());
935  }
936  }
937 } // namespace internal
938 
939 
940 
941 template <typename T>
942 void
943 TableHandler::add_value(const std::string &key, const T value)
944 {
945  // see if the column already exists
946  if (columns.find(key) == columns.end())
947  declare_column(key);
948 
949  if (auto_fill_mode == true)
950  {
951  // follow the algorithm given in the introduction to this class
952  // of padding columns as necessary
953  unsigned int max_col_length = 0;
954  for (const auto &column : columns)
955  max_col_length =
956  std::max(max_col_length,
957  static_cast<unsigned int>(column.second.entries.size()));
958 
959  while (columns[key].entries.size() + 1 < max_col_length)
960  {
961  columns[key].entries.push_back(internal::TableEntry(T()));
962  internal::TableEntry &entry = columns[key].entries.back();
963  entry.cache_string(columns[key].scientific, columns[key].precision);
964  columns[key].max_length =
965  std::max(columns[key].max_length,
966  static_cast<unsigned int>(
967  entry.get_cached_string().length()));
968  }
969  }
970 
971  // now push the value given to this function
972  columns[key].entries.push_back(internal::TableEntry(value));
973  internal::TableEntry &entry = columns[key].entries.back();
974  entry.cache_string(columns[key].scientific, columns[key].precision);
975  columns[key].max_length =
976  std::max(columns[key].max_length,
977  static_cast<unsigned int>(entry.get_cached_string().length()));
978 }
979 
980 
981 
982 template <class Archive>
983 void
984 TableHandler::Column::save(Archive &ar, const unsigned int /*version*/) const
985 {
986  ar &entries &tex_caption &tex_format &precision &scientific &flag &max_length;
987 }
988 
989 
990 
991 template <class Archive>
992 void
993 TableHandler::Column::load(Archive &ar, const unsigned int /*version*/)
994 {
995  ar &entries &tex_caption &tex_format &precision &scientific &flag &max_length;
996  invalidate_cache();
997 }
998 
999 
1000 template <class Archive>
1001 void
1002 TableHandler::serialize(Archive &ar, const unsigned int)
1003 {
1004  ar &column_order &columns &supercolumns &tex_supercaptions &tex_table_caption
1005  &tex_table_label &auto_fill_mode;
1006 }
1007 
1008 
1010 
1011 #endif
std::map< std::string, std::string > tex_supercaptions
unsigned int max_length
void save(Archive &ar, const unsigned int version) const
void serialize(Archive &archive, const unsigned int version)
std::map< std::string, Column > columns
void add_value(const std::string &key, const T value)
const std::string & get_cached_string() const
void cache_string(bool scientific, unsigned int precision) const
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
Definition: config.h:408
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:515
static const char T
std::string cached_value
#define Assert(cond, exc)
Definition: exceptions.h:1465
void save(Archive &ar, const unsigned int version) const
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:395
unsigned int precision
boost::variant< int, unsigned int, std::uint64_t, double, std::string > value_type
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
Definition: config.h:445
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:394
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:584
void serialize(Archive &ar, const unsigned int version)
std::vector< internal::TableEntry > entries
std::string tex_caption
std::map< std::string, std::vector< std::string > > supercolumns
std::string tex_table_label
static ::ExceptionBase & ExcInternalError()
void load(Archive &ar, const unsigned int version)