Compare commits

..

4 Commits

Author SHA1 Message Date
alandefreitas bff5cb65a5 Boost super-project tests target
fix #53
2024-02-20 13:53:27 -03:00
Krystian Stasiowski 42bb99ed25 support platforms without wchar_t
closes #51
2023-10-24 14:22:30 -04:00
Krystian Stasiowski 175f467a03 select hash implementation with macros based on word size
fixes #46
2023-05-29 11:30:18 -04:00
Krystian Stasiowski 6275cd7fe3 disable string_view overloads when type is convertible to basic_static_string
fixes #47
2023-05-29 10:51:06 -04:00
6 changed files with 240 additions and 116 deletions
+2 -2
View File
@@ -23,7 +23,7 @@ endif ()
# Options # Options
if (NOT BOOST_SUPERPROJECT_VERSION) if (NOT BOOST_SUPERPROJECT_VERSION)
option(BOOST_STATIC_STRING_INSTALL "Install boost::static_string files" ${BOOST_STATIC_STRING_IS_ROOT}) option(BOOST_STATIC_STRING_INSTALL "Install boost::static_string files" ${BOOST_STATIC_STRING_IS_ROOT})
option(BOOST_STATIC_STRING_BUILD_TESTS "Build boost::static_string tests" ${BUILD_TESTING}) option(BOOST_STATIC_STRING_BUILD_TESTS "Build boost::static_string tests" OFF)
else () else ()
set(BOOST_STATIC_STRING_BUILD_TESTS ${BUILD_TESTING}) set(BOOST_STATIC_STRING_BUILD_TESTS ${BUILD_TESTING})
endif () endif ()
@@ -112,7 +112,7 @@ if (BOOST_STATIC_STRING_INSTALL AND NOT BOOST_SUPERPROJECT_VERSION)
endif () endif ()
if (BOOST_STATIC_STRING_BUILD_TESTS) if (BUILD_TESTING OR BOOST_STATIC_STRING_BUILD_TESTS)
add_subdirectory(test) add_subdirectory(test)
endif () endif ()
+29
View File
@@ -14,6 +14,17 @@
// Are we dependent on Boost? // Are we dependent on Boost?
// #define BOOST_STATIC_STRING_STANDALONE // #define BOOST_STATIC_STRING_STANDALONE
#include <cstdint>
// detect 32/64 bit
#if UINTPTR_MAX == UINT64_MAX
#define BOOST_STATIC_STRING_ARCH 64
#elif UINTPTR_MAX == UINT32_MAX
#define BOOST_STATIC_STRING_ARCH 32
#else
#error Unknown or unsupported architecture, please open an issue
#endif
// Can we have deduction guides? // Can we have deduction guides?
#if __cpp_deduction_guides >= 201703L #if __cpp_deduction_guides >= 201703L
#define BOOST_STATIC_STRING_USE_DEDUCT #define BOOST_STATIC_STRING_USE_DEDUCT
@@ -228,6 +239,24 @@ defined(BOOST_STATIC_STRING_CPP14)
#define BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR #define BOOST_STATIC_STRING_GCC5_BAD_CONSTEXPR
#endif #endif
#ifndef BOOST_STATIC_STRING_STANDALONE
#if ! defined(BOOST_NO_CWCHAR) && ! defined(BOOST_NO_SWPRINTF)
#define BOOST_STATIC_STRING_HAS_WCHAR
#endif
#else
#ifndef __has_include
// If we don't have __has_include in standalone,
// we will assume that <cwchar> exists.
#define BOOST_STATIC_STRING_HAS_WCHAR
#elif __has_include(<cwchar>)
#define BOOST_STATIC_STRING_HAS_WCHAR
#endif
#endif
#ifdef BOOST_STATIC_STRING_HAS_WCHAR
#include <cwchar>
#endif
// Define the basic string_view type used by the library // Define the basic string_view type used by the library
// Conversions to and from other available string_view types // Conversions to and from other available string_view types
// are still defined. // are still defined.
+119 -94
View File
@@ -34,7 +34,6 @@
#include <algorithm> #include <algorithm>
#include <cstdint> #include <cstdint>
#include <cstdio> #include <cstdio>
#include <cwchar>
#include <functional> #include <functional>
#include <initializer_list> #include <initializer_list>
#include <limits> #include <limits>
@@ -58,9 +57,11 @@ template<std::size_t N>
using static_string = using static_string =
basic_static_string<N, char, std::char_traits<char>>; basic_static_string<N, char, std::char_traits<char>>;
#ifdef BOOST_STATIC_STRING_HAS_WCHAR
template<std::size_t N> template<std::size_t N>
using static_wstring = using static_wstring =
basic_static_string<N, wchar_t, std::char_traits<wchar_t>>; basic_static_string<N, wchar_t, std::char_traits<wchar_t>>;
#endif
template<std::size_t N> template<std::size_t N>
using static_u16string = using static_u16string =
@@ -145,31 +146,36 @@ struct is_string_like<
// directly and other convertible types such as std::string. // directly and other convertible types such as std::string.
// When no string_view type is available, then we check for the // When no string_view type is available, then we check for the
// data and size member functions, and use them directly for assignments. // data and size member functions, and use them directly for assignments.
template<typename T, typename CharT, typename Traits, typename = void> // Types convertible to basic_static_string are not considered viewable
// to prevent any ambiguity during overload resolution.
template<std::size_t N, typename T, typename CharT, typename Traits, typename = void>
struct enable_if_viewable { }; struct enable_if_viewable { };
template<typename T, typename CharT, typename Traits> template<std::size_t N, typename T, typename CharT, typename Traits>
struct enable_if_viewable<T, CharT, Traits, struct enable_if_viewable<N, T, CharT, Traits,
typename std::enable_if< typename std::enable_if<
#if !defined(BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW) #if !defined(BOOST_STATIC_STRING_HAS_ANY_STRING_VIEW)
is_string_like<T, CharT>::value is_string_like<T, CharT>::value &&
!std::is_convertible<const T&, const basic_static_string<N, CharT, Traits>&>::value
#elif defined(BOOST_STATIC_STRING_STANDALONE) #elif defined(BOOST_STATIC_STRING_STANDALONE)
std::is_convertible<const T&, std::basic_string_view<CharT, Traits>>::value && std::is_convertible<const T&, std::basic_string_view<CharT, Traits>>::value &&
!std::is_convertible<const T&, const CharT*>::value !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string<N, CharT, Traits>&>::value
#else #else
( (
std::is_convertible<const T&, basic_string_view<CharT, Traits>>::value || std::is_convertible<const T&, basic_string_view<CharT, Traits>>::value ||
std::is_convertible<const T&, core::basic_string_view<CharT>>::value std::is_convertible<const T&, core::basic_string_view<CharT>>::value
) && ) &&
!std::is_convertible<const T&, const CharT*>::value !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string<N, CharT, Traits>&>::value
#endif #endif
>::type> >::type>
{ {
using type = void; using type = void;
}; };
template<typename T, typename CharT, typename Traits> template<std::size_t N, typename T, typename CharT, typename Traits>
using enable_if_viewable_t = typename enable_if_viewable<T, CharT, Traits>::type; using enable_if_viewable_t = typename enable_if_viewable<N, T, CharT, Traits>::type;
// The common string_view type used in private operations with enable_if_viewable_t // The common string_view type used in private operations with enable_if_viewable_t
// - T const& itself when no string_view type is available // - T const& itself when no string_view type is available
@@ -550,6 +556,7 @@ to_static_string_int_impl(Integer value) noexcept
return static_string<N>(digits_begin, std::distance(digits_begin, digits_end)); return static_string<N>(digits_begin, std::distance(digits_begin, digits_end));
} }
#ifdef BOOST_STATIC_STRING_HAS_WCHAR
template<std::size_t N, typename Integer> template<std::size_t N, typename Integer>
inline inline
static_wstring<N> static_wstring<N>
@@ -561,6 +568,7 @@ to_static_wstring_int_impl(Integer value) noexcept
digits_end, value, std::is_signed<Integer>{}); digits_end, value, std::is_signed<Integer>{});
return static_wstring<N>(digits_begin, std::distance(digits_begin, digits_end)); return static_wstring<N>(digits_begin, std::distance(digits_begin, digits_end));
} }
#endif
BOOST_STATIC_STRING_CPP11_CONSTEXPR BOOST_STATIC_STRING_CPP11_CONSTEXPR
inline inline
@@ -638,6 +646,7 @@ to_static_string_float_impl(long double value) noexcept
return static_string<N>(buffer); return static_string<N>(buffer);
} }
#ifdef BOOST_STATIC_STRING_HAS_WCHAR
template<std::size_t N> template<std::size_t N>
inline inline
static_wstring<N> static_wstring<N>
@@ -711,6 +720,7 @@ to_static_wstring_float_impl(long double value) noexcept
// this will not throw // this will not throw
return static_wstring<N>(buffer); return static_wstring<N>(buffer);
} }
#endif
#if defined(__GNUC__) && __GNUC__ >= 7 #if defined(__GNUC__) && __GNUC__ >= 7
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
@@ -1117,7 +1127,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
explicit explicit
@@ -1137,7 +1147,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -1314,7 +1324,8 @@ public:
@code @code
std::is_convertible<const T&, string_view>::value && std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const CharT*>::value !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value
@endcode @endcode
@return `*this` @return `*this`
@@ -1325,7 +1336,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -1603,7 +1614,8 @@ public:
@code @code
std::is_convertible<const T&, string_view>::value && std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const CharT*>::value !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value
@endcode @endcode
@return `*this` @return `*this`
@@ -1614,7 +1626,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -1648,7 +1660,8 @@ public:
@code @code
std::is_convertible<const T&, string_view>::value && std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const CharT*>::value !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value
@endcode @endcode
@return `*this` @return `*this`
@@ -1664,7 +1677,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
basic_static_string& basic_static_string&
@@ -2594,7 +2607,8 @@ public:
@par Constraints @par Constraints
`std::is_convertible<const T&, string_view>::value && `std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const CharT*>::value`. !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value`.
@param index The index to insert at. @param index The index to insert at.
@param t The string to insert from. @param t The string to insert from.
@@ -2604,7 +2618,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -2635,7 +2649,8 @@ public:
@par Constraints @par Constraints
`std::is_convertible<const T&, string_view>::value && `std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const_pointer>::value`. !std::is_convertible<const T&, const_pointer>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value`.
@return `*this` @return `*this`
@@ -2651,7 +2666,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -3006,7 +3021,8 @@ public:
@code @code
std::is_convertible<T const&, string_view>::value && std::is_convertible<T const&, string_view>::value &&
!std::is_convertible<T const&, char const*>::value !std::is_convertible<T const&, char const*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value
@endcode @endcode
@return `*this` @return `*this`
@@ -3017,7 +3033,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -3043,7 +3059,8 @@ public:
@code @code
std::is_convertible<T const&, string_view>::value && std::is_convertible<T const&, string_view>::value &&
!std::is_convertible<T const&, char const*>::value !std::is_convertible<T const&, char const*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value
@endcode @endcode
@return `*this` @return `*this`
@@ -3059,7 +3076,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -3181,7 +3198,8 @@ public:
@code @code
std::is_convertible<T const&, string_view>::value && std::is_convertible<T const&, string_view>::value &&
!std::is_convertible<T const&, char const*>::value !std::is_convertible<T const&, char const*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value
@endcode @endcode
@return `*this` @return `*this`
@@ -3192,7 +3210,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -3440,7 +3458,8 @@ public:
@code @code
std::is_convertible<const T&, string_view>::value && std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const_pointer>::value. !std::is_convertible<const T&, const_pointer>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value.
@endcode @endcode
@return The result of lexicographically comparing `s` and the string. @return The result of lexicographically comparing `s` and the string.
@@ -3449,7 +3468,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -3484,7 +3503,8 @@ public:
@code @code
std::is_convertible<const T&, string_view>::value && std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const_pointer>::value. !std::is_convertible<const T&, const_pointer>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value.
@endcode @endcode
@return The result of lexicographically comparing `s` and `sub`. @return The result of lexicographically comparing `s` and `sub`.
@@ -3497,7 +3517,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -3535,7 +3555,8 @@ public:
@code @code
std::is_convertible<const T&, string_view>::value && std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const_pointer>::value. !std::is_convertible<const T&, const_pointer>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value.
@endcode @endcode
@return The result of lexicographically comparing `sub1` and `sub2`. @return The result of lexicographically comparing `sub1` and `sub2`.
@@ -3552,7 +3573,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -3867,7 +3888,8 @@ public:
@par Constraints @par Constraints
`std::is_convertible<const T&, string_view>::value && `std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const CharT*>::value`. !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value`.
@return `*this` @return `*this`
@@ -3880,7 +3902,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -3913,7 +3935,8 @@ public:
@par Constraints @par Constraints
`std::is_convertible<const T&, string_view>::value && `std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const CharT*>::value`. !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value`.
@return `*this` @return `*this`
@@ -3930,7 +3953,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -4129,7 +4152,8 @@ public:
@par Constraints @par Constraints
`std::is_convertible<const T&, string_view>::value && `std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const CharT*>::value`. !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value`.
@return `*this` @return `*this`
@@ -4142,7 +4166,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -4392,7 +4416,8 @@ public:
@par Constraints @par Constraints
`std::is_convertible<const T&, string_view>::value && `std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const CharT*>::value`. !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value`.
@return The lowest index `idx` greater than or equal to `pos` @return The lowest index `idx` greater than or equal to `pos`
where each element of `{sv.begin(), sv.end())` is equal to where each element of `{sv.begin(), sv.end())` is equal to
@@ -4405,7 +4430,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -4549,7 +4574,8 @@ public:
@par Constraints @par Constraints
`std::is_convertible<const T&, string_view>::value && `std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const CharT*>::value`. !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value`.
@return The highest index `idx` less than or equal to `pos` @return The highest index `idx` less than or equal to `pos`
where each element of `{sv.begin(), sv.end())` is equal to where each element of `{sv.begin(), sv.end())` is equal to
@@ -4562,7 +4588,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -4702,7 +4728,8 @@ public:
@par Constraints @par Constraints
`std::is_convertible<const T&, string_view>::value && `std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const CharT*>::value`. !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value`.
@return The index corrosponding to the first occurrence of @return The index corrosponding to the first occurrence of
any of the characters in `{sv.begin(), sv.end())` within any of the characters in `{sv.begin(), sv.end())` within
@@ -4714,7 +4741,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -4849,7 +4876,8 @@ public:
@par Constraints @par Constraints
`std::is_convertible<const T&, string_view>::value && `std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const CharT*>::value`. !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value`.
@return The index corrosponding to the last occurrence of @return The index corrosponding to the last occurrence of
any of the characters in `{sv.begin(), sv.end())` within any of the characters in `{sv.begin(), sv.end())` within
@@ -4861,7 +4889,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -4995,7 +5023,8 @@ public:
@par Constraints @par Constraints
`std::is_convertible<const T&, string_view>::value && `std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const CharT*>::value`. !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value`.
@return The index corrosponding to the first occurrence of @return The index corrosponding to the first occurrence of
a character that is not in `{sv.begin(), sv.end())` within a character that is not in `{sv.begin(), sv.end())` within
@@ -5007,7 +5036,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5140,7 +5169,8 @@ public:
@par Constraints @par Constraints
`std::is_convertible<const T&, string_view>::value && `std::is_convertible<const T&, string_view>::value &&
!std::is_convertible<const T&, const CharT*>::value`. !std::is_convertible<const T&, const CharT*>::value &&
!std::is_convertible<const T&, const basic_static_string&>::value`.
@return The index corrosponding to the last occurrence of @return The index corrosponding to the last occurrence of
a character that is not in `{sv.begin(), sv.end())` within a character that is not in `{sv.begin(), sv.end())` within
@@ -5152,7 +5182,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5284,7 +5314,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5348,7 +5378,7 @@ public:
*/ */
template<typename T template<typename T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5617,7 +5647,7 @@ operator==(
template<std::size_t N, typename CharT, typename Traits, class T template<std::size_t N, typename CharT, typename Traits, class T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5635,7 +5665,7 @@ operator==(
template<std::size_t N, typename CharT, typename Traits, class T template<std::size_t N, typename CharT, typename Traits, class T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5679,7 +5709,7 @@ operator!=(
template<std::size_t N, typename CharT, typename Traits, class T template<std::size_t N, typename CharT, typename Traits, class T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5697,7 +5727,7 @@ operator!=(
template<std::size_t N, typename CharT, typename Traits, class T template<std::size_t N, typename CharT, typename Traits, class T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5741,7 +5771,7 @@ operator<(
template<std::size_t N, typename CharT, typename Traits, class T template<std::size_t N, typename CharT, typename Traits, class T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5759,7 +5789,7 @@ operator<(
template<std::size_t N, typename CharT, typename Traits, class T template<std::size_t N, typename CharT, typename Traits, class T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5803,7 +5833,7 @@ operator<=(
template<std::size_t N, typename CharT, typename Traits, class T template<std::size_t N, typename CharT, typename Traits, class T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5821,7 +5851,7 @@ operator<=(
template<std::size_t N, typename CharT, typename Traits, class T template<std::size_t N, typename CharT, typename Traits, class T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5865,7 +5895,7 @@ operator>(
template<std::size_t N, typename CharT, typename Traits, class T template<std::size_t N, typename CharT, typename Traits, class T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5883,7 +5913,7 @@ operator>(
template<std::size_t N, typename CharT, typename Traits, class T template<std::size_t N, typename CharT, typename Traits, class T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5928,7 +5958,7 @@ operator>=(
template<std::size_t N, typename CharT, typename Traits, class T template<std::size_t N, typename CharT, typename Traits, class T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -5946,7 +5976,7 @@ operator>=(
template<std::size_t N, typename CharT, typename Traits, class T template<std::size_t N, typename CharT, typename Traits, class T
#ifndef BOOST_STATIC_STRING_DOCS #ifndef BOOST_STATIC_STRING_DOCS
, typename = detail::enable_if_viewable_t<T, CharT, Traits> , typename = detail::enable_if_viewable_t<N, T, CharT, Traits>
#endif #endif
> >
BOOST_STATIC_STRING_CPP14_CONSTEXPR BOOST_STATIC_STRING_CPP14_CONSTEXPR
@@ -6202,6 +6232,7 @@ to_static_string(long double value) noexcept
std::numeric_limits<long double>::max_digits10 + 4>(value); std::numeric_limits<long double>::max_digits10 + 4>(value);
} }
#ifdef BOOST_STATIC_STRING_HAS_WCHAR
/// Converts `value` to a `static_wstring` /// Converts `value` to a `static_wstring`
static_wstring<std::numeric_limits<int>::digits10 + 2> static_wstring<std::numeric_limits<int>::digits10 + 2>
inline inline
@@ -6282,6 +6313,7 @@ to_static_wstring(long double value) noexcept
return detail::to_static_wstring_float_impl< return detail::to_static_wstring_float_impl<
std::numeric_limits<long double>::max_digits10 + 4>(value); std::numeric_limits<long double>::max_digits10 + 4>(value);
} }
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// //
@@ -6322,7 +6354,9 @@ hash_value(
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
using static_strings::static_string; using static_strings::static_string;
#ifdef BOOST_STATIC_STRING_HAS_WCHAR
using static_strings::static_wstring; using static_strings::static_wstring;
#endif
using static_strings::static_u16string; using static_strings::static_u16string;
using static_strings::static_u32string; using static_strings::static_u32string;
} // boost } // boost
@@ -6351,39 +6385,30 @@ struct hash<
return std::hash<view_type>()(view_type(str.data(), str.size())); return std::hash<view_type>()(view_type(str.data(), str.size()));
#else #else
std::size_t seed = 0; std::size_t seed = 0;
for (CharT const& c : str) { for (CharT const& c : str)
mix_impl(std::integral_constant<bool, sizeof(std::size_t) >= 8>{}, seed, c); {
#if BOOST_STATIC_STRING_ARCH == 64
seed += 0x9e3779b9 + std::hash<CharT>()( c );
std::size_t const m = (std::size_t(0xe9846af) << 32) + 0x9b1a615d;
seed ^= seed >> 32;
seed *= m;
seed ^= seed >> 32;
seed *= m;
seed ^= seed >> 28;
#elif BOOST_STATIC_STRING_ARCH == 32
seed += 0x9e3779b9 + std::hash<CharT>()( c );
std::size_t const m1 = 0x21f0aaad;
std::size_t const m2 = 0x735a2d97;
seed ^= seed >> 16;
seed *= m1;
seed ^= seed >> 15;
seed *= m2;
seed ^= seed >> 15;
#endif
} }
return seed; return seed;
#endif #endif
} }
static
void
mix_impl(std::true_type, std::size_t& seed, CharT c)
{
seed += 0x9e3779b9 + std::hash<CharT>()( c );
std::size_t const m = (std::size_t(0xe9846af) << 32) + 0x9b1a615d;
seed ^= seed >> 32;
seed *= m;
seed ^= seed >> 32;
seed *= m;
seed ^= seed >> 28;
}
static
void
mix_impl(std::false_type, std::size_t& seed, CharT c)
{
seed += 0x9e3779b9 + std::hash<CharT>()( c );
std::size_t const m1 = 0x21f0aaad;
std::size_t const m2 = 0x735a2d97;
seed ^= seed >> 16;
seed *= m1;
seed ^= seed >> 15;
seed *= m2;
seed ^= seed >> 15;
}
}; };
} // std } // std
+1
View File
@@ -11,6 +11,7 @@
"String" "String"
], ],
"maintainers": [ "maintainers": [
"Krystian Stasiowski <sdkrystian@gmail.com>",
"Alan de Freitas <alandefreitas@gmail.com>", "Alan de Freitas <alandefreitas@gmail.com>",
"Vinnie Falco <vinnie.falco@gmail.com>" "Vinnie Falco <vinnie.falco@gmail.com>"
], ],
+7
View File
@@ -7,6 +7,12 @@
# Official repository: https://github.com/boostorg/static_string # Official repository: https://github.com/boostorg/static_string
# #
# Custom target used by the boost super-project
if(NOT TARGET tests)
add_custom_target(tests)
set_property(TARGET tests PROPERTY FOLDER _deps)
endif()
set(BOOST_STATIC_STRING_TESTS_FILES set(BOOST_STATIC_STRING_TESTS_FILES
CMakeLists.txt CMakeLists.txt
Jamfile Jamfile
@@ -23,3 +29,4 @@ add_executable(boost_static_string_tests ${BOOST_STATIC_STRING_TESTS_FILES})
# See: BOOST_STATIC_STRING_UNIT_TEST_LIBRARIES # See: BOOST_STATIC_STRING_UNIT_TEST_LIBRARIES
target_link_libraries(boost_static_string_tests PRIVATE Boost::static_string) target_link_libraries(boost_static_string_tests PRIVATE Boost::static_string)
add_test(NAME boost_static_string_tests COMMAND boost_static_string_tests) add_test(NAME boost_static_string_tests COMMAND boost_static_string_tests)
add_dependencies(tests boost_static_string_tests)
+82 -20
View File
@@ -245,29 +245,52 @@ testR(S s, typename S::size_type pos, typename S::size_type n1, const typename S
template<typename Arithmetic> template<typename Arithmetic>
bool bool
testTS(Arithmetic value, const char* str_expected = "", const wchar_t* wstr_expected = L"", bool test_expected = false) testTS(Arithmetic value, const char* str_expected = "", bool test_expected = false)
{ {
const auto str = to_static_string(value); const auto str = to_static_string(value);
const auto wstr = to_static_wstring(value);
if (std::is_floating_point<Arithmetic>::value) if (std::is_floating_point<Arithmetic>::value)
{ {
const auto std_res = std::to_string(value); const auto std_res = std::to_string(value);
const auto wstd_res = std::to_wstring(value); return str == std_res.data();
return str == std_res.data() && wstr == wstd_res.data();
} }
else else
{ {
if (std::is_signed<Arithmetic>::value) if (std::is_signed<Arithmetic>::value)
{ {
return Arithmetic(std::strtoll(str.begin(), nullptr, 10)) == value && return
Arithmetic(std::wcstoll(wstr.begin(), nullptr, 10)) == value && Arithmetic(std::strtoll(str.begin(), nullptr, 10)) == value &&
(test_expected ? str == str_expected && wstr == wstr_expected : true); (! test_expected || str == str_expected);
} }
else else
{ {
return Arithmetic(std::strtoull(str.begin(), nullptr, 10)) == value && return Arithmetic(std::strtoull(str.begin(), nullptr, 10)) == value &&
Arithmetic(std::wcstoull(wstr.begin(), nullptr, 10)) == value && (! test_expected || str == str_expected);
(test_expected ? str == str_expected && wstr == wstr_expected : true); }
}
}
template<typename Arithmetic>
bool
testTWS(Arithmetic value, const wchar_t* wstr_expected = L"", bool test_expected = false)
{
const auto wstr = to_static_wstring(value);
if (std::is_floating_point<Arithmetic>::value)
{
const auto wstd_res = std::to_wstring(value);
return wstr == wstd_res.data();
}
else
{
if (std::is_signed<Arithmetic>::value)
{
return
Arithmetic(std::wcstoll(wstr.begin(), nullptr, 10)) == value &&
(! test_expected || wstr == wstr_expected);
}
else
{
return Arithmetic(std::wcstoull(wstr.begin(), nullptr, 10)) == value &&
(! test_expected || wstr == wstr_expected);
} }
} }
} }
@@ -3913,16 +3936,16 @@ testGeneral()
void void
testToStaticString() testToStaticString()
{ {
BOOST_TEST(testTS(0, "0", L"0", true)); BOOST_TEST(testTS(0, "0", true));
BOOST_TEST(testTS(0u, "0", L"0", true)); BOOST_TEST(testTS(0u, "0", true));
BOOST_TEST(testTS(0xffff, "65535", L"65535", true)); BOOST_TEST(testTS(0xffff, "65535", true));
BOOST_TEST(testTS(0x10000, "65536", L"65536", true)); BOOST_TEST(testTS(0x10000, "65536", true));
BOOST_TEST(testTS(0xffffffff, "4294967295", L"4294967295", true)); BOOST_TEST(testTS(0xffffffff, "4294967295", true));
BOOST_TEST(testTS(-65535, "-65535", L"-65535", true)); BOOST_TEST(testTS(-65535, "-65535", true));
BOOST_TEST(testTS(-65536, "-65536", L"-65536", true)); BOOST_TEST(testTS(-65536, "-65536", true));
BOOST_TEST(testTS(-4294967295ll, "-4294967295", L"-4294967295", true)); BOOST_TEST(testTS(-4294967295ll, "-4294967295", true));
BOOST_TEST(testTS(1, "1", L"1", true)); BOOST_TEST(testTS(1, "1", true));
BOOST_TEST(testTS(-1, "-1", L"-1", true)); BOOST_TEST(testTS(-1, "-1", true));
BOOST_TEST(testTS(0.1)); BOOST_TEST(testTS(0.1));
BOOST_TEST(testTS(0.0000001)); BOOST_TEST(testTS(0.0000001));
BOOST_TEST(testTS(-0.0000001)); BOOST_TEST(testTS(-0.0000001));
@@ -3956,6 +3979,35 @@ testToStaticString()
BOOST_TEST(str.find('e') != static_string<0>::npos || str.find('.') != BOOST_TEST(str.find('e') != static_string<0>::npos || str.find('.') !=
static_string<0>::npos || str == "infinity" || str == "inf"); static_string<0>::npos || str == "infinity" || str == "inf");
} }
#ifdef BOOST_STATIC_STRING_HAS_WCHAR
BOOST_TEST(testTWS(0, L"0", true));
BOOST_TEST(testTWS(0u, L"0", true));
BOOST_TEST(testTWS(0xffff, L"65535", true));
BOOST_TEST(testTWS(0x10000, L"65536", true));
BOOST_TEST(testTWS(0xffffffff, L"4294967295", true));
BOOST_TEST(testTWS(-65535, L"-65535", true));
BOOST_TEST(testTWS(-65536, L"-65536", true));
BOOST_TEST(testTWS(-4294967295ll, L"-4294967295", true));
BOOST_TEST(testTWS(1, L"1", true));
BOOST_TEST(testTWS(-1, L"-1", true));
BOOST_TEST(testTWS(0.1));
BOOST_TEST(testTWS(0.0000001));
BOOST_TEST(testTWS(-0.0000001));
BOOST_TEST(testTWS(-0.1));
BOOST_TEST(testTWS(1234567890.0001));
BOOST_TEST(testTWS(1.123456789012345));
BOOST_TEST(testTWS(-1234567890.1234));
BOOST_TEST(testTWS(-1.123456789012345));
BOOST_TEST(testTWS(std::numeric_limits<long long>::max()));
BOOST_TEST(testTWS(std::numeric_limits<long long>::min()));
BOOST_TEST(testTWS(std::numeric_limits<unsigned long long>::max()));
BOOST_TEST(testTWS(std::numeric_limits<unsigned long long>::max()));
BOOST_TEST(testTWS(std::numeric_limits<long double>::min()));
BOOST_TEST(testTWS(std::numeric_limits<float>::min()));
{ {
auto str = to_static_wstring(std::numeric_limits<float>::max()); auto str = to_static_wstring(std::numeric_limits<float>::max());
BOOST_TEST(str.find('e') != static_string<0>::npos || str.find('.') != BOOST_TEST(str.find('e') != static_string<0>::npos || str.find('.') !=
@@ -3971,6 +4023,7 @@ testToStaticString()
BOOST_TEST(str.find('e') != static_string<0>::npos || str.find('.') != BOOST_TEST(str.find('e') != static_string<0>::npos || str.find('.') !=
static_string<0>::npos || str == L"infinity" || str == L"inf"); static_string<0>::npos || str == L"infinity" || str == L"inf");
} }
#endif
} }
// done // done
@@ -6007,7 +6060,7 @@ testFind()
void void
testReplace() testReplace()
{ {
// replace(size_type pos1, size_type n1, const charT* s, size_type n2); // replace(size_type pos1, size_type n1, const charT* s, size_type n2);
{ {
static_string<20> fs1 = "helloworld"; static_string<20> fs1 = "helloworld";
BOOST_TEST(fs1.replace(5, 2, fs1.data() + 1, 8) == "helloelloworlrld"); BOOST_TEST(fs1.replace(5, 2, fs1.data() + 1, 8) == "helloelloworlrld");
@@ -7393,6 +7446,15 @@ testOperatorPlus()
} }
} }
// issue 47
struct issue_47 : static_string<32>
{
bool compare(const issue_47& other) const
{
return *this < other;
}
};
int int
runTests() runTests()
{ {