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.
This commit is contained in:
Daniel James
2016-11-01 16:31:21 +00:00
parent a87c559a0b
commit 281e11b292
5 changed files with 71 additions and 21 deletions

View File

@@ -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

View File

@@ -10,7 +10,9 @@
template <class T>
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<T, std::size_t>, BOOST_HASH_TEST_NAMESPACE::hash<T> >::value));
#endif
}

View File

@@ -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 <typename Arg1, typename Result>
struct unary_function
{
typedef Arg1 argument_type;
typedef Result result_type;
};
template <typename Arg1, typename Arg2, typename Result>
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 Predicate>
class unary_negate
: public std::unary_function<typename unary_traits<Predicate>::argument_type,bool>
: public boost::functional::detail::unary_function<typename unary_traits<Predicate>::argument_type,bool>
{
public:
explicit unary_negate(typename unary_traits<Predicate>::param_type x)
@@ -181,7 +211,8 @@ namespace boost
// --------------------------------------------------------------------------
template <class Predicate>
class binary_negate
: public std::binary_function<typename binary_traits<Predicate>::first_argument_type,
: public boost::functional::detail::binary_function<
typename binary_traits<Predicate>::first_argument_type,
typename binary_traits<Predicate>::second_argument_type,
bool>
{
@@ -218,7 +249,8 @@ namespace boost
// --------------------------------------------------------------------------
template <class Operation>
class binder1st
: public std::unary_function<typename binary_traits<Operation>::second_argument_type,
: public boost::functional::detail::unary_function<
typename binary_traits<Operation>::second_argument_type,
typename binary_traits<Operation>::result_type>
{
public:
@@ -264,7 +296,8 @@ namespace boost
// --------------------------------------------------------------------------
template <class Operation>
class binder2nd
: public std::unary_function<typename binary_traits<Operation>::first_argument_type,
: public boost::functional::detail::unary_function<
typename binary_traits<Operation>::first_argument_type,
typename binary_traits<Operation>::result_type>
{
public:
@@ -309,7 +342,7 @@ namespace boost
// mem_fun, etc
// --------------------------------------------------------------------------
template <class S, class T>
class mem_fun_t : public std::unary_function<T*, S>
class mem_fun_t : public boost::functional::detail::unary_function<T*, S>
{
public:
explicit mem_fun_t(S (T::*p)())
@@ -325,7 +358,7 @@ namespace boost
};
template <class S, class T, class A>
class mem_fun1_t : public std::binary_function<T*, A, S>
class mem_fun1_t : public boost::functional::detail::binary_function<T*, A, S>
{
public:
explicit mem_fun1_t(S (T::*p)(A))
@@ -341,7 +374,7 @@ namespace boost
};
template <class S, class T>
class const_mem_fun_t : public std::unary_function<const T*, S>
class const_mem_fun_t : public boost::functional::detail::unary_function<const T*, S>
{
public:
explicit const_mem_fun_t(S (T::*p)() const)
@@ -357,7 +390,7 @@ namespace boost
};
template <class S, class T, class A>
class const_mem_fun1_t : public std::binary_function<const T*, A, S>
class const_mem_fun1_t : public boost::functional::detail::binary_function<const T*, A, S>
{
public:
explicit const_mem_fun1_t(S (T::*p)(A) const)
@@ -402,7 +435,7 @@ namespace boost
// mem_fun_ref, etc
// --------------------------------------------------------------------------
template <class S, class T>
class mem_fun_ref_t : public std::unary_function<T&, S>
class mem_fun_ref_t : public boost::functional::detail::unary_function<T&, S>
{
public:
explicit mem_fun_ref_t(S (T::*p)())
@@ -418,7 +451,7 @@ namespace boost
};
template <class S, class T, class A>
class mem_fun1_ref_t : public std::binary_function<T&, A, S>
class mem_fun1_ref_t : public boost::functional::detail::binary_function<T&, A, S>
{
public:
explicit mem_fun1_ref_t(S (T::*p)(A))
@@ -434,7 +467,7 @@ namespace boost
};
template <class S, class T>
class const_mem_fun_ref_t : public std::unary_function<const T&, S>
class const_mem_fun_ref_t : public boost::functional::detail::unary_function<const T&, S>
{
public:
explicit const_mem_fun_ref_t(S (T::*p)() const)
@@ -451,7 +484,7 @@ namespace boost
};
template <class S, class T, class A>
class const_mem_fun1_ref_t : public std::binary_function<const T&, A, S>
class const_mem_fun1_ref_t : public boost::functional::detail::binary_function<const T&, A, S>
{
public:
explicit const_mem_fun1_ref_t(S (T::*p)(A) const)
@@ -497,7 +530,7 @@ namespace boost
// ptr_fun
// --------------------------------------------------------------------------
template <class Arg, class Result>
class pointer_to_unary_function : public std::unary_function<Arg,Result>
class pointer_to_unary_function : public boost::functional::detail::unary_function<Arg,Result>
{
public:
explicit pointer_to_unary_function(Result (*f)(Arg))
@@ -521,7 +554,7 @@ namespace boost
}
template <class Arg1, class Arg2, class Result>
class pointer_to_binary_function : public std::binary_function<Arg1,Arg2,Result>
class pointer_to_binary_function : public boost::functional::detail::binary_function<Arg1,Arg2,Result>
{
public:
explicit pointer_to_binary_function(Result (*f)(Arg1, Arg2))

View File

@@ -254,7 +254,7 @@ namespace boost
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
template <class T> struct hash
: std::unary_function<T, std::size_t>
: boost::hash_detail::hash_base<T>
{
#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 <class T, unsigned int n> struct hash<T[n]>
: std::unary_function<T[n], std::size_t>
: boost::hash_detail::hash_base<T[n]>
{
std::size_t operator()(const T* val) const
{
@@ -296,7 +296,7 @@ namespace boost
{
template <class T>
struct inner
: std::unary_function<T, std::size_t>
: boost::hash_detail::hash_base<T>
{
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
std::size_t operator()(T const& val) const

View File

@@ -62,6 +62,18 @@ namespace boost
{
namespace hash_detail
{
#if defined(_HAS_AUTO_PTR_ETC) && !_HAS_AUTO_PTR_ETC
template <typename T>
struct hash_base
{
typedef T argument_type;
typedef std::size_t result_type;
};
#else
template <typename T>
struct hash_base : std::unary_function<T, std::size_t> {};
#endif
struct enable_hash_value { typedef std::size_t type; };
template <typename T> struct basic_numbers {};
@@ -419,7 +431,7 @@ namespace boost
#define BOOST_HASH_SPECIALIZE(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
: public boost::hash_detail::hash_base<type> \
{ \
std::size_t operator()(type v) const \
{ \
@@ -429,7 +441,7 @@ namespace boost
#define BOOST_HASH_SPECIALIZE_REF(type) \
template <> struct hash<type> \
: public std::unary_function<type, std::size_t> \
: public boost::hash_detail::hash_base<type> \
{ \
std::size_t operator()(type const& v) const \
{ \
@@ -483,7 +495,7 @@ namespace boost
template <class T>
struct hash<T*>
: public std::unary_function<T*, std::size_t>
: public boost::hash_detail::hash_base<T*>
{
std::size_t operator()(T* v) const
{
@@ -516,7 +528,7 @@ namespace boost
{
template <class T>
struct inner
: public std::unary_function<T, std::size_t>
: public boost::hash_detail::hash_base<T>
{
std::size_t operator()(T val) const
{