]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/spirit/home/x3/support/traits/container_traits.hpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / boost / spirit / home / x3 / support / traits / container_traits.hpp
CommitLineData
7c673cae
FG
1/*=============================================================================
2 Copyright (c) 2001-2014 Joel de Guzman
3 Copyright (c) 2001-2011 Hartmut Kaiser
4 http://spirit.sourceforge.net/
5
6 Distributed under the Boost Software License, Version 1.0. (See accompanying
7 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8=============================================================================*/
9#if !defined(BOOST_SPIRIT_X3_CONTAINER_FEBRUARY_06_2007_1001AM)
10#define BOOST_SPIRIT_X3_CONTAINER_FEBRUARY_06_2007_1001AM
11
12#include <boost/fusion/support/category_of.hpp>
13#include <boost/spirit/home/x3/support/unused.hpp>
7c673cae 14#include <boost/fusion/include/deque.hpp>
7c673cae 15#include <boost/mpl/identity.hpp>
f67539c2 16#include <boost/type_traits/make_void.hpp>
7c673cae
FG
17
18#include <vector>
19#include <string>
20#include <iterator>
21#include <algorithm>
22
23namespace boost { namespace spirit { namespace x3 { namespace traits
24{
25 ///////////////////////////////////////////////////////////////////////////
26 // This file contains some container utils for stl containers.
27 ///////////////////////////////////////////////////////////////////////////
28
29 namespace detail
30 {
f67539c2
TL
31 template <typename T, typename Enabler = void>
32 struct is_container_impl : mpl::false_ {};
33
34 template <typename T>
35 struct is_container_impl<T, void_t<
36 typename T::value_type, typename T::iterator,
37 typename T::size_type, typename T::reference> > : mpl::true_ {};
38
39 template <typename T, typename Enabler = void>
40 struct is_associative_impl : mpl::false_ {};
41
42 template <typename T>
43 struct is_associative_impl<T, void_t<typename T::key_type>>
44 : mpl::true_ {};
7c673cae
FG
45 }
46
47 template <typename T>
f67539c2 48 using is_container = typename detail::is_container_impl<T>::type;
7c673cae
FG
49
50 template <typename T>
f67539c2 51 using is_associative = typename detail::is_associative_impl<T>::type;
7c673cae 52
11fdf7f2
TL
53 template<typename T, typename Enable = void>
54 struct is_reservable : mpl::false_ {};
55
56 template<typename T>
57 struct is_reservable<T, decltype(std::declval<T&>().reserve(0))>
58 : mpl::true_ {};
7c673cae
FG
59
60 ///////////////////////////////////////////////////////////////////////////
61 namespace detail
62 {
63 template <typename T>
64 struct remove_value_const : mpl::identity<T> {};
65
66 template <typename T>
67 struct remove_value_const<T const> : remove_value_const<T> {};
68
69 template <typename F, typename S>
70 struct remove_value_const<std::pair<F, S>>
71 {
72 typedef typename remove_value_const<F>::type first_type;
73 typedef typename remove_value_const<S>::type second_type;
74 typedef std::pair<first_type, second_type> type;
75 };
76 }
77
78 ///////////////////////////////////////////////////////////////////////
79 template <typename Container, typename Enable = void>
80 struct container_value
81 : detail::remove_value_const<typename Container::value_type>
82 {};
83
84 template <typename Container>
85 struct container_value<Container const> : container_value<Container> {};
86
87 // There is no single container value for fusion maps, but because output
88 // of this metafunc is used to check wheter parser's attribute can be
89 // saved to container, we simply return whole fusion::map as is
90 // so that check can be done in traits::is_substitute specialisation
91 template <typename T>
92 struct container_value<T
93 , typename enable_if<typename mpl::eval_if <
94 fusion::traits::is_sequence<T>
95 , fusion::traits::is_associative<T>
96 , mpl::false_ >::type >::type>
97 : mpl::identity<T> {};
98
99 template <>
100 struct container_value<unused_type> : mpl::identity<unused_type> {};
101
102 ///////////////////////////////////////////////////////////////////////////
103 template <typename Container, typename Enable = void>
104 struct container_iterator
105 : mpl::identity<typename Container::iterator> {};
106
107 template <typename Container>
108 struct container_iterator<Container const>
109 : mpl::identity<typename Container::const_iterator> {};
110
111 template <>
112 struct container_iterator<unused_type>
113 : mpl::identity<unused_type const*> {};
114
115 template <>
116 struct container_iterator<unused_type const>
117 : mpl::identity<unused_type const*> {};
118
119 ///////////////////////////////////////////////////////////////////////////
120 template <typename Container, typename T>
121 bool push_back(Container& c, T&& val);
122
123 template <typename Container, typename Enable = void>
124 struct push_back_container
125 {
126 template <typename T>
127 static bool call(Container& c, T&& val)
128 {
92f5a8d4 129 c.insert(c.end(), static_cast<T&&>(val));
7c673cae
FG
130 return true;
131 }
132 };
133
134 template <typename Container, typename T>
135 inline bool push_back(Container& c, T&& val)
136 {
92f5a8d4 137 return push_back_container<Container>::call(c, static_cast<T&&>(val));
7c673cae
FG
138 }
139
140 template <typename Container>
141 inline bool push_back(Container&, unused_type)
142 {
143 return true;
144 }
145
146 template <typename T>
147 inline bool push_back(unused_type, T&&)
148 {
149 return true;
150 }
151
152 inline bool push_back(unused_type, unused_type)
153 {
154 return true;
155 }
156
157 ///////////////////////////////////////////////////////////////////////////
158 template <typename Container, typename Iterator>
159 bool append(Container& c, Iterator first, Iterator last);
160
161 template <typename Container, typename Enable = void>
162 struct append_container
163 {
164 private:
165 template <typename Iterator>
b32b8144 166 static void reserve(Container& /* c */, Iterator /* first */, Iterator /* last */, mpl::false_)
7c673cae
FG
167 {
168 // Not all containers have "reserve"
169 }
170
171 template <typename Iterator>
172 static void reserve(Container& c, Iterator first, Iterator last, mpl::true_)
173 {
174 c.reserve(c.size() + std::distance(first, last));
175 }
176
177 template <typename Iterator>
178 static void insert(Container& c, Iterator first, Iterator last, mpl::false_)
179 {
180 c.insert(c.end(), first, last);
181 }
182
183 template <typename Iterator>
184 static void insert(Container& c, Iterator first, Iterator last, mpl::true_)
185 {
186 c.insert(first, last);
187 }
188
189 public:
190 template <typename Iterator>
191 static bool call(Container& c, Iterator first, Iterator last)
192 {
193 reserve(c, first, last, is_reservable<Container>{});
194 insert(c, first, last, is_associative<Container>{});
195 return true;
196 }
197 };
198
199 template <typename Container, typename Iterator>
200 inline bool append(Container& c, Iterator first, Iterator last)
201 {
202 return append_container<Container>::call(c, first, last);
203 }
204
205 template <typename Iterator>
b32b8144 206 inline bool append(unused_type, Iterator /* first */, Iterator /* last */)
7c673cae
FG
207 {
208 return true;
209 }
210
211 ///////////////////////////////////////////////////////////////////////////
212 template <typename Container, typename Enable = void>
213 struct is_empty_container
214 {
215 static bool call(Container const& c)
216 {
217 return c.empty();
218 }
219 };
220
221 template <typename Container>
222 inline bool is_empty(Container const& c)
223 {
224 return is_empty_container<Container>::call(c);
225 }
226
227 inline bool is_empty(unused_type)
228 {
229 return true;
230 }
231
232 ///////////////////////////////////////////////////////////////////////////
233 template <typename Container, typename Enable = void>
234 struct begin_container
235 {
236 static typename container_iterator<Container>::type call(Container& c)
237 {
238 return c.begin();
239 }
240 };
241
242 template <typename Container>
243 inline typename container_iterator<Container>::type
244 begin(Container& c)
245 {
246 return begin_container<Container>::call(c);
247 }
248
249 inline unused_type const*
250 begin(unused_type)
251 {
252 return &unused;
253 }
254
255 ///////////////////////////////////////////////////////////////////////////
256 template <typename Container, typename Enable = void>
257 struct end_container
258 {
259 static typename container_iterator<Container>::type call(Container& c)
260 {
261 return c.end();
262 }
263 };
264
265 template <typename Container>
266 inline typename container_iterator<Container>::type
267 end(Container& c)
268 {
269 return end_container<Container>::call(c);
270 }
271
272 inline unused_type const*
273 end(unused_type)
274 {
275 return &unused;
276 }
277
278
279 ///////////////////////////////////////////////////////////////////////////
280 template <typename Iterator, typename Enable = void>
281 struct deref_iterator
282 {
92f5a8d4 283 typedef typename std::iterator_traits<Iterator>::reference type;
7c673cae
FG
284 static type call(Iterator& it)
285 {
286 return *it;
287 }
288 };
289
290 template <typename Iterator>
291 typename deref_iterator<Iterator>::type
292 deref(Iterator& it)
293 {
294 return deref_iterator<Iterator>::call(it);
295 }
296
297 inline unused_type
298 deref(unused_type const*)
299 {
300 return unused;
301 }
302
303 ///////////////////////////////////////////////////////////////////////////
304 template <typename Iterator, typename Enable = void>
305 struct next_iterator
306 {
307 static void call(Iterator& it)
308 {
309 ++it;
310 }
311 };
312
313 template <typename Iterator>
314 void next(Iterator& it)
315 {
316 next_iterator<Iterator>::call(it);
317 }
318
319 inline void next(unused_type const*)
320 {
321 // do nothing
322 }
323
324 ///////////////////////////////////////////////////////////////////////////
325 template <typename Iterator, typename Enable = void>
326 struct compare_iterators
327 {
328 static bool call(Iterator const& it1, Iterator const& it2)
329 {
330 return it1 == it2;
331 }
332 };
333
334 template <typename Iterator>
335 bool compare(Iterator& it1, Iterator& it2)
336 {
337 return compare_iterators<Iterator>::call(it1, it2);
338 }
339
340 inline bool compare(unused_type const*, unused_type const*)
341 {
342 return false;
343 }
344
345 ///////////////////////////////////////////////////////////////////////////
346 template <typename T>
347 struct build_container : mpl::identity<std::vector<T>> {};
348
349 template <typename T>
350 struct build_container<boost::fusion::deque<T> > : build_container<T> {};
351
352 template <>
353 struct build_container<unused_type> : mpl::identity<unused_type> {};
354
355 template <>
356 struct build_container<char> : mpl::identity<std::string> {};
357
358}}}}
359
360#endif