Reference documentation for deal.II version 8.4.2
table_handler.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2016 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 
131  value_type value;
132 
136  mutable std::string cached_value;
137 
138  friend class ::TableHandler;
139  };
140 }
141 
142 
263 {
264 public:
324  {
325  table_with_headers,
326  table_with_separate_column_description,
327  simple_table_with_separate_column_description,
328  org_mode_table
329  };
330 
334  TableHandler ();
335 
342  template <typename T>
343  void add_value (const std::string &key,
344  const T value);
345 
350  void set_auto_fill_mode (const bool state);
351 
364  void add_column_to_supercolumn (const std::string &key,
365  const std::string &superkey);
366 
383  void set_column_order (const std::vector<std::string> &new_order);
384 
390  void set_precision (const std::string &key,
391  const unsigned int precision);
392 
397  void set_scientific (const std::string &key,
398  const bool scientific);
399 
405  void set_tex_caption (const std::string &key,
406  const std::string &tex_caption);
407 
411  void set_tex_table_caption (const std::string &table_caption);
412 
416  void set_tex_table_label (const std::string &table_label);
417 
423  void set_tex_supercaption (const std::string &superkey,
424  const std::string &tex_supercaption);
425 
432  void set_tex_format (const std::string &key,
433  const std::string &format="c");
434 
446  void write_text (std::ostream &out,
447  const TextOutputFormat format = table_with_headers) const;
448 
455  void write_tex (std::ostream &file, const bool with_header=true) const;
456 
461  void clear ();
462 
468  void clear_current_row ();
469 
474  template <class Archive>
475  void serialize(Archive &ar, const unsigned int version);
476 
485  DeclException1 (ExcColumnNotExistent,
486  std::string,
487  << "Column <" << arg1 << "> does not exist.");
488 
492  DeclException1 (ExcSuperColumnNotExistent,
493  std::string,
494  << "Supercolumn <" << arg1 << "> does not exist.");
495 
499  DeclException1 (ExcColumnOrSuperColumnNotExistent,
500  std::string,
501  << "Column or supercolumn <" << arg1 << "> does not exist.");
502 
506  DeclException4 (ExcWrongNumberOfDataEntries,
507  std::string, int, std::string, int,
508  << "Column <" << arg1 << "> has got " << arg2
509  << " rows, but Column <" << arg3 << "> has got " << arg4 << ".");
510 
514  DeclException1 (ExcUndefinedTexFormat,
515  std::string,
516  << "<" << arg1 << "> is not a tex column format. Use "
517  << "'l', 'c', or 'r' to indicate left, centered, or "
518  << "right aligned text.");
520 protected:
521 
526  struct Column
527  {
531  Column ();
532 
536  Column (const std::string &tex_caption);
537 
542  void pad_column_below (const unsigned int length);
543 
548  template <class Archive>
549  void save(Archive &ar, const unsigned int version) const;
550  template<class Archive>
551  void load(Archive &ar, const unsigned int version);
552  BOOST_SERIALIZATION_SPLIT_MEMBER()
553 
554 
555 
559  void invalidate_cache();
560 
565  std::vector<internal::TableEntry> entries;
566 
573  std::string tex_caption;
574 
582  std::string tex_format;
583 
588  unsigned int precision;
589 
594 
602  unsigned int flag;
603 
608  unsigned int max_length;
609  };
610 
619  void get_selected_columns (std::vector<std::string> &sel_columns) const;
620 
626  unsigned int n_rows() const;
627 
633  std::vector<std::string> column_order;
634 
642  mutable std::map<std::string,Column> columns;
643 
652  std::map<std::string, std::vector<std::string> > supercolumns;
653 
661  std::map<std::string, std::string> tex_supercaptions;
662 
666  std::string tex_table_caption;
670  std::string tex_table_label;
671 
676 };
677 
678 
679 namespace internal
680 {
681  template <typename T>
683  :
684  value (t)
685  {}
686 
687 
688  template <typename T>
689  T TableEntry::get () const
690  {
691  // we don't quite know the data type in 'value', but
692  // it must be one of the ones in the type list of the
693  // boost::variant. so if T is not in the list, or if
694  // the data stored in the TableEntry is not of type
695  // T, then we will get an exception that we can
696  // catch and produce an error message
697  try
698  {
699  return boost::get<T>(value);
700  }
701  catch (...)
702  {
703  Assert(false, ExcMessage ("This TableEntry object does not store a datum of type T"));
704  throw;
705  }
706  }
707 
708 
709 
710  template <class Archive>
711  void TableEntry::save (Archive &ar,
712  const unsigned int) const
713  {
714  // write first an identifier for the kind
715  // of data stored and then the actual
716  // data, in its correct data type
717  if (const int *p = boost::get<int>(&value))
718  {
719  char c = 'i';
720  ar &c & *p;
721  }
722  else if (const unsigned int *p = boost::get<unsigned int>(&value))
723  {
724  char c = 'u';
725  ar &c & *p;
726  }
727  else if (const double *p = boost::get<double>(&value))
728  {
729  char c = 'd';
730  ar &c & *p;
731  }
732  else if (const std::string *p = boost::get<std::string>(&value))
733  {
734  char c = 's';
735  ar &c & *p;
736  }
737  else if (const unsigned long long int *p = boost::get<unsigned long long int>(&value))
738  {
739  char c = 'l';
740  ar &c & *p;
741  }
742  else
743  Assert (false, ExcInternalError());
744  }
745 
746 
747 
748  template <class Archive>
749  void TableEntry::load (Archive &ar,
750  const unsigned int)
751  {
752  // following what we do in the save()
753  // function, first read in the data type
754  // as a one-character id, and then read
755  // the data
756  char c;
757  ar &c;
758 
759  switch (c)
760  {
761  case 'i':
762  {
763  int val;
764  ar &val;
765  value = val;
766  break;
767  }
768 
769  case 'u':
770  {
771  unsigned int val;
772  ar &val;
773  value = val;
774  break;
775  }
776 
777  case 'd':
778  {
779  double val;
780  ar &val;
781  value = val;
782  break;
783  }
784 
785  case 's':
786  {
787  std::string val;
788  ar &val;
789  value = val;
790  break;
791  }
792 
793  case 'l':
794  {
795  unsigned long long int val;
796  ar &val;
797  value = val;
798  break;
799  }
800 
801  default:
802  Assert (false, ExcInternalError());
803  }
804  }
805 }
806 
807 template <typename T>
808 void TableHandler::add_value (const std::string &key,
809  const T value)
810 {
811  // see if the column already exists
812  if (columns.find(key) == columns.end())
813  {
814  std::pair<std::string, Column> new_column(key, Column(key));
815  columns.insert(new_column);
816  column_order.push_back(key);
817  }
818 
819  if (auto_fill_mode == true)
820  {
821  // follow the algorithm given in the introduction to this class
822  // of padding columns as necessary
823  unsigned int n = 0;
824  for (std::map< std::string, Column >::iterator p = columns.begin(); p != columns.end(); ++p)
825  n = (n >= p->second.entries.size() ? n : p->second.entries.size());
826 
827  while (columns[key].entries.size()+1 < n)
828  {
829  columns[key].entries.push_back (internal::TableEntry(T()));
830  internal::TableEntry &entry = columns[key].entries.back();
831  entry.cache_string(columns[key].scientific, columns[key].precision);
832  columns[key].max_length = std::max(columns[key].max_length, static_cast<unsigned int>(entry.get_cached_string().length()));
833  }
834  }
835 
836  // now push the value given to this function
837  columns[key].entries.push_back (internal::TableEntry(value));
838  internal::TableEntry &entry = columns[key].entries.back();
839  entry.cache_string(columns[key].scientific, columns[key].precision);
840  columns[key].max_length = std::max(columns[key].max_length, static_cast<unsigned int>(entry.get_cached_string().length()));
841 }
842 
843 
844 template <class Archive>
845 void
846 TableHandler::Column::save(Archive &ar, const unsigned int /*version*/) const
847 {
848  ar &entries &tex_caption
849  & tex_format &precision
850  & scientific
851  & flag
852  & max_length;
853 }
854 
855 template<class Archive>
856 void
857 TableHandler::Column::load(Archive &ar, const unsigned int /*version*/)
858 {
859  ar &entries &tex_caption
860  & tex_format &precision
861  & scientific
862  & flag
863  & max_length;
864  invalidate_cache();
865 }
866 
867 
868 template <class Archive>
869 void
871  const unsigned int)
872 {
873  ar &column_order &columns
874  & supercolumns &tex_supercaptions
875  & tex_table_caption
876  & tex_table_label
877  & auto_fill_mode;
878 }
879 
880 
881 DEAL_II_NAMESPACE_CLOSE
882 
883 #endif
std::map< std::string, std::string > tex_supercaptions
unsigned int max_length
void save(Archive &ar, const unsigned int version) const
::ExceptionBase & ExcMessage(std::string arg1)
void add_value(const std::string &key, const T value)
const std::string & get_cached_string() const
void cache_string(bool scientific, unsigned int precision) const
void load(Archive &ar, const unsigned int version)
std::vector< std::string > column_order
std::string tex_format
std::string tex_table_caption
double get_numeric_value() const
TableEntry get_default_constructed_copy() const
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:542
std::string cached_value
#define Assert(cond, exc)
Definition: exceptions.h:294
void save(Archive &ar, const unsigned int version) const
unsigned int precision
boost::variant< int, unsigned int, unsigned long long int, double, std::string > value_type
#define DeclException4(Exception4, type1, type2, type3, type4, outsequence)
Definition: exceptions.h:572
void serialize(Archive &ar, const unsigned int version)
std::vector< internal::TableEntry > entries
std::map< std::string, Column > columns
std::string tex_caption
std::map< std::string, std::vector< std::string > > supercolumns
std::string tex_table_label