From 0074926e5cd815f004b4f33961ca89fc5754c8c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Wed, 9 May 2018 20:16:27 +0200 Subject: [PATCH] Provide a polyfill over `std::to_string` Android apparently does not support `std::to_string`, so we add a small polyfill over it. Right now only the ULP matcher uses it, but we have had plans to use it in `StringMaker` and friends, as it performs a lot better than `std::stringstream` based stringification on MSVC. See #1280 for more details --- CMakeLists.txt | 1 + docs/configuration.md | 13 +++++++++ .../internal/catch_compiler_capabilities.h | 10 ++++++- include/internal/catch_matchers_floating.cpp | 3 +- include/internal/catch_to_string.hpp | 28 +++++++++++++++++++ 5 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 include/internal/catch_to_string.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c877a3ca..4fdbab59 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,6 +187,7 @@ set(INTERNAL_HEADERS ${HEADER_DIR}/internal/catch_test_spec_parser.h ${HEADER_DIR}/internal/catch_text.h ${HEADER_DIR}/internal/catch_timer.h + ${HEADER_DIR}/internal/catch_to_string.hpp ${HEADER_DIR}/internal/catch_tostring.h ${HEADER_DIR}/internal/catch_totals.h ${HEADER_DIR}/internal/catch_uncaught_exceptions.h diff --git a/docs/configuration.md b/docs/configuration.md index 00d012df..dca3109f 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -99,6 +99,19 @@ This means that defining `CATCH_CONFIG_DEFAULT_REPORTER` to `"console"` is equivalent with the out-of-the-box experience. +## C++11 toggles + + CATCH_CONFIG_CPP11_TO_STRING // Use `std::to_string` + +Because we support platforms whose standard library does not contain +`std::to_string`, it is possible to force Catch to use a workaround +based on `std::stringstream`. On platforms other than Android, +the default is to use `std::to_string`. On Android, the default is to +use the `stringstream` workaround. As always, it is possible to override +Catch's selection, by defining either `CATCH_CONFIG_CPP11_TO_STRING` or +`CATCH_CONFIG_NO_CPP11_TO_STRING`. + + ## C++17 toggles CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS // Use std::uncaught_exceptions instead of std::uncaught_exception diff --git a/include/internal/catch_compiler_capabilities.h b/include/internal/catch_compiler_capabilities.h index c78c9d6d..cdfe601e 100644 --- a/include/internal/catch_compiler_capabilities.h +++ b/include/internal/catch_compiler_capabilities.h @@ -76,7 +76,11 @@ # define CATCH_CONFIG_COLOUR_NONE #endif - +//////////////////////////////////////////////////////////////////////////////// +// Android somehow still does not support std::to_string +#if defined(__ANDROID__) +# define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +#endif //////////////////////////////////////////////////////////////////////////////// // Not all Windows environments support SEH properly @@ -146,6 +150,10 @@ # define CATCH_CONFIG_WCHAR #endif +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING) +# define CATCH_CONFIG_CPP11_TO_STRING +#endif + #if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS #endif diff --git a/include/internal/catch_matchers_floating.cpp b/include/internal/catch_matchers_floating.cpp index b758bcf9..72728a83 100644 --- a/include/internal/catch_matchers_floating.cpp +++ b/include/internal/catch_matchers_floating.cpp @@ -6,6 +6,7 @@ */ #include "catch_matchers_floating.h" +#include "catch_to_string.hpp" #include "catch_tostring.h" #include @@ -115,7 +116,7 @@ namespace Floating { } std::string WithinUlpsMatcher::describe() const { - return "is within " + std::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : ""); + return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + ((m_type == FloatingPointKind::Float)? "f" : ""); } }// namespace Floating diff --git a/include/internal/catch_to_string.hpp b/include/internal/catch_to_string.hpp new file mode 100644 index 00000000..3e2b5879 --- /dev/null +++ b/include/internal/catch_to_string.hpp @@ -0,0 +1,28 @@ +/* + * Created by Martin on 9/5/2018. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_CATCH_TO_STRING_H_INCLUDED +#define TWOBLUECUBES_CATCH_TO_STRING_H_INCLUDED + +#include + +#include "catch_compiler_capabilities.h" +#include "catch_stream.h" + +namespace Catch { + template + std::string to_string(T const& t) { +#if defined(CATCH_CONFIG_CPP11_TO_STRING) + return std::to_string(t); +#else + ReusableStringStream rss; + rss << t; + return rss.str(); +#endif + } +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_TO_STRING_H_INCLUDED