]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED |
2 | #define BOOST_MP11_FUNCTION_HPP_INCLUDED | |
3 | ||
92f5a8d4 | 4 | // Copyright 2015-2019 Peter Dimov. |
b32b8144 | 5 | // |
92f5a8d4 | 6 | // Distributed under the Boost Software License, Version 1.0. |
b32b8144 | 7 | // |
92f5a8d4 TL |
8 | // See accompanying file LICENSE_1_0.txt or copy at |
9 | // http://www.boost.org/LICENSE_1_0.txt | |
b32b8144 FG |
10 | |
11 | #include <boost/mp11/integral.hpp> | |
12 | #include <boost/mp11/utility.hpp> | |
13 | #include <boost/mp11/detail/mp_list.hpp> | |
14 | #include <boost/mp11/detail/mp_count.hpp> | |
15 | #include <boost/mp11/detail/mp_plus.hpp> | |
16 | #include <boost/mp11/detail/mp_min_element.hpp> | |
11fdf7f2 | 17 | #include <boost/mp11/detail/mp_void.hpp> |
92f5a8d4 | 18 | #include <boost/mp11/detail/config.hpp> |
b32b8144 FG |
19 | #include <type_traits> |
20 | ||
21 | namespace boost | |
22 | { | |
23 | namespace mp11 | |
24 | { | |
25 | ||
26 | // mp_void<T...> | |
11fdf7f2 | 27 | // in detail/mp_void.hpp |
b32b8144 FG |
28 | |
29 | // mp_and<T...> | |
92f5a8d4 | 30 | #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1910 ) |
b32b8144 FG |
31 | |
32 | namespace detail | |
33 | { | |
34 | ||
35 | template<class... T> struct mp_and_impl; | |
36 | ||
37 | } // namespace detail | |
38 | ||
39 | template<class... T> using mp_and = mp_to_bool< typename detail::mp_and_impl<T...>::type >; | |
40 | ||
41 | namespace detail | |
42 | { | |
43 | ||
44 | template<> struct mp_and_impl<> | |
45 | { | |
46 | using type = mp_true; | |
47 | }; | |
48 | ||
49 | template<class T> struct mp_and_impl<T> | |
50 | { | |
51 | using type = T; | |
52 | }; | |
53 | ||
54 | template<class T1, class... T> struct mp_and_impl<T1, T...> | |
55 | { | |
56 | using type = mp_eval_if< mp_not<T1>, T1, mp_and, T... >; | |
57 | }; | |
58 | ||
59 | } // namespace detail | |
60 | ||
61 | #else | |
62 | ||
63 | namespace detail | |
64 | { | |
65 | ||
66 | template<class L, class E = void> struct mp_and_impl | |
67 | { | |
68 | using type = mp_false; | |
69 | }; | |
70 | ||
71 | template<class... T> struct mp_and_impl< mp_list<T...>, mp_void<mp_if<T, void>...> > | |
72 | { | |
73 | using type = mp_true; | |
74 | }; | |
75 | ||
76 | } // namespace detail | |
77 | ||
78 | template<class... T> using mp_and = typename detail::mp_and_impl<mp_list<T...>>::type; | |
79 | ||
80 | #endif | |
81 | ||
82 | // mp_all<T...> | |
92f5a8d4 TL |
83 | // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86355 |
84 | #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) || BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 ) | |
b32b8144 FG |
85 | |
86 | template<class... T> using mp_all = mp_bool< mp_count_if< mp_list<T...>, mp_not >::value == 0 >; | |
87 | ||
88 | #elif defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) | |
89 | ||
90 | template<class... T> using mp_all = mp_bool<(static_cast<bool>(T::value) && ...)>; | |
91 | ||
92 | #else | |
93 | ||
94 | template<class... T> using mp_all = mp_and<mp_to_bool<T>...>; | |
95 | ||
96 | #endif | |
97 | ||
98 | // mp_or<T...> | |
99 | namespace detail | |
100 | { | |
101 | ||
102 | template<class... T> struct mp_or_impl; | |
103 | ||
104 | } // namespace detail | |
105 | ||
106 | template<class... T> using mp_or = mp_to_bool< typename detail::mp_or_impl<T...>::type >; | |
107 | ||
108 | namespace detail | |
109 | { | |
110 | ||
111 | template<> struct mp_or_impl<> | |
112 | { | |
113 | using type = mp_false; | |
114 | }; | |
115 | ||
116 | template<class T> struct mp_or_impl<T> | |
117 | { | |
118 | using type = T; | |
119 | }; | |
120 | ||
121 | template<class T1, class... T> struct mp_or_impl<T1, T...> | |
122 | { | |
123 | using type = mp_eval_if< T1, T1, mp_or, T... >; | |
124 | }; | |
125 | ||
126 | } // namespace detail | |
127 | ||
128 | // mp_any<T...> | |
92f5a8d4 TL |
129 | // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86356 |
130 | #if defined( BOOST_MP11_HAS_FOLD_EXPRESSIONS ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, != 0 ) && !BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) | |
b32b8144 FG |
131 | |
132 | template<class... T> using mp_any = mp_bool<(static_cast<bool>(T::value) || ...)>; | |
133 | ||
134 | #else | |
135 | ||
136 | template<class... T> using mp_any = mp_bool< mp_count_if< mp_list<T...>, mp_to_bool >::value != 0 >; | |
137 | ||
138 | #endif | |
139 | ||
140 | // mp_same<T...> | |
141 | namespace detail | |
142 | { | |
143 | ||
144 | template<class... T> struct mp_same_impl; | |
145 | ||
146 | template<> struct mp_same_impl<> | |
147 | { | |
148 | using type = mp_true; | |
149 | }; | |
150 | ||
151 | template<class T1, class... T> struct mp_same_impl<T1, T...> | |
152 | { | |
153 | using type = mp_all<std::is_same<T1, T>...>; | |
154 | }; | |
155 | ||
156 | } // namespace detail | |
157 | ||
158 | template<class... T> using mp_same = typename detail::mp_same_impl<T...>::type; | |
159 | ||
92f5a8d4 TL |
160 | // mp_similar<T...> |
161 | namespace detail | |
162 | { | |
163 | ||
164 | template<class... T> struct mp_similar_impl; | |
165 | ||
166 | template<> struct mp_similar_impl<> | |
167 | { | |
168 | using type = mp_true; | |
169 | }; | |
170 | ||
171 | template<class T> struct mp_similar_impl<T> | |
172 | { | |
173 | using type = mp_true; | |
174 | }; | |
175 | ||
176 | template<class T> struct mp_similar_impl<T, T> | |
177 | { | |
178 | using type = mp_true; | |
179 | }; | |
180 | ||
181 | template<class T1, class T2> struct mp_similar_impl<T1, T2> | |
182 | { | |
183 | using type = mp_false; | |
184 | }; | |
185 | ||
186 | template<template<class...> class L, class... T1, class... T2> struct mp_similar_impl<L<T1...>, L<T2...>> | |
187 | { | |
188 | using type = mp_true; | |
f67539c2 TL |
189 | }; |
190 | ||
191 | template<template<class...> class L, class... T> struct mp_similar_impl<L<T...>, L<T...>> | |
192 | { | |
193 | using type = mp_true; | |
92f5a8d4 TL |
194 | }; |
195 | ||
196 | template<class T1, class T2, class T3, class... T> struct mp_similar_impl<T1, T2, T3, T...> | |
197 | { | |
198 | using type = mp_all< typename mp_similar_impl<T1, T2>::type, typename mp_similar_impl<T1, T3>::type, typename mp_similar_impl<T1, T>::type... >; | |
199 | }; | |
200 | ||
201 | } // namespace detail | |
202 | ||
203 | template<class... T> using mp_similar = typename detail::mp_similar_impl<T...>::type; | |
204 | ||
205 | #if BOOST_MP11_GCC | |
206 | # pragma GCC diagnostic push | |
207 | # pragma GCC diagnostic ignored "-Wsign-compare" | |
208 | #endif | |
209 | ||
b32b8144 FG |
210 | // mp_less<T1, T2> |
211 | template<class T1, class T2> using mp_less = mp_bool<(T1::value < 0 && T2::value >= 0) || ((T1::value < T2::value) && !(T1::value >= 0 && T2::value < 0))>; | |
212 | ||
92f5a8d4 TL |
213 | #if BOOST_MP11_GCC |
214 | # pragma GCC diagnostic pop | |
215 | #endif | |
216 | ||
b32b8144 FG |
217 | // mp_min<T...> |
218 | template<class T1, class... T> using mp_min = mp_min_element<mp_list<T1, T...>, mp_less>; | |
219 | ||
220 | // mp_max<T...> | |
221 | template<class T1, class... T> using mp_max = mp_max_element<mp_list<T1, T...>, mp_less>; | |
222 | ||
223 | } // namespace mp11 | |
224 | } // namespace boost | |
225 | ||
226 | #endif // #ifndef BOOST_MP11_FUNCTION_HPP_INCLUDED |