Merge pull request #89 from glenfe/develop

Add enable_if_ and enable_if_t. Sever dependency on Core.
This commit is contained in:
jzmaddock
2018-08-27 18:10:48 +01:00
committed by GitHub
9 changed files with 183 additions and 8 deletions

44
doc/enable_if.qbk Normal file
View File

@ -0,0 +1,44 @@
[/
Copyright 2018 Glen Joseph Fernandes
(glenjofe@gmail.com)
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).
]
[section:enable_if enable_if_]
template<bool B, class T = void>
struct enable_if_;
template<bool B, class T = void>
using enable_if_t = typename enable_if_<B, T>::type;
__type If `B` is true, then the member `type` is defined to be `T`. Otherwise
there is no member `type`.
__header `#include <boost/type_traits/enable_if.hpp>`
__examples
The following function can be used to destroy each element of an array and
specially handle arrays of trivially destrucibtle types.
template<class T>
typename boost::enable_if_<!boost::has_trivial_destructor<T>::value>::type
destroy(T* ptr, std::size_t size)
{
while (size > 0) {
ptr[--size].~T();
}
}
template<class T>
typename boost::enable_if_<boost::has_trivial_destructor<T>::value>::type
destroy(T*, std::size_t) { }
[all_compilers] The type alias `enable_if_t` is only available if the compiler
supports template aliases.
[endsect]

View File

@ -309,6 +309,7 @@ that is the result of the transformation.
[include declval.qbk]
[include detected.qbk]
[include detected_or.qbk]
[include enable_if.qbk]
[include extent.qbk]
[include floating_point_promotion.qbk]
[include function_traits.qbk]

View File

@ -24,6 +24,7 @@
#include <boost/type_traits/copy_cv.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/declval.hpp>
#include <boost/type_traits/enable_if.hpp>
#include <boost/type_traits/extent.hpp>
#include <boost/type_traits/floating_point_promotion.hpp>
#include <boost/type_traits/function_traits.hpp>

View File

