Reference documentation for deal.II version 9.1.0-pre
table_handler.cc
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.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #include <deal.II/base/table.h>
17 #include <deal.II/base/table_handler.h>
18 
19 #include <boost/io/ios_state.hpp>
20 
21 #include <iomanip>
22 #include <iostream>
23 #include <sstream>
24 
25 
26 DEAL_II_NAMESPACE_OPEN
27 
28 
29 /*---------------------------------------------------------------------*/
30 
31 // inline and template functions
32 namespace internal
33 {
34  double
36  {
37  // we don't quite know the data type in 'value', but
38  // it must be one of the ones in the type list of the
39  // boost::variant. Go through this list and return
40  // the value if this happens to be a number
41  //
42  // first try with int
43  try
44  {
45  return boost::get<int>(value);
46  }
47  catch (...)
48  {}
49 
50 
51  // ... then with unsigned int...
52  try
53  {
54  return boost::get<unsigned int>(value);
55  }
56  catch (...)
57  {}
58 
59  // ... then with unsigned long long int...
60  try
61  {
62  return boost::get<unsigned long long int>(value);
63  }
64  catch (...)
65  {}
66 
67  // ...and finally with double precision:
68  try
69  {
70  return boost::get<double>(value);
71  }
72  catch (...)
73  {
74  Assert(false,
75  ExcMessage("The number stored by this element of the "
76  "table is not a number."))
77  }
78 
79  return 0;
80  }
81 
82  void
83  TableEntry::cache_string(bool scientific, unsigned int precision) const
84  {
85  std::ostringstream ss;
86 
87  ss << std::setprecision(precision);
88 
89  if (scientific)
90  ss.setf(std::ios::scientific, std::ios::floatfield);
91  else
92  ss.setf(std::ios::fixed, std::ios::floatfield);
93 
94  ss << value;
95 
96  cached_value = ss.str();
97  if (cached_value.size() == 0)
98  cached_value = "\"\"";
99  }
100 
101  const std::string &
103  {
104  return cached_value;
105  }
106 
107 
108  namespace Local
109  {
110  // see which type we can cast to, then use this type to create
111  // a default constructed object
112  struct GetDefaultValue : public boost::static_visitor<>
113  {
114  template <typename T>
115  void
116  operator()(T &operand) const
117  {
118  operand = T();
119  }
120  };
121  } // namespace Local
122 
123  TableEntry
125  {
126  TableEntry new_entry = *this;
127  boost::apply_visitor(Local::GetDefaultValue(), new_entry.value);
128 
129  return new_entry;
130  }
131 
132 
133 } // namespace internal
134 
135 /* ------------------------------------------------ */
136 
137 TableHandler::Column::Column(const std::string &tex_caption)
138  : tex_caption(tex_caption)
139  , tex_format("c")
140  , precision(4)
141  , scientific(false)
142  , flag(0)
143  , max_length(0)
144 {}
145 
146 
147 
149  : tex_caption()
150  , tex_format("c")
151  , precision(4)
152  , scientific(false)
153  , flag(0)
154  , max_length(0)
155 {}
156 
157 
158 
159 void
161 {
162  // we should never have a column that is completely
163  // empty and that needs to be padded
164  Assert(entries.size() > 0, ExcInternalError());
165 
166  // add as many elements as necessary
167  while (entries.size() < size)
168  {
169  entries.push_back(entries.back().get_default_constructed_copy());
170  internal::TableEntry &entry = entries.back();
172  max_length =
173  std::max(max_length,
174  static_cast<unsigned int>(entry.get_cached_string().length()));
175  }
176 }
177 
178 
179 void
181 {
182  max_length = 0;
183 
184  for (std::vector<::internal::TableEntry>::iterator it = entries.begin();
185  it != entries.end();
186  ++it)
187  {
188  it->cache_string(this->scientific, this->precision);
189  max_length =
190  std::max(max_length,
191  static_cast<unsigned int>(it->get_cached_string().length()));
192  }
193 }
194 
195 
196 /*---------------------------------------------------------------------*/
197 
198 
200  : auto_fill_mode(false)
201 {}
202 
203 
204 
205 void
206 TableHandler::declare_column(const std::string &key)
207 {
208  // see if the column already exists; insert it if not
209  Assert(columns.find(key) == columns.end(),
210  ExcMessage("You are trying to declare a column with key <" + key +
211  "> but such a column already exists."));
212 
213  columns.insert(std::make_pair(key, Column(key)));
214  column_order.push_back(key);
215 }
216 
217 
218 
219 void
221 {
222  // figure out the longest current column
223  unsigned int max_col_length = 0;
224  for (std::map<std::string, Column>::iterator p = columns.begin();
225  p != columns.end();
226  ++p)
227  max_col_length =
228  std::max(max_col_length,
229  static_cast<unsigned int>(p->second.entries.size()));
230 
231 
232  // then pad all columns to that length with empty strings
233  for (std::map<std::string, Column>::iterator col = columns.begin();
234  col != columns.end();
235  ++col)
236  while (col->second.entries.size() < max_col_length)
237  {
238  col->second.entries.emplace_back("");
239  internal::TableEntry &entry = col->second.entries.back();
240  entry.cache_string(col->second.scientific, col->second.precision);
241  col->second.max_length =
242  std::max(col->second.max_length,
243  static_cast<unsigned int>(
244  entry.get_cached_string().length()));
245  }
246 }
247 
248 
249 
250 void
252 {
253  auto_fill_mode = state;
254 }
255 
256 
257 void
259  const std::string &superkey)
260 {
261  Assert(columns.count(key), ExcColumnNotExistent(key));
262 
263  if (!supercolumns.count(superkey))
264  {
265  std::pair<std::string, std::vector<std::string>> new_column(
266  superkey, std::vector<std::string>());
267  supercolumns.insert(new_column);
268  // replace key in column_order
269  // by superkey
270  for (unsigned int j = 0; j < column_order.size(); ++j)
271  if (column_order[j] == key)
272  {
273  column_order[j] = superkey;
274  break;
275  }
276  }
277  else
278  {
279  // remove key from column_order
280  // for erase we need an iterator
281  for (std::vector<std::string>::iterator order_iter = column_order.begin();
282  order_iter != column_order.end();
283  ++order_iter)
284  if (*order_iter == key)
285  {
286  column_order.erase(order_iter);
287  break;
288  }
289  }
290 
291  if (supercolumns.count(superkey))
292  {
293  supercolumns[superkey].push_back(key);
294  // By default set the
295  // tex_supercaption to superkey
296  std::pair<std::string, std::string> new_tex_supercaption(superkey,
297  superkey);
298  tex_supercaptions.insert(new_tex_supercaption);
299  }
300  else
301  Assert(false, ExcInternalError());
302 }
303 
304 
305 
306 void
307 TableHandler::set_column_order(const std::vector<std::string> &new_order)
308 {
309  for (unsigned int j = 0; j < new_order.size(); ++j)
310  Assert(supercolumns.count(new_order[j]) || columns.count(new_order[j]),
311  ExcColumnOrSuperColumnNotExistent(new_order[j]));
312 
313  column_order = new_order;
314 }
315 
316 
317 void
318 TableHandler::set_tex_caption(const std::string &key,
319  const std::string &tex_caption)
320 {
321  Assert(columns.count(key), ExcColumnNotExistent(key));
322  columns[key].tex_caption = tex_caption;
323 }
324 
325 
326 
327 void
328 TableHandler::set_tex_table_caption(const std::string &table_caption)
329 {
330  tex_table_caption = table_caption;
331 }
332 
333 
334 
335 void
336 TableHandler::set_tex_table_label(const std::string &table_label)
337 {
338  tex_table_label = table_label;
339 }
340 
341 
342 
343 void
344 TableHandler::set_tex_supercaption(const std::string &superkey,
345  const std::string &tex_supercaption)
346 {
347  Assert(supercolumns.count(superkey), ExcSuperColumnNotExistent(superkey));
348  Assert(tex_supercaptions.count(superkey), ExcInternalError());
349  tex_supercaptions[superkey] = tex_supercaption;
350 }
351 
352 
353 
354 void
355 TableHandler::set_tex_format(const std::string &key,
356  const std::string &tex_format)
357 {
358  Assert(columns.count(key), ExcColumnNotExistent(key));
359  Assert(tex_format == "l" || tex_format == "c" || tex_format == "r",
360  ExcUndefinedTexFormat(tex_format));
361  columns[key].tex_format = tex_format;
362 }
363 
364 
365 
366 void
367 TableHandler::set_precision(const std::string &key,
368  const unsigned int precision)
369 {
370  Assert(columns.count(key), ExcColumnNotExistent(key));
371  if (columns[key].precision != precision)
372  {
373  columns[key].precision = precision;
374  columns[key].invalidate_cache();
375  }
376 }
377 
378 
379 void
380 TableHandler::set_scientific(const std::string &key, const bool scientific)
381 {
382  Assert(columns.count(key), ExcColumnNotExistent(key));
383  if (columns[key].scientific != scientific)
384  {
385  columns[key].scientific = scientific;
386  columns[key].invalidate_cache();
387  }
388 }
389 
390 
391 void
392 TableHandler::write_text(std::ostream &out, const TextOutputFormat format) const
393 {
394  AssertThrow(out, ExcIO());
395  boost::io::ios_flags_saver restore_flags(out);
396 
397  // first pad the table from below if necessary
398  if (auto_fill_mode == true)
399  {
400  unsigned int max_rows = 0;
401  for (std::map<std::string, Column>::const_iterator p = columns.begin();
402  p != columns.end();
403  ++p)
404  max_rows = std::max<unsigned int>(max_rows, p->second.entries.size());
405 
406  for (std::map<std::string, Column>::iterator p = columns.begin();
407  p != columns.end();
408  ++p)
409  p->second.pad_column_below(max_rows);
410  }
411 
412  std::vector<std::string> sel_columns;
413  get_selected_columns(sel_columns);
414 
415  const unsigned int nrows = n_rows();
416  const unsigned int n_cols = sel_columns.size();
417 
418  // cache the columns and compute the widths of each column for alignment
419  std::vector<const Column *> cols;
420  std::vector<unsigned int> column_widths(n_cols, 0);
421  for (unsigned int j = 0; j < n_cols; ++j)
422  {
423  std::string key = sel_columns[j];
424  const std::map<std::string, Column>::const_iterator col_iter =
425  columns.find(key);
426  Assert(col_iter != columns.end(), ExcInternalError());
427  cols.push_back(&(col_iter->second));
428 
429  column_widths[j] = col_iter->second.max_length;
430  }
431 
432  switch (format)
433  {
434  case org_mode_table:
435  {
436  // write the captions
437  out << "| " << std::left;
438  for (unsigned int j = 0; j < n_cols; ++j)
439  {
440  const std::string &key = sel_columns[j];
441  column_widths[j] =
442  std::max(column_widths[j], (unsigned int)key.length());
443  out << std::setw(column_widths[j]);
444  out << key << " | ";
445  }
446  out << std::endl;
447 
448  // write the body
449  for (unsigned int i = 0; i < nrows; ++i)
450  {
451  out << "| ";
452  for (unsigned int j = 0; j < n_cols; ++j)
453  {
454  const Column &column = *(cols[j]);
455 
456  out << std::setw(column_widths[j]);
457  out << column.entries[i].get_cached_string();
458  out << " | ";
459  }
460  out << '\n';
461  }
462 
463  out << std::flush;
464  return;
465  }
466 
468  {
469  // write the captions
470  for (unsigned int j = 0; j < n_cols; ++j)
471  {
472  const std::string &key = sel_columns[j];
473  out << "# " << j + 1 << ": " << key << '\n';
474  }
475 
476  // write the body
477  for (unsigned int i = 0; i < nrows; ++i)
478  {
479  for (unsigned int j = 0; j < n_cols; ++j)
480  {
481  const Column &column = *(cols[j]);
482 
483  out << column.entries[i].get_cached_string();
484  out << ' ';
485  }
486  out << '\n';
487  }
488 
489  out << std::flush;
490  return;
491  }
492 
494  {
495  // writing the captions for table_with_separate_column_description
496  // means that we ignore supercolumns and output the column
497  // header for each column. enumerate columns starting with 1
498  for (unsigned int j = 0; j < n_cols; ++j)
499  {
500  std::string key = sel_columns[j];
501  out << "# " << j + 1 << ": " << key << '\n';
502  }
503  break;
504  }
505 
506  case table_with_headers:
507  {
508  // This format output supercolumn headers and aligns them centered
509  // over all the columns that belong to it.
510  for (unsigned int j = 0; j < column_order.size(); ++j)
511  {
512  const std::string &key = column_order[j];
513  unsigned int width = 0;
514  {
515  // compute the width of this column or supercolumn
516  const std::map<std::string,
517  std::vector<std::string>>::const_iterator
518  super_iter = supercolumns.find(key);
519  if (super_iter != supercolumns.end())
520  {
521  const unsigned int n_subcolumns = super_iter->second.size();
522  for (unsigned int k = 0; k < n_subcolumns; ++k)
523  {
524  const std::map<std::string, Column>::const_iterator
525  col_iter = columns.find(super_iter->second[k]);
526  Assert(col_iter != columns.end(), ExcInternalError());
527 
528  width += col_iter->second.max_length;
529  }
530  width += n_subcolumns - 1; // separators between subcolumns
531  }
532  else
533  {
534  const std::map<std::string, Column>::const_iterator
535  col_iter = columns.find(key);
536 
537  width = col_iter->second.max_length;
538  }
539  }
540 
541  // header is longer than the column(s) under it
542  if (width < key.length())
543  {
544  // make the column or the last column in this
545  // supercolumn wide enough
546  std::string colname;
547 
548  const std::map<std::string,
549  std::vector<std::string>>::const_iterator
550  super_iter = supercolumns.find(key);
551  if (super_iter != supercolumns.end())
552  colname = super_iter->second.back();
553  else
554  colname = key;
555 
556  // find column and change output width
557  for (unsigned int i = 0; i < n_cols; ++i)
558  {
559  if (sel_columns[i] == colname)
560  {
561  column_widths[i] += key.length() - width;
562  break;
563  }
564  }
565 
566  width = key.length();
567  }
568 
569  // now write key. try to center it somehow
570  const unsigned int front_padding = (width - key.length()) / 2,
571  rear_padding =
572  (width - key.length()) - front_padding;
573  for (unsigned int i = 0; i < front_padding; ++i)
574  out << ' ';
575  out << key;
576  for (unsigned int i = 0; i < rear_padding; ++i)
577  out << ' ';
578 
579  out << ' ';
580  }
581  out << '\n';
582  break;
583  }
584 
585  default:
586  Assert(false, ExcInternalError());
587  }
588 
589 
590  // finally output the data itself for
591  // table_with_headers or table_with_separate_column_description:
592  for (unsigned int i = 0; i < nrows; ++i)
593  {
594  for (unsigned int j = 0; j < n_cols; ++j)
595  {
596  const Column &column = *(cols[j]);
597  out << std::setw(column_widths[j]);
598  out << column.entries[i].get_cached_string();
599 
600  // pad after this column
601  out << ' ';
602  }
603  out << '\n';
604  }
605  out << std::flush;
606 }
607 
608 
609 void
610 TableHandler::write_tex(std::ostream &out, const bool with_header) const
611 {
612  // TODO[TH]: update code similar to
613  // write_text() to use the cache
614  AssertThrow(out, ExcIO());
615  if (with_header)
616  out << "\\documentclass[10pt]{report}" << std::endl
617  << "\\usepackage{float}" << std::endl
618  << std::endl
619  << std::endl
620  << "\\begin{document}" << std::endl;
621 
622  out << "\\begin{table}[H]" << std::endl
623  << "\\begin{center}" << std::endl
624  << "\\begin{tabular}{|";
625 
626  // first pad the table from below if necessary
627  if (auto_fill_mode == true)
628  {
629  unsigned int max_rows = 0;
630  for (std::map<std::string, Column>::const_iterator p = columns.begin();
631  p != columns.end();
632  ++p)
633  max_rows = std::max<unsigned int>(max_rows, p->second.entries.size());
634 
635  for (std::map<std::string, Column>::iterator p = columns.begin();
636  p != columns.end();
637  ++p)
638  p->second.pad_column_below(max_rows);
639  }
640 
641  std::vector<std::string> sel_columns;
642  get_selected_columns(sel_columns);
643 
644  // write the column formats
645  for (unsigned int j = 0; j < column_order.size(); ++j)
646  {
647  std::string key = column_order[j];
648  // avoid `supercolumns[key]'
649  const std::map<std::string, std::vector<std::string>>::const_iterator
650  super_iter = supercolumns.find(key);
651 
652  if (super_iter != supercolumns.end())
653  {
654  const unsigned int n_subcolumns = super_iter->second.size();
655  for (unsigned int k = 0; k < n_subcolumns; ++k)
656  {
657  // avoid `columns[supercolumns[key]]'
658  const std::map<std::string, Column>::const_iterator col_iter =
659  columns.find(super_iter->second[k]);
660  Assert(col_iter != columns.end(), ExcInternalError());
661 
662  out << col_iter->second.tex_format << "|";
663  }
664  }
665  else
666  {
667  // avoid `columns[key]';
668  const std::map<std::string, Column>::const_iterator col_iter =
669  columns.find(key);
670  Assert(col_iter != columns.end(), ExcInternalError());
671  out << col_iter->second.tex_format << "|";
672  }
673  }
674  out << "} \\hline" << std::endl;
675 
676  // write the caption line of the table
677 
678  for (unsigned int j = 0; j < column_order.size(); ++j)
679  {
680  std::string key = column_order[j];
681  const std::map<std::string, std::vector<std::string>>::const_iterator
682  super_iter = supercolumns.find(key);
683 
684  if (super_iter != supercolumns.end())
685  {
686  const unsigned int n_subcolumns = super_iter->second.size();
687  // avoid use of `tex_supercaptions[key]'
688  std::map<std::string, std::string>::const_iterator
689  tex_super_cap_iter = tex_supercaptions.find(key);
690  out << std::endl
691  << "\\multicolumn{" << n_subcolumns << "}{|c|}{"
692  << tex_super_cap_iter->second << "}";
693  }
694  else
695  {
696  // col_iter->second=columns[col];
697  const std::map<std::string, Column>::const_iterator col_iter =
698  columns.find(key);
699  Assert(col_iter != columns.end(), ExcInternalError());
700  out << col_iter->second.tex_caption;
701  }
702  if (j < column_order.size() - 1)
703  out << " & ";
704  }
705  out << "\\\\ \\hline" << std::endl;
706 
707  // write the n rows
708  const unsigned int nrows = n_rows();
709  for (unsigned int i = 0; i < nrows; ++i)
710  {
711  const unsigned int n_cols = sel_columns.size();
712 
713  for (unsigned int j = 0; j < n_cols; ++j)
714  {
715  std::string key = sel_columns[j];
716  // avoid `column[key]'
717  const std::map<std::string, Column>::const_iterator col_iter =
718  columns.find(key);
719  Assert(col_iter != columns.end(), ExcInternalError());
720 
721  const Column &column = col_iter->second;
722 
723  out << std::setprecision(column.precision);
724 
725  if (col_iter->second.scientific)
726  out.setf(std::ios::scientific, std::ios::floatfield);
727  else
728  out.setf(std::ios::fixed, std::ios::floatfield);
729 
730  out << column.entries[i].value;
731 
732  if (j < n_cols - 1)
733  out << " & ";
734  }
735  out << "\\\\ \\hline" << std::endl;
736  }
737 
738  out << "\\end{tabular}" << std::endl << "\\end{center}" << std::endl;
739  if (tex_table_caption != "")
740  out << "\\caption{" << tex_table_caption << "}" << std::endl;
741  if (tex_table_label != "")
742  out << "\\label{" << tex_table_label << "}" << std::endl;
743  out << "\\end{table}" << std::endl;
744  if (with_header)
745  out << "\\end{document}" << std::endl;
746 }
747 
748 
749 void
751 {
752  columns.clear();
753  supercolumns.clear();
754  column_order.clear();
755  tex_supercaptions.clear();
756 
757  tex_table_label.clear();
758  tex_table_caption.clear();
759 }
760 
761 
762 unsigned int
764 {
765  if (columns.size() == 0)
766  return 0;
767 
768  std::map<std::string, Column>::const_iterator col_iter = columns.begin();
769  unsigned int n = col_iter->second.entries.size();
770  std::string first_name = col_iter->first;
771 
772  for (++col_iter; col_iter != columns.end(); ++col_iter)
773  Assert(col_iter->second.entries.size() == n,
775  col_iter->first, col_iter->second.entries.size(), first_name, n));
776 
777  return n;
778 }
779 
780 
781 void
782 TableHandler::get_selected_columns(std::vector<std::string> &sel_columns) const
783 {
784  sel_columns.clear();
785 
786  for (unsigned int j = 0; j < column_order.size(); ++j)
787  {
788  std::string key = column_order[j];
789  const std::map<std::string, std::vector<std::string>>::const_iterator
790  super_iter = supercolumns.find(key);
791 
792  if (super_iter != supercolumns.end())
793  {
794  // i.e. key is a supercolumn key
795  const unsigned int n_subcolumns = super_iter->second.size();
796  for (unsigned int k = 0; k < n_subcolumns; ++k)
797  {
798  const std::string subkey = super_iter->second[k];
799  Assert(columns.count(subkey), ExcInternalError());
800  sel_columns.push_back(subkey);
801  }
802  }
803  else
804  {
805  Assert(columns.count(key), ExcInternalError());
806  // i.e. key is a column key
807  sel_columns.push_back(key);
808  }
809  }
810 }
811 
812 
813 void
815 {
816  // Figure out what is the currect (max) length of the columns
817  // so that we "shave" one off.
818  std::vector<internal::TableEntry>::size_type n = 0;
819  for (std::map<std::string, Column>::iterator p = columns.begin();
820  p != columns.end();
821  ++p)
822  n = std::max(n, p->second.entries.size());
823 
824  // shave the top most element
825  if (n != 0)
826  for (std::map<std::string, Column>::iterator p = columns.begin();
827  p != columns.end();
828  ++p)
829  if (p->second.entries.size() == n)
830  p->second.entries.pop_back();
831 }
832 
833 
834 DEAL_II_NAMESPACE_CLOSE
std::map< std::string, std::string > tex_supercaptions
void set_precision(const std::string &key, const unsigned int precision)
void declare_column(const std::string &key)
unsigned int max_length
static::ExceptionBase & ExcIO()
void set_tex_supercaption(const std::string &superkey, const std::string &tex_supercaption)
std::map< std::string, Column > columns
static::ExceptionBase & ExcColumnOrSuperColumnNotExistent(std::string arg1)
void set_tex_caption(const std::string &key, const std::string &tex_caption)
#define AssertThrow(cond, exc)
Definition: exceptions.h:1329
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")
static::ExceptionBase & ExcSuperColumnNotExistent(std::string arg1)
void get_selected_columns(std::vector< std::string > &sel_columns) const
static::ExceptionBase & ExcWrongNumberOfDataEntries(std::string arg1, int arg2, std::string arg3, int arg4)
std::vector< std::string > column_order
std::string tex_format
void cache_string(bool scientific, unsigned int precision) const
static::ExceptionBase & ExcMessage(std::string arg1)
std::string tex_table_caption
std::string cached_value
#define Assert(cond, exc)
Definition: exceptions.h:1227
void write_tex(std::ostream &file, const bool with_header=true) const
void set_tex_table_label(const std::string &table_label)
const std::string & get_cached_string() const
unsigned int precision
void clear_current_row()
static::ExceptionBase & ExcUndefinedTexFormat(std::string arg1)
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
static::ExceptionBase & ExcColumnNotExistent(std::string arg1)
std::vector< internal::TableEntry > entries
void start_new_row()
std::string tex_caption
void set_tex_table_caption(const std::string &table_caption)
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
static::ExceptionBase & ExcInternalError()
void set_auto_fill_mode(const bool state)