Reference documentation for deal.II version 8.5.1
table_handler.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2017 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 at
12 // the top level of the deal.II distribution.
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 #include <deal.II/base/exceptions.h>
22 
23 #include <map>
24 #include <vector>
25 #include <string>
26 #include <fstream>
27 
28 #include <ostream>
29 
30 #include <boost/variant.hpp>
31 #include <boost/serialization/map.hpp>
32 #include <boost/serialization/string.hpp>
33 #include <boost/serialization/vector.hpp>
34 #include <boost/serialization/split_member.hpp>
35 
36 
37 DEAL_II_NAMESPACE_OPEN
38 
39 class TableHandler;
40 
41 namespace internal
42 {
51  struct TableEntry
52  {
53  public:
57  TableEntry ();
58 
63  template <typename T>
64  TableEntry (const T &t);
65 
72  template <typename T>
73  T get () const;
74 
81  double get_numeric_value () const;
82 
90  void cache_string(bool scientific, unsigned int precision) const;
91 
96  const std::string &get_cached_string() const;
97 
98 
105 
110  template <class Archive>
111  void save (Archive &ar, const unsigned int version) const;
112 
117  template <class Archive>
118  void load (Archive &ar, const unsigned int version);
119 
120  BOOST_SERIALIZATION_SPLIT_MEMBER()
121 
122  private:
126  typedef boost::variant<int,unsigned int,unsigned long long int,double,std::string> value_type;
127 
132 
136  mutable std::string cached_value;
137 
138  friend class ::TableHandler;
139  };
140 }
141 
142 
263 {
264 public:
324  {
342  };
343 
347  TableHandler ();
348 
355  template <typename T>
356  void add_value (const std::string &key,
357  const T value);
358 
363  void set_auto_fill_mode (const bool state);
364 
377  void add_column_to_supercolumn (const std::string &key,
378  const std::string &superkey);
379 
396  void set_column_order (const std::vector<std::string> &new_order);
397 
403  void set_precision (const std::string &key,
404  const unsigned int precision);
405 
410  void set_scientific (const std::string &key,
411  const bool scientific);
412 
418  void set_tex_caption (const std::string &key,
419  const std::string &tex_caption);
420 
424  void set_tex_table_caption (const std::string &table_caption);
425 
429  void set_tex_table_label (const std::string &table_label);
430 
436  void set_tex_supercaption (const std::string &superkey,
437  const std::string &tex_supercaption);
438 
445  void set_tex_format (const std::string &key,
446  const std::string &format="c");
447 
459  void write_text (std::ostream &out,
460  const TextOutputFormat format = table_with_headers) const;
461 
469  void write_tex (std::ostream &file, const bool with_header=true) const;
470 
475  void clear ();
476 
482  void clear_current_row ();
483 
488  template <class Archive>
489  void serialize(Archive &ar, const unsigned int version);
490 
500  std::string,
501  << "Column <" << arg1 << "> does not exist.");
502 
507  std::string,
508  << "Supercolumn <" << arg1 << "> does not exist.");
509 
514  std::string,
515  << "Column or supercolumn <" << arg1 << "> does not exist.");
516 
521  std::string, int, std::string, int,
522  << "Column <" << arg1 << "> has " << arg2
523  << " rows, but Column <" << arg3 << "> has " << arg4 << " rows.");
524 
529  std::string,
530  << "<" << arg1 << "> is not a tex column format. Use "
531  << "'l', 'c', or 'r' to indicate left, centered, or "
532  << "right aligned text.");
534 protected:
535 
540  struct Column
541  {
545  Column ();
546 
550  Column (const std::string &tex_caption);
551 
556  void pad_column_below (const unsigned int length);
557 
562  template <class Archive>
563  void save(Archive &ar, const unsigned int version) const;
564  template<class Archive>
565  void load(Archive &ar, const unsigned int version);
566  BOOST_SERIALIZATION_SPLIT_MEMBER()
567 
568 
569 
573  void invalidate_cache();
574 
579  std::vector<internal::TableEntry> entries;
580 
587  std::string tex_caption;
588 
596  std::string tex_format;
597 
602  unsigned int precision;
603 
608 
616  unsigned int flag;
617 
622  unsigned int max_length;
623  };
624 
633  void get_selected_columns (std::vector<std::string> &sel_columns) const;
634 
640  unsigned int n_rows() const;
641 
647  std::vector<std::string> column_order;
648 
656  mutable std::map<std::string,Column> columns;
657 
666  std::map<std::string, std::vector<std::string> > supercolumns;
667 
675  std::map<std::string, std::string> tex_supercaptions;
676 
680  std::string tex_table_caption;
684  std::string tex_table_label;
685 
690 };
691 
692 
693 namespace internal
694 {
695  template <typename T>
697  :
698  value (t)
699  {}
700 
701 
702  template <typename T>
703  T TableEntry::get () const
704  {
705  // we don't quite know the data type in 'value', but
706  // it must be one of the ones in the type list of the
707  // boost::variant. so if T is not in the list, or if
708  // the data stored in the TableEntry is not of type
709  // T, then we will get an exception that we can
710  // catch and produce an error message
711  try
712  {
713  return boost::get<T>(value);
714  }
715  catch (...)
716  {
717  Assert(false, ExcMessage ("This TableEntry object does not store a datum of type T"));
718  throw;
719  }
720  }
721 
722 
723 
724  template <class Archive>
725  void TableEntry::save (Archive &ar,
726  const unsigned int) const
727  {
728  // write first an identifier for the kind
729  // of data stored and then the actual
730  // data, in its correct data type
731  if (const int *p = boost::get<int>(&value))
732  {
733  char c = 'i';
734  ar &c & *p;
735  }
736  else if (const unsigned int *p = boost::get<unsigned int>(&value))
737  {
738  char c = 'u';
739  ar &c & *p;
740  }
741  else if (const double *p = boost::get<double>(&value))
742  {
743  char c = 'd';
744  ar &c & *p;
745  }
746  else if (const std::string *p = boost::get<std::string>(&value))
747  {
748  char c = 's';
749  ar &c & *p;
750  }
751  else if (const unsigned long long int *p = boost::get<unsigned long long int>(&value))
752  {
753  char c = 'l';
754  ar &c & *p;
755  }
756  else
757  Assert (false, ExcInternalError());
758  }
759 
760 
761 
762  template <class Archive>
763  void TableEntry::load (Archive &ar,
764  const unsigned int)
765  {
766  // following what we do in the save()
767  // function, first read in the data type
768  // as a one-character id, and then read
769  // the data
770  char c;
771  ar &c;
772 
773  switch (c)
774  {
775  case 'i':
776  {
777  int val;
778  ar &val;
779  value = val;
780  break;
781  }
782 
783  case 'u':
784  {
785  unsigned int val;
786  ar &val;
787  value = val;
788  break;
789  }
790 
791  case 'd':
792  {
793  double val;
794  ar &val;
795  value = val;
796  break;
797  }
798 
799  case 's':
800  {
801  std::string val;
802  ar &val;
803  value = val;
804  break;
805  }
806 
807  case 'l':
808  {
809  unsigned long long int val;
810  ar &val;
811  value = val;
812  break;
813  }
814 
815  default:
816  Assert (false, ExcInternalError());
817  }
818  }
819 }
820 
821 template <typename T>
822 void TableHandler::add_value (const std::string &key,
823  const T value)
824 {
825  // see if the column already exists
826  if (columns.find(key) == columns.end())
827  {
828  std::pair<std::string, Column> new_column(key, Column(key));
829  columns.insert(new_column);
830  column_order.push_back(key);
831  }
832 
833  if (auto_fill_mode == true)
834  {
835  // follow the algorithm given in the introduction to this class
836  // of padding columns as necessary
837  unsigned int n = 0;
838  for (std::map< std::string, Column >::iterator p = columns.begin(); p != columns.end(); ++p)
839  n = (n >= p->second.entries.size() ? n : p->second.entries.size());
840 
841  while (columns[key].entries.size()+1 < n)
842  {
843  columns[key].entries.push_back (internal::TableEntry(T()));
844  internal::TableEntry &entry = columns[key].entries.back();
845  entry.cache_string(columns[key].scientific, columns[key].precision);
846  columns[key].max_length = std::max(columns[key].max_length, static_cast<unsigned int>(entry.get_cached_string().length()));
847  }
848  }
849 
850  // now push the value given to this function
851  columns[key].entries.push_back (internal::TableEntry(value));
852  internal::TableEntry &entry = columns[key].entries.back();
853  entry.cache_string(columns[key].scientific, columns[key].precision);
854  columns[key].max_length = std::max(columns[key].max_length, static_cast<unsigned int>(entry.get_cached_string().length()));
855 }
856 
857 
858 template <class Archive>
859 void
860 TableHandler::Column::save(Archive &ar, const unsigned int /*version*/) const
861 {
862  ar &entries &tex_caption
864  & scientific
865  & flag
866  & max_length;
867 }
868 
869 template<class Archive>
870 void
871 TableHandler::Column::load(Archive &ar, const unsigned int /*version*/)
872 {
873  ar &entries &tex_caption
874  & tex_format &precision
875  & scientific
876  & flag
877  & max_length;
878  invalidate_cache();
879 }
880 
881 
882 template <class Archive>
883 void
885  const unsigned int)
886 {
887  ar &column_order &columns
891  & auto_fill_mode;
892 }
893 
894 
895 DEAL_II_NAMESPACE_CLOSE
896 
897 #endif
std::map< std::string, std::string > tex_supercaptions
void set_precision(const std::string &key, const unsigned int precision)
unsigned int max_length
void save(Archive &ar, const unsigned int version) const
void set_tex_supercaption(const std::string &superkey, const std::string &tex_supercaption)
static ::ExceptionBase & ExcColumnOrSuperColumnNotExistent(std::string arg1)
void add_value(const std::string &key, const T value)
const std::string & get_cached_string() const
void set_tex_caption(const std::string &key, const std::string &tex_caption)
void cache_string(bool scientific, unsigned int precision) const
void add_column_to_supercolumn(const std::string &key, const std::string &superkey)
void set_tex_format(const std::string &key, const std::string &format="c")
void get_selected_columns(std::vector< std::string > &sel_columns) const
static ::ExceptionBase & ExcSuperColumnNotExistent(std::string arg1)
static ::ExceptionBase & ExcWrongNumberOfDataEntries(std::string arg1, int arg2, std::string arg3, int arg4)
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:564
void write_text(std::ostream &out, const TextOutputFormat format=table_with_headers) const
std::string cached_value
#define Assert(cond, exc)
Definition: exceptions.h:313
void save(Archive &ar, const unsigned int version) const
void set_tex_table_label(const std::string &table_label)
unsigned int precision
void write_tex(std::ostream &file, const bool with_header=true) const
void clear_current_row()
boost::variant< int, unsigned int, unsigned long long int, double, std::string > value_type
static ::ExceptionBase & ExcUndefinedTexFormat(std::string arg1)
void set_column_order(const std::vector< std::string > &new_order)
void set_scientific(const std::string &key, const bool scientific)
void pad_column_below(const unsigned int length)
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:600
static ::ExceptionBase & ExcColumnNotExistent(std::string arg1)
void serialize(Archive &ar, const unsigned int version)
std::vector< internal::TableEntry > entries
std::map< std::string, Column > columns
unsigned int n_rows() const
std::string tex_caption
void set_tex_table_caption(const std::string &table_caption)
std::map< std::string, std::vector< std::string > > supercolumns
std::string tex_table_label
static ::ExceptionBase & ExcInternalError()
void set_auto_fill_mode(const bool state)