]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/hana/set.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / hana / set.hpp
CommitLineData
7c673cae
FG
1/*!
2@file
3Defines `boost::hana::set`.
4
b32b8144 5@copyright Louis Dionne 2013-2017
7c673cae
FG
6Distributed under the Boost Software License, Version 1.0.
7(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
8 */
9
10#ifndef BOOST_HANA_SET_HPP
11#define BOOST_HANA_SET_HPP
12
13#include <boost/hana/fwd/set.hpp>
14
15#include <boost/hana/at.hpp>
16#include <boost/hana/bool.hpp>
17#include <boost/hana/concept/comparable.hpp>
18#include <boost/hana/concept/constant.hpp>
19#include <boost/hana/concept/hashable.hpp>
20#include <boost/hana/config.hpp>
21#include <boost/hana/contains.hpp>
22#include <boost/hana/core/make.hpp>
23#include <boost/hana/core/to.hpp>
24#include <boost/hana/detail/decay.hpp>
25#include <boost/hana/detail/fast_and.hpp>
26#include <boost/hana/detail/has_duplicates.hpp>
27#include <boost/hana/detail/operators/adl.hpp>
28#include <boost/hana/detail/operators/comparable.hpp>
29#include <boost/hana/detail/operators/searchable.hpp>
30#include <boost/hana/equal.hpp>
31#include <boost/hana/erase_key.hpp>
32#include <boost/hana/find_if.hpp>
33#include <boost/hana/fold_left.hpp>
34#include <boost/hana/fwd/any_of.hpp>
35#include <boost/hana/fwd/core/to.hpp>
36#include <boost/hana/fwd/difference.hpp>
37#include <boost/hana/fwd/intersection.hpp>
38#include <boost/hana/fwd/union.hpp>
39#include <boost/hana/insert.hpp>
40#include <boost/hana/is_subset.hpp>
41#include <boost/hana/length.hpp>
42#include <boost/hana/or.hpp>
43#include <boost/hana/remove.hpp>
44#include <boost/hana/tuple.hpp>
45#include <boost/hana/unpack.hpp>
46#include <boost/hana/value.hpp>
47
48#include <cstddef>
49#include <type_traits>
50#include <utility>
51
52
53BOOST_HANA_NAMESPACE_BEGIN
54 //////////////////////////////////////////////////////////////////////////
55 // set
56 //////////////////////////////////////////////////////////////////////////
57 //! @cond
58 template <typename ...Xs>
92f5a8d4 59 struct set final
7c673cae
FG
60 : detail::operators::adl<set<Xs...>>
61 , detail::searchable_operators<set<Xs...>>
62 {
63 tuple<Xs...> storage;
64 using hana_tag = set_tag;
65 static constexpr std::size_t size = sizeof...(Xs);
66
67 explicit constexpr set(tuple<Xs...> const& xs)
68 : storage(xs)
69 { }
70
71 explicit constexpr set(tuple<Xs...>&& xs)
72 : storage(static_cast<tuple<Xs...>&&>(xs))
73 { }
74
b32b8144 75 constexpr set() = default;
7c673cae
FG
76 constexpr set(set const& other) = default;
77 constexpr set(set&& other) = default;
78 };
79 //! @endcond
80
81 //////////////////////////////////////////////////////////////////////////
82 // Operators
83 //////////////////////////////////////////////////////////////////////////
84 namespace detail {
85 template <>
86 struct comparable_operators<set_tag> {
87 static constexpr bool value = true;
88 };
89 }
90
91 //////////////////////////////////////////////////////////////////////////
92 // make<set_tag>
93 //////////////////////////////////////////////////////////////////////////
94 template <>
95 struct make_impl<set_tag> {
96 template <typename ...Xs>
97 static constexpr auto apply(Xs&& ...xs) {
98#if defined(BOOST_HANA_CONFIG_ENABLE_DEBUG_MODE)
99 static_assert(detail::fast_and<hana::Comparable<Xs>::value...>::value,
100 "hana::make_set(xs...) requires all the 'xs' to be Comparable");
101
102 static_assert(detail::fast_and<hana::Hashable<Xs>::value...>::value,
103 "hana::make_set(xs...) requires all the 'xs' to be Hashable");
104
105 static_assert(detail::fast_and<
106 Constant<decltype(hana::equal(xs, xs))>::value...
107 >::value,
108 "hana::make_set(xs...) requires all the 'xs' to be "
109 "Comparable at compile-time");
110
111 static_assert(!detail::has_duplicates<Xs&&...>::value,
112 "hana::make_set(xs...) requires all the 'xs' to be unique");
113#endif
114
115 return set<typename detail::decay<Xs>::type...>{
116 hana::make_tuple(static_cast<Xs&&>(xs)...)
117 };
118 }
119 };
120
121 //////////////////////////////////////////////////////////////////////////
122 // Comparable
123 //////////////////////////////////////////////////////////////////////////
124 template <>
125 struct equal_impl<set_tag, set_tag> {
126 template <typename S1, typename S2>
127 static constexpr auto equal_helper(S1 const& s1, S2 const& s2, hana::true_)
128 { return hana::is_subset(s1, s2); }
129
130 template <typename S1, typename S2>
131 static constexpr auto equal_helper(S1 const&, S2 const&, hana::false_)
132 { return hana::false_c; }
133
134 template <typename S1, typename S2>
135 static constexpr decltype(auto) apply(S1&& s1, S2&& s2) {
136 return equal_impl::equal_helper(s1, s2, hana::bool_c<
137 decltype(hana::length(s1.storage))::value ==
138 decltype(hana::length(s2.storage))::value
139 >);
140 }
141 };
142
143 //////////////////////////////////////////////////////////////////////////
144 // Foldable
145 //////////////////////////////////////////////////////////////////////////
146 template <>
147 struct unpack_impl<set_tag> {
148 template <typename Set, typename F>
149 static constexpr decltype(auto) apply(Set&& set, F&& f) {
150 return hana::unpack(static_cast<Set&&>(set).storage,
151 static_cast<F&&>(f));
152 }
153 };
154
155 //////////////////////////////////////////////////////////////////////////
156 // Searchable
157 //////////////////////////////////////////////////////////////////////////
158 template <>
159 struct find_if_impl<set_tag> {
160 template <typename Xs, typename Pred>
161 static constexpr auto apply(Xs&& xs, Pred&& pred) {
162 return hana::find_if(static_cast<Xs&&>(xs).storage, static_cast<Pred&&>(pred));
163 }
164 };
165
166 template <>
167 struct any_of_impl<set_tag> {
168 template <typename Pred>
169 struct any_of_helper {
170 Pred const& pred;
171 template <typename ...X>
172 constexpr auto operator()(X const& ...x) const {
173 return hana::or_(pred(x)...);
174 }
175 constexpr auto operator()() const {
176 return hana::false_c;
177 }
178 };
179
180 template <typename Xs, typename Pred>
181 static constexpr auto apply(Xs const& xs, Pred const& pred) {
182 return hana::unpack(xs.storage, any_of_helper<Pred>{pred});
183 }
184 };
185
186 template <>
187 struct is_subset_impl<set_tag, set_tag> {
188 template <typename Ys>
189 struct all_contained {
190 Ys const& ys;
191 template <typename ...X>
192 constexpr auto operator()(X const& ...x) const {
193 return hana::bool_c<detail::fast_and<
194 hana::value<decltype(hana::contains(ys, x))>()...
195 >::value>;
196 }
197 };
198
199 template <typename Xs, typename Ys>
200 static constexpr auto apply(Xs const& xs, Ys const& ys) {
201 return hana::unpack(xs, all_contained<Ys>{ys});
202 }
203 };
204
205 //////////////////////////////////////////////////////////////////////////
206 // Conversions
207 //////////////////////////////////////////////////////////////////////////
208 template <typename F>
209 struct to_impl<set_tag, F, when<hana::Foldable<F>::value>> {
210 template <typename Xs>
211 static constexpr decltype(auto) apply(Xs&& xs) {
212 return hana::fold_left(static_cast<Xs&&>(xs),
213 hana::make_set(),
214 hana::insert);
215 }
216 };
217
218 //////////////////////////////////////////////////////////////////////////
219 // insert
220 //////////////////////////////////////////////////////////////////////////
221 template <>
222 struct insert_impl<set_tag> {
223 template <typename Xs, typename X, typename Indices>
224 static constexpr auto
225 insert_helper(Xs&& xs, X&&, hana::true_, Indices) {
226 return static_cast<Xs&&>(xs);
227 }
228
229 template <typename Xs, typename X, std::size_t ...n>
230 static constexpr auto
231 insert_helper(Xs&& xs, X&& x, hana::false_, std::index_sequence<n...>) {
232 return hana::make_set(
233 hana::at_c<n>(static_cast<Xs&&>(xs).storage)..., static_cast<X&&>(x)
234 );
235 }
236
237 template <typename Xs, typename X>
238 static constexpr auto apply(Xs&& xs, X&& x) {
239 constexpr bool c = hana::value<decltype(hana::contains(xs, x))>();
240 constexpr std::size_t size = std::remove_reference<Xs>::type::size;
241 return insert_helper(static_cast<Xs&&>(xs), static_cast<X&&>(x),
242 hana::bool_c<c>, std::make_index_sequence<size>{});
243 }
244 };
245
246 //////////////////////////////////////////////////////////////////////////
247 // erase_key
248 //////////////////////////////////////////////////////////////////////////
249 template <>
250 struct erase_key_impl<set_tag> {
251 template <typename Xs, typename X>
252 static constexpr decltype(auto) apply(Xs&& xs, X&& x) {
253 return hana::unpack(
254 hana::remove(static_cast<Xs&&>(xs).storage,
255 static_cast<X&&>(x)),
256 hana::make_set
257 );
258 }
259 };
260
261 //////////////////////////////////////////////////////////////////////////
262 // intersection
263 //////////////////////////////////////////////////////////////////////////
264 namespace detail {
265 template <typename Ys>
266 struct set_insert_if_contains {
267 Ys const& ys;
268
269 template <typename Result, typename Key>
270 static constexpr auto helper(Result&& result, Key&& key, hana::true_) {
271 return hana::insert(static_cast<Result&&>(result), static_cast<Key&&>(key));
272 }
273
274 template <typename Result, typename Key>
275 static constexpr auto helper(Result&& result, Key&&, hana::false_) {
276 return static_cast<Result&&>(result);
277 }
278
279 template <typename Result, typename Key>
280 constexpr auto operator()(Result&& result, Key&& key) const {
281 constexpr bool keep = hana::value<decltype(hana::contains(ys, key))>();
282 return set_insert_if_contains::helper(static_cast<Result&&>(result),
283 static_cast<Key&&>(key),
284 hana::bool_c<keep>);
285 }
286 };
287 }
288
289 template <>
290 struct intersection_impl<set_tag> {
291 template <typename Xs, typename Ys>
292 static constexpr auto apply(Xs&& xs, Ys const& ys) {
293 return hana::fold_left(static_cast<Xs&&>(xs), hana::make_set(),
294 detail::set_insert_if_contains<Ys>{ys});
295 }
296 };
297
298 //////////////////////////////////////////////////////////////////////////
299 // union_
300 //////////////////////////////////////////////////////////////////////////
301 template <>
302 struct union_impl<set_tag> {
303 template <typename Xs, typename Ys>
304 static constexpr auto apply(Xs&& xs, Ys&& ys) {
305 return hana::fold_left(static_cast<Xs&&>(xs), static_cast<Ys&&>(ys),
306 hana::insert);
307 }
308 };
309
310 //////////////////////////////////////////////////////////////////////////
311 // difference
312 //////////////////////////////////////////////////////////////////////////
313 template <>
314 struct difference_impl<set_tag> {
315 template <typename Xs, typename Ys>
316 static constexpr auto apply(Xs&& xs, Ys&& ys) {
317 return hana::fold_left(static_cast<Ys&&>(ys), static_cast<Xs&&>(xs),
318 hana::erase_key);
319 }
320 };
321BOOST_HANA_NAMESPACE_END
322
323#endif // !BOOST_HANA_SET_HPP