From 281e11b2923249869cce3131a415118bb9e2f1e1 Mon Sep 17 00:00:00 2001 From: Daniel James Date: Tue, 1 Nov 2016 16:31:21 +0000 Subject: [PATCH] Support for removed function objects in C++17 std::unary_function and std::binary_function are removed in C++17, and Visual C++ is the first compiler to do this (when the appropriate macro is defined). I'm not sure what the long term solution should be, but hopefully this will work for now. --- .travis.yml | 3 + hash/test/compile_time.hpp | 2 + include/boost/functional.hpp | 61 +++++++++++++++----- include/boost/functional/hash/extensions.hpp | 6 +- include/boost/functional/hash/hash.hpp | 20 +++++-- 5 files changed, 71 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index 59ee847..da716e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,8 @@ matrix: env: BJAM_TOOLSET=clang-std03 - compiler: clang env: BJAM_TOOLSET=clang-std11 + - compiler: clang + env: BJAM_TOOLSET=clang-pretend_no_auto_ptr_etc before_script: - | @@ -31,6 +33,7 @@ before_script: echo "using gcc : std11 : g++-4.8 -Werror --std=c++11 ;" >> ~/user-config.jam echo "using clang : std03 : clang++ -Werror --std=c++03 ;" >> ~/user-config.jam echo "using clang : std11 : clang++ -Werror --std=c++11 ;" >> ~/user-config.jam + echo "using clang : pretend_no_auto_ptr_etc : clang++ -Werror --std=c++11 -D_HAS_AUTO_PTR_ETC=0 ;" >> ~/user-config.jam - cat ~/user-config.jam - touch Jamroot.jam diff --git a/hash/test/compile_time.hpp b/hash/test/compile_time.hpp index 40f39d8..db6bc59 100644 --- a/hash/test/compile_time.hpp +++ b/hash/test/compile_time.hpp @@ -10,7 +10,9 @@ template void compile_time_tests(T*) { +#if !defined(_HAS_AUTO_PTR_ETC) || _HAS_AUTO_PTR_ETC BOOST_STATIC_ASSERT((boost::is_base_and_derived< std::unary_function, BOOST_HASH_TEST_NAMESPACE::hash >::value)); +#endif } diff --git a/include/boost/functional.hpp b/include/boost/functional.hpp index b618485..6443078 100644 --- a/include/boost/functional.hpp +++ b/include/boost/functional.hpp @@ -18,6 +18,36 @@ namespace boost { + namespace functional + { + namespace detail { +#if defined(_HAS_AUTO_PTR_ETC) && !_HAS_AUTO_PTR_ETC + // std::unary_function and std::binary_function were both removed + // in C++17. + + template + struct unary_function + { + typedef Arg1 argument_type; + typedef Result result_type; + }; + + template + struct binary_function + { + typedef Arg1 first_argument_type; + typedef Arg2 second_argument_type; + typedef Result result_type; + }; +#else + // Use the standard objects when we have them. + + using std::unary_function; + using std::binary_function; +#endif + } + } + #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION // -------------------------------------------------------------------------- // The following traits classes allow us to avoid the need for ptr_fun @@ -147,7 +177,7 @@ namespace boost // -------------------------------------------------------------------------- template class unary_negate - : public std::unary_function::argument_type,bool> + : public boost::functional::detail::unary_function::argument_type,bool> { public: explicit unary_negate(typename unary_traits::param_type x) @@ -181,7 +211,8 @@ namespace boost // -------------------------------------------------------------------------- template class binary_negate - : public std::binary_function::first_argument_type, + : public boost::functional::detail::binary_function< + typename binary_traits::first_argument_type, typename binary_traits::second_argument_type, bool> { @@ -218,7 +249,8 @@ namespace boost // -------------------------------------------------------------------------- template class binder1st - : public std::unary_function::second_argument_type, + : public boost::functional::detail::unary_function< + typename binary_traits::second_argument_type, typename binary_traits::result_type> { public: @@ -264,7 +296,8 @@ namespace boost // -------------------------------------------------------------------------- template class binder2nd - : public std::unary_function::first_argument_type, + : public boost::functional::detail::unary_function< + typename binary_traits::first_argument_type, typename binary_traits::result_type> { public: @@ -309,7 +342,7 @@ namespace boost // mem_fun, etc // -------------------------------------------------------------------------- template - class mem_fun_t : public std::unary_function + class mem_fun_t : public boost::functional::detail::unary_function { public: explicit mem_fun_t(S (T::*p)()) @@ -325,7 +358,7 @@ namespace boost }; template - class mem_fun1_t : public std::binary_function + class mem_fun1_t : public boost::functional::detail::binary_function { public: explicit mem_fun1_t(S (T::*p)(A)) @@ -341,7 +374,7 @@ namespace boost }; template - class const_mem_fun_t : public std::unary_function + class const_mem_fun_t : public boost::functional::detail::unary_function { public: explicit const_mem_fun_t(S (T::*p)() const) @@ -357,7 +390,7 @@ namespace boost }; template - class const_mem_fun1_t : public std::binary_function + class const_mem_fun1_t : public boost::functional::detail::binary_function { public: explicit const_mem_fun1_t(S (T::*p)(A) const) @@ -402,7 +435,7 @@ namespace boost // mem_fun_ref, etc // -------------------------------------------------------------------------- template - class mem_fun_ref_t : public std::unary_function + class mem_fun_ref_t : public boost::functional::detail::unary_function { public: explicit mem_fun_ref_t(S (T::*p)()) @@ -418,7 +451,7 @@ namespace boost }; template - class mem_fun1_ref_t : public std::binary_function + class mem_fun1_ref_t : public boost::functional::detail::binary_function { public: explicit mem_fun1_ref_t(S (T::*p)(A)) @@ -434,7 +467,7 @@ namespace boost }; template - class const_mem_fun_ref_t : public std::unary_function + class const_mem_fun_ref_t : public boost::functional::detail::unary_function { public: explicit const_mem_fun_ref_t(S (T::*p)() const) @@ -451,7 +484,7 @@ namespace boost }; template - class const_mem_fun1_ref_t : public std::binary_function + class const_mem_fun1_ref_t : public boost::functional::detail::binary_function { public: explicit const_mem_fun1_ref_t(S (T::*p)(A) const) @@ -497,7 +530,7 @@ namespace boost // ptr_fun // -------------------------------------------------------------------------- template - class pointer_to_unary_function : public std::unary_function + class pointer_to_unary_function : public boost::functional::detail::unary_function { public: explicit pointer_to_unary_function(Result (*f)(Arg)) @@ -521,7 +554,7 @@ namespace boost } template - class pointer_to_binary_function : public std::binary_function + class pointer_to_binary_function : public boost::functional::detail::binary_function { public: explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2)) diff --git a/include/boost/functional/hash/extensions.hpp b/include/boost/functional/hash/extensions.hpp index eafaefe..cb3c856 100644 --- a/include/boost/functional/hash/extensions.hpp +++ b/include/boost/functional/hash/extensions.hpp @@ -254,7 +254,7 @@ namespace boost #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template struct hash - : std::unary_function + : boost::hash_detail::hash_base { #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) std::size_t operator()(T const& val) const @@ -271,7 +271,7 @@ namespace boost #if BOOST_WORKAROUND(__DMC__, <= 0x848) template struct hash - : std::unary_function + : boost::hash_detail::hash_base { std::size_t operator()(const T* val) const { @@ -296,7 +296,7 @@ namespace boost { template struct inner - : std::unary_function + : boost::hash_detail::hash_base { #if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) std::size_t operator()(T const& val) const diff --git a/include/boost/functional/hash/hash.hpp b/include/boost/functional/hash/hash.hpp index 2e21091..a6c8181 100644 --- a/include/boost/functional/hash/hash.hpp +++ b/include/boost/functional/hash/hash.hpp @@ -62,6 +62,18 @@ namespace boost { namespace hash_detail { +#if defined(_HAS_AUTO_PTR_ETC) && !_HAS_AUTO_PTR_ETC + template + struct hash_base + { + typedef T argument_type; + typedef std::size_t result_type; + }; +#else + template + struct hash_base : std::unary_function {}; +#endif + struct enable_hash_value { typedef std::size_t type; }; template struct basic_numbers {}; @@ -419,7 +431,7 @@ namespace boost #define BOOST_HASH_SPECIALIZE(type) \ template <> struct hash \ - : public std::unary_function \ + : public boost::hash_detail::hash_base \ { \ std::size_t operator()(type v) const \ { \ @@ -429,7 +441,7 @@ namespace boost #define BOOST_HASH_SPECIALIZE_REF(type) \ template <> struct hash \ - : public std::unary_function \ + : public boost::hash_detail::hash_base \ { \ std::size_t operator()(type const& v) const \ { \ @@ -483,7 +495,7 @@ namespace boost template struct hash - : public std::unary_function + : public boost::hash_detail::hash_base { std::size_t operator()(T* v) const { @@ -516,7 +528,7 @@ namespace boost { template struct inner - : public std::unary_function + : public boost::hash_detail::hash_base { std::size_t operator()(T val) const {