]> git.lyx.org Git - lyx.git/blob - 3rdparty/boost/boost/type_traits/detail/is_likely_lambda.hpp
Update to boost 1.72
[lyx.git] / 3rdparty / boost / boost / type_traits / detail / is_likely_lambda.hpp
1 /* Copyright 2017 Joaquin M Lopez Munoz.
2  * Distributed under the Boost Software License, Version 1.0.
3  * (See accompanying file LICENSE_1_0.txt or copy at
4  * http://www.boost.org/LICENSE_1_0.txt)
5  *
6  * See http://www.boost.org/libs/poly_collection for library home page.
7  */
8
9 #ifndef BOOST_TT_DETAIL_IS_LIKELY_STATELESS_LAMBDA_HPP
10 #define BOOST_TT_DETAIL_IS_LIKELY_STATELESS_LAMBDA_HPP
11
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15
16 #include <boost/type_traits/detail/config.hpp>
17 #include <boost/type_traits/integral_constant.hpp>
18
19 #if defined(BOOST_TT_HAS_ACCURATE_BINARY_OPERATOR_DETECTION)
20 //
21 // We don't need or use this, just define a dummy class:
22 //
23 namespace boost{ namespace type_traits_detail{
24
25 template<typename T>
26 struct is_likely_stateless_lambda : public false_type {};
27
28 }}
29
30 #elif !defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !BOOST_WORKAROUND(BOOST_MSVC, < 1900)\
31          && !(BOOST_WORKAROUND(BOOST_MSVC, == 1900) && defined(__CLR_VER))
32
33 #include <boost/type_traits/is_convertible.hpp>
34 #include <boost/type_traits/enable_if.hpp>
35
36 namespace boost{
37
38 namespace type_traits_detail{
39
40 /* Stateless lambda expressions have one (and only one) call operator and are
41  * convertible to a function pointer with the same signature. Non-lambda types
42  * could satisfy this too, hence the "likely" qualifier.
43  */
44
45 template<typename T>
46 struct has_one_operator_call_helper
47 {
48   template<typename Q> static boost::true_type  test(decltype(&Q::operator())*);
49   template<typename>   static boost::false_type test(...);
50
51   using type=decltype(test<T>(nullptr));
52 };
53
54 template<typename T>
55 using has_one_operator_call=typename has_one_operator_call_helper<T>::type;
56
57 template<typename T>
58 struct equivalent_function_pointer
59 {
60   template<typename Q,typename R,typename... Args>
61   static auto helper(R (Q::*)(Args...)const)->R(*)(Args...);
62   template<typename Q,typename R,typename... Args>
63   static auto helper(R (Q::*)(Args...))->R(*)(Args...);
64
65   using type=decltype(helper(&T::operator()));
66 };
67
68 template<typename T,typename=void>
69 struct is_likely_stateless_lambda : false_type{};
70
71 template<typename T>
72 struct is_likely_stateless_lambda<
73   T,
74   typename boost::enable_if_<has_one_operator_call<T>::value>::type> :
75      boost::is_convertible<T, typename equivalent_function_pointer<T>::type
76 >{};
77
78 } /* namespace type_traits_detail */
79
80 } /* namespace boost */
81
82 #else
83  //
84  // Can't implement this:
85  //
86 namespace boost {
87    namespace type_traits_detail {
88
89       template<typename T>
90       struct is_likely_stateless_lambda : public boost::integral_constant<bool, false> {};
91 }}
92
93 #endif
94 #endif
95