@ -30,7 +30,7 @@ struct is_likely_stateless_lambda : public false_type {};
#elif !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !BOOST_WORKAROUND(BOOST_MSVC, < 1900)
#include <boost/type_traits/is_convertible.hpp>
#include <boost/core/enable_if.hpp>
#include <boost/type_traits/enable_if.hpp>
namespace boost{
@ -70,7 +70,7 @@ struct is_likely_stateless_lambda : false_type{};
template<typename T>
struct is_likely_stateless_lambda<
T,
typename boost::enable_if_c<has_one_operator_call<T>::value>::type> :
typename boost::enable_if_<has_one_operator_call<T>::value>::type> :
boost::is_convertible<T, typename equivalent_function_pointer<T>::type
>{};

View File

@ -0,0 +1,37 @@
/*
Copyright 2003 The Trustees of Indiana University
Authors: Jaakko Jarvi (jajarvi at osl.iu.edu)
Jeremiah Willcock (jewillco at osl.iu.edu)
Andrew Lumsdaine (lums at osl.iu.edu)
Copyright 2018 Glen Joseph Fernandes
(glenjofe@gmail.com)
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)
*/
#ifndef BOOST_TT_ENABLE_IF_HPP_INCLUDED
#define BOOST_TT_ENABLE_IF_HPP_INCLUDED
#include <boost/config.hpp>
namespace boost {
template<bool B, class T = void>
struct enable_if_ {
typedef T type;
};
template<class T>
struct enable_if_<false, T> { };
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<bool B, class T = void>
using enable_if_t = typename enable_if_<B, T>::type;
#endif
} /* boost */
#endif

View File

@ -16,7 +16,7 @@
#include <boost/type_traits/has_nothrow_assign.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/enable_if.hpp>
#include <boost/type_traits/declval.hpp>
#include <boost/type_traits/is_complete.hpp>
#include <boost/static_assert.hpp>
@ -48,7 +48,7 @@ struct false_or_cpp11_noexcept_move_assignable: public ::boost::false_type {};
template <class T>
struct false_or_cpp11_noexcept_move_assignable <
T,
typename ::boost::enable_if_c<sizeof(T) && BOOST_NOEXCEPT_EXPR(::boost::declval<T&>() = ::boost::declval<T>())>::type
typename ::boost::enable_if_<sizeof(T) && BOOST_NOEXCEPT_EXPR(::boost::declval<T&>() = ::boost::declval<T>())>::type
> : public ::boost::integral_constant<bool, BOOST_NOEXCEPT_EXPR(::boost::declval<T&>() = ::boost::declval<T>())>
{};

View File

@ -35,7 +35,7 @@ template <class T> struct is_nothrow_move_constructible<const volatile T> : publ
#elif !defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_SFINAE_EXPR) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40700)
#include <boost/type_traits/declval.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/enable_if.hpp>
namespace boost{ namespace detail{
@ -45,7 +45,7 @@ struct false_or_cpp11_noexcept_move_constructible: public ::boost::false_type {}
template <class T>
struct false_or_cpp11_noexcept_move_constructible <
T,
typename ::boost::enable_if_c<sizeof(T) && BOOST_NOEXCEPT_EXPR(T(::boost::declval<T>()))>::type
typename ::boost::enable_if_<sizeof(T) && BOOST_NOEXCEPT_EXPR(T(::boost::declval<T>()))>::type
> : public ::boost::integral_constant<bool, BOOST_NOEXCEPT_EXPR(T(::boost::declval<T>()))>
{};

92
test/enable_if_test.cpp Normal file
View File

@ -0,0 +1,92 @@
/*
Copyright 2018 Glen Joseph Fernandes
(glenjofe@gmail.com)
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)
*/
#include <boost/type_traits/enable_if.hpp>
#include "test.hpp"
template<bool B>
struct Constant {
enum {
value = B
};
};
template<class T>
struct Check
: Constant<false> { };
template<>
struct Check<long>
: Constant<true> { };
class Construct {
public:
template<class T>
Construct(T, typename boost::enable_if_<Check<T>::value>::type* = 0)
: value_(true) { }
template<class T>
Construct(T, typename boost::enable_if_<!Check<T>::value>::type* = 0)
: value_(false) { }
bool value() const {
return value_;
}
private:
bool value_;
};
template<class T, class E = void>
struct Specialize;
template<class T>
struct Specialize<T, typename boost::enable_if_<Check<T>::value>::type>
: Constant<true> { };
template<class T>
struct Specialize<T, typename boost::enable_if_<!Check<T>::value>::type>
: Constant<false> { };
template<class T>
typename boost::enable_if_<Check<T>::value, bool>::type Returns(T)
{
return true;
}
template<class T>
typename boost::enable_if_<!Check<T>::value, bool>::type Returns(T)
{
return false;
}
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<class T>
boost::enable_if_t<Check<T>::value, bool> Alias(T)
{
return true;
}
template<class T>
boost::enable_if_t<!Check<T>::value, bool> Alias(T)
{
return false;
}
#endif
TT_TEST_BEGIN(enable_if)
BOOST_CHECK(!Construct(1).value());
BOOST_CHECK(Construct(1L).value());
BOOST_CHECK(!Specialize<int>::value);
BOOST_CHECK(Specialize<long>::value);
BOOST_CHECK(!Returns(1));
BOOST_CHECK(Returns(1L));
#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
BOOST_CHECK(!Alias(1));
BOOST_CHECK(Alias(1L));
#endif
TT_TEST_END

View File

@ -11,7 +11,7 @@
#endif
#include "test.hpp"
#include "check_integral_constant.hpp"
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/enable_if.hpp>
template <class T>
@ -30,7 +30,7 @@ template<typename T>
struct test_bug_4530
{
template<typename A>
test_bug_4530(A&&, typename boost::enable_if< ::tt::is_convertible<A&&, T> >::type* =0);
test_bug_4530(A&&, typename boost::enable_if_< ::tt::is_convertible<A&&, T>::value >::type* =0);
};
struct A4530