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