1
0
forked from boostorg/bind

Compare commits

...

10 Commits

Author SHA1 Message Date
Peter Dimov
e41ba84da8 Add protect_cpp20_test.cpp 2020-06-30 22:06:37 +03:00
Peter Dimov
9ce9a7ce99 Define protect(f)::result_type only when F::result_type is defined 2020-06-30 21:58:58 +03:00
Peter Dimov
1aac698358 Add protect_test2.cpp 2020-06-30 21:39:22 +03:00
Peter Dimov
3cbcd02965 Update protect.hpp to use perfect forwarding on C++11 2020-06-30 21:31:46 +03:00
Peter Dimov
8cea63f1c9 msvc-9.0 doesn't have std::bit_and, or, xor 2020-06-30 04:33:51 +03:00
Peter Dimov
b601e8924d Move result_traits to its own header; add specializations for <functional> objects on MSVC >= C++17 2020-06-30 04:23:39 +03:00
Peter Dimov
c4fc8e5065 Remove std::bit_not test, as it's C++14 2020-06-30 03:29:23 +03:00
Peter Dimov
ba0ca52695 Add cxxstd=latest to Appveyor 2020-06-30 03:13:48 +03:00
Peter Dimov
24242b037f Update .travis.yml 2020-06-30 03:12:26 +03:00
Peter Dimov
5340508c16 Test <functional> objects which had their result_types removed in C++20 2020-06-30 03:07:18 +03:00
9 changed files with 373 additions and 34 deletions

View File

@@ -4,8 +4,6 @@
language: cpp
sudo: false
dist: xenial
branches:
@@ -128,6 +126,17 @@ matrix:
sources:
- ubuntu-toolchain-r-test
- os: linux
dist: bionic
compiler: g++-10
env: TOOLSET=gcc COMPILER=g++-10 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- g++-10
sources:
- ubuntu-toolchain-r-test
- os: linux
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11
@@ -264,6 +273,18 @@ matrix:
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
compiler: clang++-10
env: TOOLSET=clang COMPILER=clang++-10 CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- clang-10
sources:
- ubuntu-toolchain-r-test
- sourceline: 'deb https://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main'
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
- os: linux
dist: trusty
compiler: clang++-libc++
@@ -273,6 +294,15 @@ matrix:
packages:
- libc++-dev
- os: linux
dist: bionic
compiler: clang++-libc++
env: TOOLSET=clang COMPILER=clang++-libc++ CXXSTD=03,11,14,17,2a
addons:
apt:
packages:
- libc++-dev
- os: osx
compiler: clang++
env: TOOLSET=clang COMPILER=clang++ CXXSTD=03,11,14,1z

View File

@@ -25,7 +25,7 @@ environment:
ADDRESS_MODEL: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
TOOLSET: msvc-14.2
CXXSTD: 14,17
CXXSTD: 14,17,latest
ADDRESS_MODEL: 32,64
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
ADDPATH: C:\cygwin\bin;

View File

