From 68c46450deef214845590264c9d963a0014a8125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ion=20Gazta=C3=B1aga?= Date: Thu, 4 Aug 2016 23:22:29 +0200 Subject: [PATCH] Fixed Trac ticket #11476 ("has_member_function_callable_with.hpp is massively broken with BOOST_NO_CXX11_DECLTYPE") --- doc/intrusive.qbk | 1 + .../has_member_function_callable_with.hpp | 145 ++++++++++-------- proj/vc7ide/Intrusive.sln | 16 ++ ..._function_callable_with_no_decltype.vcproj | 133 ++++++++++++++++ ..._function_callable_with_no_variadic.vcproj | 133 ++++++++++++++++ test/any_test.cpp | 1 - ...ber_function_callable_with_no_decltype.cpp | 12 ++ ...ber_function_callable_with_no_variadic.cpp | 12 ++ 8 files changed, 392 insertions(+), 61 deletions(-) create mode 100644 proj/vc7ide/has_member_function_callable_with_no_decltype/has_member_function_callable_with_no_decltype.vcproj create mode 100644 proj/vc7ide/has_member_function_callable_with_no_variadic/has_member_function_callable_with_no_variadic.vcproj create mode 100644 test/has_member_function_callable_with_no_decltype.cpp create mode 100644 test/has_member_function_callable_with_no_variadic.cpp diff --git a/doc/intrusive.qbk b/doc/intrusive.qbk index e5498f0..cf1567d 100644 --- a/doc/intrusive.qbk +++ b/doc/intrusive.qbk @@ -3838,6 +3838,7 @@ to be inserted in intrusive containers are allocated using `std::vector` or `std [section:release_notes_boost_1_62_00 Boost 1.62 Release] * Fixed bugs: + * [@https://svn.boost.org/trac/boost/ticket/11476 Boost Trac #11476: ['has_member_function_callable_with.hpp is massively broken with BOOST_NO_CXX11_DECLTYPE]] * [@https://svn.boost.org/trac/boost/ticket/11994 Boost Trac #11994: ['Support intrusive container key extractors that return the key by value]] * [@https://svn.boost.org/trac/boost/ticket/12184 Boost Trac #12184: ['clang -Wdocumentation warning]] * [@https://svn.boost.org/trac/boost/ticket/12190 Boost Trac #12190: ['Intrusive List + Flat Map combination crashes]] diff --git a/include/boost/intrusive/detail/has_member_function_callable_with.hpp b/include/boost/intrusive/detail/has_member_function_callable_with.hpp index 2e73305..92ef60e 100644 --- a/include/boost/intrusive/detail/has_member_function_callable_with.hpp +++ b/include/boost/intrusive/detail/has_member_function_callable_with.hpp @@ -11,13 +11,22 @@ #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP -//Mark that we don't support 0 arg calls due to compiler ICE in GCC 3.4/4.0/4.1 and -//wrong SFINAE for GCC 4.2/4.3 -#if defined(__GNUC__) && !defined(__clang__) && ((__GNUC__*100 + __GNUC_MINOR__*10) >= 340) && ((__GNUC__*100 + __GNUC_MINOR__*10) <= 430) - #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED -#elif defined(BOOST_INTEL) && (BOOST_INTEL < 1200 ) - #define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +#ifndef BOOST_CONFIG_HPP +# include #endif + +//In case no decltype and no variadics, mark that we don't support 0 arg calls due to +//compiler ICE in GCC 3.4/4.0/4.1 and, wrong SFINAE for GCC 4.2/4.3/MSVC10/MSVC11 +#if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +# if defined(BOOST_GCC) && (BOOST_GCC < 40400) +# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +# elif defined(BOOST_INTEL) && (BOOST_INTEL < 1200) +# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800) +# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +# endif +#endif //#if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + #include #include #include @@ -27,6 +36,11 @@ namespace boost_intrusive_hmfcw { typedef char yes_type; struct no_type{ char dummy[2]; }; +struct dont_care +{ + dont_care(...); +}; + #if defined(BOOST_NO_CXX11_DECLTYPE) #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) @@ -39,11 +53,6 @@ struct make_dontcare #endif -struct dont_care -{ - dont_care(...); -}; - struct private_type { static private_type p; @@ -56,7 +65,7 @@ yes_type is_private_type(private_type const &); #endif //#if defined(BOOST_NO_CXX11_DECLTYPE) -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE) template struct remove_cv { typedef T type; }; template struct remove_cv { typedef T type; }; @@ -124,7 +133,31 @@ BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG // declaration, special case and 0 arg specializaton // ///////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////// + + template + class BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + struct BaseMixin + { + void BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME() + {} //Some compilers require the definition or linker errors happen + }; + + struct Base + : public boost_intrusive_hmfcw::remove_cv::type, public BaseMixin + { //Declare the unneeded default constructor as some old compilers wrongly require it with is_convertible + Base(){} + }; + template class Helper{}; + + template + static boost_intrusive_hmfcw::no_type deduce + (U*, Helper* = 0); + static boost_intrusive_hmfcw::yes_type deduce(...); + + public: + static const bool value = sizeof(boost_intrusive_hmfcw::yes_type) == sizeof(deduce((Base*)0)); + }; #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) ///////////////////////////////////////////////////////// @@ -136,54 +169,46 @@ BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG ///////////////////////////////////////////////////////// //defined(BOOST_NO_CXX11_DECLTYPE) must be true - template + template struct FunWrapTmpl : Fun { using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME; + FunWrapTmpl(); + template boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(DontCares...) const; }; - template - struct BOOST_MOVE_CAT(has_member_function_callable_with_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) - { - typedef FunWrapTmpl::type...> FunWrap; + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME); - static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == - sizeof(boost_intrusive_hmfcw::is_private_type - ( (::boost::move_detail::declval< FunWrap >(). + //No BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME member specialization + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + + { + static const bool value = false; + }; + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == sizeof(boost_intrusive_hmfcw::is_private_type + ( (::boost::move_detail::declval + < FunWrapTmpl >(). BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval()...), 0) ) ) ); }; + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + : public BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + ::value + , Args...> + {}; #else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - //Preprocessor must be used to generate specializations instead of variadic templates - - template - class BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) - { - struct BaseMixin - { - void BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME() - {} //Some compilers require the definition or linker errors happen - }; - - struct Base - : public boost_intrusive_hmfcw::remove_cv::type, public BaseMixin - { //Declare the unneeded default constructor as some old compilers wrongly require it with is_convertible - Base(){} - }; - template class Helper{}; - - template - static boost_intrusive_hmfcw::no_type deduce - (U*, Helper* = 0); - static boost_intrusive_hmfcw::yes_type deduce(...); - - public: - static const bool value = sizeof(boost_intrusive_hmfcw::yes_type) == sizeof(deduce((Base*)0)); - }; - ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// // @@ -222,24 +247,24 @@ BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG #if !defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) - template().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(), 0)> - struct BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) - { boost_intrusive_hmfcw::yes_type dummy[N ? 1 : 2]; }; + template().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(), 0)> + struct BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { boost_intrusive_hmfcw::yes_type dummy[N ? 1 : 2]; }; - template - struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) - { - template static BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) - Test(BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)*); - template static boost_intrusive_hmfcw::no_type Test(...); - static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_hmfcw::yes_type); - }; + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + template static BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + Test(BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)*); + template static boost_intrusive_hmfcw::no_type Test(...); + static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_hmfcw::yes_type); + }; #else //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) template struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) - {//GCC [3.4-4.3) gives ICE when instantiating the 0 arg version so it is not supported. + { //Some compilers gives ICE when instantiating the 0 arg version so it is not supported. static const bool value = true; }; diff --git a/proj/vc7ide/Intrusive.sln b/proj/vc7ide/Intrusive.sln index 4c5221f..b9c3f29 100644 --- a/proj/vc7ide/Intrusive.sln +++ b/proj/vc7ide/Intrusive.sln @@ -135,6 +135,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bs_set", "bs_set\bs_set.vcp ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "has_member_function_callable_with_no_decltype", "has_member_function_callable_with_no_decltype\has_member_function_callable_with_no_decltype.vcproj", "{3579B1A4-95A8-1EB8-02AB-95140325B465}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "has_member_function_callable_with_no_variadic", "has_member_function_callable_with_no_variadic\has_member_function_callable_with_no_variadic.vcproj", "{3702AA54-9B1D-5489-CB81-95327B170465}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -279,6 +287,14 @@ Global {19EA9747-E42A-C76A-17C7-A5C920B71727}.Debug.Build.0 = Debug|Win32 {19EA9747-E42A-C76A-17C7-A5C920B71727}.Release.ActiveCfg = Release|Win32 {19EA9747-E42A-C76A-17C7-A5C920B71727}.Release.Build.0 = Release|Win32 + {3579B1A4-95A8-1EB8-02AB-95140325B465}.Debug.ActiveCfg = Debug|Win32 + {3579B1A4-95A8-1EB8-02AB-95140325B465}.Debug.Build.0 = Debug|Win32 + {3579B1A4-95A8-1EB8-02AB-95140325B465}.Release.ActiveCfg = Release|Win32 + {3579B1A4-95A8-1EB8-02AB-95140325B465}.Release.Build.0 = Release|Win32 + {3702AA54-9B1D-5489-CB81-95327B170465}.Debug.ActiveCfg = Debug|Win32 + {3702AA54-9B1D-5489-CB81-95327B170465}.Debug.Build.0 = Debug|Win32 + {3702AA54-9B1D-5489-CB81-95327B170465}.Release.ActiveCfg = Release|Win32 + {3702AA54-9B1D-5489-CB81-95327B170465}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/proj/vc7ide/has_member_function_callable_with_no_decltype/has_member_function_callable_with_no_decltype.vcproj b/proj/vc7ide/has_member_function_callable_with_no_decltype/has_member_function_callable_with_no_decltype.vcproj new file mode 100644 index 0000000..496decb --- /dev/null +++ b/proj/vc7ide/has_member_function_callable_with_no_decltype/has_member_function_callable_with_no_decltype.vcproj @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proj/vc7ide/has_member_function_callable_with_no_variadic/has_member_function_callable_with_no_variadic.vcproj b/proj/vc7ide/has_member_function_callable_with_no_variadic/has_member_function_callable_with_no_variadic.vcproj new file mode 100644 index 0000000..01ea843 --- /dev/null +++ b/proj/vc7ide/has_member_function_callable_with_no_variadic/has_member_function_callable_with_no_variadic.vcproj @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/any_test.cpp b/test/any_test.cpp index efc7d98..7552899 100644 --- a/test/any_test.cpp +++ b/test/any_test.cpp @@ -1,4 +1,3 @@ - ///////////////////////////////////////////////////////////////////////////// // // (C) Copyright Olaf Krzikalla 2004-2006. diff --git a/test/has_member_function_callable_with_no_decltype.cpp b/test/has_member_function_callable_with_no_decltype.cpp new file mode 100644 index 0000000..98037ba --- /dev/null +++ b/test/has_member_function_callable_with_no_decltype.cpp @@ -0,0 +1,12 @@ +#include + +#ifndef BOOST_NO_CXX11_DECLTYPE +# define BOOST_NO_CXX11_DECLTYPE +# include "has_member_function_callable_with.cpp" +#else + int main() + { + return 0; + } +#endif + diff --git a/test/has_member_function_callable_with_no_variadic.cpp b/test/has_member_function_callable_with_no_variadic.cpp new file mode 100644 index 0000000..1be7832 --- /dev/null +++ b/test/has_member_function_callable_with_no_variadic.cpp @@ -0,0 +1,12 @@ +#include + +#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +# include "has_member_function_callable_with.cpp" +#else + int main() + { + return 0; + } +#endif +