Chebyshev
Unit testing for scientific software
Loading...
Searching...
No Matches
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#include <fstream>
15
16#include "../prec/prec_structures.h"
17#include "../benchmark/benchmark_structures.h"
18#include "../err/err_structures.h"
19
20
21namespace chebyshev {
22
24 namespace output {
25
26
30
31 using FieldInterpreter = std::function<std::string(const std::string&)>;
32
35
38 FieldInterpreter fieldInterpreter = [](const std::string& s) { return s; };
39
41 std::map<std::string, long double> additionalFields {};
42
43 // Default constructor
44 field_options() {}
45
46 // Construct field options from the custom column width.
47 field_options(unsigned int columnWidth) : columnWidth(columnWidth) {}
48 };
49
50
54
55 using OutputFormat_t = std::function<
56 std::string(
57 const std::vector<std::vector<std::string>>&,
58 const std::vector<std::string>&,
59 const output_settings&)>;
60
63 std::map<std::string, std::string> fieldNames {};
64
66 std::map<std::string, field_options> fieldOptions {};
67
69 std::vector<std::string> outputFiles {};
70
72 std::map<std::string, std::ofstream> openFiles {};
73
76
78 unsigned int outputPrecision = 1;
79
81 OutputFormat_t outputFormat {};
82
85 OutputFormat_t defaultFileOutputFormat {};
86
88 std::map<std::string, OutputFormat_t> fileOutputFormat {};
89
91 bool quiet = false;
92
94 bool outputToFile = true;
95
97 bool wasSetup = false;
98
99 };
100
101
105 using OutputFormat = output_settings::OutputFormat_t;
106
107
120 namespace format {
121
122
126
127 return [](
128 const std::vector<std::vector<std::string>>& table,
129 const std::vector<std::string>& fields,
130 const output_settings& settings) -> std::string {
131
132 if(!table.size())
133 return "";
134
135 std::stringstream result;
136
137 for (size_t i = 0; i < table.size(); ++i) {
138
139 if(table[i].size() != fields.size()) {
140 std::runtime_error(
141 "Number of columns and fields argument must have "
142 "the same size in output::format::barebone");
143 }
144
145 for (size_t j = 0; j < table[i].size(); ++j) {
146
147 auto it = settings.fieldOptions.find(fields[j]);
148
149 if(it != settings.fieldOptions.end() && i)
150 result << std::setw(it->second.columnWidth)
151 << std::left << it->second.fieldInterpreter(table[i][j]);
152 else if(it != settings.fieldOptions.end())
153 result << std::setw(it->second.columnWidth)
154 << std::left << table[i][j];
155 else
156 result << std::setw(settings.defaultColumnWidth)
157 << std::left << table[i][j];
158 }
159
160 result << "\n";
161 }
162
163 return result.str();
164 };
165 }
166
167
174
175 return [](
176 const std::vector<std::vector<std::string>>& table,
177 const std::vector<std::string>& fields,
178 const output_settings& settings) -> std::string {
179
180 if(!table.size())
181 return "";
182
183 std::stringstream result;
184 std::stringstream header_str;
185
186 header_str << " | ";
187
188 for (size_t i = 0; i < table[0].size(); ++i) {
189
190 auto it = settings.fieldOptions.find(fields[i]);
191
192 if(it != settings.fieldOptions.end())
193 header_str << std::setw(it->second.columnWidth) << table[0][i] << " | ";
194 else
195 header_str << std::setw(settings.defaultColumnWidth) << table[0][i] << " | ";
196 }
197
198 std::string header = header_str.str();
199 std::string decoration = " +";
200 for (size_t i = 4; i < header.size(); ++i)
201 decoration += "-";
202 decoration += "+ \n";
203
204 for (size_t i = 1; i < table.size(); ++i) {
205
206 if(table[i].size() != fields.size()) {
207 std::runtime_error(
208 "Number of columns and <fields> argument must have "
209 "the same size in output::format::simple");
210 }
211
212 result << " | ";
213
214 for (size_t j = 0; j < table[i].size(); ++j) {
215
216 auto it = settings.fieldOptions.find(fields[j]);
217
218 if(it != settings.fieldOptions.end())
219 result << std::setw(it->second.columnWidth)
220 << it->second.fieldInterpreter(table[i][j]) << " | ";
221 else
222 result << std::setw(settings.defaultColumnWidth)
223 << table[i][j] << " | ";
224 }
225
226 result << "\n";
227 }
228
229 return decoration
230 + header + "\n"
231 + decoration
232 + result.str()
233 + decoration;
234 };
235 }
236
237
244 inline OutputFormat fancy(bool adaptiveWidth = true) {
245
246 return [adaptiveWidth](
247 const std::vector<std::vector<std::string>>& table,
248 const std::vector<std::string>& fields,
249 const output_settings& settings) -> std::string {
250
251 if(!table.size())
252 return "";
253
254 // Effective length of the string
255 // (needed because Unicode is used)
256 size_t eff_length = 0;
257 std::stringstream header_str;
258
259 header_str << " │ ";
260 eff_length += 3;
261
262 // Processed table
263 auto proc_table = table;
264
265 // Field value interpretation step
266 for (size_t i = 0; i < proc_table[0].size(); ++i) {
267
268 auto it = settings.fieldOptions.find(fields[i]);
269
270 if (it == settings.fieldOptions.end())
271 continue;
272
273 for (size_t j = 1; j < proc_table.size(); ++j)
274 proc_table[j][i] = it->second.fieldInterpreter(table[j][i]);
275 }
276
277 std::vector<size_t> computedWidth;
278
279 // Compute the ideal column width
280 if (adaptiveWidth) {
281
282 computedWidth.resize(proc_table[0].size());
283
284 for (size_t i = 0; i < proc_table[0].size(); ++i) {
285
286 computedWidth[i] = settings.defaultColumnWidth;
287
288 for (size_t j = 0; j < proc_table.size(); ++j)
289 if (proc_table[j][i].size() > computedWidth[i])
291 }
292 }
293
294 // Print table header
295 for (size_t i = 0; i < table[0].size(); ++i) {
296
297 auto it = settings.fieldOptions.find(fields[i]);
298
299 unsigned int width = 0;
300
301 if(it != settings.fieldOptions.end() && !adaptiveWidth)
302 width = it->second.columnWidth;
303 else if (adaptiveWidth)
305 else
306 width = settings.defaultColumnWidth;
307
308 header_str << std::setw(width) << table[0][i] << " │ ";
309 eff_length += width + 3;
310 }
311
312 std::string header = " ┌";
313
314 // Upper outline
315 for (size_t i = 4; i < eff_length; ++i)
316 header += "─";
317 header += "┐ \n";
318
319 header += header_str.str() + "\n";
320
321 // Lower outline
322 header += " ├";
323 for (size_t i = 4; i < eff_length; ++i)
324 header += "─";
325 header += "┤ \n";
326
327 std::stringstream result;
328
329 for (size_t i = 1; i < proc_table.size(); ++i) {
330
331 if(proc_table[i].size() != fields.size()) {
332 std::runtime_error(
333 "Number of columns and <fields> argument must have "
334 "the same size in output::format::fancy");
335 }
336
337 result << " │ ";
338
339 for (size_t j = 0; j < proc_table[i].size(); ++j) {
340
341 auto it = settings.fieldOptions.find(fields[j]);
342
343 if(it != settings.fieldOptions.end() && !adaptiveWidth)
344 result << std::setw(it->second.columnWidth)
345 << proc_table[i][j] << " │ ";
346 else if (adaptiveWidth) {
347 result << std::setw(computedWidth[j])
348 << proc_table[i][j] << " │ ";
349 } else
350 result << std::setw(settings.defaultColumnWidth)
351 << proc_table[i][j] << " │ ";
352 }
353
354 result << "\n";
355 }
356
357 std::string underline = " └";
358 for (size_t i = 4; i < eff_length; ++i) {
359 underline += "─";
360 }
361 underline += "┘ \n";
362
363 return header + result.str() + underline;
364 };
365 }
366
367
373 inline OutputFormat csv(const std::string& separator = ",") {
374
375 return [separator](
376 const std::vector<std::vector<std::string>>& table,
377 const std::vector<std::string>& fields,
378 const output_settings& settings) -> std::string {
379
380 std::stringstream s;
381
382 for (size_t i = 0; i < table.size(); ++i) {
383
384 if(table[i].size() != fields.size()) {
385 throw std::runtime_error(
386 "Number of columns and <fields> argument must have "
387 "the same size in output::format::csv");
388 }
389
390
391 for (size_t j = 0; j < table[i].size(); ++j) {
392
393 auto it = settings.fieldOptions.find(fields[j]);
394
395 if(it != settings.fieldOptions.end() && i)
396 s << "\"" << it->second.fieldInterpreter(table[i][j]) << "\"";
397 else
398 s << "\"" << table[i][j] << "\"";
399
400 if(j != table[i].size() - 1)
401 s << separator;
402 }
403
404 s << "\n";
405 }
406
407 return s.str();
408 };
409 }
410
411
415
416 return [](
417 const std::vector<std::vector<std::string>>& table,
418 const std::vector<std::string>& fields,
419 const output_settings& settings) -> std::string {
420
421 if(!table.size())
422 return "";
423
424 std::stringstream result;
425 std::stringstream header_str;
426
427 header_str << "|";
428
429 for (size_t i = 0; i < table[0].size(); ++i) {
430
431 auto it = settings.fieldOptions.find(fields[i]);
432
433 if(it != settings.fieldOptions.end())
434 header_str << std::setw(it->second.columnWidth)
435 << std::left << table[0][i];
436 else
437 header_str << std::setw(settings.defaultColumnWidth)
438 << std::left << table[0][i];
439
440 header_str << "|";
441 }
442
443 std::string header = header_str.str();
444 std::string decoration = "|";
445 for (size_t i = 1; i < header.size() - 1; ++i)
446 decoration += (header[i] == '|') ? "|" : "-";
447 decoration += "|\n";
448
449 for (size_t i = 1; i < table.size(); ++i) {
450
451 if(table[i].size() != fields.size()) {
452 std::runtime_error(
453 "Number of columns and <fields> argument must have "
454 "the same size in output::format::markdown");
455 }
456
457 result << "|";
458
459 for (size_t j = 0; j < table[i].size(); ++j) {
460
461 auto it = settings.fieldOptions.find(fields[j]);
462
463 if(it != settings.fieldOptions.end())
464 result << std::setw(it->second.columnWidth)
465 << std::left << it->second.fieldInterpreter(table[i][j]);
466 else
467 result << std::setw(settings.defaultColumnWidth)
468 << std::left << table[i][j];
469
470 result << "|";
471 }
472
473 result << "\n";
474 }
475
476 return header + "\n" + decoration + result.str();
477 };
478 }
479
480
484
485 return [=](
486 const std::vector<std::vector<std::string>>& table,
487 const std::vector<std::string>& fields,
488 const output_settings& settings) -> std::string {
489
490 if(!table.size())
491 return "";
492
493 std::stringstream result;
494 result << "\\begin{tabular}{";
495
496 if(fields.size())
497 result << "|";
498
499 for (unsigned int i = 0; i < fields.size(); ++i)
500 result << "c|";
501
502 result << "}\n\\hline\n";
503
504 for (size_t i = 0; i < table[0].size(); ++i) {
505
506 result << table[0][i];
507
508 if(i != table[0].size() - 1)
509 result << " & ";
510 }
511 result << " \\\\\n\\hline\n";
512
513 for (size_t i = 1; i < table.size(); ++i) {
514
515 if(table[i].size() != fields.size()) {
516 std::runtime_error(
517 "Number of columns and <fields> argument must have "
518 "the same size in output::format::latex");
519 }
520
521 for (size_t j = 0; j < table[i].size(); ++j) {
522
523 auto it = settings.fieldOptions.find(fields[j]);
524
525 if(it != settings.fieldOptions.end())
526 result << it->second.fieldInterpreter(table[i][j]);
527 else
528 result << table[i][j];
529
530 if(j != table[i].size() - 1)
531 result << " & ";
532 }
533
534 result << " \\\\\n";
535 }
536
537 result << "\\hline\n\\end{tabular}\n";
538
539 return result.str();
540 };
541 }
542
543 }
544
545
548 public:
549
552
553
555 inline void setup() {
556
557 // Skip subsequent setup calls
558 if (settings.wasSetup)
559 return;
560
561 // Estimate fields
562 settings.fieldNames["name"] = "Function";
563 settings.fieldNames["maxErr"] = "Max Err.";
564 settings.fieldNames["meanErr"] = "Mean Err.";
565 settings.fieldNames["rmsErr"] = "RMS Err.";
566 settings.fieldNames["relErr"] = "Rel. Err.";
567 settings.fieldNames["absErr"] = "Abs. Err.";
568 settings.fieldNames["tolerance"] = "Tolerance";
569 settings.fieldNames["failed"] = "Result";
570 settings.fieldNames["iterations"] = "Iterations";
571
572 // Equation fields
573 settings.fieldNames["difference"] = "Difference";
574 settings.fieldNames["evaluated"] = "Evaluated";
575 settings.fieldNames["expected"] = "Expected";
576
577 // Benchmark fields
578 settings.fieldNames["totalRuntime"] = "Tot. Time (ms)";
579 settings.fieldNames["averageRuntime"] = "Avg. Time (ms)";
580 settings.fieldNames["stdevRuntime"] = "Stdev. Time (ms)";
581 settings.fieldNames["runsPerSecond"] = "Runs per Sec.";
582 settings.fieldNames["runs"] = "Runs";
583 settings.fieldNames["seed"] = "Seed";
584
585 // Error checking
586 settings.fieldNames["correctType"] = "Correct Type";
587 settings.fieldNames["description"] = "Description";
588 settings.fieldNames["expectedFlags"] = "Exp. Flags";
589 settings.fieldNames["thrown"] = "Has Thrown";
590
591 // Set wider column width for some fields
592 settings.fieldOptions["name"].columnWidth = 20;
593 settings.fieldOptions["averageRuntime"].columnWidth = 14;
594 settings.fieldOptions["stdevRuntime"].columnWidth = 16;
595 settings.fieldOptions["runsPerSecond"].columnWidth = 14;
596 settings.fieldOptions["description"].columnWidth = 20;
597
598 // Set a special field interpreter for the "failed" field
599 settings.fieldOptions["failed"].fieldInterpreter = [](const std::string& s) {
600 if(s == "0") return "PASS";
601 else if(s == "1") return "FAIL";
602 else return "UNKNOWN";
603 };
604
605 // Set the default output formats
608
609 settings.wasSetup = true;
610 }
611
612
615 inline void terminate() {
616
617 // Close all open files
618 for (auto& file_pair : settings.openFiles)
619 if(file_pair.second.is_open())
620 file_pair.second.close();
621 }
622
623
626 setup();
627 }
628
629
632 terminate();
633 }
634
635
641 inline std::string resolve_field(
642 const std::string& fieldName, prec::estimate_result r) {
643
644 std::stringstream value;
645
646 if(fieldName == "name") {
647 value << r.name;
648 } else if(fieldName == "maxErr") {
649 value << std::scientific
650 << std::setprecision(settings.outputPrecision)
651 << r.maxErr;
652 } else if(fieldName == "meanErr") {
653 value << std::scientific
654 << std::setprecision(settings.outputPrecision)
655 << r.meanErr;
656 } else if(fieldName == "rmsErr") {
657 value << std::scientific
658 << std::setprecision(settings.outputPrecision)
659 << r.rmsErr;
660 } else if(fieldName == "relErr") {
661 value << std::scientific
662 << std::setprecision(settings.outputPrecision)
663 << r.relErr;
664 } else if(fieldName == "absErr") {
665 value << std::scientific
666 << std::setprecision(settings.outputPrecision)
667 << r.absErr;
668 } else if(fieldName == "tolerance") {
669 value << std::scientific
670 << std::setprecision(settings.outputPrecision)
671 << r.tolerance;
672 } else if(fieldName == "failed") {
673 value << r.failed;
674 } else {
675
676 if(r.additionalFields.find(fieldName) == r.additionalFields.end())
677 return "";
678
679 value << r.additionalFields[fieldName];
680 }
681
682 return value.str();
683 }
684
685
691 inline std::string resolve_field(
692 const std::string& fieldName, prec::equation_result r) {
693
694 std::stringstream value;
695
696 if(fieldName == "name") {
697 value << r.name;
698 } else if(fieldName == "evaluated") {
699 value << r.evaluated;
700 } else if(fieldName == "expected") {
701 value << r.expected;
702 } else if(fieldName == "difference") {
703 value << std::scientific
704 << std::setprecision(settings.outputPrecision)
705 << r.difference;
706 } else if(fieldName == "tolerance") {
707 value << std::scientific
708 << std::setprecision(settings.outputPrecision)
709 << r.tolerance;
710 } else if(fieldName == "failed") {
711 value << r.failed;
712 } else {
713
714 if(r.additionalFields.find(fieldName) == r.additionalFields.end())
715 return "";
716
717 value << r.additionalFields[fieldName];
718 }
719
720 return value.str();
721 }
722
723
726 inline std::string resolve_field(
727 const std::string& fieldName, benchmark::benchmark_result r) {
728
729 std::stringstream value;
730
731 if(fieldName == "name") {
732 value << r.name;
733 } else if(fieldName == "runs") {
734 value << r.runs;
735 } else if(fieldName == "iterations") {
736 value << r.iterations;
737 } else if(fieldName == "totalRuntime") {
738 value << std::scientific
739 << std::setprecision(settings.outputPrecision)
740 << r.totalRuntime;
741 } else if(fieldName == "averageRuntime") {
742 value << std::scientific
743 << std::setprecision(settings.outputPrecision)
744 << r.averageRuntime;
745 } else if(fieldName == "stdevRuntime") {
746 value << std::scientific
747 << std::setprecision(settings.outputPrecision)
748 << r.stdevRuntime;
749 } else if(fieldName == "runsPerSecond") {
750 if(r.runsPerSecond > 1000)
751 value << uint64_t(r.runsPerSecond);
752 else
753 value << r.runsPerSecond;
754 } else if(fieldName == "failed") {
755 value << r.failed;
756 } else if(fieldName == "seed") {
757 value << r.seed;
758 } else {
759
760 if(r.additionalFields.find(fieldName) == r.additionalFields.end())
761 return "";
762
763 value << r.additionalFields[fieldName];
764 }
765
766 return value.str();
767 }
768
769
775 inline std::string resolve_field(
776 const std::string& fieldName, err::assert_result r) {
777
778 std::stringstream value;
779
780 if(fieldName == "name") {
781 value << r.name;
782 } else if(fieldName == "evaluated") {
783 value << r.evaluated;
784 } else if(fieldName == "description") {
785 value << r.description;
786 } else if(fieldName == "failed") {
787 value << r.failed;
788 } else {
789 return "";
790 }
791
792 return value.str();
793 }
794
795
801 inline std::string resolve_field(
802 const std::string& fieldName, err::errno_result r) {
803
804 std::stringstream value;
805
806 if(fieldName == "name") {
807 value << r.name;
808 } else if(fieldName == "evaluated") {
809 value << r.evaluated;
810 } else if(fieldName == "expectedFlags") {
811
812 int res_flag = 0xFFFFFFFF;
813 for (int flag : r.expectedFlags)
814 res_flag &= flag;
815
816 value << res_flag;
817
818 } else if(fieldName == "failed") {
819 value << r.failed;
820 } else {
821 return "";
822 }
823
824 return value.str();
825 }
826
827
833 inline std::string resolve_field(
834 const std::string& fieldName, err::exception_result r) {
835
836 std::stringstream value;
837
838 if(fieldName == "name") {
839 value << r.name;
840 } else if(fieldName == "thrown") {
841 value << r.thrown;
842 } else if(fieldName == "correctType") {
843 value << r.correctType;
844 } else if(fieldName == "failed") {
845 value << r.failed;
846 } else {
847 return "";
848 }
849
850 return value.str();
851 }
852
853
863 template<typename ResultType>
864 inline auto generate_table(
865 const std::map<std::string, std::vector<ResultType>>& results,
866 const std::vector<std::string>& fields) {
867
868 std::vector<std::vector<std::string>> table;
869
870 // Construct header
871 std::vector<std::string> header (fields.size());
872 for (size_t i = 0; i < fields.size(); ++i) {
873
874 const auto it = settings.fieldNames.find(fields[i]);
875
876 // Associate string to field name
877 if(it != settings.fieldNames.end())
878 header[i] = it->second;
879 else
880 header[i] = fields[i];
881 }
882 table.emplace_back(header);
883
884 // Construct rows
885 for (const auto& p : results) {
886 for (const auto& result : p.second) {
887
888 // Skip results marked as quiet
889 if (result.quiet)
890 continue;
891
892 std::vector<std::string> row (fields.size());
893
894 for (size_t i = 0; i < fields.size(); ++i)
896
897 table.emplace_back(row);
898 }
899 }
900
901 return table;
902 }
903
904
911 inline bool open_file(const std::string& filename) {
912
913 const auto file_pair = settings.openFiles.find(filename);
914
915 // If the file is not already open, try to open it and write to it
916 if (file_pair == settings.openFiles.end() || !file_pair->second.is_open()) {
917
919
920 if (!settings.openFiles[filename].is_open()) {
922 return false;
923 }
924 }
925
926 return true;
927 }
928
929
935 template<typename ResultType>
936 inline void print_results(
937 const std::map<std::string, std::vector<ResultType>>& results,
938 const std::vector<std::string>& fields,
939 const std::vector<std::string>& filenames) {
940
941 // Skip output on no test case results
942 if(results.empty())
943 return;
944
945 // Table data as a string matrix
946 std::vector<std::vector<std::string>> table = generate_table(results, fields);
947
948 // Write to standard output
949 if(!settings.quiet) {
950 std::cout << "\n";
951 std::cout << settings.outputFormat(table, fields, settings);
952 std::cout << "\n";
953 }
954
955 // Skip printing to file
957 return;
958
959 // Write to the module specific output files
960 for (const auto& filename : filenames) {
961
962 if (!open_file(filename)) {
963 std::cout << "Unable to write to output file: " << filename << std::endl;
964 continue;
965 }
966
968
969 // Apply formatting according to set options
970 const auto it = settings.fileOutputFormat.find(filename);
971
972 if(it != settings.fileOutputFormat.end())
973 file << it->second(table, fields, settings);
974 else
976
977 std::cout << "Results have been saved in: " << filename << std::endl;
978 }
979
980 // Write to the generic output files
981 for (const auto& filename : settings.outputFiles) {
982
983 if (!open_file(filename)) {
984 std::cout << "Unable to write to output file: " << filename << std::endl;
985 continue;
986 }
987
989
990 // Apply formatting according to set options
991 const auto it = settings.fileOutputFormat.find(filename);
992
993 if(it != settings.fileOutputFormat.end())
994 file << it->second(table, fields, settings);
995 else
997
998 std::cout << "Results have been saved in: " << filename << std::endl;
999 }
1000 }
1001 };
1002 }
1003}
1004
1005#endif
module context.
Definition output.h:547
std::string resolve_field(const std::string &fieldName, benchmark::benchmark_result r)
Resolve the field of a benchmark result by name, returning the value as a string.
Definition output.h:726
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:864
void terminate()
Terminate the output module by closing all output files and resetting its settings.
Definition output.h:615
void setup()
Setup printing to the output stream with default options.
Definition output.h:555
output_context()
Default constructor for the output module.
Definition output.h:625
bool open_file(const std::string &filename)
Try to open a new output file, returning whether it was correctly opened.
Definition output.h:911
std::string resolve_field(const std::string &fieldName, err::errno_result r)
Resolve the field of an errno checking result by name, returning the value as a string.
Definition output.h:801
std::string resolve_field(const std::string &fieldName, err::exception_result r)
Resolve the field of an exception checking result by name, returning the value as a string.
Definition output.h:833
~output_context()
Destructor which automatically terminates the module.
Definition output.h:631
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:641
std::string resolve_field(const std::string &fieldName, err::assert_result r)
Resolve the field of an assertion result by name, returning the value as a string.
Definition output.h:775
std::string resolve_field(const std::string &fieldName, prec::equation_result r)
Resolve the field of an equation result by name, returning the value as a string.
Definition output.h:691
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.
Definition output.h:936
output_settings settings
Settings for the output module.
Definition output.h:551
#define CHEBYSHEV_OUTPUT_WIDTH
Default width of output columns.
Definition common.h:32
OutputFormat markdown()
Format the table as Markdown.
Definition output.h:414
OutputFormat barebone()
Bare bone output format which just prints the result table as is, without any formatting beyond adjus...
Definition output.h:125
OutputFormat fancy(bool adaptiveWidth=true)
Fancy output format which uses Unicode characters to print a continuous outline around the table.
Definition output.h:244
OutputFormat latex()
Format the table as a LaTeX table in the tabular environment.
Definition output.h:483
OutputFormat simple()
Simple output format which prints the fields separated by the separator string and padding,...
Definition output.h:173
OutputFormat csv(const std::string &separator=",")
Format function for CSV format files.
Definition output.h:373
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:105
General namespace of the framework.
Definition benchmark.h:22
constexpr FloatType get_nan()
Get a quiet NaN of the specified floating point type.
Definition common.h:65
Structure holding the results of a benchmark.
Definition benchmark_structures.h:23
Result of assertion checking of a function.
Definition err_structures.h:21
Result of errno checking of a function.
Definition err_structures.h:42
Result of exception checking of a function.
Definition err_structures.h:63
Custom options for printing a certain field.
Definition output.h:29
unsigned int columnWidth
Width for the column associated with the field.
Definition output.h:34
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:38
std::map< std::string, long double > additionalFields
Additional custom options.
Definition output.h:41
Global settings of printing results to standard output.
Definition output.h:53
bool quiet
Whether to output to standard output.
Definition output.h:91
std::map< std::string, OutputFormat_t > fileOutputFormat
The output format to use for a specific file, by filename.
Definition output.h:88
std::vector< std::string > outputFiles
A list of output files.
Definition output.h:69
bool outputToFile
Whether to print the results to file.
Definition output.h:94
OutputFormat_t defaultFileOutputFormat
The default output format to use for files, when no format has been set for a file.
Definition output.h:85
std::map< std::string, field_options > fieldOptions
Options for the different fields.
Definition output.h:66
OutputFormat_t outputFormat
The output format to use to print to standard output.
Definition output.h:81
unsigned int defaultColumnWidth
Default width for a field.
Definition output.h:75
std::map< std::string, std::string > fieldNames
Map of field name to output string (e.g.
Definition output.h:63
std::map< std::string, std::ofstream > openFiles
A map of open output files, by filename.
Definition output.h:72
unsigned int outputPrecision
The number of digits to show in scientific notation.
Definition output.h:78
bool wasSetup
Whether the output module was setup.
Definition output.h:97
A structure holding the result of an evaluation.
Definition prec_structures.h:167
A structure holding the result of precision estimation.
Definition prec_structures.h:25