Reference documentation for deal.II version Git 6abe6d7889 2020-08-12 13:30:05 -0400
\(\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 
293 {
294 public:
354  {
371  org_mode_table
372  };
373 
377  TableHandler();
378 
379 
401  void
402  declare_column(const std::string &key);
403 
410  template <typename T>
411  void
412  add_value(const std::string &key, const T value);
413 
427  void
428  start_new_row();
429 
434  void
435  set_auto_fill_mode(const bool state);
436 
449  void
450  add_column_to_supercolumn(const std::string &key,
451  const std::string &superkey);
452 
469  void
470  set_column_order(const std::vector<std::string> &new_order);
471 
477  void
478  set_precision(const std::string &key, const unsigned int precision);
479 
484  void
485  set_scientific(const std::string &key, const bool scientific);
486 
492  void
493  set_tex_caption(const std::string &key, const std::string &tex_caption);
494 
498  void
499  set_tex_table_caption(const std::string &table_caption);
500 
504  void
505  set_tex_table_label(const std::string &table_label);
506 
512  void
513  set_tex_supercaption(const std::string &superkey,
514  const std::string &tex_supercaption);
515 
522  void
523  set_tex_format(const std::string &key, const std::string &format = "c");
524 
536  void
537  write_text(std::ostream & out,
538  const TextOutputFormat format = table_with_headers) const;
539 
547  void
548  write_tex(std::ostream &file, const bool with_header = true) const;
549 
554  void
555  clear();
556 
562  void
563  clear_current_row();
564 
569  template <class Archive>
570  void
571  serialize(Archive &ar, const unsigned int version);
572 
581  DeclException1(ExcColumnNotExistent,
582  std::string,
583  << "Column <" << arg1 << "> does not exist.");
584 
588  DeclException1(ExcSuperColumnNotExistent,
589  std::string,
590  << "Supercolumn <" << arg1 << "> does not exist.");
591 
595  DeclException1(ExcColumnOrSuperColumnNotExistent,
596  std::string,
597  << "Column or supercolumn <" << arg1 << "> does not exist.");
598 
602  DeclException4(ExcWrongNumberOfDataEntries,
603  std::string,
604  int,
605  std::string,
606  int,
607  << "Column <" << arg1 << "> has " << arg2
608  << " rows, but Column <" << arg3 << "> has " << arg4
609  << " rows.");
610 
614  DeclException1(ExcUndefinedTexFormat,
615  std::string,
616  << "<" << arg1 << "> is not a tex column format. Use "
617  << "'l', 'c', or 'r' to indicate left, centered, or "
618  << "right aligned text.");
620 protected:
625  struct Column
626  {
630  Column();
631 
635  Column(const std::string &tex_caption);
636 
641  void
642  pad_column_below(const unsigned int length);
643 
648  template <class Archive>
649  void
650  save(Archive &ar, const unsigned int version) const;
651 
656  template <class Archive>
657  void
658  load(Archive &ar, const unsigned int version);
659 
660 #ifdef DOXYGEN
661 
665  template <class Archive>
666  void
667  serialize(Archive &archive, const unsigned int version);
668 #else
669  // This macro defines the serialize() method that is compatible with
670  // the templated save() and load() method that have been implemented.
671  BOOST_SERIALIZATION_SPLIT_MEMBER()
672 #endif
673 
674 
679  void
680  invalidate_cache();
681 
686  std::vector<internal::TableEntry> entries;
687 
694  std::string tex_caption;
695 
703  std::string tex_format;
704 
709  unsigned int precision;
710 
715 
723  unsigned int flag;
724 
729  unsigned int max_length;
730  };
731 
740  void
741  get_selected_columns(std::vector<std::string> &sel_columns) const;
742 
748  unsigned int
749  n_rows() const;
750 
756  std::vector<std::string> column_order;
757 
765  mutable std::map<std::string, Column> columns;
766 
775  std::map<std::string, std::vector<std::string>> supercolumns;
776 
784  std::map<std::string, std::string> tex_supercaptions;
785 
789  std::string tex_table_caption;
793  std::string tex_table_label;
794 
799 };
800 
801 
802 namespace internal
803 {
804  template <typename T>
806  : value(t)
807  {}
808 
809 
810  template <typename T>
811  T
813  {
814  // we don't quite know the data type in 'value', but
815  // it must be one of the ones in the type list of the
816  // boost::variant. so if T is not in the list, or if
817  // the data stored in the TableEntry is not of type
818  // T, then we will get an exception that we can
819  // catch and produce an error message
820  try
821  {
822  return boost::get<T>(value);
823  }
824  catch (...)
825  {
826  Assert(false,
827  ExcMessage(
828  "This TableEntry object does not store a datum of type T"));
829  throw;
830  }
831  }
832 
833 
834 
835  template <class Archive>
836  void
837  TableEntry::save(Archive &ar, const unsigned int) const
838  {
839  // write first an identifier for the kind
840  // of data stored and then the actual
841  // data, in its correct data type
842  if (const int *p = boost::get<int>(&value))
843  {
844  char c = 'i';
845  ar &c &*p;
846  }
847  else if (const unsigned int *p = boost::get<unsigned int>(&value))
848  {
849  char c = 'u';
850  ar &c &*p;
851  }
852  else if (const double *p = boost::get<double>(&value))
853  {
854  char c = 'd';
855  ar &c &*p;
856  }
857  else if (const std::string *p = boost::get<std::string>(&value))
858  {
859  char c = 's';
860  ar &c &*p;
861  }
862  else if (const std::uint64_t *p = boost::get<std::uint64_t>(&value))
863  {
864  char c = 'l';
865  ar &c &*p;
866  }
867  else
868  Assert(false, ExcInternalError());
869  }
870 
871 
872 
873  template <class Archive>
874  void
875  TableEntry::load(Archive &ar, const unsigned int)
876  {
877  // following what we do in the save()
878  // function, first read in the data type
879  // as a one-character id, and then read
880  // the data
881  char c;
882  ar & c;
883 
884  switch (c)
885  {
886  case 'i':
887  {
888  int val;
889  ar &val;
890  value = val;
891  break;
892  }
893 
894  case 'u':
895  {
896  unsigned int val;
897  ar & val;
898  value = val;
899  break;
900  }
901 
902  case 'd':
903  {
904  double val;
905  ar & val;
906  value = val;
907  break;
908  }
909 
910  case 's':
911  {
912  std::string val;
913  ar & val;
914  value = val;
915  break;
916  }
917 
918  case 'l':
919  {
920  std::uint64_t val;
921  ar & val;
922  value = val;
923  break;
924  }
925 
926  default:
927  Assert(false, ExcInternalError());
928  }
929  }
930 } // namespace internal
931 
932 
933 
934 template <typename T>
935 void
936 TableHandler::add_value(const std::string &key, const T value)
937 {
938  // see if the column already exists
939  if (columns.find(key) == columns.end())
940  declare_column(key);
941 
942  if (auto_fill_mode == true)
943  {
944  // follow the algorithm given in the introduction to this class
945  // of padding columns as necessary
946  unsigned int max_col_length = 0;
947  for (const auto &column : columns)
948  max_col_length =
949  std::max(max_col_length,
950  static_cast<unsigned int>(column.second.entries.size()));
951 
952  while (columns[key].entries.size() + 1 < max_col_length)
953  {
954  columns[key].entries.push_back(internal::TableEntry(T()));
955  internal::TableEntry &entry = columns[key].entries.back();
956  entry.cache_string(columns[key].scientific, columns[key].precision);
957  columns[key].max_length =
958  std::max(columns[key].max_length,
959  static_cast<unsigned int>(
960  entry.get_cached_string().length()));
961  }
962  }
963 
964  // now push the value given to this function
965  columns[key].entries.push_back(internal::TableEntry(value));
966  internal::TableEntry &entry = columns[key].entries.back();
967  entry.cache_string(columns[key].scientific, columns[key].precision);
968  columns[key].max_length =
969  std::max(columns[key].max_length,
970  static_cast<unsigned int>(entry.get_cached_string().length()));
971 }
972 
973 
974 
975 template <class Archive>
976 void
977 TableHandler::Column::save(Archive &ar, const unsigned int /*version*/) const
978 {
979  ar &entries &tex_caption &tex_format &precision &scientific &flag &max_length;
980 }
981 
982 
983 
984 template <class Archive>
985 void
986 TableHandler::Column::load(Archive &ar, const unsigned int /*version*/)
987 {
988  ar &entries &tex_caption &tex_format &precision &scientific &flag &max_length;
989  invalidate_cache();
990 }
991 
992 
993 template <class Archive>
994 void
995 TableHandler::serialize(Archive &ar, const unsigned int)
996 {
997  ar &column_order &columns &supercolumns &tex_supercaptions &tex_table_caption
998  &tex_table_label &auto_fill_mode;
999 }
1000 
1001 
1003 
1004 #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:376
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:1411
void save(Archive &ar, const unsigned int version) const
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:363
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:413
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:362
#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
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)