Add StringMaker for std::(w)string_view

Fixes #1375
This commit is contained in:
melak47 2018-09-04 17:01:26 +02:00 committed by Martin Hořeňovský
parent 1eb42eed97
commit a575536abe
5 changed files with 68 additions and 13 deletions

View File

@ -127,6 +127,7 @@ Catch's selection, by defining either `CATCH_CONFIG_CPP11_TO_STRING` or
## C++17 toggles ## C++17 toggles
CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS // Use std::uncaught_exceptions instead of std::uncaught_exception CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS // Use std::uncaught_exceptions instead of std::uncaught_exception
CATCH_CONFIG_CPP17_STRING_VIEW // Provide StringMaker specialization for std::string_view
Catch contains basic compiler/standard detection and attempts to use Catch contains basic compiler/standard detection and attempts to use
some C++17 features whenever appropriate. This automatic detection some C++17 features whenever appropriate. This automatic detection

View File

@ -29,11 +29,11 @@
#ifdef __cplusplus #ifdef __cplusplus
# if __cplusplus >= 201402L # if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
# define CATCH_CPP14_OR_GREATER # define CATCH_CPP14_OR_GREATER
# endif # endif
# if __cplusplus >= 201703L # if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
# define CATCH_CPP17_OR_GREATER # define CATCH_CPP17_OR_GREATER
# endif # endif
@ -154,6 +154,16 @@
#define CATCH_INTERNAL_CONFIG_COUNTER #define CATCH_INTERNAL_CONFIG_COUNTER
#endif #endif
////////////////////////////////////////////////////////////////////////////////
// Check if string_view is available and usable
// The check is split apart to work around v140 (VS2015) preprocessor issue...
#if defined(__has_include)
#if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)
# define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW
#endif
#endif
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) #if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
# define CATCH_CONFIG_COUNTER # define CATCH_CONFIG_COUNTER
#endif #endif
@ -177,6 +187,10 @@
# define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS # define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS
#endif #endif
#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)
# define CATCH_CONFIG_CPP17_STRING_VIEW
#endif
#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) #if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)
# define CATCH_INTERNAL_CONFIG_NEW_CAPTURE # define CATCH_INTERNAL_CONFIG_NEW_CAPTURE
#endif #endif

View File

@ -116,14 +116,9 @@ std::string StringMaker<std::string>::convert(const std::string& str) {
return s; return s;
} }
#ifdef CATCH_CONFIG_WCHAR #ifdef CATCH_CONFIG_CPP17_STRING_VIEW
std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) { std::string StringMaker<std::string_view>::convert(std::string_view str) {
std::string s; return ::Catch::Detail::stringify(std::string{ str });
s.reserve(wstr.size());
for (auto c : wstr) {
s += (c <= 0xff) ? static_cast<char>(c) : '?';
}
return ::Catch::Detail::stringify(s);
} }
#endif #endif
@ -141,7 +136,23 @@ std::string StringMaker<char*>::convert(char* str) {
return{ "{null string}" }; return{ "{null string}" };
} }
} }
#ifdef CATCH_CONFIG_WCHAR #ifdef CATCH_CONFIG_WCHAR
std::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {
std::string s;
s.reserve(wstr.size());
for (auto c : wstr) {
s += (c <= 0xff) ? static_cast<char>(c) : '?';
}
return ::Catch::Detail::stringify(s);
}
# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
std::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {
return StringMaker<std::wstring>::convert(std::wstring(str));
}
# endif
std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) { std::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {
if (str) { if (str) {
return ::Catch::Detail::stringify(std::wstring{ str }); return ::Catch::Detail::stringify(std::wstring{ str });

View File

@ -16,6 +16,10 @@
#include "catch_compiler_capabilities.h" #include "catch_compiler_capabilities.h"
#include "catch_stream.h" #include "catch_stream.h"
#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
#include <string_view>
#endif
#ifdef __OBJC__ #ifdef __OBJC__
#include "catch_objc_arc.hpp" #include "catch_objc_arc.hpp"
#endif #endif
@ -152,10 +156,11 @@ namespace Catch {
struct StringMaker<std::string> { struct StringMaker<std::string> {
static std::string convert(const std::string& str); static std::string convert(const std::string& str);
}; };
#ifdef CATCH_CONFIG_WCHAR
#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
template<> template<>
struct StringMaker<std::wstring> { struct StringMaker<std::string_view> {
static std::string convert(const std::wstring& wstr); static std::string convert(std::string_view str);
}; };
#endif #endif
@ -169,6 +174,18 @@ namespace Catch {
}; };
#ifdef CATCH_CONFIG_WCHAR #ifdef CATCH_CONFIG_WCHAR
template<>
struct StringMaker<std::wstring> {
static std::string convert(const std::wstring& wstr);
};
# ifdef CATCH_CONFIG_CPP17_STRING_VIEW
template<>
struct StringMaker<std::wstring_view> {
static std::string convert(std::wstring_view str);
};
# endif
template<> template<>
struct StringMaker<wchar_t const *> { struct StringMaker<wchar_t const *> {
static std::string convert(wchar_t const * str); static std::string convert(wchar_t const * str);

View File

@ -116,6 +116,18 @@ TEST_CASE("Static arrays are convertible to string", "[toString]") {
} }
} }
#ifdef CATCH_CONFIG_CPP17_STRING_VIEW
TEST_CASE("String views are stringified like other strings", "[toString][approvals]") {
std::string_view view{"abc"};
CHECK(Catch::Detail::stringify(view) == R"("abc")");
std::string_view arr[] { view };
CHECK(Catch::Detail::stringify(arr) == R"({ "abc" })");
}
#endif
namespace { namespace {
struct WhatException : std::exception { struct WhatException : std::exception {