deal.II version GIT relicensing-2287-g6548a49e0a 2024-12-20 18:30:00+00:00
\(\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// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 1999 - 2024 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15#ifndef dealii_table_handler_h
16#define dealii_table_handler_h
17
18
19#include <deal.II/base/config.h>
20
22
23#include <boost/serialization/map.hpp>
24#include <boost/serialization/split_member.hpp>
25#include <boost/serialization/string.hpp>
26#include <boost/serialization/vector.hpp>
27
28#include <fstream>
29#include <map>
30#include <ostream>
31#include <string>
32#include <variant>
33#include <vector>
34
35
37
38// Forward declaration
39#ifndef DOXYGEN
40class TableHandler;
41#endif
42
43namespace internal
44{
54 {
55 public:
59 TableEntry() = default;
60
65 template <typename T>
66 explicit TableEntry(const T &t);
67
74 template <typename T>
75 T
76 get() const;
77
84 double
85 get_numeric_value() const;
86
94 void
95 cache_string(bool scientific, unsigned int precision) const;
96
101 const std::string &
102 get_cached_string() const;
103
104
112
118 template <class Archive>
119 void
120 save(Archive &ar, const unsigned int version) const;
121
127 template <class Archive>
128 void
129 load(Archive &ar, const unsigned int version);
130
131#ifdef DOXYGEN
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:
151 std::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{
294public:
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
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
564
570 template <class Archive>
571 void
572 serialize(Archive &ar, const unsigned int version);
573
583 std::string,
584 << "Column <" << arg1 << "> does not exist.");
585
590 std::string,
591 << "Supercolumn <" << arg1 << "> does not exist.");
592
597 std::string,
598 << "Column or supercolumn <" << arg1 << "> does not exist.");
599
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
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.");
621protected:
626 struct Column
627 {
631 Column();
632
636 explicit Column(const std::string &tex_caption);
637
642 void
643 pad_column_below(const unsigned int length);
644
650 template <class Archive>
651 void
652 save(Archive &ar, const unsigned int version) const;
653
659 template <class Archive>
660 void
661 load(Archive &ar, const unsigned int version);
662
663#ifdef DOXYGEN
669 template <class Archive>
670 void
671 serialize(Archive &archive, const unsigned int version);
672#else
673 // This macro defines the serialize() method that is compatible with
674 // the templated save() and load() method that have been implemented.
675 BOOST_SERIALIZATION_SPLIT_MEMBER()
676#endif
677
678
683 void
685
690 std::vector<internal::TableEntry> entries;
691
698 std::string tex_caption;
699
707 std::string tex_format;
708
713 unsigned int precision;
714
719
727 unsigned int flag;
728
733 unsigned int max_length;
734 };
735
744 void
745 get_selected_columns(std::vector<std::string> &sel_columns) const;
746
752 unsigned int
753 n_rows() const;
754
760 std::vector<std::string> column_order;
761
769 mutable std::map<std::string, Column> columns;
770
779 std::map<std::string, std::vector<std::string>> supercolumns;
780
788 std::map<std::string, std::string> tex_supercaptions;
789
793 std::string tex_table_caption;
797 std::string tex_table_label;
798
803};
804
805
806namespace internal
807{
808 template <typename T>
810 : value(t)
811 {}
812
813
814 template <typename T>
815 T
817 {
818 // we don't quite know the data type in 'value', but
819 // it must be one of the ones in the type list of the
820 // std::variant. so if T is not in the list, or if
821 // the data stored in the TableEntry is not of type
822 // T, then we will get an exception that we can
823 // catch and produce an error message
824 try
825 {
826 return std::get<T>(value);
827 }
828 catch (...)
829 {
830 Assert(false,
832 "This TableEntry object does not store a datum of type T"));
833 throw;
834 }
835 }
836
837
838
839 template <class Archive>
840 void
841 TableEntry::save(Archive &ar, const unsigned int) const
842 {
843 // write first an identifier for the kind
844 // of data stored and then the actual
845 // data, in its correct data type
846 if (std::holds_alternative<int>(value))
847 {
848 const int p = std::get<int>(value);
849 char c = 'i';
850 ar &c &p;
851 }
852 else if (std::holds_alternative<unsigned int>(value))
853 {
854 const unsigned int p = std::get<unsigned int>(value);
855 char c = 'u';
856 ar &c &p;
857 }
858 else if (std::holds_alternative<double>(value))
859 {
860 const double p = std::get<double>(value);
861 char c = 'd';
862 ar &c &p;
863 }
864 else if (std::holds_alternative<std::string>(value))
865 {
866 const std::string p = std::get<std::string>(value);
867 char c = 's';
868 ar &c &p;
869 }
870 else if (std::holds_alternative<std::uint64_t>(value))
871 {
872 const std::uint64_t p = std::get<std::uint64_t>(value);
873 char c = 'l';
874 ar &c &p;
875 }
876 else
878 }
879
880
881
882 template <class Archive>
883 void
884 TableEntry::load(Archive &ar, const unsigned int)
885 {
886 // following what we do in the save()
887 // function, first read in the data type
888 // as a one-character id, and then read
889 // the data
890 char c;
891 ar &c;
892
893 switch (c)
894 {
895 case 'i':
896 {
897 int val;
898 ar &val;
899 value = val;
900 break;
901 }
902
903 case 'u':
904 {
905 unsigned int val;
906 ar &val;
907 value = val;
908 break;
909 }
910
911 case 'd':
912 {
913 double val;
914 ar &val;
915 value = val;
916 break;
917 }
918
919 case 's':
920 {
921 std::string val;
922 ar &val;
923 value = val;
924 break;
925 }
926
927 case 'l':
928 {
929 std::uint64_t val;
930 ar &val;
931 value = val;
932 break;
933 }
934
935 default:
937 }
938 }
939} // namespace internal
940
941
942
943template <typename T>
944void
945TableHandler::add_value(const std::string &key, const T value)
946{
947 // see if the column already exists
948 if (columns.find(key) == columns.end())
949 declare_column(key);
950
951 if (auto_fill_mode == true)
952 {
953 // follow the algorithm given in the introduction to this class
954 // of padding columns as necessary
955 unsigned int max_col_length = 0;
956 for (const auto &column : columns)
957 max_col_length =
958 std::max(max_col_length,
959 static_cast<unsigned int>(column.second.entries.size()));
960
961 while (columns[key].entries.size() + 1 < max_col_length)
962 {
963 columns[key].entries.push_back(internal::TableEntry(T()));
964 const internal::TableEntry &entry = columns[key].entries.back();
965 entry.cache_string(columns[key].scientific, columns[key].precision);
966 columns[key].max_length =
967 std::max(columns[key].max_length,
968 static_cast<unsigned int>(
969 entry.get_cached_string().size()));
970 }
971 }
972
973 // now push the value given to this function
974 columns[key].entries.push_back(internal::TableEntry(value));
975 const internal::TableEntry &entry = columns[key].entries.back();
976 entry.cache_string(columns[key].scientific, columns[key].precision);
977 columns[key].max_length =
978 std::max(columns[key].max_length,
979 static_cast<unsigned int>(entry.get_cached_string().size()));
980}
981
982
983
984template <class Archive>
985void
986TableHandler::Column::save(Archive &ar, const unsigned int /*version*/) const
987{
989}
990
991
992
993template <class Archive>
994void
995TableHandler::Column::load(Archive &ar, const unsigned int /*version*/)
996{
997 ar &entries &tex_caption &tex_format &precision &scientific &flag &max_length;
998 invalidate_cache();
999}
1000
1001
1002template <class Archive>
1003void
1009
1010
1012
1013#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:498
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:499
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:580
#define Assert(cond, exc)
static ::ExceptionBase & ExcUndefinedTexFormat(std::string arg1)
static ::ExceptionBase & ExcColumnOrSuperColumnNotExistent(std::string arg1)
#define DeclException1(Exception1, type1, outsequence)
Definition exceptions.h:511
static ::ExceptionBase & ExcMessage(std::string arg1)
#define DEAL_II_ASSERT_UNREACHABLE()
::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
std::variant< int, unsigned int, std::uint64_t, double, std::string > value_type
void cache_string(bool scientific, unsigned int precision) const