]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/mp11/utility.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / mp11 / utility.hpp
1 #ifndef BOOST_MP11_UTILITY_HPP_INCLUDED
2 #define BOOST_MP11_UTILITY_HPP_INCLUDED
3
4 // Copyright 2015, 2017 Peter Dimov.
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 //
8 // See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt
10
11 #include <boost/mp11/integral.hpp>
12 #include <boost/config.hpp>
13 #include <boost/detail/workaround.hpp>
14
15 namespace boost
16 {
17 namespace mp11
18 {
19
20 // mp_identity
21 template<class T> struct mp_identity
22 {
23 using type = T;
24 };
25
26 // mp_identity_t
27 template<class T> using mp_identity_t = typename mp_identity<T>::type;
28
29 // mp_inherit
30 template<class... T> struct mp_inherit: T... {};
31
32 // mp_if, mp_if_c
33 namespace detail
34 {
35
36 template<bool C, class T, class... E> struct mp_if_c_impl
37 {
38 };
39
40 template<class T, class... E> struct mp_if_c_impl<true, T, E...>
41 {
42 using type = T;
43 };
44
45 template<class T, class E> struct mp_if_c_impl<false, T, E>
46 {
47 using type = E;
48 };
49
50 } // namespace detail
51
52 template<bool C, class T, class... E> using mp_if_c = typename detail::mp_if_c_impl<C, T, E...>::type;
53 template<class C, class T, class... E> using mp_if = typename detail::mp_if_c_impl<static_cast<bool>(C::value), T, E...>::type;
54
55 // mp_valid
56 // implementation by Bruno Dutra (by the name is_evaluable)
57 namespace detail
58 {
59
60 template<template<class...> class F, class... T> struct mp_valid_impl
61 {
62 template<template<class...> class G, class = G<T...>> static mp_true check(int);
63 template<template<class...> class> static mp_false check(...);
64
65 using type = decltype(check<F>(0));
66 };
67
68 } // namespace detail
69
70 template<template<class...> class F, class... T> using mp_valid = typename detail::mp_valid_impl<F, T...>::type;
71
72 // mp_defer
73 namespace detail
74 {
75
76 template<template<class...> class F, class... T> struct mp_defer_impl
77 {
78 using type = F<T...>;
79 };
80
81 struct mp_no_type
82 {
83 };
84
85 } // namespace detail
86
87 template<template<class...> class F, class... T> using mp_defer = mp_if<mp_valid<F, T...>, detail::mp_defer_impl<F, T...>, detail::mp_no_type>;
88
89 // mp_eval_if, mp_eval_if_c
90 namespace detail
91 {
92
93 template<bool C, class T, template<class...> class F, class... U> struct mp_eval_if_c_impl;
94
95 template<class T, template<class...> class F, class... U> struct mp_eval_if_c_impl<true, T, F, U...>
96 {
97 using type = T;
98 };
99
100 template<class T, template<class...> class F, class... U> struct mp_eval_if_c_impl<false, T, F, U...>: mp_defer<F, U...>
101 {
102 };
103
104 } // namespace detail
105
106 template<bool C, class T, template<class...> class F, class... U> using mp_eval_if_c = typename detail::mp_eval_if_c_impl<C, T, F, U...>::type;
107 template<class C, class T, template<class...> class F, class... U> using mp_eval_if = typename detail::mp_eval_if_c_impl<static_cast<bool>(C::value), T, F, U...>::type;
108 template<class C, class T, class Q, class... U> using mp_eval_if_q = typename detail::mp_eval_if_c_impl<static_cast<bool>(C::value), T, Q::template fn, U...>::type;
109
110 // mp_cond
111
112 // so elegant; so doesn't work
113 // template<class C, class T, class... E> using mp_cond = mp_eval_if<C, T, mp_cond, E...>;
114
115 namespace detail
116 {
117
118 template<class C, class T, class... E> struct mp_cond_impl;
119
120 } // namespace detail
121
122 template<class C, class T, class... E> using mp_cond = typename detail::mp_cond_impl<C, T, E...>::type;
123
124 namespace detail
125 {
126
127 template<class C, class T, class... E> using mp_cond_ = mp_eval_if<C, T, mp_cond, E...>;
128
129 template<class C, class T, class... E> struct mp_cond_impl: mp_defer<mp_cond_, C, T, E...>
130 {
131 };
132
133 } // namespace detail
134
135 // mp_quote
136 template<template<class...> class F> struct mp_quote
137 {
138 // the indirection through mp_defer works around the language inability
139 // to expand T... into a fixed parameter list of an alias template
140
141 template<class... T> using fn = typename mp_defer<F, T...>::type;
142 };
143
144 // mp_quote_trait
145 template<template<class...> class F> struct mp_quote_trait
146 {
147 template<class... T> using fn = typename F<T...>::type;
148 };
149
150 // mp_invoke
151 #if BOOST_WORKAROUND( BOOST_MSVC, < 1900 )
152
153 namespace detail
154 {
155
156 template<class Q, class... T> struct mp_invoke_impl: mp_defer<Q::template fn, T...> {};
157
158 } // namespace detail
159
160 template<class Q, class... T> using mp_invoke = typename detail::mp_invoke_impl<Q, T...>::type;
161
162 #elif BOOST_WORKAROUND( BOOST_GCC, < 50000 )
163
164 template<class Q, class... T> using mp_invoke = typename mp_defer<Q::template fn, T...>::type;
165
166 #else
167
168 template<class Q, class... T> using mp_invoke = typename Q::template fn<T...>;
169
170 #endif
171
172 } // namespace mp11
173 } // namespace boost
174
175 #endif // #ifndef BOOST_MP11_UTILITY_HPP_INCLUDED