Reference documentation for deal.II version Git 423cd11810 2020-05-28 01:07:25 +0200
\(\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 - 2020 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 
120  template <class Archive>
121  void
122  save(Archive &ar, const unsigned int version) const;
123 
128  template <class Archive>
129  void
130  load(Archive &ar, const unsigned int version);
131 
132 #ifdef DOXYGEN
133 
137  template <class Archive>
138  void
139  serialize(Archive &archive, const unsigned int version);
140 #else
141  // This macro defines the serialize() method that is compatible with
142  // the templated save() and load() method that have been implemented.
143  BOOST_SERIALIZATION_SPLIT_MEMBER()
144 #endif
145 
146  private:
150  using value_type =
151  boost::variant<int, unsigned int, std::uint64_t, double, std::string>;
152 
157 
161  mutable std::string cached_value;
162 
163  friend class ::TableHandler;
164  };
165 } // namespace internal
166 
167 
294 {
295 public:
355  {
372  org_mode_table
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
564  clear_current_row();
565 
570  template <class Archive>
571  void
572  serialize(Archive &ar, const unsigned int version);
573 
582  DeclException1(ExcColumnNotExistent,
583  std::string,
584  << "Column <" << arg1 << "> does not exist.");
585 
589  DeclException1(ExcSuperColumnNotExistent,
590  std::string,
591  << "Supercolumn <" << arg1 << "> does not exist.");
592 
596  DeclException1(ExcColumnOrSuperColumnNotExistent,
597  std::string,
598  << "Column or supercolumn <" << arg1 << "> does not exist.");
599 
603  DeclException4(ExcWrongNumberOfDataEntries,
604  std::string,
605  int,
606  std::string,
607  int,
608  << "Column <" << arg1 << "> has " << arg2
609  << " rows, but Column <" << arg3 << "> has " << arg4
610  << " rows.");
611 
615  DeclException1(ExcUndefinedTexFormat,
616  std::string,
617  << "<" << arg1 << "> is not a tex column format. Use "
618  << "'l', 'c', or 'r' to indicate left, centered, or "
619  << "right aligned text.");
621 protected:
626  struct Column
627  {
631  Column();
632 
636  Column(const std::string &tex_caption);
637 
642  void
643  pad_column_below(const unsigned int length);
644 
649  template <class Archive>
650  void
651  save(Archive &ar, const unsigned int version) const;
652 
657  template <class Archive>
658  void
659  load(Archive &ar, const unsigned int version);
660 
661 #ifdef DOXYGEN
662 
666  template <class Archive>
667  void
668  serialize(Archive &archive, const unsigned int version);
669 #else
670  // This macro defines the serialize() method that is compatible with
671  // the templated save() and load() method that have been implemented.
672  BOOST_SERIALIZATION_SPLIT_MEMBER()
673 #endif
674 
675 
680  void
681  invalidate_cache();
682 
687  std::vector<internal::TableEntry> entries;
688 
695  std::string tex_caption;
696 
704  std::string tex_format;
705 
710  unsigned int precision;
711 
716 
724  unsigned int flag;
725 
730  unsigned int max_length;
731  };
732 
741  void
742  get_selected_columns(std::vector<std::string> &sel_columns) const;
743 
749  unsigned int
750  n_rows() const;
751 
757  std::vector<std::string> column_order;
758 
766  mutable std::map<std::string, Column> columns;
767 
776  std::map<std::string, std::vector<std::string>> supercolumns;
777 
785  std::map<std::string, std::string> tex_supercaptions;
786 
790  std::string tex_table_caption;
794  std::string tex_table_label;
795 
800 };
801 
802 
803 namespace internal
804 {
805  template <typename T>
807  : value(t)
808  {}
809 
810 
811  template <typename T>
812  T
814  {
815  // we don't quite know the data type in 'value', but
816  // it must be one of the ones in the type list of the
817  // boost::variant. so if T is not in the list, or if
818  // the data stored in the TableEntry is not of type
819  // T, then we will get an exception that we can
820  // catch and produce an error message
821  try
822  {
823  return boost::get<T>(value);
824  }
825  catch (...)
826  {
827  Assert(false,
828  ExcMessage(
829  "This TableEntry object does not store a datum of type T"));
830  throw;
831  }
832  }
833 
834 
835 
836  template <class Archive>
837  void
838  TableEntry::save(Archive &ar, const unsigned int) const
839  {
840  // write first an identifier for the kind
841  // of data stored and then the actual
842  // data, in its correct data type
843  if (const int *p = boost::get<int>(&value))
844  {
845  char c = 'i';
846  ar &c &*p;
847  }
848  else if (const unsigned int *p = boost::get<unsigned int>(&value))
849  {
850  char c = 'u';
851  ar &c &*p;
852  }
853  else if (const double *p = boost::get<double>(&value))
854  {
855  char c = 'd';
856  ar &c &*p;
857  }
858  else if (const std::string *p = boost::get<std::string>(&value))
859  {
860  char c = 's';
861  ar &c &*p;
862  }
863  else if (const std::uint64_t *p = boost::get<std::uint64_t>(&value))
864  {
865  char c = 'l';
866  ar &c &*p;
867  }
868  else
869  Assert(false, ExcInternalError());
870  }
871 
872 
873 
874  template <class Archive>
875  void
876  TableEntry::load(Archive &ar, const unsigned int)
877  {
878  // following what we do in the save()
879  // function, first read in the data type
880  // as a one-character id, and then read
881  // the data
882  char c;
883  ar & c;
884 
885  switch (c)
886  {
887  case 'i':
888  {
889  int val;
890  ar &val;
891  value = val;
892  break;
893  }
894 
895  case 'u':
896  {
897  unsigned int val;
898  ar & val;
899  value = val;
900  break;
901  }
902 
903  case 'd':
904  {
905  double val;
906  ar & val;
907  value = val;
908  break;
909  }
910 
911  case 's':
912  {
913  std::string val;
914  ar & val;
915  value = val;
916  break;
917  }
918 
919  case 'l':
920  {
921  std::uint64_t val;
922  ar & val;
923  value = val;
924  break;
925  }
926 
927  default:
928  Assert(false, ExcInternalError());
929  }
930  }
931 } // namespace internal
932 
933 
934 
935 template <typename T>
936 void
937 TableHandler::add_value(const std::string &key, const T value)
938 {
939  // see if the column already exists
940  if (columns.find(key) == columns.end())
941  declare_column(key);
942 
943  if (auto_fill_mode == true)
944  {
945  // follow the algorithm given in the introduction to this class
946  // of padding columns as necessary
947  unsigned int max_col_length = 0;
948  for (const auto &column : columns)
949  max_col_length =
950  std::max(max_col_length,
951  static_cast<unsigned int>(column.second.entries.size()));
952 
953  while (columns[key].entries.size() + 1 < max_col_length)
954  {
955  columns[key].entries.push_back(internal::TableEntry(T()));
956  internal::TableEntry &entry = columns[key].entries.back();
957  entry.cache_string(columns[key].scientific, columns[key].precision);
958  columns[key].max_length =
959  std::max(columns[key].max_length,
960  static_cast<unsigned int>(
961  entry.get_cached_string().length()));
962  }
963  }
964 
965  // now push the value given to this function
966  columns[key].entries.push_back(internal::TableEntry(value));
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>(entry.get_cached_string().length()));
972 }
973 
974 
975 
976 template <class Archive>
977 void
978 TableHandler::Column::save(Archive &ar, const unsigned int /*version*/) const
979 {
980  ar &entries &tex_caption &tex_format &precision &scientific &flag &max_length;
981 }
982 
983 
984 
985 template <class Archive>
986 void
987 TableHandler::Column::load(Archive &ar, const unsigned int /*version*/)
988 {
989  ar &entries &tex_caption &tex_format &precision &scientific &flag &max_length;
990  invalidate_cache();
991 }
992 
993 
994 template <class Archive>
995 void
996 TableHandler::serialize(Archive &ar, const unsigned int)
997 {
998  ar &column_order &columns &supercolumns &tex_supercaptions &tex_table_caption
999  &tex_table_label &auto_fill_mode;
1000 }
1001 
1002 
1004 
1005 #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:375
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
static const char T
std::string cached_value
#define Assert(cond, exc)
Definition: exceptions.h:1419
void save(Archive &ar, const unsigned int version) const
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:362
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:412
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:361
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:587
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
T max(const T &t, const MPI_Comm &mpi_communicator)
std::string tex_table_label
static ::ExceptionBase & ExcInternalError()
void load(Archive &ar, const unsigned int version)