Reference documentation for deal.II version 8.1.0
table_handler.h
1 // ---------------------------------------------------------------------
2 // @f$Id: table_handler.h 30316 2013-08-15 11:59:44Z bangerth @f$
3 //
4 // Copyright (C) 1999 - 2013 by the deal.II authors
5 //
6 // This file is part of the deal.II library.
7 //
8 // The deal.II library is free software; you can use it, redistribute
9 // it, and/or modify it under the terms of the GNU Lesser General
10 // Public License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 // The full text of the license can be found in the file LICENSE at
13 // the top level of the deal.II distribution.
14 //
15 // ---------------------------------------------------------------------
16 
17 #ifndef __deal2__table_handler_h
18 #define __deal2__table_handler_h
19 
20 
21 #include <deal.II/base/config.h>
23 
24 #include <map>
25 #include <vector>
26 #include <string>
27 #include <fstream>
28 
29 #include <ostream>
30 
31 #include <boost/variant.hpp>
32 #include <boost/serialization/map.hpp>
33 #include <boost/serialization/string.hpp>
34 #include <boost/serialization/vector.hpp>
35 #include <boost/serialization/split_member.hpp>
36 
37 
39 
40 class TableHandler;
41 
42 namespace internal
43 {
53  struct TableEntry
54  {
55  public:
59  TableEntry ();
60 
64  template <typename T>
65  TableEntry (const T &t);
66 
73  template <typename T>
74  T get () const;
75 
82  double get_numeric_value () const;
83 
90  void cache_string(bool scientific, unsigned int precision) const;
91 
95  const std::string &get_cached_string() const;
96 
97 
105 
111  template <class Archive>
112  void save (Archive &ar, const unsigned int version) const;
113 
119  template <class Archive>
120  void load (Archive &ar, const unsigned int version);
121 
122  BOOST_SERIALIZATION_SPLIT_MEMBER()
123 
124  private:
128  typedef boost::variant<int,unsigned int,unsigned long long int,double,std::string> value_type;
129 
133  value_type value;
134 
138  mutable std::string cached_value;
139 
140  friend class ::TableHandler;
141  };
142 }
143 
144 
265 {
266 public:
326  {
327  table_with_headers,
328  table_with_separate_column_description,
329  simple_table_with_separate_column_description,
330  org_mode_table
331  };
332 
336  TableHandler ();
337 
348  template <typename T>
349  void add_value (const std::string &key,
350  const T value);
351 
356  void set_auto_fill_mode (const bool state);
357 
380  void add_column_to_supercolumn (const std::string &key,
381  const std::string &superkey);
382 
412  void set_column_order (const std::vector<std::string> &new_order);
413 
422  void set_precision (const std::string &key,
423  const unsigned int precision);
424 
431  void set_scientific (const std::string &key,
432  const bool scientific);
433 
442  void set_tex_caption (const std::string &key,
443  const std::string &tex_caption);
444 
449  void set_tex_table_caption (const std::string &table_caption);
450 
455  void set_tex_table_label (const std::string &table_label);
456 
466  void set_tex_supercaption (const std::string &superkey,
467  const std::string &tex_supercaption);
468 
478  void set_tex_format (const std::string &key,
479  const std::string &format="c");
480 
500  void write_text (std::ostream &out,
501  const TextOutputFormat format = table_with_headers) const;
502 
515  void write_tex (std::ostream &file, const bool with_header=true) const;
516 
522  template <class Archive>
523  void serialize(Archive &ar, const unsigned int version);
524 
531  DeclException1 (ExcColumnNotExistent,
532  std::string,
533  << "Column <" << arg1 << "> does not exist.");
534 
538  DeclException1 (ExcSuperColumnNotExistent,
539  std::string,
540  << "Supercolumn <" << arg1 << "> does not exist.");
541 
545  DeclException1 (ExcColumnOrSuperColumnNotExistent,
546  std::string,
547  << "Column or supercolumn <" << arg1 << "> does not exist.");
548 
552  DeclException4 (ExcWrongNumberOfDataEntries,
553  std::string, int, std::string, int,
554  << "Column <" << arg1 << "> has got " << arg2
555  << " rows, but Column <" << arg3 << "> has got " << arg4 << ".");
556 
560  DeclException1 (ExcUndefinedTexFormat,
561  std::string,
562  << "<" << arg1 << "> is not a tex column format. Use l,c,r.");
564 protected:
565 
571  struct Column
572  {
576  Column ();
577 
581  Column (const std::string &tex_caption);
582 
587  void pad_column_below (const unsigned int length);
588 
594  template <class Archive>
595  void save(Archive &ar, const unsigned int version) const;
596  template<class Archive>
597  void load(Archive &ar, const unsigned int version);
598  BOOST_SERIALIZATION_SPLIT_MEMBER()
599 
600 
601 
605  void invalidate_cache();
606 
615  std::vector<internal::TableEntry> entries;
616 
627  std::string tex_caption;
628 
640  std::string tex_format;
641 
648  unsigned int precision;
649 
655 
668  unsigned int flag;
669 
673  unsigned int max_length;
674  };
675 
689  void get_selected_columns (std::vector<std::string> &sel_columns) const;
690 
700  unsigned int n_rows() const;
701 
711  std::vector<std::string> column_order;
712 
723  mutable std::map<std::string,Column> columns;
724 
737  std::map<std::string, std::vector<std::string> > supercolumns;
738 
750  std::map<std::string, std::string> tex_supercaptions;
751 
755  std::string tex_table_caption;
759  std::string tex_table_label;
760 
765 };
766 
767 
768 namespace internal
769 {
770  template <typename T>
772  :
773  value (t)
774  {}
775 
776 
777  template <typename T>
778  T TableEntry::get () const
779  {
780  // we don't quite know the data type in 'value', but
781  // it must be one of the ones in the type list of the
782  // boost::variant. so if T is not in the list, or if
783  // the data stored in the TableEntry is not of type
784  // T, then we will get an exception that we can
785  // catch and produce an error message
786  try
787  {
788  return boost::get<T>(value);
789  }
790  catch (...)
791  {
792  Assert(false, ExcMessage ("This TableEntry object does not store a datum of type T"));
793  throw;
794  }
795  }
796 
797 
798 
799  template <class Archive>
800  void TableEntry::save (Archive &ar,
801  const unsigned int) const
802  {
803  // write first an identifier for the kind
804  // of data stored and then the actual
805  // data, in its correct data type
806  if (const int *p = boost::get<int>(&value))
807  {
808  char c = 'i';
809  ar &c & *p;
810  }
811  else if (const unsigned int *p = boost::get<unsigned int>(&value))
812  {
813  char c = 'u';
814  ar &c & *p;
815  }
816  else if (const double *p = boost::get<double>(&value))
817  {
818  char c = 'd';
819  ar &c & *p;
820  }
821  else if (const std::string *p = boost::get<std::string>(&value))
822  {
823  char c = 's';
824  ar &c & *p;
825  }
826  else
827  Assert (false, ExcInternalError());
828  }
829 
830 
831 
832  template <class Archive>
833  void TableEntry::load (Archive &ar,
834  const unsigned int)
835  {
836  // following what we do in the save()
837  // function, first read in the data type
838  // as a one-character id, and then read
839  // the data
840  char c;
841  ar &c;
842 
843  switch (c)
844  {
845  case 'i':
846  {
847  int val;
848  ar &val;
849  value = val;
850  break;
851  }
852 
853  case 'u':
854  {
855  unsigned int val;
856  ar &val;
857  value = val;
858  break;
859  }
860 
861  case 'd':
862  {
863  double val;
864  ar &val;
865  value = val;
866  break;
867  }
868 
869  case 's':
870  {
871  std::string val;
872  ar &val;
873  value = val;
874  break;
875  }
876 
877  default:
878  Assert (false, ExcInternalError());
879  }
880  }
881 }
882 
883 template <typename T>
884 void TableHandler::add_value (const std::string &key,
885  const T value)
886 {
887  // see if the column already exists
888  if (columns.find(key) == columns.end())
889  {
890  std::pair<std::string, Column> new_column(key, Column(key));
891  columns.insert(new_column);
892  column_order.push_back(key);
893  }
894 
895  if (auto_fill_mode == true)
896  {
897  // follow the algorithm given in the introduction to this class
898  // of padding columns as necessary
899  unsigned int n = 0;
900  for (std::map< std::string, Column >::iterator p = columns.begin(); p != columns.end(); ++p)
901  n = (n >= p->second.entries.size() ? n : p->second.entries.size());
902 
903  while (columns[key].entries.size()+1 < n)
904  {
905  columns[key].entries.push_back (internal::TableEntry(T()));
906  internal::TableEntry &entry = columns[key].entries.back();
907  entry.cache_string(columns[key].scientific, columns[key].precision);
908  columns[key].max_length = std::max(columns[key].max_length, static_cast<unsigned int>(entry.get_cached_string().length()));
909  }
910  }
911 
912  // now push the value given to this function
913  columns[key].entries.push_back (internal::TableEntry(value));
914  internal::TableEntry &entry = columns[key].entries.back();
915  entry.cache_string(columns[key].scientific, columns[key].precision);
916  columns[key].max_length = std::max(columns[key].max_length, static_cast<unsigned int>(entry.get_cached_string().length()));
917 }
918 
919 
920 template <class Archive>
921 void
922 TableHandler::Column::save(Archive &ar, const unsigned int version) const
923 {
924  ar &entries &tex_caption
926  & scientific
927  & flag
928  & max_length;
929 }
930 
931 template<class Archive>
932 void
933 TableHandler::Column::load(Archive &ar, const unsigned int version)
934 {
935  ar &entries &tex_caption
936  & tex_format &precision
937  & scientific
938  & flag
939  & max_length;
940  invalidate_cache();
941 }
942 
943 
944 template <class Archive>
945 void
947  const unsigned int)
948 {
949  ar &column_order &columns
953  & auto_fill_mode;
954 }
955 
956 
957 DEAL_II_NAMESPACE_CLOSE
958 
959 #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)
::ExceptionBase & ExcMessage(std::string arg1)
void add_value(const std::string &key, const T value)
void set_tex_caption(const std::string &key, const std::string &tex_caption)
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 save(Archive &ar, const unsigned int version) const
void get_selected_columns(std::vector< std::string > &sel_columns) const
void load(Archive &ar, const unsigned int version)
DeclException4(ExcWrongNumberOfDataEntries, std::string, int, std::string, int,<< "Column <"<< arg1<< "> has got "<< arg2<< " rows, but Column <"<< arg3<< "> has got "<< arg4<< ".")
std::vector< std::string > column_order
std::string tex_format
void cache_string(bool scientific, unsigned int precision) const
std::string tex_table_caption
const std::string & get_cached_string() const
std::string cached_value
#define Assert(cond, exc)
Definition: exceptions.h:299
void write_tex(std::ostream &file, const bool with_header=true) const
void set_tex_table_label(const std::string &table_label)
unsigned int precision
DeclException1(ExcColumnNotExistent, std::string,<< "Column <"<< arg1<< "> does not exist.")
boost::variant< int, unsigned int, unsigned long long int, double, std::string > value_type
double get_numeric_value() const
void set_column_order(const std::vector< std::string > &new_order)
unsigned int n_rows() const
void set_scientific(const std::string &key, const bool scientific)
void pad_column_below(const unsigned int length)
TableEntry get_default_constructed_copy() const
void serialize(Archive &ar, const unsigned int version)
std::vector< internal::TableEntry > entries
std::map< std::string, Column > columns
std::string tex_caption
void set_tex_table_caption(const std::string &table_caption)
::ExceptionBase & ExcInternalError()
std::map< std::string, std::vector< std::string > > supercolumns
void write_text(std::ostream &out, const TextOutputFormat format=table_with_headers) const
std::string tex_table_label
void set_auto_fill_mode(const bool state)