Reference documentation for deal.II version 9.3.3
\(\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
43class TableHandler;
44#endif
45
46namespace internal
47{
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
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:
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{
297public:
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
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.");
624protected:
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
809namespace 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,
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
941template <typename T>
942void
943TableHandler::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
982template <class Archive>
983void
984TableHandler::Column::save(Archive &ar, const unsigned int /*version*/) const
985{
987}
988
989
990
991template <class Archive>
992void
993TableHandler::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
1000template <class Archive>
1001void
1002TableHandler::serialize(Archive &ar, const unsigned int)
1003{
1006}
1007
1008
1010
1011#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:402
#define DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
Definition: config.h:416
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:403
#define DEAL_II_ENABLE_EXTRA_DIAGNOSTICS
Definition: config.h:454
static ::ExceptionBase & ExcSuperColumnNotExistent(std::string arg1)
static ::ExceptionBase & ExcWrongNumberOfDataEntries(std::string arg1, int arg2, std::string arg3, int arg4)
static ::ExceptionBase & ExcColumnNotExistent(std::string arg1)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:584
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)
void save(Archive &ar, const unsigned int version) const
unsigned int n_rows() const
void get_selected_columns(std::vector< std::string > &sel_columns) const
#define Assert(cond, exc)
Definition: exceptions.h:1465
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
static ::ExceptionBase & ExcUndefinedTexFormat(std::string arg1)
std::string tex_table_caption
static ::ExceptionBase & ExcInternalError()
unsigned int max_length
static ::ExceptionBase & ExcColumnOrSuperColumnNotExistent(std::string arg1)
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:515
unsigned int precision
void load(Archive &ar, const unsigned int version)
std::string tex_format
std::vector< std::string > column_order
std::vector< internal::TableEntry > entries
static ::ExceptionBase & ExcMessage(std::string arg1)
std::string tex_caption
std::map< std::string, Column > columns
static const char T
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
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
boost::variant< int, unsigned int, std::uint64_t, double, std::string > value_type