@@ -27,6 +27,7 @@
#include <boost/type.hpp>
#include <boost/is_placeholder.hpp>
#include <boost/bind/arg.hpp>
#include <boost/bind/detail/result_traits.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/visit_each.hpp>
#include <boost/core/enable_if.hpp>
@@ -59,29 +60,6 @@ template<class T> class weak_ptr;
namespace _bi // implementation details
{
// result_traits
template<class R, class F> struct result_traits
{
typedef R type;
};
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
struct unspecified {};
template<class F> struct result_traits<unspecified, F>
{
typedef typename F::result_type type;
};
template<class F> struct result_traits< unspecified, reference_wrapper<F> >
{
typedef typename F::result_type type;
};
#endif
// ref_compare
template<class T> bool ref_compare( T const & a, T const & b, long )

View File

@@ -0,0 +1,154 @@
#ifndef BOOST_BIND_DETAIL_RESULT_TRAITS_HPP_INCLUDED
#define BOOST_BIND_DETAIL_RESULT_TRAITS_HPP_INCLUDED
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
//
// bind/detail/result_traits.hpp
//
// boost/bind.hpp support header, return type deduction
//
// Copyright 2006, 2020 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
//
// See http://www.boost.org/libs/bind/bind.html for documentation.
//
#if defined(_MSVC_LANG) && _MSVC_LANG >= 17
#include <functional>
#endif
namespace boost
{
namespace _bi
{
template<class R, class F> struct result_traits
{
typedef R type;
};
struct unspecified {};
template<class F> struct result_traits<unspecified, F>
{
typedef typename F::result_type type;
};
template<class F> struct result_traits< unspecified, reference_wrapper<F> >
{
typedef typename F::result_type type;
};
#if defined(_MSVC_LANG) && _MSVC_LANG >= 17
template<class T> struct result_traits< unspecified, std::plus<T> >
{
typedef T type;
};
template<class T> struct result_traits< unspecified, std::minus<T> >
{
typedef T type;
};
template<class T> struct result_traits< unspecified, std::multiplies<T> >
{
typedef T type;
};
template<class T> struct result_traits< unspecified, std::divides<T> >
{
typedef T type;
};
template<class T> struct result_traits< unspecified, std::modulus<T> >
{
typedef T type;
};
template<class T> struct result_traits< unspecified, std::negate<T> >
{
typedef T type;
};
template<class T> struct result_traits< unspecified, std::equal_to<T> >
{
typedef bool type;
};
template<class T> struct result_traits< unspecified, std::not_equal_to<T> >
{
typedef bool type;
};
template<class T> struct result_traits< unspecified, std::greater<T> >
{
typedef bool type;
};
template<class T> struct result_traits< unspecified, std::less<T> >
{
typedef bool type;
};
template<class T> struct result_traits< unspecified, std::greater_equal<T> >
{
typedef bool type;
};
template<class T> struct result_traits< unspecified, std::less_equal<T> >
{
typedef bool type;
};
template<class T> struct result_traits< unspecified, std::logical_and<T> >
{
typedef bool type;
};
template<class T> struct result_traits< unspecified, std::logical_or<T> >
{
typedef bool type;
};
template<class T> struct result_traits< unspecified, std::logical_not<T> >
{
typedef bool type;
};
template<class T> struct result_traits< unspecified, std::bit_and<T> >
{
typedef T type;
};
template<class T> struct result_traits< unspecified, std::bit_or<T> >
{
typedef T type;
};
template<class T> struct result_traits< unspecified, std::bit_xor<T> >
{
typedef T type;
};
template<class T> struct result_traits< unspecified, std::bit_not<T> >
{
typedef T type;
};
#endif
} // namespace _bi
} // namespace boost
#endif // #ifndef BOOST_BIND_DETAIL_RESULT_TRAITS_HPP_INCLUDED

View File

@@ -2,10 +2,10 @@
#define BOOST_BIND_PROTECT_HPP_INCLUDED
//
// protect.hpp
// protect.hpp
//
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
// Copyright (c) 2009 Steven Watanabe
// Copyright 2002, 2020 Peter Dimov
// Copyright 2009 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
@@ -13,7 +13,8 @@
//
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/config/workaround.hpp>
#include <utility>
namespace boost
{
@@ -21,8 +22,53 @@ namespace boost
namespace _bi
{
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_DECLTYPE)
template<class T> struct protect_make_void
{
typedef void type;
};
template<class F, class E = void> struct protect_result_type
{
};
template<class F> struct protect_result_type< F, typename protect_make_void<typename F::result_type>::type >
{
typedef typename F::result_type result_type;
};
template<class F> class protected_bind_t: public protect_result_type<F>
{
private:
F f_;
public:
explicit protected_bind_t( F f ): f_( f )
{
}
template<class... A> auto operator()( A&&... a ) -> decltype( f_( std::forward<A>(a)... ) )
{
return f_( std::forward<A>(a)... );
}
template<class... A> auto operator()( A&&... a ) const -> decltype( f_( std::forward<A>(a)... ) )
{
return f_( std::forward<A>(a)... );
}
};
#else
template<class F> class protected_bind_t
{
private:
F f_;
public:
typedef typename F::result_type result_type;
@@ -286,12 +332,10 @@ public:
}
#endif
private:
F f_;
};
#endif
} // namespace _bi
template<class F> _bi::protected_bind_t<F> protect(F f)

View File

@@ -74,3 +74,6 @@ run bind_noexcept_test.cpp ;
run bind_noexcept_mf_test.cpp ;
run global_placeholders.cpp ;
run mem_fn_noexcept_test.cpp ;
run bind_cpp20_test.cpp ;
run protect_test2.cpp ;
run protect_cpp20_test.cpp ;

42
test/bind_cpp20_test.cpp Normal file
View File

