From f49b052a68bc05d5497acf1f6c0c2d6ef65c6eef Mon Sep 17 00:00:00 2001 From: Spartan322 Date: Thu, 27 Mar 2025 17:27:31 -0400 Subject: [PATCH] Add support for disabled exceptions Add support for disabled RTTI --- src/include/nanobench.h | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/include/nanobench.h b/src/include/nanobench.h index d233dcc..d103449 100644 --- a/src/include/nanobench.h +++ b/src/include/nanobench.h @@ -124,6 +124,20 @@ // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58265 #define ANKERL_NANOBENCH_PRIVATE_NOEXCEPT_STRING_MOVE() std::is_nothrow_move_assignable::value +#if __cpp_exceptions || _HAS_EXCEPTIONS +# define ANKERL_NANOBENCH_THROW(...) throw __VA_ARGS__ +#elif defined(_MSC_VER) +# define ANKERL_NANOBENCH_THROW(...) (_invoke_watson(nullptr, nullptr, nullptr, 0, 0)) +#else +# define ANKERL_NANOBENCH_THROW(...) (__builtin_abort()) +#endif + +#if defined(_CPPRTTI) || defined(__GXX_RTTI) +# define ANKERL_NANOBENCH_HAS_RTTI 1 +#else +# define ANKERL_NANOBENCH_HAS_RTTI 0 +#endif + // declarations /////////////////////////////////////////////////////////////////////////////////// namespace ankerl { @@ -1712,7 +1726,7 @@ static std::ostream& generateResultTag(Node const& n, Result const& r, std::ostr // static std::regex const regOpArg2("^([a-zA-Z]+)\\(([a-zA-Z]*)\\s*,\\s+([a-zA-Z]*)\\)$"); // nothing matches :( - throw std::runtime_error("command '" + std::string(n.begin, n.end) + "' not understood"); + ANKERL_NANOBENCH_THROW(std::runtime_error("command '" + std::string(n.begin, n.end) + "' not understood")); } static void generateResultMeasurement(std::vector const& nodes, size_t idx, Result const& r, std::ostream& out) { @@ -1725,10 +1739,10 @@ static void generateResultMeasurement(std::vector const& nodes, size_t idx break; case Node::Type::inverted_section: - throw std::runtime_error("got a inverted section inside measurement"); + ANKERL_NANOBENCH_THROW(std::runtime_error("got a inverted section inside measurement")); case Node::Type::section: - throw std::runtime_error("got a section inside measurement"); + ANKERL_NANOBENCH_THROW(std::runtime_error("got a section inside measurement")); case Node::Type::tag: { auto m = Result::fromString(std::string(n.begin, n.end)); @@ -1755,7 +1769,7 @@ static void generateResult(std::vector const& nodes, size_t idx, std::vect break; case Node::Type::inverted_section: - throw std::runtime_error("got a inverted section inside result"); + ANKERL_NANOBENCH_THROW(std::runtime_error("got a inverted section inside result")); case Node::Type::section: if (n == "measurement") { @@ -1763,7 +1777,7 @@ static void generateResult(std::vector const& nodes, size_t idx, std::vect generateResultMeasurement(n.children, i, r, out); } } else { - throw std::runtime_error("got a section inside result"); + ANKERL_NANOBENCH_THROW(std::runtime_error("got a section inside result")); } break; @@ -1914,7 +1928,7 @@ void render(char const* mustacheTemplate, std::vector const& results, st break; case templates::Node::Type::inverted_section: - throw std::runtime_error("unknown list '" + std::string(n.begin, n.end) + "'"); + ANKERL_NANOBENCH_THROW(std::runtime_error("unknown list '" + std::string(n.begin, n.end) + "'")); case templates::Node::Type::section: if (n == "result") { @@ -1924,9 +1938,9 @@ void render(char const* mustacheTemplate, std::vector const& results, st } } else if (n == "measurement") { if (results.size() != 1) { - throw std::runtime_error( + ANKERL_NANOBENCH_THROW(std::runtime_error( "render: can only use section 'measurement' here if there is a single result, but there are " + - detail::fmt::to_s(results.size())); + detail::fmt::to_s(results.size()))); } // when we only have a single result, we can immediately go into its measurement. auto const& r = results.front(); @@ -1934,7 +1948,7 @@ void render(char const* mustacheTemplate, std::vector const& results, st generateResultMeasurement(n.children, i, r, out); } } else { - throw std::runtime_error("render: unknown section '" + std::string(n.begin, n.end) + "'"); + ANKERL_NANOBENCH_THROW(std::runtime_error("render: unknown section '" + std::string(n.begin, n.end) + "'")); } break; @@ -1945,7 +1959,7 @@ void render(char const* mustacheTemplate, std::vector const& results, st } else { // This just uses the last result's config. if (!generateConfigTag(n, results.back().config(), out)) { - throw std::runtime_error("unknown tag '" + std::string(n.begin, n.end) + "'"); + ANKERL_NANOBENCH_THROW(std::runtime_error("unknown tag '" + std::string(n.begin, n.end) + "'")); } } break; @@ -2812,7 +2826,9 @@ Number::Number(int width, int precision, double value) std::ostream& Number::write(std::ostream& os) const { StreamStateRestorer const restorer(os); + #if ANKERL_NANOBENCH_HAS_RTTI os.imbue(std::locale(os.getloc(), new NumSep(','))); + #endif os << std::setw(mWidth) << std::setprecision(mPrecision) << std::fixed << mValue; return os; } @@ -3390,8 +3406,8 @@ Rng::Rng(std::vector const& data) : mX(0) , mY(0) { if (data.size() != 2) { - throw std::runtime_error("ankerl::nanobench::Rng::Rng: needed exactly 2 entries in data, but got " + - detail::fmt::to_s(data.size())); + ANKERL_NANOBENCH_THROW(std::runtime_error("ankerl::nanobench::Rng::Rng: needed exactly 2 entries in data, but got " + + detail::fmt::to_s(data.size()))); } mX = data[0]; mY = data[1];