diff --git a/doc/changes.qbk b/doc/changes.qbk new file mode 100644 index 0000000..f1b877a --- /dev/null +++ b/doc/changes.qbk @@ -0,0 +1,88 @@ +[/ + Copyright 2021 Peter Dimov + Distributed under the Boost Software License, Version 1.0. + https://boost.org/LICENSE_1_0.txt) +] + +[section Revision History] + +[section Changes in 1.78.0] + +* Added a generic implementation to `boost/core/cmath.hpp`, enabled when `BOOST_CORE_USE_GENERIC_CMATH` + is defined or when the platform does not provide the necessary facilities in ``. +* Added `boost::core::type_name`. + +[endsect] + +[section Changes in 1.77.0] + +* `boost/core/uncaught_exceptions.hpp` has been modified for compatibility with Mac OS 10.4 and older. + +[endsect] + +[section Changes in 1.76.0] + +* Add implicit conversion between compatible reference wrappers. +* Add `boost/core/cmath.hpp`, a portable implementation of the floating point classification functions from ``. +* Add `boost/core/bit.hpp`, a portable implementation of the C++20 standard header ``. +* Fix `BOOST_TEST_EQ`, `BOOST_TEST_NE` for character types under C++20. +* Revise allocator access utilities (now support VS2013, and no workarounds use `allocator_traits`.) + +[endsect] + +[section Changes in 1.74.0] + +* Implemented the allocator access utilities which provide a replacement for `allocator_traits` + with individual traits and functions for each facility. They support the C++11 allocator model + when possible and provide a fallback for C++98 compatibility. + +[endsect] + +[section Changes in 1.71.0] + +* Added functions `alloc_construct`, `alloc_construct_n`, `alloc_destroy`, and `alloc_destroy_n` + in `` for allocator aware and exception safe construction and + destruction of objects and arrays. +* Added constexpr functions `first_scalar` in `` for obtaining a pointer + to the first scalar element of an array. Given a pointer of type `T*` they return a pointer of type + `remove_all_extents_t*`. +* Added class template `noinit_adaptor` in `` which is an allocator adaptor + that converts any allocator into one whose `construct(ptr)` performs default initialization via placement + `new`, and whose `destroy(ptr)` invokes the `value_type` destructor directly. +* Added class template `default_allocator` in ``, which can serve as a minimal + default allocator that has interface similar to C++20 `std::allocator`, supports configurations with disabled + exceptions and does not have `std` as an associated namespace. The allocator uses `operator new` and + `operator delete` for allocation. +* In `` header, added workarounds for better compatibility with QNX SDP 7.0 + when libc++/libc++abi libraries are used. +* The `` header is now marked as deprecated and will be removed in a future release. + `` should be used instead. + +[endsect] + +[section Changes in 1.69.0] + +* Implemented `boost::empty_value`, for library authors to conveniently leverage the Empty Base Optimization to + store objects of potentially empty types. +* Implemented `boost::quick_exit` to provide the C++11 standard library facility `std::quick_exit` functionality. +* Reduced the number of statics in Lightweight Test, and employ lighter abort behavior for MSVC compilers upon + failure to call `boost::report_errors`. + +[endsect] + +[section Changes in 1.67.0] + +* Updated `to_address` and `pointer_traits` to reflect the design adopted for C++20 in + [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0653r2.html P0653R2]. + +[endsect] + +[section Changes in 1.65.0] + +* Implemented `pointer_traits` for C++03 and higher, that implements + [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0653r0.html P0653r0]. +* Added `BOOST_TEST_GT` and `BOOST_TEST_GE` to Lightweight Test. + +[endsect] + +[endsect] diff --git a/doc/core.qbk b/doc/core.qbk index 9c20459..17538fe 100644 --- a/doc/core.qbk +++ b/doc/core.qbk @@ -38,6 +38,8 @@ criteria for inclusion is that the utility component be: [endsect] +[include changes.qbk] + [include addressof.qbk] [include allocator_access.qbk] [include alloc_construct.qbk] diff --git a/include/boost/core/lightweight_test_trait.hpp b/include/boost/core/lightweight_test_trait.hpp index bddc3ce..77a1fcd 100644 --- a/include/boost/core/lightweight_test_trait.hpp +++ b/include/boost/core/lightweight_test_trait.hpp @@ -11,7 +11,7 @@ // // BOOST_TEST_TRAIT_TRUE, BOOST_TEST_TRAIT_FALSE, BOOST_TEST_TRAIT_SAME // -// Copyright 2014 Peter Dimov +// Copyright 2014, 2021 Peter Dimov // // Copyright 2019 Glen Joseph Fernandes // (glenjofe@gmail.com) @@ -21,60 +21,15 @@ // http://www.boost.org/LICENSE_1_0.txt #include -#include +#include #include #include namespace boost { - namespace detail { -template struct test_print { }; - -template inline std::ostream& operator<<(std::ostream& o, test_print) -{ - return o << boost::core::demangled_name(BOOST_CORE_TYPEID(T)); -} - -template inline std::ostream& operator<<(std::ostream& o, test_print) -{ - return o << test_print(); -} - -template inline std::ostream& operator<<(std::ostream& o, test_print) -{ - return o << test_print() << " const"; -} - -template inline std::ostream& operator<<(std::ostream& o, test_print) -{ - return o << test_print() << " volatile"; -} - -template inline std::ostream& operator<<(std::ostream& o, test_print) -{ - return o << test_print() << " const volatile"; -} - -template inline std::ostream& operator<<(std::ostream& o, test_print) -{ - return o << test_print(); -} - -template inline std::ostream& operator<<(std::ostream& o, test_print) -{ - return o << test_print() << " &"; -} - -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -template inline std::ostream& operator<<(std::ostream& o, test_print) -{ - return o << test_print() << " &&"; -} -#endif - template< class T > inline void test_trait_impl( char const * trait, void (*)( T ), bool expected, char const * file, int line, char const * function ) { @@ -86,7 +41,7 @@ template< class T > inline void test_trait_impl( char const * trait, void (*)( T { BOOST_LIGHTWEIGHT_TEST_OSTREAM << file << "(" << line << "): predicate '" << trait << "' [" - << boost::core::demangled_name( BOOST_CORE_TYPEID(T) ) << "]" + << boost::core::type_name() << "]" << " test failed in function '" << function << "' (should have been " << ( expected? "true": "false" ) << ")" << std::endl; @@ -112,8 +67,8 @@ template inline void test_trait_same_impl( char const * type BOOST_LIGHTWEIGHT_TEST_OSTREAM << file << "(" << line << "): test 'is_same<" << types << ">'" << " failed in function '" << function - << "' ('" << test_print() - << "' != '" << test_print() << "')" + << "' ('" << boost::core::type_name() + << "' != '" << boost::core::type_name() << "')" << std::endl; ++test_results().errors(); @@ -121,7 +76,6 @@ template inline void test_trait_same_impl( char const * type } } // namespace detail - } // namespace boost #define BOOST_TEST_TRAIT_TRUE(type) ( ::boost::detail::test_trait_impl(#type, (void(*)type)0, true, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) ) diff --git a/include/boost/core/type_name.hpp b/include/boost/core/type_name.hpp index 9a82dd3..5512c0c 100644 --- a/include/boost/core/type_name.hpp +++ b/include/boost/core/type_name.hpp @@ -14,6 +14,7 @@ // https://www.boost.org/LICENSE_1_0.txt #include +#include #include #include #include @@ -73,6 +74,33 @@ template struct tn_is_reference #endif +// tn_remove_const + +template struct tn_remove_const +{ + typedef T type; +}; + +template struct tn_remove_const +{ + typedef T type; +}; + +// tn_is_function (also catches references but that's OK) + +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable: 4180 4181) +#endif + +template::type> struct tn_is_function: core::is_same +{ +}; + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + #if !defined(BOOST_NO_TYPEID) // typeid_name @@ -216,9 +244,9 @@ inline std::string tn_to_string( std::size_t n ) template int tn_add_each_impl( std::string& st ) { if( !st.empty() ) st += ", "; - st += type_name( tn_identity() ); + st += type_name( tn_identity(), "" ); return 0; -}; +} template std::string tn_add_each() { @@ -228,57 +256,87 @@ template std::string tn_add_each() (void)A{ 0, tn_add_each_impl( st )... }; return st; -}; +} #endif // primary -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return typeid_name(); + return typeid_name() + suffix; } +// integrals + +inline std::string type_name( tn_identity, std::string const& suffix ) +{ + return "unsigned" + suffix; +} + +#if defined(_MSC_VER) + +inline std::string type_name( tn_identity, std::string const& suffix ) +{ + return "long long" + suffix; +} + +inline std::string type_name( tn_identity, std::string const& suffix ) +{ + return "unsigned long long" + suffix; +} + +#endif + +#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L + +inline std::string type_name( tn_identity, std::string const& suffix ) +{ + return "char8_t" + suffix; +} + +#endif + // cv #if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900 -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + " const"; + return type_name( tn_identity(), " const" + suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + " volatile"; + return type_name( tn_identity(), " volatile" + suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + " const volatile"; + return type_name( tn_identity(), " const volatile" + suffix ); } #else template -typename tn_enable_if::value, std::string>::type -type_name( tn_identity ) +typename tn_enable_if::value, std::string>::type +type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + " const"; + return type_name( tn_identity(), " const" + suffix ); } template -typename tn_enable_if::value, std::string>::type -type_name( tn_identity ) +typename tn_enable_if::value, std::string>::type +type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + " volatile"; + return type_name( tn_identity(), " volatile" + suffix ); } template -typename tn_enable_if::value, std::string>::type -type_name( tn_identity ) +typename tn_enable_if::value, std::string>::type +type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + " const volatile"; + return type_name( tn_identity(), " const volatile" + suffix ); } #endif @@ -287,27 +345,27 @@ type_name( tn_identity ) #if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900 -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + "&"; + return type_name( tn_identity(), "&" + suffix ); } #else template typename tn_enable_if::value, std::string>::type -type_name( tn_identity ) +type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + "&"; + return type_name( tn_identity(), "&" + suffix ); } #endif #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + "&&"; + return type_name( tn_identity(), "&&" + suffix ); } #endif @@ -316,65 +374,178 @@ template std::string type_name( tn_identity ) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -template std::string type_name( tn_identity ) +template std::string function_type_name( tn_identity, std::string const& trailer, std::string const& suffix ) { - return type_name( tn_identity() ) + '(' + tn_add_each() + ')'; + std::string r = type_name( tn_identity(), "" ); + + if( !suffix.empty() ) + { + r += '('; + + if( suffix[ 0 ] == ' ' ) + { + r += suffix.substr( 1 ); + } + else + { + r += suffix; + } + + r += ')'; + } + + r += '(' + tn_add_each() + ')'; + r += trailer; + + return r; +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), "", suffix ); +} + +#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900 + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " volatile", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const volatile", suffix ); } #endif +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " &", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const &", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " volatile &", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const volatile &", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " &&", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const &&", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " volatile &&", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const volatile &&", suffix ); +} + +#endif + +#if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " volatile noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const volatile noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " & noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const & noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " volatile & noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const volatile & noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " && noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const && noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " volatile && noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const volatile && noexcept", suffix ); +} + +#endif + +#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + // pointers -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + "*"; + return type_name( tn_identity(), "*" + suffix ); } -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - -// function pointers - -template std::string type_name( tn_identity ) -{ - return type_name( tn_identity() ) + "(*)(" + tn_add_each() + ')'; -} - -template std::string type_name( tn_identity ) -{ - return type_name( tn_identity() ) + "(*&)(" + tn_add_each() + ')'; -} - -template std::string type_name( tn_identity ) -{ - return type_name( tn_identity() ) + "(* const)(" + tn_add_each() + ')'; -} - -template std::string type_name( tn_identity ) -{ - return type_name( tn_identity() ) + "(* const&)(" + tn_add_each() + ')'; -} - -#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - -template std::string type_name( tn_identity ) -{ - return type_name( tn_identity() ) + "(*&&)(" + tn_add_each() + ')'; -} - -template std::string type_name( tn_identity ) -{ - return type_name( tn_identity() ) + "(* const&&)(" + tn_add_each() + ')'; -} - -#endif - -#endif - // arrays template std::pair array_prefix_suffix( tn_identity ) { - return std::pair( type_name( tn_identity() ), "" ); + return std::pair( type_name( tn_identity(), "" ), "" ); } template std::pair array_prefix_suffix( tn_identity ) @@ -386,163 +557,210 @@ template std::pair array_prefi return r; } -template std::string array_type_name( tn_identity ) +template std::string array_type_name( tn_identity, std::string const& suffix ) { std::pair r = array_prefix_suffix( tn_identity() ); - return r.first + "[]" + r.second; + + if( suffix.empty() ) + { + return r.first + "[]" + r.second; + } + else + { + return r.first + '(' + suffix + ")[]" + r.second; + } } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } -template std::string array_type_name( tn_identity ) +template std::string array_type_name( tn_identity, std::string const& suffix ) { std::pair r = array_prefix_suffix( tn_identity() ); - return r.first + r.second; + + if( suffix.empty() ) + { + return r.first + r.second; + } + else + { + return r.first + '(' + suffix + ")" + r.second; + } } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } +// pointers to members + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return type_name( tn_identity(), ' ' + type_name( tn_identity(), "" ) + "::*" + suffix ); +} + +#if defined(BOOST_MSVC) && BOOST_MSVC < 1900 && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), "", ' ' + type_name( tn_identity(), "" ) + "::*" + suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const", ' ' + type_name( tn_identity(), "" ) + "::*" + suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " volatile", ' ' + type_name( tn_identity(), "" ) + "::*" + suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const volatile", ' ' + type_name( tn_identity(), "" ) + "::*" + suffix ); +} + +#endif + // nullptr_t #if !defined(BOOST_NO_CXX11_NULLPTR) -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::nullptr_t"; + return "std::nullptr_t" + suffix; } #endif // strings -template class L, class Ch> std::string type_name( tn_identity< L, std::allocator > > ) +template class L, class Ch> std::string type_name( tn_identity< L, std::allocator > >, std::string const& suffix ) { std::string tn = sequence_template_name< L, std::allocator > >(); - return tn + '<' + type_name( tn_identity() ) + '>'; + return tn + '<' + type_name( tn_identity(), "" ) + '>' + suffix; } -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::string"; + return "std::string" + suffix; } -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::wstring"; + return "std::wstring" + suffix; } #if !defined(BOOST_NO_CXX11_CHAR16_T) -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::u16string"; + return "std::u16string" + suffix; } #endif #if !defined(BOOST_NO_CXX11_CHAR32_T) -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::u32string"; + return "std::u32string" + suffix; } #endif #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L -inline std::string type_name( tn_identity> ) +inline std::string type_name( tn_identity>, std::string const& suffix ) { - return "std::u8string"; + return "std::u8string" + suffix; } #endif // string views (et al) -template class L, class Ch> std::string type_name( tn_identity< L > > ) +template class L, class Ch> std::string type_name( tn_identity< L > >, std::string const& suffix ) { std::string tn = sequence_template_name< L > >(); - return tn + '<' + type_name( tn_identity() ) + '>'; + return tn + '<' + type_name( tn_identity(), "" ) + '>' + suffix; } // needed for libstdc++ -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::ostream"; + return "std::ostream" + suffix; } #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::string_view"; + return "std::string_view" + suffix; } -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::wstring_view"; + return "std::wstring_view" + suffix; } #if !defined(BOOST_NO_CXX11_CHAR16_T) -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::u16string_view"; + return "std::u16string_view" + suffix; } #endif #if !defined(BOOST_NO_CXX11_CHAR32_T) -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::u32string_view"; + return "std::u32string_view" + suffix; } #endif #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L -inline std::string type_name( tn_identity> ) +inline std::string type_name( tn_identity>, std::string const& suffix ) { - return "std::u8string_view"; + return "std::u8string_view" + suffix; } #endif @@ -553,87 +771,87 @@ inline std::string type_name( tn_identity> ) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -template class L, class... T> std::string type_name( tn_identity< L > ) +template class L, class... T> std::string type_name( tn_identity< L >, std::string const& suffix ) { std::string tn = class_template_name< L >(); std::string st = tn_add_each(); - return tn + '<' + st + '>'; + return tn + '<' + st + '>' + suffix; } #else -template class L, class T1> std::string type_name( tn_identity< L > ) +template class L, class T1> std::string type_name( tn_identity< L >, std::string const& suffix ) { std::string tn = class_template_name< L >(); - return tn + '<' + type_name( tn_identity() ) + '>'; + return tn + '<' + type_name( tn_identity(), "" ) + '>' + suffix; } -template class L, class T1, class T2> std::string type_name( tn_identity< L > ) +template class L, class T1, class T2> std::string type_name( tn_identity< L >, std::string const& suffix ) { std::string tn = class_template_name< L >(); - return tn + '<' + type_name( tn_identity() ) + ", " + type_name( tn_identity() ) + '>'; + return tn + '<' + type_name( tn_identity(), "" ) + ", " + type_name( tn_identity(), "" ) + '>' + suffix; } #endif // sequence containers -template class L, class T> std::string type_name( tn_identity< L > > ) +template class L, class T> std::string type_name( tn_identity< L > >, std::string const& suffix ) { std::string tn = sequence_template_name< L > >(); - return tn + '<' + type_name( tn_identity() ) + '>'; + return tn + '<' + type_name( tn_identity(), "" ) + '>' + suffix; } // set -template class L, class T> std::string type_name( tn_identity< L, std::allocator > > ) +template class L, class T> std::string type_name( tn_identity< L, std::allocator > >, std::string const& suffix ) { std::string tn = set_template_name< L, std::allocator > >(); - return tn + '<' + type_name( tn_identity() ) + '>'; + return tn + '<' + type_name( tn_identity(), "" ) + '>' + suffix; } // map -template class L, class T, class U> std::string type_name( tn_identity< L, std::allocator > > > ) +template class L, class T, class U> std::string type_name( tn_identity< L, std::allocator > > >, std::string const& suffix ) { std::string tn = map_template_name< L, std::allocator > > >(); - return tn + '<' + type_name( tn_identity() ) + ", " + type_name( tn_identity() ) + '>'; + return tn + '<' + type_name( tn_identity(), "" ) + ", " + type_name( tn_identity(), "" ) + '>' + suffix; } #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) // unordered_set -template class L, class T> std::string type_name( tn_identity< L, std::equal_to, std::allocator > > ) +template class L, class T> std::string type_name( tn_identity< L, std::equal_to, std::allocator > >, std::string const& suffix ) { std::string tn = set_template_name< L, std::equal_to, std::allocator > >(); - return tn + '<' + type_name( tn_identity() ) + '>'; + return tn + '<' + type_name( tn_identity(), "" ) + '>' + suffix; } // unordered_map -template class L, class T, class U> std::string type_name( tn_identity< L, std::equal_to, std::allocator > > > ) +template class L, class T, class U> std::string type_name( tn_identity< L, std::equal_to, std::allocator > > >, std::string const& suffix ) { std::string tn = map_template_name< L, std::equal_to, std::allocator > > >(); - return tn + '<' + type_name( tn_identity() ) + ", " + type_name( tn_identity() ) + '>'; + return tn + '<' + type_name( tn_identity(), "" ) + ", " + type_name( tn_identity(), "" ) + '>' + suffix; } #endif // array -template class L, class T, std::size_t N> std::string type_name( tn_identity< L > ) +template class L, class T, std::size_t N> std::string type_name( tn_identity< L >, std::string const& suffix ) { std::string tn = array_template_name< L >(); - return tn + '<' + type_name( tn_identity() ) + ", " + tn_to_string( N ) + '>'; + return tn + '<' + type_name( tn_identity(), "" ) + ", " + tn_to_string( N ) + '>' + suffix; } } // namespace detail template std::string type_name() { - return core::detail::type_name( core::detail::tn_identity() ); + return core::detail::type_name( core::detail::tn_identity(), "" ); } } // namespace core diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 43ce2d9..f174ba2 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -1,6 +1,6 @@ # Boost.Core Library test Jamfile # -# Copyright (c) 2014, 2017 Peter Dimov +# Copyright (c) 2014-2021 Peter Dimov # # Distributed under the Boost Software License, Version 1.0. # See accompanying file LICENSE_1_0.txt or copy at @@ -112,9 +112,9 @@ run-fail lightweight_test_fail4.cpp ; run-fail lightweight_test_fail5.cpp ; run-fail lightweight_test_fail6.cpp ; run-fail lightweight_test_fail7.cpp ; -run-fail lightweight_test_fail7.cpp : : : off : lightweight_test_fail7_no_rtti ; +run-fail lightweight_test_fail7.cpp : : : off gcc-4.4:no : lightweight_test_fail7_no_rtti ; run-fail lightweight_test_fail8.cpp ; -run-fail lightweight_test_fail8.cpp : : : off : lightweight_test_fail8_no_rtti ; +run-fail lightweight_test_fail8.cpp : : : off gcc-4.4:no : lightweight_test_fail8_no_rtti ; run-fail lightweight_test_fail9.cpp ; run-fail lightweight_test_fail10.cpp ; run-fail lightweight_test_fail11.cpp : ; @@ -232,7 +232,7 @@ run no_exceptions_support_test.cpp ; run no_exceptions_support_test.cpp : : : off : no_exceptions_support_test_nx ; run cmath_test.cpp ; -run cmath_test.cpp : : : BOOST_CORE_USE_GENERIC_CMATH : cmath_test_generic ; +run cmath_test.cpp : : : BOOST_CORE_USE_GENERIC_CMATH msvc-8.0:no : cmath_test_generic ; run bit_cast_test.cpp ; run bit_rotate_test.cpp ; diff --git a/test/type_name_test.cpp b/test/type_name_test.cpp index 6ab08f5..6b61def 100644 --- a/test/type_name_test.cpp +++ b/test/type_name_test.cpp @@ -67,7 +67,42 @@ struct Ch int main() { + TEST(signed char); + TEST(unsigned char); + TEST(short); + TEST(unsigned short); TEST(int); + TEST(unsigned); + TEST(long); + TEST(unsigned long); + TEST(long long); + TEST(unsigned long long); + + TEST(char); + TEST(wchar_t); +#if !defined(BOOST_NO_CXX11_CHAR16_T) + TEST(char16_t); +#endif +#if !defined(BOOST_NO_CXX11_CHAR16_T) + TEST(char32_t); +#endif +#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L + TEST(char8_t); +#endif +#if defined(__cpp_lib_byte) && __cpp_lib_byte >= 201603L + TEST(std::byte); +#endif + + TEST(bool); + + TEST(float); + TEST(double); + TEST(long double); + + TEST(void); + TEST(void const); + TEST(void volatile); + TEST(void const volatile); TEST(A); TEST(B); @@ -94,33 +129,133 @@ int main() #endif - TEST(void); - TEST(void const); - TEST(void volatile); - TEST(void const volatile); - TEST(A*); TEST(B const* volatile*); TEST(void*); TEST(void const* volatile*); +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + TEST(void()); + TEST(int(float, A, B*)); + + TEST(void(*)()); + TEST(void(**)()); + TEST(void(***)()); + + TEST(void(* const* const*)()); + TEST(void(* const* const&)()); + + TEST(void(&)()); + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + + TEST(void(&&)()); + +#endif + +#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900 + + TEST(void() const); + TEST(void() volatile); + TEST(void() const volatile); + +#endif + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + + TEST(void() &); + TEST(void() const &); + TEST(void() volatile &); + TEST(void() const volatile &); + + TEST(void() &&); + TEST(void() const &&); + TEST(void() volatile &&); + TEST(void() const volatile &&); + +#endif + +#if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) + + TEST(void() noexcept); + TEST(void() const noexcept); + TEST(void() volatile noexcept); + TEST(void() const volatile noexcept); + + TEST(void() & noexcept); + TEST(void() const & noexcept); + TEST(void() volatile & noexcept); + TEST(void() const volatile & noexcept); + + TEST(void() && noexcept); + TEST(void() const && noexcept); + TEST(void() volatile && noexcept); + TEST(void() const volatile && noexcept); + +#endif + +#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + TEST(A[]); TEST(A const[]); TEST(A volatile[]); TEST(A const volatile[]); +#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1700 + TEST(A(&)[]); +#endif + TEST(A const(***)[]); + TEST(B[1]); TEST(B const[1]); TEST(B volatile[1]); TEST(B const volatile[1]); + TEST(B(&)[1]); + TEST(B const(***)[1]); + TEST(A[][2][3]); TEST(A const[][2][3]); +#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1700 + TEST(A(&)[][2][3]); +#endif + TEST(A const(***)[][2][3]); + TEST(B[1][2][3]); TEST(B const volatile[1][2][3]); + TEST(B(&)[1][2][3]); + TEST(B const volatile(***)[1][2][3]); + + TEST(int A::*); + TEST(int const B::*); + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + TEST(void(A::*)()); + TEST(void(A::*)() const); + TEST(void(A::*)() volatile); + TEST(void(A::*)() const volatile); + +#endif + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + + TEST(void(A::*)() &); + TEST(void(A::*)() const &&); + +#endif + +#if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) + + TEST(void(A::*)() volatile & noexcept); + TEST(void(A::*)() const volatile && noexcept); + +#endif + #if !defined(BOOST_NO_CXX11_NULLPTR) TEST(std::nullptr_t);