forked from boostorg/core
Merge branch 'develop' into feature/string-view
This commit is contained in:
88
doc/changes.qbk
Normal file
88
doc/changes.qbk
Normal file
@ -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 `<cmath>`.
|
||||||
|
* 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 `<cmath>`.
|
||||||
|
* Add `boost/core/bit.hpp`, a portable implementation of the C++20 standard header `<bit>`.
|
||||||
|
* 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 `<boost/core/alloc_construct.hpp>` for allocator aware and exception safe construction and
|
||||||
|
destruction of objects and arrays.
|
||||||
|
* Added constexpr functions `first_scalar` in `<boost/core/first_scalar.hpp>` 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<T>*`.
|
||||||
|
* Added class template `noinit_adaptor` in `<boost/core/noinit_adaptor.hpp>` 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 `<boost/core/default_allocator.hpp>`, 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 `<boost/core/uncaught_exceptions.hpp>` header, added workarounds for better compatibility with QNX SDP 7.0
|
||||||
|
when libc++/libc++abi libraries are used.
|
||||||
|
* The `<boost/detail/sp_typeinfo.hpp>` header is now marked as deprecated and will be removed in a future release.
|
||||||
|
`<boost/core/typeinfo.hpp>` 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]
|
@ -38,6 +38,8 @@ criteria for inclusion is that the utility component be:
|
|||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
[include changes.qbk]
|
||||||
|
|
||||||
[include addressof.qbk]
|
[include addressof.qbk]
|
||||||
[include allocator_access.qbk]
|
[include allocator_access.qbk]
|
||||||
[include alloc_construct.qbk]
|
[include alloc_construct.qbk]
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
//
|
//
|
||||||
// BOOST_TEST_TRAIT_TRUE, BOOST_TEST_TRAIT_FALSE, BOOST_TEST_TRAIT_SAME
|
// 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
|
// Copyright 2019 Glen Joseph Fernandes
|
||||||
// (glenjofe@gmail.com)
|
// (glenjofe@gmail.com)
|
||||||
@ -21,60 +21,15 @@
|
|||||||
// http://www.boost.org/LICENSE_1_0.txt
|
// http://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
#include <boost/core/lightweight_test.hpp>
|
#include <boost/core/lightweight_test.hpp>
|
||||||
#include <boost/core/typeinfo.hpp>
|
#include <boost/core/type_name.hpp>
|
||||||
#include <boost/core/is_same.hpp>
|
#include <boost/core/is_same.hpp>
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
template<class, int = 0> struct test_print { };
|
|
||||||
|
|
||||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T, 2>)
|
|
||||||
{
|
|
||||||
return o << boost::core::demangled_name(BOOST_CORE_TYPEID(T));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T, 1>)
|
|
||||||
{
|
|
||||||
return o << test_print<T, 2>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<const T, 1>)
|
|
||||||
{
|
|
||||||
return o << test_print<T, 2>() << " const";
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<volatile T, 1>)
|
|
||||||
{
|
|
||||||
return o << test_print<T, 2>() << " volatile";
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<const volatile T, 1>)
|
|
||||||
{
|
|
||||||
return o << test_print<T, 2>() << " const volatile";
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T>)
|
|
||||||
{
|
|
||||||
return o << test_print<T, 1>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T&>)
|
|
||||||
{
|
|
||||||
return o << test_print<T, 1>() << " &";
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
|
||||||
template<class T> inline std::ostream& operator<<(std::ostream& o, test_print<T&&>)
|
|
||||||
{
|
|
||||||
return o << test_print<T, 1>() << " &&";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template< class T > inline void test_trait_impl( char const * trait, void (*)( T ),
|
template< class T > inline void test_trait_impl( char const * trait, void (*)( T ),
|
||||||
bool expected, char const * file, int line, char const * function )
|
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
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||||
<< file << "(" << line << "): predicate '" << trait << "' ["
|
<< file << "(" << line << "): predicate '" << trait << "' ["
|
||||||
<< boost::core::demangled_name( BOOST_CORE_TYPEID(T) ) << "]"
|
<< boost::core::type_name<T>() << "]"
|
||||||
<< " test failed in function '" << function
|
<< " test failed in function '" << function
|
||||||
<< "' (should have been " << ( expected? "true": "false" ) << ")"
|
<< "' (should have been " << ( expected? "true": "false" ) << ")"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
@ -112,8 +67,8 @@ template<class T1, class T2> inline void test_trait_same_impl( char const * type
|
|||||||
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
BOOST_LIGHTWEIGHT_TEST_OSTREAM
|
||||||
<< file << "(" << line << "): test 'is_same<" << types << ">'"
|
<< file << "(" << line << "): test 'is_same<" << types << ">'"
|
||||||
<< " failed in function '" << function
|
<< " failed in function '" << function
|
||||||
<< "' ('" << test_print<T1>()
|
<< "' ('" << boost::core::type_name<T1>()
|
||||||
<< "' != '" << test_print<T2>() << "')"
|
<< "' != '" << boost::core::type_name<T2>() << "')"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
++test_results().errors();
|
++test_results().errors();
|
||||||
@ -121,7 +76,6 @@ template<class T1, class T2> inline void test_trait_same_impl( char const * type
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
#define BOOST_TEST_TRAIT_TRUE(type) ( ::boost::detail::test_trait_impl(#type, (void(*)type)0, true, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
|
#define BOOST_TEST_TRAIT_TRUE(type) ( ::boost::detail::test_trait_impl(#type, (void(*)type)0, true, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION) )
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
// https://www.boost.org/LICENSE_1_0.txt
|
// https://www.boost.org/LICENSE_1_0.txt
|
||||||
|
|
||||||
#include <boost/core/demangle.hpp>
|
#include <boost/core/demangle.hpp>
|
||||||
|
#include <boost/core/is_same.hpp>
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -73,6 +74,33 @@ template<class T> struct tn_is_reference<T&&>
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// tn_remove_const
|
||||||
|
|
||||||
|
template<class T> struct tn_remove_const
|
||||||
|
{
|
||||||
|
typedef T type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T> struct tn_remove_const<T 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<class T, class U = typename tn_remove_const<T>::type> struct tn_is_function: core::is_same<U, U const>
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC)
|
||||||
|
# pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_TYPEID)
|
#if !defined(BOOST_NO_TYPEID)
|
||||||
|
|
||||||
// typeid_name
|
// typeid_name
|
||||||
@ -216,9 +244,9 @@ inline std::string tn_to_string( std::size_t n )
|
|||||||
template<class T> int tn_add_each_impl( std::string& st )
|
template<class T> int tn_add_each_impl( std::string& st )
|
||||||
{
|
{
|
||||||
if( !st.empty() ) st += ", ";
|
if( !st.empty() ) st += ", ";
|
||||||
st += type_name( tn_identity<T>() );
|
st += type_name( tn_identity<T>(), "" );
|
||||||
return 0;
|
return 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
template<class... T> std::string tn_add_each()
|
template<class... T> std::string tn_add_each()
|
||||||
{
|
{
|
||||||
@ -228,57 +256,87 @@ template<class... T> std::string tn_add_each()
|
|||||||
(void)A{ 0, tn_add_each_impl<T>( st )... };
|
(void)A{ 0, tn_add_each_impl<T>( st )... };
|
||||||
|
|
||||||
return st;
|
return st;
|
||||||
};
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// primary
|
// primary
|
||||||
|
|
||||||
template<class T> std::string type_name( tn_identity<T> )
|
template<class T> std::string type_name( tn_identity<T>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return typeid_name<T>();
|
return typeid_name<T>() + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// integrals
|
||||||
|
|
||||||
|
inline std::string type_name( tn_identity<unsigned>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return "unsigned" + suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
|
inline std::string type_name( tn_identity<long long>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return "long long" + suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string type_name( tn_identity<unsigned long long>, 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<char8_t>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return "char8_t" + suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// cv
|
// cv
|
||||||
|
|
||||||
#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900
|
#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900
|
||||||
|
|
||||||
template<class T> std::string type_name( tn_identity<T const> )
|
template<class T> std::string type_name( tn_identity<T const>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return type_name( tn_identity<T>() ) + " const";
|
return type_name( tn_identity<T>(), " const" + suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> std::string type_name( tn_identity<T volatile> )
|
template<class T> std::string type_name( tn_identity<T volatile>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return type_name( tn_identity<T>() ) + " volatile";
|
return type_name( tn_identity<T>(), " volatile" + suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> std::string type_name( tn_identity<T const volatile> )
|
template<class T> std::string type_name( tn_identity<T const volatile>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return type_name( tn_identity<T>() ) + " const volatile";
|
return type_name( tn_identity<T>(), " const volatile" + suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
typename tn_enable_if<!tn_is_reference<T>::value, std::string>::type
|
typename tn_enable_if<!tn_is_function<T>::value, std::string>::type
|
||||||
type_name( tn_identity<T const> )
|
type_name( tn_identity<T const>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return type_name( tn_identity<T>() ) + " const";
|
return type_name( tn_identity<T>(), " const" + suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
typename tn_enable_if<!tn_is_reference<T>::value, std::string>::type
|
typename tn_enable_if<!tn_is_function<T>::value, std::string>::type
|
||||||
type_name( tn_identity<T volatile> )
|
type_name( tn_identity<T volatile>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return type_name( tn_identity<T>() ) + " volatile";
|
return type_name( tn_identity<T>(), " volatile" + suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
typename tn_enable_if<!tn_is_reference<T>::value, std::string>::type
|
typename tn_enable_if<!tn_is_function<T>::value, std::string>::type
|
||||||
type_name( tn_identity<T const volatile> )
|
type_name( tn_identity<T const volatile>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return type_name( tn_identity<T>() ) + " const volatile";
|
return type_name( tn_identity<T>(), " const volatile" + suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -287,27 +345,27 @@ type_name( tn_identity<T const volatile> )
|
|||||||
|
|
||||||
#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900
|
#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900
|
||||||
|
|
||||||
template<class T> std::string type_name( tn_identity<T&> )
|
template<class T> std::string type_name( tn_identity<T&>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return type_name( tn_identity<T>() ) + "&";
|
return type_name( tn_identity<T>(), "&" + suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
typename tn_enable_if<!tn_is_reference<T>::value, std::string>::type
|
typename tn_enable_if<!tn_is_reference<T>::value, std::string>::type
|
||||||
type_name( tn_identity<T&> )
|
type_name( tn_identity<T&>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return type_name( tn_identity<T>() ) + "&";
|
return type_name( tn_identity<T>(), "&" + suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||||
|
|
||||||
template<class T> std::string type_name( tn_identity<T&&> )
|
template<class T> std::string type_name( tn_identity<T&&>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return type_name( tn_identity<T>() ) + "&&";
|
return type_name( tn_identity<T>(), "&&" + suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -316,65 +374,178 @@ template<class T> std::string type_name( tn_identity<T&&> )
|
|||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
template<class R, class... A> std::string type_name( tn_identity<R(A...)> )
|
template<class R, class... A> std::string function_type_name( tn_identity<R(A...)>, std::string const& trailer, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return type_name( tn_identity<R>() ) + '(' + tn_add_each<A...>() + ')';
|
std::string r = type_name( tn_identity<R>(), "" );
|
||||||
|
|
||||||
|
if( !suffix.empty() )
|
||||||
|
{
|
||||||
|
r += '(';
|
||||||
|
|
||||||
|
if( suffix[ 0 ] == ' ' )
|
||||||
|
{
|
||||||
|
r += suffix.substr( 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r += suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
r += ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
r += '(' + tn_add_each<A...>() + ')';
|
||||||
|
r += trailer;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...)>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), "", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) const>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " const", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) volatile>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " volatile", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) const volatile>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " const volatile", suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS)
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) &>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " &", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) const &>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " const &", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) volatile &>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " volatile &", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) const volatile &>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " const volatile &", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) &&>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " &&", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) const &&>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " const &&", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) volatile &&>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " volatile &&", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) const volatile &&>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " const volatile &&", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED )
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) noexcept>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " noexcept", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) const noexcept>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " const noexcept", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) volatile noexcept>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " volatile noexcept", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) const volatile noexcept>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " const volatile noexcept", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) & noexcept>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " & noexcept", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) const & noexcept>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " const & noexcept", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) volatile & noexcept>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " volatile & noexcept", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) const volatile & noexcept>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " const volatile & noexcept", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) && noexcept>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " && noexcept", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) const && noexcept>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " const && noexcept", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) volatile && noexcept>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " volatile && noexcept", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class... A> std::string type_name( tn_identity<R(A...) const volatile && noexcept>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " const volatile && noexcept", suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
// pointers
|
// pointers
|
||||||
|
|
||||||
template<class T> std::string type_name( tn_identity<T*> )
|
template<class T> std::string type_name( tn_identity<T*>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return type_name( tn_identity<T>() ) + "*";
|
return type_name( tn_identity<T>(), "*" + suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
|
||||||
|
|
||||||
// function pointers
|
|
||||||
|
|
||||||
template<class R, class... A> std::string type_name( tn_identity<R(*)(A...)> )
|
|
||||||
{
|
|
||||||
return type_name( tn_identity<R>() ) + "(*)(" + tn_add_each<A...>() + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class R, class... A> std::string type_name( tn_identity<R(*&)(A...)> )
|
|
||||||
{
|
|
||||||
return type_name( tn_identity<R>() ) + "(*&)(" + tn_add_each<A...>() + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class R, class... A> std::string type_name( tn_identity<R(* const)(A...)> )
|
|
||||||
{
|
|
||||||
return type_name( tn_identity<R>() ) + "(* const)(" + tn_add_each<A...>() + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class R, class... A> std::string type_name( tn_identity<R(* const&)(A...)> )
|
|
||||||
{
|
|
||||||
return type_name( tn_identity<R>() ) + "(* const&)(" + tn_add_each<A...>() + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
|
||||||
|
|
||||||
template<class R, class... A> std::string type_name( tn_identity<R(*&&)(A...)> )
|
|
||||||
{
|
|
||||||
return type_name( tn_identity<R>() ) + "(*&&)(" + tn_add_each<A...>() + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class R, class... A> std::string type_name( tn_identity<R(* const&&)(A...)> )
|
|
||||||
{
|
|
||||||
return type_name( tn_identity<R>() ) + "(* const&&)(" + tn_add_each<A...>() + ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// arrays
|
// arrays
|
||||||
|
|
||||||
template<class T> std::pair<std::string, std::string> array_prefix_suffix( tn_identity<T> )
|
template<class T> std::pair<std::string, std::string> array_prefix_suffix( tn_identity<T> )
|
||||||
{
|
{
|
||||||
return std::pair<std::string, std::string>( type_name( tn_identity<T>() ), "" );
|
return std::pair<std::string, std::string>( type_name( tn_identity<T>(), "" ), "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, std::size_t N> std::pair<std::string, std::string> array_prefix_suffix( tn_identity<T[N]> )
|
template<class T, std::size_t N> std::pair<std::string, std::string> array_prefix_suffix( tn_identity<T[N]> )
|
||||||
@ -386,163 +557,210 @@ template<class T, std::size_t N> std::pair<std::string, std::string> array_prefi
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> std::string array_type_name( tn_identity<T[]> )
|
template<class T> std::string array_type_name( tn_identity<T[]>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
std::pair<std::string, std::string> r = array_prefix_suffix( tn_identity<T>() );
|
std::pair<std::string, std::string> r = array_prefix_suffix( tn_identity<T>() );
|
||||||
return r.first + "[]" + r.second;
|
|
||||||
|
if( suffix.empty() )
|
||||||
|
{
|
||||||
|
return r.first + "[]" + r.second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return r.first + '(' + suffix + ")[]" + r.second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> std::string type_name( tn_identity<T[]> )
|
template<class T> std::string type_name( tn_identity<T[]>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return array_type_name( tn_identity<T[]>() );
|
return array_type_name( tn_identity<T[]>(), suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> std::string type_name( tn_identity<T const[]> )
|
template<class T> std::string type_name( tn_identity<T const[]>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return array_type_name( tn_identity<T const[]>() );
|
return array_type_name( tn_identity<T const[]>(), suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> std::string type_name( tn_identity<T volatile[]> )
|
template<class T> std::string type_name( tn_identity<T volatile[]>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return array_type_name( tn_identity<T volatile[]>() );
|
return array_type_name( tn_identity<T volatile[]>(), suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> std::string type_name( tn_identity<T const volatile[]> )
|
template<class T> std::string type_name( tn_identity<T const volatile[]>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return array_type_name( tn_identity<T const volatile[]>() );
|
return array_type_name( tn_identity<T const volatile[]>(), suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, std::size_t N> std::string array_type_name( tn_identity<T[N]> )
|
template<class T, std::size_t N> std::string array_type_name( tn_identity<T[N]>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
std::pair<std::string, std::string> r = array_prefix_suffix( tn_identity<T[N]>() );
|
std::pair<std::string, std::string> r = array_prefix_suffix( tn_identity<T[N]>() );
|
||||||
return r.first + r.second;
|
|
||||||
|
if( suffix.empty() )
|
||||||
|
{
|
||||||
|
return r.first + r.second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return r.first + '(' + suffix + ")" + r.second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, std::size_t N> std::string type_name( tn_identity<T[N]> )
|
template<class T, std::size_t N> std::string type_name( tn_identity<T[N]>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return array_type_name( tn_identity<T[N]>() );
|
return array_type_name( tn_identity<T[N]>(), suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, std::size_t N> std::string type_name( tn_identity<T const[N]> )
|
template<class T, std::size_t N> std::string type_name( tn_identity<T const[N]>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return array_type_name( tn_identity<T const[N]>() );
|
return array_type_name( tn_identity<T const[N]>(), suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, std::size_t N> std::string type_name( tn_identity<T volatile[N]> )
|
template<class T, std::size_t N> std::string type_name( tn_identity<T volatile[N]>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return array_type_name( tn_identity<T volatile[N]>() );
|
return array_type_name( tn_identity<T volatile[N]>(), suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, std::size_t N> std::string type_name( tn_identity<T const volatile[N]> )
|
template<class T, std::size_t N> std::string type_name( tn_identity<T const volatile[N]>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return array_type_name( tn_identity<T const volatile[N]>() );
|
return array_type_name( tn_identity<T const volatile[N]>(), suffix );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pointers to members
|
||||||
|
|
||||||
|
template<class R, class T> std::string type_name( tn_identity<R T::*>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return type_name( tn_identity<R>(), ' ' + type_name( tn_identity<T>(), "" ) + "::*" + suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC) && BOOST_MSVC < 1900 && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
template<class R, class T, class... A> std::string type_name( tn_identity<R(T::*)(A...)>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), "", ' ' + type_name( tn_identity<T>(), "" ) + "::*" + suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class T, class... A> std::string type_name( tn_identity<R(T::*)(A...) const>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " const", ' ' + type_name( tn_identity<T>(), "" ) + "::*" + suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class T, class... A> std::string type_name( tn_identity<R(T::*)(A...) volatile>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " volatile", ' ' + type_name( tn_identity<T>(), "" ) + "::*" + suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class R, class T, class... A> std::string type_name( tn_identity<R(T::*)(A...) const volatile>, std::string const& suffix )
|
||||||
|
{
|
||||||
|
return function_type_name( tn_identity<R(A...)>(), " const volatile", ' ' + type_name( tn_identity<T>(), "" ) + "::*" + suffix );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// nullptr_t
|
// nullptr_t
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||||
|
|
||||||
inline std::string type_name( tn_identity<std::nullptr_t> )
|
inline std::string type_name( tn_identity<std::nullptr_t>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return "std::nullptr_t";
|
return "std::nullptr_t" + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// strings
|
// strings
|
||||||
|
|
||||||
template<template<class Ch, class Tr, class A> class L, class Ch> std::string type_name( tn_identity< L<Ch, std::char_traits<Ch>, std::allocator<Ch> > > )
|
template<template<class Ch, class Tr, class A> class L, class Ch> std::string type_name( tn_identity< L<Ch, std::char_traits<Ch>, std::allocator<Ch> > >, std::string const& suffix )
|
||||||
{
|
{
|
||||||
std::string tn = sequence_template_name< L<Ch, std::char_traits<Ch>, std::allocator<Ch> > >();
|
std::string tn = sequence_template_name< L<Ch, std::char_traits<Ch>, std::allocator<Ch> > >();
|
||||||
return tn + '<' + type_name( tn_identity<Ch>() ) + '>';
|
return tn + '<' + type_name( tn_identity<Ch>(), "" ) + '>' + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string type_name( tn_identity<std::string> )
|
inline std::string type_name( tn_identity<std::string>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return "std::string";
|
return "std::string" + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string type_name( tn_identity<std::wstring> )
|
inline std::string type_name( tn_identity<std::wstring>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return "std::wstring";
|
return "std::wstring" + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||||
|
|
||||||
inline std::string type_name( tn_identity<std::u16string> )
|
inline std::string type_name( tn_identity<std::u16string>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return "std::u16string";
|
return "std::u16string" + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||||
|
|
||||||
inline std::string type_name( tn_identity<std::u32string> )
|
inline std::string type_name( tn_identity<std::u32string>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return "std::u32string";
|
return "std::u32string" + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
|
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
|
||||||
|
|
||||||
inline std::string type_name( tn_identity<std::basic_string<char8_t>> )
|
inline std::string type_name( tn_identity<std::basic_string<char8_t>>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return "std::u8string";
|
return "std::u8string" + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// string views (et al)
|
// string views (et al)
|
||||||
|
|
||||||
template<template<class Ch, class Tr> class L, class Ch> std::string type_name( tn_identity< L<Ch, std::char_traits<Ch> > > )
|
template<template<class Ch, class Tr> class L, class Ch> std::string type_name( tn_identity< L<Ch, std::char_traits<Ch> > >, std::string const& suffix )
|
||||||
{
|
{
|
||||||
std::string tn = sequence_template_name< L<Ch, std::char_traits<Ch> > >();
|
std::string tn = sequence_template_name< L<Ch, std::char_traits<Ch> > >();
|
||||||
return tn + '<' + type_name( tn_identity<Ch>() ) + '>';
|
return tn + '<' + type_name( tn_identity<Ch>(), "" ) + '>' + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
// needed for libstdc++
|
// needed for libstdc++
|
||||||
inline std::string type_name( tn_identity<std::ostream> )
|
inline std::string type_name( tn_identity<std::ostream>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return "std::ostream";
|
return "std::ostream" + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
|
#if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW)
|
||||||
|
|
||||||
inline std::string type_name( tn_identity<std::string_view> )
|
inline std::string type_name( tn_identity<std::string_view>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return "std::string_view";
|
return "std::string_view" + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string type_name( tn_identity<std::wstring_view> )
|
inline std::string type_name( tn_identity<std::wstring_view>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return "std::wstring_view";
|
return "std::wstring_view" + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
#if !defined(BOOST_NO_CXX11_CHAR16_T)
|
||||||
|
|
||||||
inline std::string type_name( tn_identity<std::u16string_view> )
|
inline std::string type_name( tn_identity<std::u16string_view>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return "std::u16string_view";
|
return "std::u16string_view" + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
#if !defined(BOOST_NO_CXX11_CHAR32_T)
|
||||||
|
|
||||||
inline std::string type_name( tn_identity<std::u32string_view> )
|
inline std::string type_name( tn_identity<std::u32string_view>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return "std::u32string_view";
|
return "std::u32string_view" + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
|
#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L
|
||||||
|
|
||||||
inline std::string type_name( tn_identity<std::basic_string_view<char8_t>> )
|
inline std::string type_name( tn_identity<std::basic_string_view<char8_t>>, std::string const& suffix )
|
||||||
{
|
{
|
||||||
return "std::u8string_view";
|
return "std::u8string_view" + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -553,87 +771,87 @@ inline std::string type_name( tn_identity<std::basic_string_view<char8_t>> )
|
|||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
template<template<class...> class L, class... T> std::string type_name( tn_identity< L<T...> > )
|
template<template<class...> class L, class... T> std::string type_name( tn_identity< L<T...> >, std::string const& suffix )
|
||||||
{
|
{
|
||||||
std::string tn = class_template_name< L<T...> >();
|
std::string tn = class_template_name< L<T...> >();
|
||||||
std::string st = tn_add_each<T...>();
|
std::string st = tn_add_each<T...>();
|
||||||
|
|
||||||
return tn + '<' + st + '>';
|
return tn + '<' + st + '>' + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
template<template<class T1> class L, class T1> std::string type_name( tn_identity< L<T1> > )
|
template<template<class T1> class L, class T1> std::string type_name( tn_identity< L<T1> >, std::string const& suffix )
|
||||||
{
|
{
|
||||||
std::string tn = class_template_name< L<T1> >();
|
std::string tn = class_template_name< L<T1> >();
|
||||||
return tn + '<' + type_name( tn_identity<T1>() ) + '>';
|
return tn + '<' + type_name( tn_identity<T1>(), "" ) + '>' + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<template<class T1, class T2> class L, class T1, class T2> std::string type_name( tn_identity< L<T1, T2> > )
|
template<template<class T1, class T2> class L, class T1, class T2> std::string type_name( tn_identity< L<T1, T2> >, std::string const& suffix )
|
||||||
{
|
{
|
||||||
std::string tn = class_template_name< L<T1, T2> >();
|
std::string tn = class_template_name< L<T1, T2> >();
|
||||||
return tn + '<' + type_name( tn_identity<T1>() ) + ", " + type_name( tn_identity<T2>() ) + '>';
|
return tn + '<' + type_name( tn_identity<T1>(), "" ) + ", " + type_name( tn_identity<T2>(), "" ) + '>' + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// sequence containers
|
// sequence containers
|
||||||
|
|
||||||
template<template<class T, class A> class L, class T> std::string type_name( tn_identity< L<T, std::allocator<T> > > )
|
template<template<class T, class A> class L, class T> std::string type_name( tn_identity< L<T, std::allocator<T> > >, std::string const& suffix )
|
||||||
{
|
{
|
||||||
std::string tn = sequence_template_name< L<T, std::allocator<T> > >();
|
std::string tn = sequence_template_name< L<T, std::allocator<T> > >();
|
||||||
return tn + '<' + type_name( tn_identity<T>() ) + '>';
|
return tn + '<' + type_name( tn_identity<T>(), "" ) + '>' + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set
|
// set
|
||||||
|
|
||||||
template<template<class T, class Pr, class A> class L, class T> std::string type_name( tn_identity< L<T, std::less<T>, std::allocator<T> > > )
|
template<template<class T, class Pr, class A> class L, class T> std::string type_name( tn_identity< L<T, std::less<T>, std::allocator<T> > >, std::string const& suffix )
|
||||||
{
|
{
|
||||||
std::string tn = set_template_name< L<T, std::less<T>, std::allocator<T> > >();
|
std::string tn = set_template_name< L<T, std::less<T>, std::allocator<T> > >();
|
||||||
return tn + '<' + type_name( tn_identity<T>() ) + '>';
|
return tn + '<' + type_name( tn_identity<T>(), "" ) + '>' + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
// map
|
// map
|
||||||
|
|
||||||
template<template<class T, class U, class Pr, class A> class L, class T, class U> std::string type_name( tn_identity< L<T, U, std::less<T>, std::allocator<std::pair<T const, U> > > > )
|
template<template<class T, class U, class Pr, class A> class L, class T, class U> std::string type_name( tn_identity< L<T, U, std::less<T>, std::allocator<std::pair<T const, U> > > >, std::string const& suffix )
|
||||||
{
|
{
|
||||||
std::string tn = map_template_name< L<T, U, std::less<T>, std::allocator<std::pair<T const, U> > > >();
|
std::string tn = map_template_name< L<T, U, std::less<T>, std::allocator<std::pair<T const, U> > > >();
|
||||||
return tn + '<' + type_name( tn_identity<T>() ) + ", " + type_name( tn_identity<U>() ) + '>';
|
return tn + '<' + type_name( tn_identity<T>(), "" ) + ", " + type_name( tn_identity<U>(), "" ) + '>' + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
|
#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL)
|
||||||
|
|
||||||
// unordered_set
|
// unordered_set
|
||||||
|
|
||||||
template<template<class T, class H, class Eq, class A> class L, class T> std::string type_name( tn_identity< L<T, std::hash<T>, std::equal_to<T>, std::allocator<T> > > )
|
template<template<class T, class H, class Eq, class A> class L, class T> std::string type_name( tn_identity< L<T, std::hash<T>, std::equal_to<T>, std::allocator<T> > >, std::string const& suffix )
|
||||||
{
|
{
|
||||||
std::string tn = set_template_name< L<T, std::hash<T>, std::equal_to<T>, std::allocator<T> > >();
|
std::string tn = set_template_name< L<T, std::hash<T>, std::equal_to<T>, std::allocator<T> > >();
|
||||||
return tn + '<' + type_name( tn_identity<T>() ) + '>';
|
return tn + '<' + type_name( tn_identity<T>(), "" ) + '>' + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unordered_map
|
// unordered_map
|
||||||
|
|
||||||
template<template<class T, class U, class H, class Eq, class A> class L, class T, class U> std::string type_name( tn_identity< L<T, U, std::hash<T>, std::equal_to<T>, std::allocator<std::pair<T const, U> > > > )
|
template<template<class T, class U, class H, class Eq, class A> class L, class T, class U> std::string type_name( tn_identity< L<T, U, std::hash<T>, std::equal_to<T>, std::allocator<std::pair<T const, U> > > >, std::string const& suffix )
|
||||||
{
|
{
|
||||||
std::string tn = map_template_name< L<T, U, std::hash<T>, std::equal_to<T>, std::allocator<std::pair<T const, U> > > >();
|
std::string tn = map_template_name< L<T, U, std::hash<T>, std::equal_to<T>, std::allocator<std::pair<T const, U> > > >();
|
||||||
return tn + '<' + type_name( tn_identity<T>() ) + ", " + type_name( tn_identity<U>() ) + '>';
|
return tn + '<' + type_name( tn_identity<T>(), "" ) + ", " + type_name( tn_identity<U>(), "" ) + '>' + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// array
|
// array
|
||||||
|
|
||||||
template<template<class T, std::size_t N> class L, class T, std::size_t N> std::string type_name( tn_identity< L<T, N> > )
|
template<template<class T, std::size_t N> class L, class T, std::size_t N> std::string type_name( tn_identity< L<T, N> >, std::string const& suffix )
|
||||||
{
|
{
|
||||||
std::string tn = array_template_name< L<T, N> >();
|
std::string tn = array_template_name< L<T, N> >();
|
||||||
return tn + '<' + type_name( tn_identity<T>() ) + ", " + tn_to_string( N ) + '>';
|
return tn + '<' + type_name( tn_identity<T>(), "" ) + ", " + tn_to_string( N ) + '>' + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template<class T> std::string type_name()
|
template<class T> std::string type_name()
|
||||||
{
|
{
|
||||||
return core::detail::type_name( core::detail::tn_identity<T>() );
|
return core::detail::type_name( core::detail::tn_identity<T>(), "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace core
|
} // namespace core
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Boost.Core Library test Jamfile
|
# 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.
|
# Distributed under the Boost Software License, Version 1.0.
|
||||||
# See accompanying file LICENSE_1_0.txt or copy at
|
# 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_fail5.cpp ;
|
||||||
run-fail lightweight_test_fail6.cpp ;
|
run-fail lightweight_test_fail6.cpp ;
|
||||||
run-fail lightweight_test_fail7.cpp ;
|
run-fail lightweight_test_fail7.cpp ;
|
||||||
run-fail lightweight_test_fail7.cpp : : : <rtti>off : lightweight_test_fail7_no_rtti ;
|
run-fail lightweight_test_fail7.cpp : : : <rtti>off <toolset>gcc-4.4:<build>no : lightweight_test_fail7_no_rtti ;
|
||||||
run-fail lightweight_test_fail8.cpp ;
|
run-fail lightweight_test_fail8.cpp ;
|
||||||
run-fail lightweight_test_fail8.cpp : : : <rtti>off : lightweight_test_fail8_no_rtti ;
|
run-fail lightweight_test_fail8.cpp : : : <rtti>off <toolset>gcc-4.4:<build>no : lightweight_test_fail8_no_rtti ;
|
||||||
run-fail lightweight_test_fail9.cpp ;
|
run-fail lightweight_test_fail9.cpp ;
|
||||||
run-fail lightweight_test_fail10.cpp ;
|
run-fail lightweight_test_fail10.cpp ;
|
||||||
run-fail lightweight_test_fail11.cpp : ;
|
run-fail lightweight_test_fail11.cpp : ;
|
||||||
@ -232,7 +232,7 @@ run no_exceptions_support_test.cpp ;
|
|||||||
run no_exceptions_support_test.cpp : : : <exception-handling>off : no_exceptions_support_test_nx ;
|
run no_exceptions_support_test.cpp : : : <exception-handling>off : no_exceptions_support_test_nx ;
|
||||||
|
|
||||||
run cmath_test.cpp ;
|
run cmath_test.cpp ;
|
||||||
run cmath_test.cpp : : : <define>BOOST_CORE_USE_GENERIC_CMATH : cmath_test_generic ;
|
run cmath_test.cpp : : : <define>BOOST_CORE_USE_GENERIC_CMATH <toolset>msvc-8.0:<build>no : cmath_test_generic ;
|
||||||
|
|
||||||
run bit_cast_test.cpp ;
|
run bit_cast_test.cpp ;
|
||||||
run bit_rotate_test.cpp ;
|
run bit_rotate_test.cpp ;
|
||||||
|
@ -67,7 +67,42 @@ struct Ch
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
TEST(signed char);
|
||||||
|
TEST(unsigned char);
|
||||||
|
TEST(short);
|
||||||
|
TEST(unsigned short);
|
||||||
TEST(int);
|
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(A);
|
||||||
TEST(B);
|
TEST(B);
|
||||||
@ -94,33 +129,133 @@ int main()
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TEST(void);
|
|
||||||
TEST(void const);
|
|
||||||
TEST(void volatile);
|
|
||||||
TEST(void const volatile);
|
|
||||||
|
|
||||||
TEST(A*);
|
TEST(A*);
|
||||||
TEST(B const* volatile*);
|
TEST(B const* volatile*);
|
||||||
|
|
||||||
TEST(void*);
|
TEST(void*);
|
||||||
TEST(void const* volatile*);
|
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[]);
|
||||||
TEST(A const[]);
|
TEST(A const[]);
|
||||||
TEST(A volatile[]);
|
TEST(A volatile[]);
|
||||||
TEST(A const volatile[]);
|
TEST(A const volatile[]);
|
||||||
|
|
||||||
|
#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1700
|
||||||
|
TEST(A(&)[]);
|
||||||
|
#endif
|
||||||
|
TEST(A const(***)[]);
|
||||||
|
|
||||||
TEST(B[1]);
|
TEST(B[1]);
|
||||||
TEST(B const[1]);
|
TEST(B const[1]);
|
||||||
TEST(B volatile[1]);
|
TEST(B volatile[1]);
|
||||||
TEST(B const volatile[1]);
|
TEST(B const volatile[1]);
|
||||||
|
|
||||||
|
TEST(B(&)[1]);
|
||||||
|
TEST(B const(***)[1]);
|
||||||
|
|
||||||
TEST(A[][2][3]);
|
TEST(A[][2][3]);
|
||||||
TEST(A const[][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[1][2][3]);
|
||||||
TEST(B const volatile[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)
|
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||||
|
|
||||||
TEST(std::nullptr_t);
|
TEST(std::nullptr_t);
|
||||||
|
Reference in New Issue
Block a user