forked from boostorg/type_traits
binary operators: add revised workaounds for gcc-4.7 and 4.8
This commit is contained in:
@ -95,6 +95,7 @@ namespace boost
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_pointer.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/detail/is_likely_lambda.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
|
94
include/boost/type_traits/detail/is_likely_lambda.hpp
Normal file
94
include/boost/type_traits/detail/is_likely_lambda.hpp
Normal file
@ -0,0 +1,94 @@
|
||||
/* Copyright 2017 Joaquin M Lopez Munoz.
|
||||
* 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/poly_collection for library home page.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_TT_DETAIL_IS_LIKELY_STATELESS_LAMBDA_HPP
|
||||
#define BOOST_TT_DETAIL_IS_LIKELY_STATELESS_LAMBDA_HPP
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <boost/type_traits/detail/config.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
|
||||
#if defined(BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION)
|
||||
//
|
||||
// We don't need or use this, just define a dummy class:
|
||||
//
|
||||
namespace boost{ namespace type_traits_detail{
|
||||
|
||||
template<typename T>
|
||||
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)
|
||||
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
namespace type_traits_detail{
|
||||
|
||||
/* Stateless lambda expressions have one (and only one) call operator and are
|
||||
* convertible to a function pointer with the same signature. Non-lambda types
|
||||
* could satisfy this too, hence the "likely" qualifier.
|
||||
*/
|
||||
|
||||
template<typename T>
|
||||
struct has_one_operator_call_helper
|
||||
{
|
||||
template<typename Q> static boost::true_type test(decltype(&Q::operator())*);
|
||||
template<typename> static boost::false_type test(...);
|
||||
|
||||
using type=decltype(test<T>(nullptr));
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using has_one_operator_call=typename has_one_operator_call_helper<T>::type;
|
||||
|
||||
template<typename T>
|
||||
struct equivalent_function_pointer
|
||||
{
|
||||
template<typename Q,typename R,typename... Args>
|
||||
static auto helper(R (Q::*)(Args...)const)->R(*)(Args...);
|
||||
template<typename Q,typename R,typename... Args>
|
||||
static auto helper(R (Q::*)(Args...))->R(*)(Args...);
|
||||
|
||||
using type=decltype(helper(&T::operator()));
|
||||
};
|
||||
|
||||
template<typename T,typename=void>
|
||||
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> :
|
||||
boost::is_convertible<T, typename equivalent_function_pointer<T>::type
|
||||
>{};
|
||||
|
||||
} /* namespace type_traits_detail */
|
||||
|
||||
} /* namespace boost */
|
||||
|
||||
#else
|
||||
//
|
||||
// Can't implement this:
|
||||
//
|
||||
namespace boost{ namespace type_traits_detail{
|
||||
|
||||
template<typename T>
|
||||
struct is_likely_stateless_lambda : public false_type {};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -38,7 +38,7 @@
|
||||
)\
|
||||
) || \
|
||||
(\
|
||||
::boost::is_class<Lhs_noref>::value && ::boost::is_convertible<Lhs_noref, void(*)()>::value\
|
||||
::boost::type_traits_detail::is_likely_stateless_lambda<Lhs_noref>::value\
|
||||
)\
|
||||
)
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
)\
|
||||
) || \
|
||||
(\
|
||||
::boost::is_class<Lhs_noref>::value && ::boost::is_convertible<Lhs_noref, void(*)()>::value\
|
||||
::boost::type_traits_detail::is_likely_stateless_lambda<Lhs_noref>::value\
|
||||
)\
|
||||
)
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
)\
|
||||
) || \
|
||||
(\
|
||||
::boost::is_class<Lhs_noref>::value && ::boost::is_convertible<Lhs_noref, void(*)()>::value\
|
||||
::boost::type_traits_detail::is_likely_stateless_lambda<Lhs_noref>::value\
|
||||
)\
|
||||
)
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
)\
|
||||
) || \
|
||||
(\
|
||||
::boost::is_class<Lhs_noref>::value && ::boost::is_convertible<Lhs_noref, void(*)()>::value\
|
||||
::boost::type_traits_detail::is_likely_stateless_lambda<Lhs_noref>::value\
|
||||
)\
|
||||
)
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
)\
|
||||
) || \
|
||||
(\
|
||||
::boost::is_class<Lhs_noref>::value && ::boost::is_convertible<Lhs_noref, void(*)()>::value\
|
||||
::boost::type_traits_detail::is_likely_stateless_lambda<Lhs_noref>::value\
|
||||
)\
|
||||
)
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
)\
|
||||
) || \
|
||||
(\
|
||||
::boost::is_class<Lhs_noref>::value && ::boost::is_convertible<Lhs_noref, void(*)()>::value\
|
||||
::boost::type_traits_detail::is_likely_stateless_lambda<Lhs_noref>::value\
|
||||
)\
|
||||
)
|
||||
|
||||
|
@ -222,15 +222,24 @@ void specific() {
|
||||
#if defined(BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION)
|
||||
// There are some things that pass that wouldn't otherwise do so:
|
||||
auto f = []() {};
|
||||
auto f2 = [](double)->int { return 2; };
|
||||
#ifndef BOOST_MSVC
|
||||
TEST_TR(decltype(f), bool, true);
|
||||
TEST_TR(decltype(f2), bool, true);
|
||||
#else
|
||||
TEST_TR(decltype(f), bool, false);
|
||||
TEST_TR(decltype(f2), bool, false);
|
||||
#endif
|
||||
(void)f;
|
||||
(void)f2;
|
||||
|
||||
#elif !defined(BOOST_NO_CXX11_LAMBDAS)
|
||||
auto f = []() {};
|
||||
auto f2 = [](double)->int { return 2; };
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME< decltype(f)>::value), 0);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME< decltype(f2)>::value), 0);
|
||||
(void)f;
|
||||
(void)f2;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -222,15 +222,24 @@ void specific() {
|
||||
#if defined(BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION)
|
||||
// There are some things that pass that wouldn't otherwise do so:
|
||||
auto f = []() {};
|
||||
auto f2 = [](double)->int { return 2; };
|
||||
#ifndef BOOST_MSVC
|
||||
TEST_TR(decltype(f), bool, true);
|
||||
TEST_TR(decltype(f2), bool, true);
|
||||
#else
|
||||
TEST_TR(decltype(f), bool, false);
|
||||
TEST_TR(decltype(f2), bool, false);
|
||||
#endif
|
||||
(void)f;
|
||||
(void)f2;
|
||||
|
||||
#elif !defined(BOOST_NO_CXX11_LAMBDAS)
|
||||
auto f = []() {};
|
||||
auto f2 = [](double)->int { return 2; };
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME< decltype(f)>::value), 0);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME< decltype(f2)>::value), 0);
|
||||
(void)f;
|
||||
(void)f2;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -222,15 +222,24 @@ void specific() {
|
||||
#if defined(BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION)
|
||||
// There are some things that pass that wouldn't otherwise do so:
|
||||
auto f = []() {};
|
||||
auto f2 = [](double)->int { return 2; };
|
||||
#ifndef BOOST_MSVC
|
||||
TEST_TR(decltype(f), bool, true);
|
||||
TEST_TR(decltype(f2), bool, true);
|
||||
#else
|
||||
TEST_TR(decltype(f), bool, false);
|
||||
TEST_TR(decltype(f2), bool, false);
|
||||
#endif
|
||||
(void)f;
|
||||
(void)f2;
|
||||
|
||||
#elif !defined(BOOST_NO_CXX11_LAMBDAS)
|
||||
auto f = []() {};
|
||||
auto f2 = [](double)->int { return 2; };
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME< decltype(f)>::value), 0);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME< decltype(f2)>::value), 0);
|
||||
(void)f;
|
||||
(void)f2;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -222,15 +222,24 @@ void specific() {
|
||||
#if defined(BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION)
|
||||
// There are some things that pass that wouldn't otherwise do so:
|
||||
auto f = []() {};
|
||||
auto f2 = [](double)->int { return 2; };
|
||||
#ifndef BOOST_MSVC
|
||||
TEST_TR(decltype(f), bool, true);
|
||||
TEST_TR(decltype(f2), bool, true);
|
||||
#else
|
||||
TEST_TR(decltype(f), bool, false);
|
||||
TEST_TR(decltype(f2), bool, false);
|
||||
#endif
|
||||
(void)f;
|
||||
(void)f2;
|
||||
|
||||
#elif !defined(BOOST_NO_CXX11_LAMBDAS)
|
||||
auto f = []() {};
|
||||
auto f2 = [](double)->int { return 2; };
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME< decltype(f)>::value), 0);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME< decltype(f2)>::value), 0);
|
||||
(void)f;
|
||||
(void)f2;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -222,15 +222,24 @@ void specific() {
|
||||
#if defined(BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION)
|
||||
// There are some things that pass that wouldn't otherwise do so:
|
||||
auto f = []() {};
|
||||
auto f2 = [](double)->int { return 2; };
|
||||
#ifndef BOOST_MSVC
|
||||
TEST_TR(decltype(f), bool, true);
|
||||
TEST_TR(decltype(f2), bool, true);
|
||||
#else
|
||||
TEST_TR(decltype(f), bool, false);
|
||||
TEST_TR(decltype(f2), bool, false);
|
||||
#endif
|
||||
(void)f;
|
||||
(void)f2;
|
||||
|
||||
#elif !defined(BOOST_NO_CXX11_LAMBDAS)
|
||||
auto f = []() {};
|
||||
auto f2 = [](double)->int { return 2; };
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME< decltype(f)>::value), 0);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME< decltype(f2)>::value), 0);
|
||||
(void)f;
|
||||
(void)f2;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -222,15 +222,24 @@ void specific() {
|
||||
#if defined(BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION)
|
||||
// There are some things that pass that wouldn't otherwise do so:
|
||||
auto f = []() {};
|
||||
auto f2 = [](double)->int { return 2; };
|
||||
#ifndef BOOST_MSVC
|
||||
TEST_TR(decltype(f), bool, true);
|
||||
TEST_TR(decltype(f2), bool, true);
|
||||
#else
|
||||
TEST_TR(decltype(f), bool, false);
|
||||
TEST_TR(decltype(f2), bool, false);
|
||||
#endif
|
||||
(void)f;
|
||||
(void)f2;
|
||||
|
||||
#elif !defined(BOOST_NO_CXX11_LAMBDAS)
|
||||
auto f = []() {};
|
||||
auto f2 = [](double)->int { return 2; };
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME< decltype(f)>::value), 0);
|
||||
BOOST_CHECK_INTEGRAL_CONSTANT((::boost::BOOST_TT_TRAIT_NAME< decltype(f2)>::value), 0);
|
||||
(void)f;
|
||||
(void)f2;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user