@@ -0,0 +1,42 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt)
#include <boost/bind/bind.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <functional>
//
int main()
{
BOOST_TEST_EQ( boost::bind( std::plus<int>(), 1, 2 )(), 3 );
BOOST_TEST_EQ( boost::bind( std::minus<int>(), 1, 2 )(), -1 );
BOOST_TEST_EQ( boost::bind( std::multiplies<int>(), 1, 2 )(), 2 );
BOOST_TEST_EQ( boost::bind( std::divides<int>(), 1, 2 )(), 0 );
BOOST_TEST_EQ( boost::bind( std::modulus<int>(), 1, 2 )(), 1 );
BOOST_TEST_EQ( boost::bind( std::negate<int>(), 1 )(), -1 );
BOOST_TEST_EQ( boost::bind( std::equal_to<int>(), 1, 2 )(), false );
BOOST_TEST_EQ( boost::bind( std::not_equal_to<int>(), 1, 2 )(), true );
BOOST_TEST_EQ( boost::bind( std::greater<int>(), 1, 2 )(), false );
BOOST_TEST_EQ( boost::bind( std::less<int>(), 1, 2 )(), true );
BOOST_TEST_EQ( boost::bind( std::greater_equal<int>(), 1, 2 )(), false );
BOOST_TEST_EQ( boost::bind( std::less_equal<int>(), 1, 2 )(), true );
BOOST_TEST_EQ( boost::bind( std::logical_and<int>(), 1, 2 )(), true );
BOOST_TEST_EQ( boost::bind( std::logical_or<int>(), 1, 2 )(), true );
BOOST_TEST_EQ( boost::bind( std::logical_not<int>(), 1 )(), false );
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1600)
BOOST_TEST_EQ( boost::bind( std::bit_and<int>(), 1, 2 )(), 0 );
BOOST_TEST_EQ( boost::bind( std::bit_or<int>(), 1, 2 )(), 3 );
BOOST_TEST_EQ( boost::bind( std::bit_xor<int>(), 1, 2 )(), 3 );
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,42 @@
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt)
#include <boost/bind/protect.hpp>
#include <boost/core/lightweight_test.hpp>
#include <boost/config.hpp>
#include <boost/config/workaround.hpp>
#include <functional>
//
int main()
{
BOOST_TEST_EQ( boost::protect( std::plus<int>() )( 1, 2 ), 3 );
BOOST_TEST_EQ( boost::protect( std::minus<int>() )( 1, 2 ), -1 );
BOOST_TEST_EQ( boost::protect( std::multiplies<int>() )( 1, 2 ), 2 );
BOOST_TEST_EQ( boost::protect( std::divides<int>() )( 1, 2 ), 0 );
BOOST_TEST_EQ( boost::protect( std::modulus<int>() )( 1, 2 ), 1 );
BOOST_TEST_EQ( boost::protect( std::negate<int>() )( 1 ), -1 );
BOOST_TEST_EQ( boost::protect( std::equal_to<int>() )( 1, 2 ), false );
BOOST_TEST_EQ( boost::protect( std::not_equal_to<int>() )( 1, 2 ), true );
BOOST_TEST_EQ( boost::protect( std::greater<int>() )( 1, 2 ), false );
BOOST_TEST_EQ( boost::protect( std::less<int>() )( 1, 2 ), true );
BOOST_TEST_EQ( boost::protect( std::greater_equal<int>() )( 1, 2 ), false );
BOOST_TEST_EQ( boost::protect( std::less_equal<int>() )( 1, 2 ), true );
BOOST_TEST_EQ( boost::protect( std::logical_and<int>() )( 1, 2 ), true );
BOOST_TEST_EQ( boost::protect( std::logical_or<int>() )( 1, 2 ), true );
BOOST_TEST_EQ( boost::protect( std::logical_not<int>() )( 1 ), false );
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1600)
BOOST_TEST_EQ( boost::protect( std::bit_and<int>() )( 1, 2 ), 0 );
BOOST_TEST_EQ( boost::protect( std::bit_or<int>() )( 1, 2 ), 3 );
BOOST_TEST_EQ( boost::protect( std::bit_xor<int>() )( 1, 2 ), 3 );
#endif
return boost::report_errors();
}

46
test/protect_test2.cpp Normal file
View File

@@ -0,0 +1,46 @@
// protect_test2.cpp
//
// Copyright 2020 Peter Dimov
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#include <boost/bind/protect.hpp>
#include <boost/core/lightweight_test_trait.hpp>
#include <boost/core/is_same.hpp>
template<class T, class F> void test( F )
{
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<typename T::result_type, typename F::result_type>));
}
struct X
{
struct result_type {};
};
struct Y
{
};
template<class T, class U> struct inherit: T, U
{
};
template<class F> void test2( F )
{
// test that F doesn't have ::result_type
BOOST_TEST_TRAIT_TRUE((boost::core::is_same<typename inherit<F, X>::result_type, typename X::result_type>));
}
int main()
{
test<X>( boost::protect( X() ) );
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_DECLTYPE)
test2( boost::protect( Y() ) );
#endif
return boost::report_errors();
}