diff --git a/include/boost/core/type_name.hpp b/include/boost/core/type_name.hpp index 8632f81..f155943 100644 --- a/include/boost/core/type_name.hpp +++ b/include/boost/core/type_name.hpp @@ -244,9 +244,9 @@ inline std::string tn_to_string( std::size_t n ) template int tn_add_each_impl( std::string& st ) { if( !st.empty() ) st += ", "; - st += type_name( tn_identity() ); + st += type_name( tn_identity(), "" ); return 0; -}; +} template std::string tn_add_each() { @@ -256,57 +256,87 @@ template std::string tn_add_each() (void)A{ 0, tn_add_each_impl( st )... }; return st; -}; +} #endif // primary -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return typeid_name(); + return typeid_name() + suffix; } +// integrals + +inline std::string type_name( tn_identity, std::string const& suffix ) +{ + return "unsigned" + suffix; +} + +#if defined(_MSC_VER) + +inline std::string type_name( tn_identity, std::string const& suffix ) +{ + return "long long" + suffix; +} + +inline std::string type_name( tn_identity, std::string const& suffix ) +{ + return "unsigned long long" + suffix; +} + +#endif + +#if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L + +inline std::string type_name( tn_identity, std::string const& suffix ) +{ + return "char8_t" + suffix; +} + +#endif + // cv #if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900 -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + " const"; + return type_name( tn_identity(), " const" + suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + " volatile"; + return type_name( tn_identity(), " volatile" + suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + " const volatile"; + return type_name( tn_identity(), " const volatile" + suffix ); } #else template typename tn_enable_if::value, std::string>::type -type_name( tn_identity ) +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 +345,27 @@ type_name( tn_identity ) #if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900 -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + "&"; + return type_name( tn_identity(), "&" + suffix ); } #else template typename tn_enable_if::value, std::string>::type -type_name( tn_identity ) +type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + "&"; + return type_name( tn_identity(), "&" + suffix ); } #endif #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + "&&"; + return type_name( tn_identity(), "&&" + suffix ); } #endif @@ -344,81 +374,178 @@ template std::string type_name( tn_identity ) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) -template std::string type_name( tn_identity ) +template std::string function_type_name( tn_identity, std::string const& trailer, std::string const& suffix ) { - return type_name( tn_identity() ) + '(' + tn_add_each() + ')'; + std::string r = type_name( tn_identity(), "" ); + + if( !suffix.empty() ) + { + r += '('; + + if( suffix[ 0 ] == ' ' ) + { + r += suffix.substr( 1 ); + } + else + { + r += suffix; + } + + r += ')'; + } + + r += '(' + tn_add_each() + ')'; + r += trailer; + + return r; +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), "", suffix ); +} + +#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900 + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " volatile", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const volatile", suffix ); } #endif +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " &", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const &", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " volatile &", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const volatile &", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " &&", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const &&", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " volatile &&", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const volatile &&", suffix ); +} + +#endif + +#if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " volatile noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const volatile noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " & noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const & noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " volatile & noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const volatile & noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " && noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const && noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " volatile && noexcept", suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const volatile && noexcept", suffix ); +} + +#endif + +#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + // pointers -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return type_name( tn_identity() ) + "*"; + return type_name( tn_identity(), "*" + suffix ); } -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - -// function 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 +557,205 @@ template std::pair array_prefi return r; } -template std::string array_type_name( tn_identity ) +template std::string array_type_name( tn_identity, std::string const& suffix ) { std::pair r = array_prefix_suffix( tn_identity() ); - return r.first + "[]" + r.second; + + if( suffix.empty() ) + { + return r.first + "[]" + r.second; + } + else + { + return r.first + '(' + suffix + ")[]" + r.second; + } } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } -template std::string array_type_name( tn_identity ) +template std::string array_type_name( tn_identity, std::string const& suffix ) { std::pair r = array_prefix_suffix( tn_identity() ); - return r.first + r.second; + + if( suffix.empty() ) + { + return r.first + r.second; + } + else + { + return r.first + '(' + suffix + ")" + r.second; + } } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } -template std::string type_name( tn_identity ) +template std::string type_name( tn_identity, std::string const& suffix ) { - return array_type_name( tn_identity() ); + return array_type_name( tn_identity(), suffix ); } +// pointers to members + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return type_name( tn_identity(), ' ' + type_name( tn_identity(), "" ) + "::*" + suffix ); +} + +#if defined(BOOST_MSVC) && BOOST_MSVC <= 1900 && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const", ' ' + type_name( tn_identity(), "" ) + "::*" + suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " volatile", ' ' + type_name( tn_identity(), "" ) + "::*" + suffix ); +} + +template std::string type_name( tn_identity, std::string const& suffix ) +{ + return function_type_name( tn_identity(), " const volatile", ' ' + type_name( tn_identity(), "" ) + "::*" + suffix ); +} + +#endif + // nullptr_t #if !defined(BOOST_NO_CXX11_NULLPTR) -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::nullptr_t"; + return "std::nullptr_t" + suffix; } #endif // strings -template class L, class Ch> std::string type_name( tn_identity< L, std::allocator > > ) +template class L, class Ch> std::string type_name( tn_identity< L, std::allocator > >, std::string const& suffix ) { std::string tn = sequence_template_name< L, std::allocator > >(); - return tn + '<' + type_name( tn_identity() ) + '>'; + return tn + '<' + type_name( tn_identity(), "" ) + '>' + suffix; } -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::string"; + return "std::string" + suffix; } -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::wstring"; + return "std::wstring" + suffix; } #if !defined(BOOST_NO_CXX11_CHAR16_T) -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::u16string"; + return "std::u16string" + suffix; } #endif #if !defined(BOOST_NO_CXX11_CHAR32_T) -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::u32string"; + return "std::u32string" + suffix; } #endif #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L -inline std::string type_name( tn_identity> ) +inline std::string type_name( tn_identity>, std::string const& suffix ) { - return "std::u8string"; + return "std::u8string" + suffix; } #endif // string views (et al) -template class L, class Ch> std::string type_name( tn_identity< L > > ) +template class L, class Ch> std::string type_name( tn_identity< L > >, std::string const& suffix ) { std::string tn = sequence_template_name< L > >(); - return tn + '<' + type_name( tn_identity() ) + '>'; + return tn + '<' + type_name( tn_identity(), "" ) + '>' + suffix; } // needed for libstdc++ -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::ostream"; + return "std::ostream" + suffix; } #if !defined(BOOST_NO_CXX17_HDR_STRING_VIEW) -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::string_view"; + return "std::string_view" + suffix; } -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::wstring_view"; + return "std::wstring_view" + suffix; } #if !defined(BOOST_NO_CXX11_CHAR16_T) -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::u16string_view"; + return "std::u16string_view" + suffix; } #endif #if !defined(BOOST_NO_CXX11_CHAR32_T) -inline std::string type_name( tn_identity ) +inline std::string type_name( tn_identity, std::string const& suffix ) { - return "std::u32string_view"; + return "std::u32string_view" + suffix; } #endif #if defined(__cpp_char8_t) && __cpp_char8_t >= 201811L -inline std::string type_name( tn_identity> ) +inline std::string type_name( tn_identity>, std::string const& suffix ) { - return "std::u8string_view"; + return "std::u8string_view" + suffix; } #endif @@ -597,87 +766,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..e6574cb 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*); @@ -111,6 +141,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) @@ -118,24 +154,108 @@ int main() TEST(void(&&)()); #endif + +#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1900 + + TEST(void() const); + TEST(void() volatile); + TEST(void() const volatile); + #endif +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + + TEST(void() &); + TEST(void() const &); + TEST(void() volatile &); + TEST(void() const volatile &); + + TEST(void() &&); + TEST(void() const &&); + TEST(void() volatile &&); + TEST(void() const volatile &&); + +#endif + +#if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) + + TEST(void() noexcept); + TEST(void() const noexcept); + TEST(void() volatile noexcept); + TEST(void() const volatile noexcept); + + TEST(void() & noexcept); + TEST(void() const & noexcept); + TEST(void() volatile & noexcept); + TEST(void() const volatile & noexcept); + + TEST(void() && noexcept); + TEST(void() const && noexcept); + TEST(void() volatile && noexcept); + TEST(void() const volatile && noexcept); + +#endif + +#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + TEST(A[]); TEST(A const[]); TEST(A volatile[]); TEST(A const volatile[]); +#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1500 + TEST(A(&)[]); +#endif + TEST(A const(***)[]); + TEST(B[1]); TEST(B const[1]); TEST(B volatile[1]); TEST(B const volatile[1]); + TEST(B(&)[1]); + TEST(B const(***)[1]); + TEST(A[][2][3]); TEST(A const[][2][3]); +#if !defined(BOOST_MSVC) || BOOST_MSVC >= 1500 + TEST(A(&)[][2][3]); +#endif + TEST(A const(***)[][2][3]); + TEST(B[1][2][3]); TEST(B const volatile[1][2][3]); + TEST(B(&)[1][2][3]); + TEST(B const volatile(***)[1][2][3]); + + TEST(int A::*); + TEST(int const B::*); + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + TEST(void(A::*)()); + TEST(void(A::*)() const); + TEST(void(A::*)() volatile); + TEST(void(A::*)() const volatile); + +#endif + +#if !defined(BOOST_NO_CXX11_REF_QUALIFIERS) + + TEST(void(A::*)() &); + TEST(void(A::*)() const &&); + +#endif + +#if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) + + TEST(void(A::*)() volatile & noexcept); + TEST(void(A::*)() const volatile && noexcept); + +#endif + #if !defined(BOOST_NO_CXX11_NULLPTR) TEST(std::nullptr_t);