From 290340fd27011d48f4e209921d76928e33a0b1f6 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 04:58:52 +0300 Subject: [PATCH 01/19] Use core::type_name in lightweight_test_trait --- include/boost/core/lightweight_test_trait.hpp | 56 ++----------------- 1 file changed, 5 insertions(+), 51 deletions(-) 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) ) From 36cec9a5cc8e2eddea8d192991310bc813901499 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 05:01:05 +0300 Subject: [PATCH 02/19] Handle references to functions --- include/boost/core/type_name.hpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/boost/core/type_name.hpp b/include/boost/core/type_name.hpp index 9a82dd3..33e717f 100644 --- a/include/boost/core/type_name.hpp +++ b/include/boost/core/type_name.hpp @@ -332,6 +332,22 @@ template std::string type_name( tn_identity ) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +// function references + +template std::string type_name( tn_identity ) +{ + return type_name( tn_identity() ) + "(&)(" + 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() + ')'; +} + +#endif + // function pointers template std::string type_name( tn_identity ) From 01bd23df5d30801deea2c16c30c3b95a6a6c89f0 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 05:04:56 +0300 Subject: [PATCH 03/19] Add tests for function types --- test/type_name_test.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/type_name_test.cpp b/test/type_name_test.cpp index 6ab08f5..52a74a5 100644 --- a/test/type_name_test.cpp +++ b/test/type_name_test.cpp @@ -105,6 +105,18 @@ int main() TEST(void*); TEST(void const* volatile*); + TEST(void()); + TEST(int(float, A, B*)); + + TEST(void(*)()); + TEST(void(&)()); + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + + TEST(void(&&)()); + +#endif + TEST(A[]); TEST(A const[]); TEST(A volatile[]); From b93317815c7b62551e34e13253008d2d56817148 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 05:30:37 +0300 Subject: [PATCH 04/19] Apply msvc-12.0 (and below) workarounds --- include/boost/core/type_name.hpp | 25 ++++++++++++++++++++++--- test/type_name_test.cpp | 3 +++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/include/boost/core/type_name.hpp b/include/boost/core/type_name.hpp index 33e717f..dfdedd3 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,24 @@ 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) + +template::type> struct tn_is_function: core::is_same +{ +}; + #if !defined(BOOST_NO_TYPEID) // typeid_name @@ -261,21 +280,21 @@ template std::string type_name( tn_identity ) #else template -typename tn_enable_if::value, std::string>::type +typename tn_enable_if::value, std::string>::type type_name( tn_identity ) { return type_name( tn_identity() ) + " const"; } template -typename tn_enable_if::value, std::string>::type +typename tn_enable_if::value, std::string>::type type_name( tn_identity ) { return type_name( tn_identity() ) + " volatile"; } template -typename tn_enable_if::value, std::string>::type +typename tn_enable_if::value, std::string>::type type_name( tn_identity ) { return type_name( tn_identity() ) + " const volatile"; diff --git a/test/type_name_test.cpp b/test/type_name_test.cpp index 52a74a5..b3439c1 100644 --- a/test/type_name_test.cpp +++ b/test/type_name_test.cpp @@ -105,6 +105,8 @@ int main() TEST(void*); TEST(void const* volatile*); +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + TEST(void()); TEST(int(float, A, B*)); @@ -115,6 +117,7 @@ int main() TEST(void(&&)()); +#endif #endif TEST(A[]); From f833040d4835f803006c0e0883f0e21ae8cfe8ac Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 05:42:41 +0300 Subject: [PATCH 05/19] Disable msvc warnings around tn_is_function --- include/boost/core/type_name.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/boost/core/type_name.hpp b/include/boost/core/type_name.hpp index dfdedd3..8632f81 100644 --- a/include/boost/core/type_name.hpp +++ b/include/boost/core/type_name.hpp @@ -88,10 +88,19 @@ template struct tn_remove_const // 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 From ccdf5ce031df3ad10c36d520e75fe126d0b19166 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 06:45:41 +0300 Subject: [PATCH 06/19] Track the type suffix independently for better decomposition of functions and arrays --- include/boost/core/type_name.hpp | 267 ++++++++++++++----------------- test/type_name_test.cpp | 18 +++ 2 files changed, 136 insertions(+), 149 deletions(-) diff --git a/include/boost/core/type_name.hpp b/include/boost/core/type_name.hpp index 8632f81..d31750b 100644 --- a/include/boost/core/type_name.hpp +++ b/include/boost/core/type_name.hpp @@ -244,7 +244,7 @@ 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; }; @@ -262,51 +262,51 @@ template std::string tn_add_each() // 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; } // 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 ) +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 ) +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 ) +type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + " const volatile"; + return type_name( tn_identity(), " const volatile" + suffix ); } #endif @@ -315,27 +315,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 @@ -344,81 +344,34 @@ template std::string type_name( tn_identity ) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + '(' + tn_add_each() + ')'; + std::string r = type_name( tn_identity(), "" ); + + if( !suffix.empty() ) + { + r += '(' + suffix + ')'; + } + + r += '(' + tn_add_each() + ')'; + + return r; } #endif // 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 references - -template std::string type_name( tn_identity ) -{ - return type_name( tn_identity() ) + "(&)(" + 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() + ')'; -} - -#endif - -// 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 ) @@ -430,163 +383,179 @@ 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 ); } // 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 @@ -597,87 +566,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/type_name_test.cpp b/test/type_name_test.cpp index b3439c1..ebd3895 100644 --- a/test/type_name_test.cpp +++ b/test/type_name_test.cpp @@ -111,6 +111,12 @@ int main() 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) @@ -125,17 +131,29 @@ int main() TEST(A volatile[]); TEST(A const volatile[]); + TEST(A(&)[]); + 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]); + TEST(A(&)[][2][3]); + 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]); + #if !defined(BOOST_NO_CXX11_NULLPTR) TEST(std::nullptr_t); From b0b48c57835edd00b903830ef187e3af93e1437d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 07:05:34 +0300 Subject: [PATCH 07/19] Support qualified function types --- include/boost/core/type_name.hpp | 131 ++++++++++++++++++++++++++++++- test/type_name_test.cpp | 38 +++++++++ 2 files changed, 168 insertions(+), 1 deletion(-) diff --git a/include/boost/core/type_name.hpp b/include/boost/core/type_name.hpp index d31750b..df13e8e 100644 --- a/include/boost/core/type_name.hpp +++ b/include/boost/core/type_name.hpp @@ -344,7 +344,7 @@ template std::string type_name( tn_identity, std::string const& su #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -template std::string type_name( tn_identity, std::string const& suffix ) +template std::string function_type_name( tn_identity, std::string const& trailer, std::string const& suffix ) { std::string r = type_name( tn_identity(), "" ); @@ -354,12 +354,141 @@ template std::string type_name( tn_identity, std:: } 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 ); +} + +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 ); +} + +#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, std::string const& suffix ) diff --git a/test/type_name_test.cpp b/test/type_name_test.cpp index ebd3895..71a2221 100644 --- a/test/type_name_test.cpp +++ b/test/type_name_test.cpp @@ -124,6 +124,44 @@ int main() TEST(void(&&)()); #endif + + TEST(void() const); + TEST(void() volatile); + TEST(void() const volatile); + +#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 TEST(A[]); From cd1a8fd238ca8f3960cc5a82e08c293b574d5602 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 07:25:35 +0300 Subject: [PATCH 08/19] Support pointers to members --- include/boost/core/type_name.hpp | 20 +++++++++++++++++++- test/type_name_test.cpp | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/include/boost/core/type_name.hpp b/include/boost/core/type_name.hpp index df13e8e..8e332e8 100644 --- a/include/boost/core/type_name.hpp +++ b/include/boost/core/type_name.hpp @@ -350,7 +350,18 @@ template std::string function_type_name( tn_identity() + ')'; @@ -580,6 +591,13 @@ template std::string 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 ); +} + // nullptr_t #if !defined(BOOST_NO_CXX11_NULLPTR) diff --git a/test/type_name_test.cpp b/test/type_name_test.cpp index 71a2221..437c0c3 100644 --- a/test/type_name_test.cpp +++ b/test/type_name_test.cpp @@ -192,6 +192,28 @@ int main() TEST(B(&)[1][2][3]); TEST(B const volatile(***)[1][2][3]); + TEST(int A::*); + TEST(int const B::*); + + TEST(void(A::*)()); + TEST(void(A::*)() const); + TEST(void(A::*)() volatile); + TEST(void(A::*)() const volatile); + +#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); From 4f6f7c37991539efb2f2ee3da216f35f4fac65f0 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 07:50:52 +0300 Subject: [PATCH 09/19] Add tests for all fundamental types --- include/boost/core/type_name.hpp | 21 +++++++++++++++++ test/type_name_test.cpp | 40 ++++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/include/boost/core/type_name.hpp b/include/boost/core/type_name.hpp index 8e332e8..d873df1 100644 --- a/include/boost/core/type_name.hpp +++ b/include/boost/core/type_name.hpp @@ -267,6 +267,27 @@ template std::string type_name( tn_identity, std::string const& suff 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 + // cv #if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900 diff --git a/test/type_name_test.cpp b/test/type_name_test.cpp index 437c0c3..4c60fda 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,11 +129,6 @@ int main() #endif - TEST(void); - TEST(void const); - TEST(void volatile); - TEST(void const volatile); - TEST(A*); TEST(B const* volatile*); From bb0c6381f640d3a5c74511689dbb9af8d1aba36c Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 08:04:01 +0300 Subject: [PATCH 10/19] Add msvc workarounds --- include/boost/core/type_name.hpp | 23 +++++++++++++++++++++++ test/type_name_test.cpp | 14 +++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/include/boost/core/type_name.hpp b/include/boost/core/type_name.hpp index d873df1..c0ec611 100644 --- a/include/boost/core/type_name.hpp +++ b/include/boost/core/type_name.hpp @@ -396,6 +396,8 @@ template std::string type_name( tn_identity, std:: 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 ); @@ -411,6 +413,8 @@ template std::string 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 ) @@ -619,6 +623,25 @@ template std::string type_name( tn_identity, std::stri 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(), " 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) diff --git a/test/type_name_test.cpp b/test/type_name_test.cpp index 4c60fda..e6574cb 100644 --- a/test/type_name_test.cpp +++ b/test/type_name_test.cpp @@ -155,10 +155,14 @@ int main() #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() &); @@ -192,14 +196,16 @@ int main() #endif -#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 >= 1500 TEST(A(&)[]); +#endif TEST(A const(***)[]); TEST(B[1]); @@ -213,7 +219,9 @@ int main() TEST(A[][2][3]); TEST(A const[][2][3]); +#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1500 TEST(A(&)[][2][3]); +#endif TEST(A const(***)[][2][3]); TEST(B[1][2][3]); @@ -225,11 +233,15 @@ int main() 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::*)() &); From 1fd2cadddd74823802742e640d78d578142f2708 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 15:38:33 +0300 Subject: [PATCH 11/19] g++ 4.4 has no string::front --- include/boost/core/type_name.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/core/type_name.hpp b/include/boost/core/type_name.hpp index c0ec611..0c622e5 100644 --- a/include/boost/core/type_name.hpp +++ b/include/boost/core/type_name.hpp @@ -373,7 +373,7 @@ template std::string function_type_name( tn_identity Date: Tue, 5 Oct 2021 15:46:22 +0300 Subject: [PATCH 12/19] Add overload for char8_t because Mac has no `typeinfo for char8_t` --- include/boost/core/type_name.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/boost/core/type_name.hpp b/include/boost/core/type_name.hpp index 0c622e5..d8ea942 100644 --- a/include/boost/core/type_name.hpp +++ b/include/boost/core/type_name.hpp @@ -288,6 +288,15 @@ inline std::string type_name( tn_identity, std::string const #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 From 6985b1ae25a51170c52434cefb169f834887aa1d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 15:53:16 +0300 Subject: [PATCH 13/19] Remove extra semicolons --- include/boost/core/type_name.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/core/type_name.hpp b/include/boost/core/type_name.hpp index d8ea942..f155943 100644 --- a/include/boost/core/type_name.hpp +++ b/include/boost/core/type_name.hpp @@ -246,7 +246,7 @@ template int tn_add_each_impl( std::string& st ) if( !st.empty() ) st += ", "; st += type_name( tn_identity(), "" ); return 0; -}; +} template std::string tn_add_each() { @@ -256,7 +256,7 @@ template std::string tn_add_each() (void)A{ 0, tn_add_each_impl( st )... }; return st; -}; +} #endif From 3e9cc2153b4783c75219351131baf770450b849a Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 17:11:31 +0300 Subject: [PATCH 14/19] Disable no-rtti tests for g++ 4.4 because breaks --- test/Jamfile.v2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 63f516f..5f8dc77 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -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 : ; From 87c21a23bb95976848a5a91dda2f917504e422e9 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 17:32:50 +0300 Subject: [PATCH 15/19] Update copyright --- test/Jamfile.v2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 5f8dc77..a55abc2 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 From 75fc48ad32c4ef7055f482a4b34dd00efe0c1b9e Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 18:46:47 +0300 Subject: [PATCH 16/19] Add a revision history section to documentation --- doc/changes.qbk | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ doc/core.qbk | 2 ++ 2 files changed, 90 insertions(+) create mode 100644 doc/changes.qbk 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] From 531726eb09333000807cdb232111efbb7c067acd Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 19:05:40 +0300 Subject: [PATCH 17/19] Update msvc workarounds in type_name_test --- test/type_name_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/type_name_test.cpp b/test/type_name_test.cpp index e6574cb..6b61def 100644 --- a/test/type_name_test.cpp +++ b/test/type_name_test.cpp @@ -203,7 +203,7 @@ int main() TEST(A volatile[]); TEST(A const volatile[]); -#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1500 +#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1700 TEST(A(&)[]); #endif TEST(A const(***)[]); @@ -219,7 +219,7 @@ int main() TEST(A[][2][3]); TEST(A const[][2][3]); -#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1500 +#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1700 TEST(A(&)[][2][3]); #endif TEST(A const(***)[][2][3]); From 3ec157eb6fe51cf6802b055e070644b555154352 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 19:16:24 +0300 Subject: [PATCH 18/19] Disable cmath_test_generic on msvc-8.0 --- test/Jamfile.v2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 63f516f..dd9fc10 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -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 ; From 0deaa2d502884c334193a4277d7b7d59de66af5e Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 5 Oct 2021 19:22:20 +0300 Subject: [PATCH 19/19] Update msvc-12.0 workaround --- include/boost/core/type_name.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/boost/core/type_name.hpp b/include/boost/core/type_name.hpp index f155943..5512c0c 100644 --- a/include/boost/core/type_name.hpp +++ b/include/boost/core/type_name.hpp @@ -632,7 +632,12 @@ template std::string type_name( tn_identity, std::stri return type_name( tn_identity(), ' ' + type_name( tn_identity(), "" ) + "::*" + suffix ); } -#if defined(BOOST_MSVC) && BOOST_MSVC <= 1900 && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#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 ) {