| 1824 | namespace nanobench { |
| 1825 | |
| 1826 | void render(char const* mustacheTemplate, std::vector<Result> const& results, std::ostream& out) { |
| 1827 | detail::fmt::StreamStateRestorer restorer(out); |
| 1828 | |
| 1829 | out.precision(std::numeric_limits<double>::digits10); |
| 1830 | auto nodes = templates::parseMustacheTemplate(&mustacheTemplate); |
| 1831 | |
| 1832 | for (auto const& n : nodes) { |
| 1833 | ANKERL_NANOBENCH_LOG("n.type=" << static_cast<int>(n.type)); |
| 1834 | switch (n.type) { |
| 1835 | case templates::Node::Type::content: |
| 1836 | out.write(n.begin, std::distance(n.begin, n.end)); |
| 1837 | break; |
| 1838 | |
| 1839 | case templates::Node::Type::inverted_section: |
| 1840 | throw std::runtime_error("unknown list '" + std::string(n.begin, n.end) + "'"); |
| 1841 | |
| 1842 | case templates::Node::Type::section: |
| 1843 | if (n == "result") { |
| 1844 | const size_t nbResults = results.size(); |
| 1845 | for (size_t i = 0; i < nbResults; ++i) { |
| 1846 | generateResult(n.children, i, results, out); |
| 1847 | } |
| 1848 | } else if (n == "measurement") { |
| 1849 | if (results.size() != 1) { |
| 1850 | throw std::runtime_error( |
| 1851 | "render: can only use section 'measurement' here if there is a single result, but there are " + |
| 1852 | detail::fmt::to_s(results.size())); |
| 1853 | } |
| 1854 | // when we only have a single result, we can immediately go into its measurement. |
| 1855 | auto const& r = results.front(); |
| 1856 | for (size_t i = 0; i < r.size(); ++i) { |
| 1857 | generateResultMeasurement(n.children, i, r, out); |
| 1858 | } |
| 1859 | } else { |
| 1860 | throw std::runtime_error("render: unknown section '" + std::string(n.begin, n.end) + "'"); |
| 1861 | } |
| 1862 | break; |
| 1863 | |
| 1864 | case templates::Node::Type::tag: |
| 1865 | if (results.size() == 1) { |
| 1866 | // result & config are both supported there |
| 1867 | generateResultTag(n, results.front(), out); |
| 1868 | } else { |
| 1869 | // This just uses the last result's config. |
| 1870 | if (!generateConfigTag(n, results.back().config(), out)) { |
| 1871 | throw std::runtime_error("unknown tag '" + std::string(n.begin, n.end) + "'"); |
| 1872 | } |
| 1873 | } |
| 1874 | break; |
| 1875 | } |
| 1876 | } |
| 1877 | } |
| 1878 | |
| 1879 | void render(std::string const& mustacheTemplate, std::vector<Result> const& results, std::ostream& out) { |
| 1880 | render(mustacheTemplate.c_str(), results, out); |
no test coverage detected