Chebyshev
Unit testing for scientific software
output.h
Go to the documentation of this file.
1 
5 
6 #ifndef CHEBYSHEV_OUTPUT_H
7 #define CHEBYSHEV_OUTPUT_H
8 
9 #include <vector>
10 #include <string>
11 #include <map>
12 #include <sstream>
13 #include <iomanip>
14 
15 #include "../prec/prec_structures.h"
16 #include "../benchmark/benchmark_structures.h"
17 #include "../err/err_structures.h"
18 
19 
20 namespace chebyshev {
21 
23  namespace output {
24 
27  struct field_options {
28 
29  using FieldInterpreter = std::function<std::string(const std::string&)>;
30 
33 
36  FieldInterpreter fieldInterpreter = [](const std::string& s) { return s; };
37 
39  std::map<std::string, long double> additionalFields {};
40 
41  // Default constructor
42  field_options() {}
43 
44  // Construct field options from the custom column width.
45  field_options(unsigned int columnWidth) : columnWidth(columnWidth) {}
46  };
47 
48 
51  struct output_settings {
52 
53  using OutputFormat_t = std::function<
55  const std::vector<std::vector<std::string>>&,
56  const std::vector<std::string>&,
57  const output_settings&)>;
58 
61  std::map<std::string, std::string> fieldNames {};
62 
64  std::map<std::string, field_options> fieldOptions {};
65 
67  std::vector<std::string> outputFiles {};
68 
70  std::map<std::string, std::ofstream> openFiles {};
71 
74 
76  unsigned int outputPrecision = 1;
77 
79  OutputFormat_t outputFormat {};
80 
83  OutputFormat_t defaultFileOutputFormat {};
84 
86  std::map<std::string, OutputFormat_t> fileOutputFormat {};
87 
89  bool quiet = false;
90 
92  bool wasSetup = false;
93 
94  } settings;
95 
96 
100  using OutputFormat = output_settings::OutputFormat_t;
101 
102 
115  namespace format {
116 
117 
121 
122  return [](
123  const std::vector<std::vector<std::string>>& table,
124  const std::vector<std::string>& fields,
125  const output_settings& settings) -> std::string {
126 
127  if(!table.size())
128  return "";
129 
130  std::stringstream result;
131 
132  for (size_t i = 0; i < table.size(); ++i) {
133 
134  if(table[i].size() != fields.size()) {
135  std::runtime_error(
136  "Number of columns and fields argument must have "
137  "the same size in output::format::barebone");
138  }
139 
140  for (size_t j = 0; j < table[i].size(); ++j) {
141 
142  auto it = settings.fieldOptions.find(fields[j]);
143 
144  if(it != settings.fieldOptions.end() && i)
145  result << std::setw(it->second.columnWidth)
146  << std::left << it->second.fieldInterpreter(table[i][j]);
147  else if(it != settings.fieldOptions.end())
148  result << std::setw(it->second.columnWidth)
149  << std::left << table[i][j];
150  else
151  result << std::setw(settings.defaultColumnWidth)
152  << std::left << table[i][j];
153  }
154 
155  result << "\n";
156  }
157 
158  return result.str();
159  };
160  }
161 
162 
168  inline OutputFormat simple() {
169 
170  return [](
171  const std::vector<std::vector<std::string>>& table,
172  const std::vector<std::string>& fields,
173  const output_settings& settings) -> std::string {
174 
175  if(!table.size())
176  return "";
177 
178  std::stringstream result;
179  std::stringstream header_str;
180 
181  header_str << " | ";
182 
183  for (size_t i = 0; i < table[0].size(); ++i) {
184 
185  auto it = settings.fieldOptions.find(fields[i]);
186 
187  if(it != settings.fieldOptions.end())
188  header_str << std::setw(it->second.columnWidth) << table[0][i] << " | ";
189  else
190  header_str << std::setw(settings.defaultColumnWidth) << table[0][i] << " | ";
191  }
192 
193  std::string header = header_str.str();
194  std::string decoration = " +";
195  for (size_t i = 4; i < header.size(); ++i)
196  decoration += "-";
197  decoration += "+ \n";
198 
199  for (size_t i = 1; i < table.size(); ++i) {
200 
201  if(table[i].size() != fields.size()) {
202  std::runtime_error(
203  "Number of columns and <fields> argument must have "
204  "the same size in output::format::simple");
205  }
206 
207  result << " | ";
208 
209  for (size_t j = 0; j < table[i].size(); ++j) {
210 
211  auto it = settings.fieldOptions.find(fields[j]);
212 
213  if(it != settings.fieldOptions.end())
214  result << std::setw(it->second.columnWidth)
215  << it->second.fieldInterpreter(table[i][j]) << " | ";
216  else
217  result << std::setw(settings.defaultColumnWidth)
218  << table[i][j] << " | ";
219  }
220 
221  result << "\n";
222  }
223 
224  return decoration
225  + header + "\n"
226  + decoration
227  + result.str()
228  + decoration;
229  };
230  }
231 
232 
236  inline OutputFormat fancy() {
237 
238  return [](
239  const std::vector<std::vector<std::string>>& table,
240  const std::vector<std::string>& fields,
241  const output_settings& settings) -> std::string {
242 
243  if(!table.size())
244  return "";
245 
246  // Effective length of the string
247  // (needed because Unicode is used)
248  size_t eff_length = 0;
249  std::stringstream header_str;
250 
251  header_str << " │ ";
252  eff_length += 3;
253 
254  for (size_t i = 0; i < table[0].size(); ++i) {
255 
256  auto it = settings.fieldOptions.find(fields[i]);
257 
258  if(it != settings.fieldOptions.end()) {
259  header_str << std::setw(it->second.columnWidth)
260  << table[0][i] << " │ ";
261  eff_length += it->second.columnWidth;
262  } else {
263  header_str << std::setw(settings.defaultColumnWidth)
264  << table[0][i] << " │ ";
265  eff_length += settings.defaultColumnWidth;
266  }
267 
268  eff_length += 3;
269  }
270 
271  std::string header = " ┌";
272 
273  // Upper outline
274  for (size_t i = 4; i < eff_length; ++i)
275  header += "─";
276  header += "┐ \n";
277 
278  header += header_str.str() + "\n";
279 
280  // Lower outline
281  header += " ├";
282  for (size_t i = 4; i < eff_length; ++i)
283  header += "─";
284  header += "┤ \n";
285 
286  std::stringstream result;
287 
288  for (size_t i = 1; i < table.size(); ++i) {
289 
290  if(table[i].size() != fields.size()) {
291  std::runtime_error(
292  "Number of columns and <fields> argument must have "
293  "the same size in output::format::fancy");
294  }
295 
296  result << " │ ";
297 
298  for (size_t j = 0; j < table[i].size(); ++j) {
299 
300  auto it = settings.fieldOptions.find(fields[j]);
301 
302  if(it != settings.fieldOptions.end())
303  result << std::setw(it->second.columnWidth)
304  << it->second.fieldInterpreter(table[i][j]) << " │ ";
305  else
306  result << std::setw(settings.defaultColumnWidth)
307  << table[i][j] << " │ ";
308  }
309 
310  result << "\n";
311  }
312 
313  std::string underline = " └";
314  for (size_t i = 4; i < eff_length; ++i) {
315  underline += "─";
316  }
317  underline += "┘ \n";
318 
319  return header + result.str() + underline;
320  };
321  }
322 
323 
329  inline OutputFormat csv(const std::string& separator = ",") {
330 
331  return [separator](
332  const std::vector<std::vector<std::string>>& table,
333  const std::vector<std::string>& fields,
334  const output_settings& settings) -> std::string {
335 
336  std::stringstream s;
337 
338  for (size_t i = 0; i < table.size(); ++i) {
339 
340  if(table[i].size() != fields.size()) {
341  throw std::runtime_error(
342  "Number of columns and <fields> argument must have "
343  "the same size in output::format::csv");
344  }
345 
346 
347  for (size_t j = 0; j < table[i].size(); ++j) {
348 
349  auto it = settings.fieldOptions.find(fields[j]);
350 
351  if(it != settings.fieldOptions.end() && i)
352  s << "\"" << it->second.fieldInterpreter(table[i][j]) << "\"";
353  else
354  s << "\"" << table[i][j] << "\"";
355 
356  if(j != table[i].size() - 1)
357  s << separator;
358  }
359 
360  s << "\n";
361  }
362 
363  return s.str();
364  };
365  }
366 
367 
371 
372  return [](
373  const std::vector<std::vector<std::string>>& table,
374  const std::vector<std::string>& fields,
375  const output_settings& settings) -> std::string {
376 
377  if(!table.size())
378  return "";
379 
380  std::stringstream result;
381  std::stringstream header_str;
382 
383  header_str << "|";
384 
385  for (size_t i = 0; i < table[0].size(); ++i) {
386 
387  auto it = settings.fieldOptions.find(fields[i]);
388 
389  if(it != settings.fieldOptions.end())
390  header_str << std::setw(it->second.columnWidth)
391  << std::left << table[0][i];
392  else
393  header_str << std::setw(settings.defaultColumnWidth)
394  << std::left << table[0][i];
395 
396  header_str << "|";
397  }
398 
399  std::string header = header_str.str();
400  std::string decoration = "|";
401  for (size_t i = 1; i < header.size() - 1; ++i)
402  decoration += (header[i] == '|') ? "|" : "-";
403  decoration += "|\n";
404 
405  for (size_t i = 1; i < table.size(); ++i) {
406 
407  if(table[i].size() != fields.size()) {
408  std::runtime_error(
409  "Number of columns and <fields> argument must have "
410  "the same size in output::format::markdown");
411  }
412 
413  result << "|";
414 
415  for (size_t j = 0; j < table[i].size(); ++j) {
416 
417  auto it = settings.fieldOptions.find(fields[j]);
418 
419  if(it != settings.fieldOptions.end())
420  result << std::setw(it->second.columnWidth)
421  << std::left << it->second.fieldInterpreter(table[i][j]);
422  else
423  result << std::setw(settings.defaultColumnWidth)
424  << std::left << table[i][j];
425 
426  result << "|";
427  }
428 
429  result << "\n";
430  }
431 
432  return header + "\n" + decoration + result.str();
433  };
434  }
435 
436 
439  inline OutputFormat latex() {
440 
441  return [=](
442  const std::vector<std::vector<std::string>>& table,
443  const std::vector<std::string>& fields,
444  const output_settings& settings) -> std::string {
445 
446  if(!table.size())
447  return "";
448 
449  std::stringstream result;
450  result << "\\begin{tabular}{";
451 
452  if(fields.size())
453  result << "|";
454 
455  for (unsigned int i = 0; i < fields.size(); ++i)
456  result << "c|";
457 
458  result << "}\n\\hline\n";
459 
460  for (size_t i = 0; i < table[0].size(); ++i) {
461 
462  result << table[0][i];
463 
464  if(i != table[0].size() - 1)
465  result << " & ";
466  }
467  result << " \\\\\n\\hline\n";
468 
469  for (size_t i = 1; i < table.size(); ++i) {
470 
471  if(table[i].size() != fields.size()) {
472  std::runtime_error(
473  "Number of columns and <fields> argument must have "
474  "the same size in output::format::latex");
475  }
476 
477  for (size_t j = 0; j < table[i].size(); ++j) {
478 
479  auto it = settings.fieldOptions.find(fields[j]);
480 
481  if(it != settings.fieldOptions.end())
482  result << it->second.fieldInterpreter(table[i][j]);
483  else
484  result << table[i][j];
485 
486  if(j != table[i].size() - 1)
487  result << " & ";
488  }
489 
490  result << " \\\\\n";
491  }
492 
493  result << "\\hline\n\\end{tabular}\n";
494 
495  return result.str();
496  };
497  }
498 
499  }
500 
501 
503  inline void setup() {
504 
505  // Skip subsequent setup calls
506  if (settings.wasSetup)
507  return;
508 
509  // Estimate fields
510  settings.fieldNames["name"] = "Function";
511  settings.fieldNames["maxErr"] = "Max Err.";
512  settings.fieldNames["meanErr"] = "Mean Err.";
513  settings.fieldNames["rmsErr"] = "RMS Err.";
514  settings.fieldNames["relErr"] = "Rel. Err.";
515  settings.fieldNames["absErr"] = "Abs. Err.";
516  settings.fieldNames["tolerance"] = "Tolerance";
517  settings.fieldNames["failed"] = "Result";
518  settings.fieldNames["iterations"] = "Iterations";
519 
520  // Equation fields
521  settings.fieldNames["difference"] = "Difference";
522  settings.fieldNames["evaluated"] = "Evaluated";
523  settings.fieldNames["expected"] = "Expected";
524 
525  // Benchmark fields
526  settings.fieldNames["totalRuntime"] = "Tot. Time (ms)";
527  settings.fieldNames["averageRuntime"] = "Avg. Time (ms)";
528  settings.fieldNames["stdevRuntime"] = "Stdev. Time (ms)";
529  settings.fieldNames["runsPerSecond"] = "Runs per Sec.";
530  settings.fieldNames["runs"] = "Runs";
531 
532  // Error checking
533  settings.fieldNames["correctType"] = "Correct Type";
534  settings.fieldNames["description"] = "Description";
535  settings.fieldNames["expectedFlags"] = "Exp. Flags";
536  settings.fieldNames["thrown"] = "Has Thrown";
537 
538  // Set wider column width for some fields
539  settings.fieldOptions["name"].columnWidth = 20;
540  settings.fieldOptions["averageRuntime"].columnWidth = 14;
541  settings.fieldOptions["stdevRuntime"].columnWidth = 16;
542  settings.fieldOptions["runsPerSecond"].columnWidth = 14;
543  settings.fieldOptions["description"].columnWidth = 20;
544 
545  // Set a special field interpreter for the "failed" field
546  settings.fieldOptions["failed"].fieldInterpreter = [](const std::string& s) {
547  if(s == "0") return "PASS";
548  else if(s == "1") return "FAIL";
549  else return "UNKNOWN";
550  };
551 
552  // Set the default output formats
553  settings.outputFormat = format::fancy();
554  settings.defaultFileOutputFormat = format::csv();
555 
556  settings.wasSetup = true;
557  }
558 
559 
562  inline void terminate() {
563 
564  // Close all open files
565  for (auto& file_pair : settings.openFiles)
566  if(file_pair.second.is_open())
567  file_pair.second.close();
568  }
569 
570 
577  const std::string& fieldName, prec::estimate_result r) {
578 
579  std::stringstream value;
580 
581  if(fieldName == "name") {
582  value << r.name;
583  } else if(fieldName == "maxErr") {
584  value << std::scientific
585  << std::setprecision(settings.outputPrecision)
586  << r.maxErr;
587  } else if(fieldName == "meanErr") {
588  value << std::scientific
589  << std::setprecision(settings.outputPrecision)
590  << r.meanErr;
591  } else if(fieldName == "rmsErr") {
592  value << std::scientific
593  << std::setprecision(settings.outputPrecision)
594  << r.rmsErr;
595  } else if(fieldName == "relErr") {
596  value << std::scientific
597  << std::setprecision(settings.outputPrecision)
598  << r.relErr;
599  } else if(fieldName == "absErr") {
600  value << std::scientific
601  << std::setprecision(settings.outputPrecision)
602  << r.absErr;
603  } else if(fieldName == "tolerance") {
604  value << std::scientific
605  << std::setprecision(settings.outputPrecision)
606  << r.tolerance;
607  } else if(fieldName == "failed") {
608  value << r.failed;
609  } else {
610 
611  if(r.additionalFields.find(fieldName) == r.additionalFields.end())
612  return "";
613 
614  value << r.additionalFields[fieldName];
615  }
616 
617  return value.str();
618  }
619 
620 
627  const std::string& fieldName, prec::equation_result r) {
628 
629  std::stringstream value;
630 
631  if(fieldName == "name") {
632  value << r.name;
633  } else if(fieldName == "evaluated") {
634  value << r.evaluated;
635  } else if(fieldName == "expected") {
636  value << r.expected;
637  } else if(fieldName == "difference") {
638  value << std::scientific
639  << std::setprecision(settings.outputPrecision)
640  << r.difference;
641  } else if(fieldName == "tolerance") {
642  value << std::scientific
643  << std::setprecision(settings.outputPrecision)
644  << r.tolerance;
645  } else if(fieldName == "failed") {
646  value << r.failed;
647  } else {
648 
649  if(r.additionalFields.find(fieldName) == r.additionalFields.end())
650  return "";
651 
652  value << r.additionalFields[fieldName];
653  }
654 
655  return value.str();
656  }
657 
658 
662  const std::string& fieldName, benchmark::benchmark_result r) {
663 
664  std::stringstream value;
665 
666  if(fieldName == "name") {
667  value << r.name;
668  } else if(fieldName == "runs") {
669  value << r.runs;
670  } else if(fieldName == "iterations") {
671  value << r.iterations;
672  } else if(fieldName == "totalRuntime") {
673  value << std::scientific
674  << std::setprecision(settings.outputPrecision)
675  << r.totalRuntime;
676  } else if(fieldName == "averageRuntime") {
677  value << std::scientific
678  << std::setprecision(settings.outputPrecision)
679  << r.averageRuntime;
680  } else if(fieldName == "stdevRuntime") {
681  value << std::scientific
682  << std::setprecision(settings.outputPrecision)
683  << r.stdevRuntime;
684  } else if(fieldName == "runsPerSecond") {
685  if(r.runsPerSecond > 1000)
686  value << uint64_t(r.runsPerSecond);
687  else
688  value << r.runsPerSecond;
689  } else if(fieldName == "failed") {
690  value << r.failed;
691  } else {
692 
693  if(r.additionalFields.find(fieldName) == r.additionalFields.end())
694  return "";
695 
696  value << r.additionalFields[fieldName];
697  }
698 
699  return value.str();
700  }
701 
702 
709  const std::string& fieldName, err::assert_result r) {
710 
711  std::stringstream value;
712 
713  if(fieldName == "name") {
714  value << r.name;
715  } else if(fieldName == "evaluated") {
716  value << r.evaluated;
717  } else if(fieldName == "description") {
718  value << r.description;
719  } else if(fieldName == "failed") {
720  value << r.failed;
721  } else {
722  return "";
723  }
724 
725  return value.str();
726  }
727 
728 
735  const std::string& fieldName, err::errno_result r) {
736 
737  std::stringstream value;
738 
739  if(fieldName == "name") {
740  value << r.name;
741  } else if(fieldName == "evaluated") {
742  value << r.evaluated;
743  } else if(fieldName == "expectedFlags") {
744 
745  int res_flag = 0xFFFFFFFF;
746  for (int flag : r.expectedFlags)
747  res_flag &= flag;
748 
749  value << res_flag;
750 
751  } else if(fieldName == "failed") {
752  value << r.failed;
753  } else {
754  return "";
755  }
756 
757  return value.str();
758  }
759 
760 
767  const std::string& fieldName, err::exception_result r) {
768 
769  std::stringstream value;
770 
771  if(fieldName == "name") {
772  value << r.name;
773  } else if(fieldName == "thrown") {
774  value << r.thrown;
775  } else if(fieldName == "correctType") {
776  value << r.correctType;
777  } else if(fieldName == "failed") {
778  value << r.failed;
779  } else {
780  return "";
781  }
782 
783  return value.str();
784  }
785 
786 
796  template<typename ResultType>
797  inline auto generate_table(
798  const std::map<std::string, std::vector<ResultType>>& results,
799  const std::vector<std::string>& fields) {
800 
801  std::vector<std::vector<std::string>> table;
802 
803  // Construct header
804  std::vector<std::string> header (fields.size());
805  for (size_t i = 0; i < fields.size(); ++i) {
806 
807  const auto it = settings.fieldNames.find(fields[i]);
808 
809  // Associate string to field name
810  if(it != settings.fieldNames.end())
811  header[i] = it->second;
812  else
813  header[i] = fields[i];
814  }
815  table.emplace_back(header);
816 
817  // Construct rows
818  for (const auto& p : results) {
819  for (const auto& result : p.second) {
820 
821  // Skip results marked as quiet
822  if (result.quiet)
823  continue;
824 
825  std::vector<std::string> row (fields.size());
826 
827  for (size_t i = 0; i < fields.size(); ++i)
828  row[i] = resolve_field(fields[i], result);
829 
830  table.emplace_back(row);
831  }
832  }
833 
834  return table;
835  }
836 
837 
844  inline bool open_file(std::string filename) {
845 
846  const auto file_pair = settings.openFiles.find(filename);
847 
848  // If the file is not already open, try to open it and write to it
849  if (file_pair == settings.openFiles.end() || !file_pair->second.is_open()) {
850 
851  settings.openFiles[filename].open(filename);
852 
853  if (!settings.openFiles[filename].is_open()) {
854  settings.openFiles.erase(filename);
855  return false;
856  }
857  }
858 
859  return true;
860  }
861 
862 
870  template<typename ResultType>
871  inline void print_results(
872  const std::map<std::string, std::vector<ResultType>>& results,
873  const std::vector<std::string>& fields,
874  const std::vector<std::string>& filenames) {
875 
876  // Skip output on no test case results
877  if(results.empty())
878  return;
879 
880  // Table data as a string matrix
881  std::vector<std::vector<std::string>> table = generate_table(results, fields);
882 
883  // Write to standard output
884  if(!settings.quiet)
885  std::cout << "\n" << settings.outputFormat(table, fields, settings) << "\n";
886 
887  // Write to the module specific output files
888  for (const auto& filename : filenames) {
889 
890  if (!open_file(filename)) {
891  std::cout << "Unable to write to output file: " << filename << std::endl;
892  continue;
893  }
894 
895  auto& file = settings.openFiles[filename];
896 
897  // Apply formatting according to set options
898  const auto it = settings.fileOutputFormat.find(filename);
899 
900  if(it != settings.fileOutputFormat.end())
901  file << it->second(table, fields, settings);
902  else
903  file << settings.defaultFileOutputFormat(table, fields, settings);
904 
905  std::cout << "Results have been saved in: " << filename << std::endl;
906  }
907 
908  // Write to the generic output files
909  for (const auto& filename : settings.outputFiles) {
910 
911  if (!open_file(filename)) {
912  std::cout << "Unable to write to output file: " << filename << std::endl;
913  continue;
914  }
915 
916  auto& file = settings.openFiles[filename];
917 
918  // Apply formatting according to set options
919  const auto it = settings.fileOutputFormat.find(filename);
920 
921  if(it != settings.fileOutputFormat.end())
922  file << it->second(table, fields, settings);
923  else
924  file << settings.defaultFileOutputFormat(table, fields, settings);
925 
926  std::cout << "Results have been saved in: " << filename << std::endl;
927  }
928  }
929  }
930 }
931 
932 #endif
#define CHEBYSHEV_OUTPUT_WIDTH
Default width of output columns.
Definition: common.h:32
OutputFormat markdown()
Format the table as Markdown.
Definition: output.h:370
OutputFormat barebone()
Bare bone output format which just prints the result table as is, without any formatting beyond adjus...
Definition: output.h:120
OutputFormat fancy()
Fancy output format which uses Unicode characters to print a continuous outline around the table.
Definition: output.h:236
OutputFormat latex()
Format the table as a LaTeX table in the tabular environment.
Definition: output.h:439
OutputFormat simple()
Simple output format which prints the fields separated by the separator string and padding,...
Definition: output.h:168
OutputFormat csv(const std::string &separator=",")
Format function for CSV format files.
Definition: output.h:329
void print_results(const std::map< std::string, std::vector< ResultType >> &results, const std::vector< std::string > &fields, const std::vector< std::string > &filenames)
Print the test results to standard output and output files with their given formats,...
Definition: output.h:871
std::string resolve_field(const std::string &fieldName, prec::estimate_result r)
Resolve the field of an estimate result by name, returning the value as a string.
Definition: output.h:576
output_settings::OutputFormat_t OutputFormat
A function which converts the table entries of a row to a string to print (e.g.
Definition: output.h:100
void setup()
Setup printing to the output stream with default options.
Definition: output.h:503
void terminate()
Terminate the output module by closing all output files and resetting its settings.
Definition: output.h:562
bool open_file(std::string filename)
Try to open a new output file, returning whether it was correctly opened.
Definition: output.h:844
auto generate_table(const std::map< std::string, std::vector< ResultType >> &results, const std::vector< std::string > &fields)
Generate a table of results as a string matrix to pass to a specific formatter of OutputFormat type.
Definition: output.h:797
std::string string(size_t length)
Generate a random string made of human-readable ASCII characters.
Definition: random.h:84
General namespace of the framework.
Definition: benchmark_structures.h:16
Structure holding the results of a benchmark.
Definition: benchmark_structures.h:23
long double averageRuntime
Estimated average runtime.
Definition: benchmark_structures.h:38
bool failed
Whether the benchmark failed because an exception was thrown.
Definition: benchmark_structures.h:48
unsigned int runs
Number of runs.
Definition: benchmark_structures.h:29
unsigned int iterations
Number of iterations.
Definition: benchmark_structures.h:32
long double runsPerSecond
Number of runs per second.
Definition: benchmark_structures.h:44
long double totalRuntime
Total runtime over all runs and iterations.
Definition: benchmark_structures.h:35
std::string name
Identifying name of the function or test case.
Definition: benchmark_structures.h:26
std::map< std::string, long double > additionalFields
Additional fields in floating point representation.
Definition: benchmark_structures.h:54
long double stdevRuntime
Sample standard deviation of the runtime.
Definition: benchmark_structures.h:41
std::vector< std::string > outputFiles
The files to write all benchmark results to.
Definition: benchmark.h:50
bool quiet
Whether to print benchmark results to standard output.
Definition: benchmark.h:35
Result of assertion checking of a function.
Definition: err_structures.h:21
std::string name
Identifying name of the function or test case.
Definition: err_structures.h:24
bool evaluated
Evaluated boolean value.
Definition: err_structures.h:27
bool failed
Whether the test failed.
Definition: err_structures.h:33
std::string description
Description of the assertion.
Definition: err_structures.h:30
Result of errno checking of a function.
Definition: err_structures.h:42
int evaluated
Evaluated errno value.
Definition: err_structures.h:48
std::string name
Identifying name of the function or test case.
Definition: err_structures.h:45
std::vector< int > expectedFlags
Expected errno flags.
Definition: err_structures.h:51
bool failed
Whether the test failed.
Definition: err_structures.h:54
Result of exception checking of a function.
Definition: err_structures.h:63
bool thrown
Whether the function has thrown.
Definition: err_structures.h:69
std::string name
Identifying name of the function or test case.
Definition: err_structures.h:66
bool correctType
Whether the type of the thrown exception was correct.
Definition: err_structures.h:73
bool failed
Whether the test failed.
Definition: err_structures.h:76
Custom options for printing a certain field.
Definition: output.h:27
unsigned int columnWidth
Width for the column associated with the field.
Definition: output.h:32
FieldInterpreter fieldInterpreter
A function which gets as input the value of a field as a string and returns a new string (e....
Definition: output.h:36
std::map< std::string, long double > additionalFields
Additional custom options.
Definition: output.h:39
Global settings of printing results to standard output.
Definition: output.h:51
bool quiet
Whether to output to standard output.
Definition: output.h:89
std::map< std::string, OutputFormat_t > fileOutputFormat
The output format to use for a specific file, by filename.
Definition: output.h:86
std::vector< std::string > outputFiles
A list of output files.
Definition: output.h:67
OutputFormat_t defaultFileOutputFormat
The default output format to use for files, when no format has been set for a file.
Definition: output.h:83
std::map< std::string, field_options > fieldOptions
Options for the different fields.
Definition: output.h:64
OutputFormat_t outputFormat
The output format to use to print to standard output.
Definition: output.h:79
unsigned int defaultColumnWidth
Default width for a field.
Definition: output.h:73
std::map< std::string, std::string > fieldNames
Map of field name to output string (e.g.
Definition: output.h:61
std::map< std::string, std::ofstream > openFiles
A map of open output files, by filename.
Definition: output.h:70
unsigned int outputPrecision
The number of digits to show in scientific notation.
Definition: output.h:76
bool wasSetup
Whether the output module was setup.
Definition: output.h:92
A structure holding the result of an evaluation.
Definition: prec_structures.h:163
long double tolerance
Tolerance on the absolute difference.
Definition: prec_structures.h:182
bool failed
Whether the test failed.
Definition: prec_structures.h:185
std::string name
Identifying name of the function or test case.
Definition: prec_structures.h:166
long double difference
Evaluated difference between expected and evaluated values.
Definition: prec_structures.h:175
std::map< std::string, long double > additionalFields
Additional fields by name, as a floating point value.
Definition: prec_structures.h:179
long double evaluated
Evaluated value.
Definition: prec_structures.h:169
long double expected
Expected value.
Definition: prec_structures.h:172
A structure holding the result of precision estimation.
Definition: prec_structures.h:25
std::string name
Identifying name of the function or test case.
Definition: prec_structures.h:28
std::map< std::string, long double > additionalFields
Additional fields by name, as a floating point value.
Definition: prec_structures.h:52
long double meanErr
Estimated mean error on interval.
Definition: prec_structures.h:40
long double relErr
Estimated relative error on interval.
Definition: prec_structures.h:46
long double maxErr
Estimated maximum absolute error on interval.
Definition: prec_structures.h:37
bool failed
Whether the test failed.
Definition: prec_structures.h:55
long double rmsErr
Estimated RMS error on interval.
Definition: prec_structures.h:43
long double absErr
Estimated absolute error on interval.
Definition: prec_structures.h:49
long double tolerance
Tolerance on the max absolute error.
Definition: prec_structures.h:34