deal.II version GIT relicensing-6834-g5b78e6bcdf 2026-10-01 11:20:01+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: Apache-2.0 WITH LLVM-exception OR LGPL-2.1-or-later
4// Copyright (C) 1999 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Detailed license information governing the source code and contributions
9// can be found in LICENSE.md and CONTRIBUTING.md at the top level directory.
10//
11// -----------------------------------------------------------------------------
12
13#ifndef dealii_table_handler_h
14#define dealii_table_handler_h
15
16
17#include <deal.II/base/config.h>
18
20
21#include <boost/serialization/map.hpp>
22#include <boost/serialization/split_member.hpp>
23#include <boost/serialization/string.hpp>
24#include <boost/serialization/vector.hpp>
25
26#include <cstdint>
27#include <map>
28#include <ostream>
29#include <string>
30#include <variant>
31#include <vector>
32
33
35
36// Forward declaration
37#ifndef DOXYGEN
38class TableHandler;
39#endif
40
41namespace internal
42{
53 {
54 public:
58 TableEntry() = default;
59
64 template <typename T>
65 explicit TableEntry(const T &t);
66
73 template <typename T>
74 T
75 get() const;
76
83 double
84 get_numeric_value() const;
85
93 void
94 cache_string(bool scientific, unsigned int precision) const;
95
100 const std::string &
101 get_cached_string() const;
102
103
111
117 template <class Archive>
118 void
119 save(Archive &ar, const unsigned int version) const;
120
126 template <class Archive>
127 void
128 load(Archive &ar, const unsigned int version);
129
130#ifdef DOXYGEN
136 template <class Archive>
137 void
138 serialize(Archive &archive, const unsigned int version);
139#else
140 // This macro defines the serialize() method that is compatible with
141 // the templated save() and load() method that have been implemented.
142 BOOST_SERIALIZATION_SPLIT_MEMBER()
143#endif
144
145 private:
150 std::variant<int, unsigned int, std::uint64_t, double, std::string>;
151
156
160 mutable std::string cached_value;
161
162 friend class ::TableHandler;
163 };
164} // namespace internal
165
166
292{
293public:
372
376 TableHandler();
377
378
400 void
401 declare_column(const std::string &key);
402
409 template <typename T>
410 void
411 add_value(const std::string &key, const T value);
412
426 void
428
433 void
434 set_auto_fill_mode(const bool state);
435
448 void
449 add_column_to_supercolumn(const std::string &key,
450 const std::string &superkey);
451
468 void
469 set_column_order(const std::vector<std::string> &new_order);
470
476 void
477 set_precision(const std::string &key, const unsigned int precision);
478
483 void
484 set_scientific(const std::string &key, const bool scientific);
485
491 void
492 set_tex_caption(const std::string &key, const std::string &tex_caption);
493
497 void
498 set_tex_table_caption(const std::string &table_caption);
499
503 void
504 set_tex_table_label(const std::string &table_label);
505
511 void
512 set_tex_supercaption(const std::string &superkey,
513 const std::string &tex_supercaption);
514
521 void
522 set_tex_format(const std::string &key, const std::string &format = "c");
523
535 void
536 write_text(std::ostream &out,
537 const TextOutputFormat format = table_with_headers) const;
538
546 void
547 write_tex(std::ostream &file, const bool with_header = true) const;
548
553 void
554 clear();
555
561 void
563
569 template <class Archive>
570 void
571 serialize(Archive &ar, const unsigned int version);
572
582 std::string,
583 << "Column <" << arg1 << "> does not exist.");
584
589 std::string,
590 << "Supercolumn <" << arg1 << "> does not exist.");
591
596 std::string,
597 << "Column or supercolumn <" << arg1 << "> does not exist.");
598
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
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.");
620protected:
625 struct Column
626 {
630 Column();
631
635 explicit Column(const std::string &tex_caption);
636
641 void
642 pad_column_below(const unsigned int length);
643
649 template <class Archive>
650 void
651 save(Archive &ar, const unsigned int version) const;
652
658 template <class Archive>
659 void
660 load(Archive &ar, const unsigned int version);
661
662#ifdef DOXYGEN
668 template <class Archive>
669 void
670 serialize(Archive &archive, const unsigned int version);
671#else
672 // This macro defines the serialize() method that is compatible with
673 // the templated save() and load() method that have been implemented.
674 BOOST_SERIALIZATION_SPLIT_MEMBER()
675#endif
676
677
682 void
684
689 std::vector<internal::TableEntry> entries;
690
697 std::string tex_caption;
698
706 std::string tex_format;
707
712 unsigned int precision;
713
718
726 unsigned int flag;
727
732 unsigned int max_length;
733 };
734
743 void
744 get_selected_columns(std::vector<std::string> &sel_columns) const;
745
751 unsigned int
752 n_rows() const;
753
759 std::vector<std::string> column_order;
760
768 mutable std::map<std::string, Column> columns;
769
778 std::map<std::string, std::vector<std::string>> supercolumns;
779
787 std::map<std::string, std::string> tex_supercaptions;
788
792 std::string tex_table_caption;
796 std::string tex_table_label;
797
802};
803
804
805namespace internal
806{
807 template <typename T>
809 : value(t)
810 {}
811
812
813 template <typename T>
814 T
816 {
817 // we don't quite know the data type in 'value', but
818 // it must be one of the ones in the type list of the
819 // std::variant. so if T is not in the list, or if
820 // the data stored in the TableEntry is not of type
821 // T, then we will get an exception that we can
822 // catch and produce an error message
823 try
824 {
825 return std::get<T>(value);
826 }
827 catch (...)
828 {
829 Assert(false,
831 "This TableEntry object does not store a datum of type T"));
832 throw;
833 }
834 }
835
836
837
838 template <class Archive>
839 void
840 TableEntry::save(Archive &ar, const unsigned int) const
841 {
842 // write first an identifier for the kind
843 // of data stored and then the actual
844 // data, in its correct data type
845 if (std::holds_alternative<int>(value))
846 {
847 const int p = std::get<int>(value);
848 char c = 'i';
849 ar &c &p;
850 }
851 else if (std::holds_alternative<unsigned int>(value))
852 {
853 const unsigned int p = std::get<unsigned int>(value);
854 char c = 'u';
855 ar &c &p;
856 }
857 else if (std::holds_alternative<double>(value))
858 {
859 const double p = std::get<double>(value);
860 char c = 'd';
861 ar &c &p;
862 }
863 else if (std::holds_alternative<std::string>(value))
864 {
865 const std::string p = std::get<std::string>(value);
866 char c = 's';
867 ar &c &p;
868 }
869 else if (std::holds_alternative<std::uint64_t>(value))
870 {
871 const std::uint64_t p = std::get<std::uint64_t>(value);
872 char c = 'l';
873 ar &c &p;
874 }
875 else
877 }
878
879
880
881 template <class Archive>
882 void
883 TableEntry::load(Archive &ar, const unsigned int)
884 {
885 // following what we do in the save()
886 // function, first read in the data type
887 // as a one-character id, and then read
888 // the data
889 char c;
890 ar &c;
891
892 switch (c)
893 {
894 case 'i':
895 {
896 int val;
897 ar &val;
898 value = val;
899 break;
900 }
901
902 case 'u':
903 {
904 unsigned int val;
905 ar &val;
906 value = val;
907 break;
908 }
909
910 case 'd':
911 {
912 double val;
913 ar &val;
914 value = val;
915 break;
916 }
917
918 case 's':
919 {
920 std::string val;
921 ar &val;
922 value = val;
923 break;
924 }
925
926 case 'l':
927 {
928 std::uint64_t val;
929 ar &val;
930 value = val;
931 break;
932 }
933
934 default:
936 }
937 }
938} // namespace internal
939
940
941
942template <typename T>
943void
944TableHandler::add_value(const std::string &key, const T value)
945{
946 // see if the column already exists
947 if (columns.find(key) == columns.end())
948 declare_column(key);
949
950 if (auto_fill_mode == true)
951 {
952 // follow the algorithm given in the introduction to this class
953 // of padding columns as necessary
954 unsigned int max_col_length = 0;
955 for (const auto &column : columns)
956 max_col_length =
957 std::max(max_col_length,
958 static_cast<unsigned int>(column.second.entries.size()));
959
960 while (columns[key].entries.size() + 1 < max_col_length)
961 {
962 columns[key].entries.emplace_back(T());
963 const internal::TableEntry &entry = columns[key].entries.back();
964 entry.cache_string(columns[key].scientific, columns[key].precision);
965 columns[key].max_length =
966 std::max(columns[key].max_length,
967 static_cast<unsigned int>(
968 entry.get_cached_string().size()));
969 }
970 }
971
972 // now push the value given to this function
973 columns[key].entries.emplace_back(value);
974 const internal::TableEntry &entry = columns[key].entries.back();
975 entry.cache_string(columns[key].scientific, columns[key].precision);
976 columns[key].max_length =
977 std::max(columns[key].max_length,
978 static_cast<unsigned int>(entry.get_cached_string().size()));
979}
980
981
982
983template <class Archive>
984void
985TableHandler::Column::save(Archive &ar, const unsigned int /*version*/) const
986{
988}
989
990
991
992template <class Archive>
993void
994TableHandler::Column::load(Archive &ar, const unsigned int /*version*/)
995{
996 ar &entries &tex_caption &tex_format &precision &scientific &flag &max_length;
997 invalidate_cache();
998}
999
1000
1001template <class Archive>
1002void
1008
1009
1011
1012#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:38
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:39
#define DEAL_II_ASSERT_UNREACHABLE()
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)
#define Assert(cond, exc)
static ::ExceptionBase & ExcUndefinedTexFormat(std::string arg1)
static ::ExceptionBase & ExcColumnOrSuperColumnNotExistent(std::string arg1)
#define DeclException1(Exception1, type1, outsequence)
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
std::variant< int, unsigned int, std::uint64_t, double, std::string > value_type
void cache_string(bool scientific, unsigned int precision) const