Reference documentation for deal.II version 9.5.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\}}\)
Loading...
Searching...
No Matches
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
24
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
30#include <fstream>
31#include <map>
32#include <ostream>
33#include <string>
34#include <vector>
35
36
38
39// Forward declaration
40#ifndef DOXYGEN
41class TableHandler;
42#endif
43
44namespace internal
45{
55 {
56 public:
60 TableEntry() = default;
61
66 template <typename T>
67 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
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:
152 std_cxx17::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{
295public:
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
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.");
622protected:
627 struct Column
628 {
632 Column();
633
637 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
807namespace 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_cxx17::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_cxx17::get<T>(value);
828 }
829 catch (...)
830 {
831 Assert(false,
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_cxx17::holds_alternative<int>(value))
848 {
849 const int p = std_cxx17::get<int>(value);
850 char c = 'i';
851 ar &c &p;
852 }
853 else if (std_cxx17::holds_alternative<unsigned int>(value))
854 {
855 const unsigned int p = std_cxx17::get<unsigned int>(value);
856 char c = 'u';
857 ar &c &p;
858 }
859 else if (std_cxx17::holds_alternative<double>(value))
860 {
861 const double p = std_cxx17::get<double>(value);
862 char c = 'd';
863 ar &c &p;
864 }
865 else if (std_cxx17::holds_alternative<std::string>(value))
866 {
867 const std::string p = std_cxx17::get<std::string>(value);
868 char c = 's';
869 ar &c &p;
870 }
871 else if (std_cxx17::holds_alternative<std::uint64_t>(value))
872 {
873 const std::uint64_t p = std_cxx17::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
944template <typename T>
945void
946TableHandler::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
985template <class Archive>
986void
987TableHandler::Column::save(Archive &ar, const unsigned int /*version*/) const
988{
990}
991
992
993
994template <class Archive>
995void
996TableHandler::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
1003template <class Archive>
1004void
1005TableHandler::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 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:472
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:473
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:579
#define Assert(cond, exc)
static ::ExceptionBase & ExcUndefinedTexFormat(std::string arg1)
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcColumnOrSuperColumnNotExistent(std::string arg1)
#define DeclException1(Exception1, type1, outsequence)
Definition exceptions.h:510
static ::ExceptionBase & ExcMessage(std::string arg1)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
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
void load(Archive &ar, const unsigned int version)
std::vector< internal::TableEntry > entries
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
const std::string & get_cached_string() const
double get_numeric_value() const
void cache_string(bool scientific, unsigned int precision) const
std_cxx17::variant< int, unsigned int, std::uint64_t, double, std::string > value_type