From f14e49ec778fdb8a3620039df5cb2f9709f2346f Mon Sep 17 00:00:00 2001 From: Corentin Jabot Date: Sun, 31 Dec 2017 18:35:55 +0100 Subject: [PATCH] Avoid out of line template definition --- include/internal/catch_tostring.cpp | 51 +++++------ include/internal/catch_tostring.h | 126 ++++++++++------------------ 2 files changed, 63 insertions(+), 114 deletions(-) diff --git a/include/internal/catch_tostring.cpp b/include/internal/catch_tostring.cpp index a9f7735e..da05d633 100644 --- a/include/internal/catch_tostring.cpp +++ b/include/internal/catch_tostring.cpp @@ -63,7 +63,6 @@ namespace Detail { rss << std::setw(2) << static_cast(bytes[i]); return rss.str(); } -} template @@ -86,14 +85,13 @@ std::string fpToString( T value, int precision ) { return d; } - //// ======================================================= //// // // Out-of-line defs for full specialization of StringMaker // //// ======================================================= //// -std::string StringMaker::convert(const std::string& str) { +std::string convert(const std::string& str) { if (!getCurrentContext().getConfig()->showInvisibles()) { return '"' + str + '"'; } @@ -116,7 +114,7 @@ std::string StringMaker::convert(const std::string& str) { return s; } -std::string StringMaker::convert(const std::wstring& wstr) { +std::string convert(const std::wstring& wstr) { std::string s; s.reserve(wstr.size()); for (auto c : wstr) { @@ -125,43 +123,41 @@ std::string StringMaker::convert(const std::wstring& wstr) { return ::Catch::Detail::stringify(s); } -std::string StringMaker::convert(char const* str) { +std::string convert(char const* str) { if (str) { return ::Catch::Detail::stringify(std::string{ str }); } else { return{ "{null string}" }; } } -std::string StringMaker::convert(char* str) { +std::string convert(char* str) { if (str) { return ::Catch::Detail::stringify(std::string{ str }); } else { return{ "{null string}" }; } } -std::string StringMaker::convert(wchar_t const * str) { +std::string convert(wchar_t const * str) { if (str) { return ::Catch::Detail::stringify(std::wstring{ str }); } else { return{ "{null string}" }; } } -std::string StringMaker::convert(wchar_t * str) { +std::string convert(wchar_t * str) { if (str) { return ::Catch::Detail::stringify(std::wstring{ str }); } else { return{ "{null string}" }; } } - - -std::string StringMaker::convert(int value) { +std::string convert(int value) { return ::Catch::Detail::stringify(static_cast(value)); } -std::string StringMaker::convert(long value) { +std::string convert(long value) { return ::Catch::Detail::stringify(static_cast(value)); } -std::string StringMaker::convert(long long value) { +std::string convert(long long value) { ReusableStringStream rss; rss << value; if (value > Detail::hexThreshold) { @@ -170,13 +166,13 @@ std::string StringMaker::convert(long long value) { return rss.str(); } -std::string StringMaker::convert(unsigned int value) { +std::string convert(unsigned int value) { return ::Catch::Detail::stringify(static_cast(value)); } -std::string StringMaker::convert(unsigned long value) { +std::string convert(unsigned long value) { return ::Catch::Detail::stringify(static_cast(value)); } -std::string StringMaker::convert(unsigned long long value) { +std::string convert(unsigned long long value) { ReusableStringStream rss; rss << value; if (value > Detail::hexThreshold) { @@ -186,11 +182,12 @@ std::string StringMaker::convert(unsigned long long value) { } -std::string StringMaker::convert(bool b) { +std::string convert(bool b) { return b ? "true" : "false"; } -std::string StringMaker::convert(char value) { + +std::string convert(char value) { if (value == '\r') { return "'\\r'"; } else if (value == '\f') { @@ -207,31 +204,25 @@ std::string StringMaker::convert(char value) { return chstr; } } -std::string StringMaker::convert(signed char c) { +std::string convert(signed char c) { return ::Catch::Detail::stringify(static_cast(c)); } -std::string StringMaker::convert(unsigned char c) { +std::string convert(unsigned char c) { return ::Catch::Detail::stringify(static_cast(c)); } -std::string StringMaker::convert(std::nullptr_t) { +std::string convert(std::nullptr_t) { return "nullptr"; } -std::string StringMaker::convert(float value) { +std::string convert(float value) { return fpToString(value, 5) + 'f'; } -std::string StringMaker::convert(double value) { +std::string convert(double value) { return fpToString(value, 10); } -std::string ratio_string::symbol() { return "a"; } -std::string ratio_string::symbol() { return "f"; } -std::string ratio_string::symbol() { return "p"; } -std::string ratio_string::symbol() { return "n"; } -std::string ratio_string::symbol() { return "u"; } -std::string ratio_string::symbol() { return "m"; } - +} } // end namespace Catch diff --git a/include/internal/catch_tostring.h b/include/internal/catch_tostring.h index 79e02448..17754afc 100644 --- a/include/internal/catch_tostring.h +++ b/include/internal/catch_tostring.h @@ -37,6 +37,26 @@ namespace Catch { extern const std::string unprintableString; + extern std::string convert(const std::string& str); + extern std::string convert(const std::wstring& wstr); + extern std::string convert(char const* str); + extern std::string convert(char* str); + extern std::string convert(wchar_t const * str); + extern std::string convert(wchar_t * str); + extern std::string convert(int value); + extern std::string convert(long value); + extern std::string convert(long long value); + extern std::string convert(unsigned int value); + extern std::string convert(unsigned long value); + extern std::string convert(unsigned long long value); + extern std::string convert(bool b); + extern std::string convert(char value); + extern std::string convert(signed char c); + extern std::string convert(unsigned char c); + extern std::string convert(std::nullptr_t); + extern std::string convert(float value); + extern std::string convert(double value); + std::string rawMemoryToString( const void *object, std::size_t size ); template @@ -44,6 +64,15 @@ namespace Catch { return rawMemoryToString( &object, sizeof(object) ); } + template + class HasConvertFunction : public std::false_type {}; + + template + class HasConvertFunction::type()))> : public std::true_type {}; + + + template class IsStreamInsertable { template @@ -54,7 +83,7 @@ namespace Catch { static auto test(...)->std::false_type; public: - static const bool value = decltype(test(0))::value; + static const bool value = decltype(test(0))::value && !HasConvertFunction::value; }; } // namespace Detail @@ -77,6 +106,12 @@ namespace Catch { convert(const Fake&) { return Detail::unprintableString; } + template + static + typename std::enable_if::value, std::string>::type + convert(const CT& t) { + return Detail::convert(t); + } }; namespace Detail { @@ -93,32 +128,6 @@ namespace Catch { // Some predefined specializations - template<> - struct StringMaker { - static std::string convert(const std::string& str); - }; - template<> - struct StringMaker { - static std::string convert(const std::wstring& wstr); - }; - - template<> - struct StringMaker { - static std::string convert(char const * str); - }; - template<> - struct StringMaker { - static std::string convert(char * str); - }; - template<> - struct StringMaker { - static std::string convert(wchar_t const * str); - }; - template<> - struct StringMaker { - static std::string convert(wchar_t * str); - }; - template struct StringMaker { static std::string convert(const char* str) { @@ -138,63 +147,6 @@ namespace Catch { } }; - template<> - struct StringMaker { - static std::string convert(int value); - }; - template<> - struct StringMaker { - static std::string convert(long value); - }; - template<> - struct StringMaker { - static std::string convert(long long value); - }; - template<> - struct StringMaker { - static std::string convert(unsigned int value); - }; - template<> - struct StringMaker { - static std::string convert(unsigned long value); - }; - template<> - struct StringMaker { - static std::string convert(unsigned long long value); - }; - - template<> - struct StringMaker { - static std::string convert(bool b); - }; - - template<> - struct StringMaker { - static std::string convert(char c); - }; - template<> - struct StringMaker { - static std::string convert(signed char c); - }; - template<> - struct StringMaker { - static std::string convert(unsigned char c); - }; - - template<> - struct StringMaker { - static std::string convert(std::nullptr_t); - }; - - template<> - struct StringMaker { - static std::string convert(float value); - }; - template<> - struct StringMaker { - static std::string convert(double value); - }; - template struct StringMaker { template @@ -460,6 +412,12 @@ struct ratio_string { return std::string(timeStamp); } }; + inline std::string ratio_string::symbol() { return "a"; } + inline std::string ratio_string::symbol() { return "f"; } + inline std::string ratio_string::symbol() { return "p"; } + inline std::string ratio_string::symbol() { return "n"; } + inline std::string ratio_string::symbol() { return "u"; } + inline std::string ratio_string::symbol() { return "m"; } } #endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER