All Classes Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
container.hpp
1 // The MIT License (MIT)
2 
3 // Copyright (c) 2012-2014 Danny Y., Rapptz
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 // this software and associated documentation files (the "Software"), to deal in
7 // the Software without restriction, including without limitation the rights to
8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 // the Software, and to permit persons to whom the Software is furnished to do so,
10 // subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 #ifndef GEARS_CONCEPTS_CONTAINER_HPP
23 #define GEARS_CONCEPTS_CONTAINER_HPP
24 
25 #include "iterator.hpp"
26 
27 namespace gears {
28 namespace concepts {
29 namespace detail {
30 struct is_container {
31  template<typename C,
32  typename T = typename Bare<C>::value_type,
33  typename R = typename Bare<C>::reference,
34  typename Cr = typename Bare<C>::const_reference,
35  typename It = typename Bare<C>::iterator,
36  typename Ci = typename Bare<C>::const_iterator,
37  typename Dt = typename Bare<C>::difference_type,
38  typename St = typename Bare<C>::size_type,
39  typename B = decltype(std::declval<LRef<C>>().begin()),
40  typename E = decltype(std::declval<LRef<C>>().end()),
41  typename Cb = decltype(std::declval<LRef<C>>().cbegin()),
42  typename Ce = decltype(std::declval<LRef<C>>().cend()),
43  typename Sw = decltype(std::declval<LRef<C>>().swap(std::declval<LRef<C>>())),
44  typename Si = decltype(std::declval<LRef<C>>().size()),
45  typename Ms = decltype(std::declval<LRef<C>>().max_size()),
46  typename Em = decltype(std::declval<LRef<C>>().empty()),
47  TrueIf<ContextualBool<Em>, std::is_same<Si, St>,
48  std::is_same<Ms, St>, std::is_same<Cb, Ci>,
49  std::is_same<Ce, Ci>, std::is_convertible<It, Ci>,
50  std::is_convertible<B, Ci>, std::is_convertible<E, Ci>,
51  ForwardIterator<It>>...>
52  static std::true_type test(int);
53  template<typename...>
54  static std::false_type test(...);
55 };
56 
57 struct is_forward_list {
58  template<typename C,
59  typename T = typename Bare<C>::value_type,
60  typename It = typename Bare<C>::const_iterator,
61  typename Ia = decltype(std::declval<LRef<C>>().insert_after(std::declval<It&>(), std::declval<T&>())),
62  typename Em = decltype(std::declval<LRef<C>>().emplace_after(std::declval<It&>())),
63  typename Ea = decltype(std::declval<LRef<C>>().erase_after(std::declval<It&>())),
64  typename Sa = decltype(std::declval<LRef<C>>().splice_after(std::declval<It&>(), std::declval<LRef<C>>()))>
65  static std::true_type test(int);
66  template<typename...>
67  static std::false_type test(...);
68 };
69 
70 struct is_reversible {
71  template<typename C,
72  typename Ri = typename Bare<C>::reverse_iterator,
73  typename Cr = typename Bare<C>::const_reverse_iterator,
74  typename Rb = decltype(std::declval<LRef<C>>().rbegin()),
75  typename Re = decltype(std::declval<LRef<C>>().rend()),
76  typename Cb = decltype(std::declval<LRef<C>>().crbegin()),
77  typename Ce = decltype(std::declval<LRef<C>>().crend()),
78  TrueIf<std::is_convertible<Ri, Cr>, std::is_convertible<Rb, Cr>,
79  std::is_convertible<Re, Cr>, std::is_same<Cb, Cr>,
80  std::is_same<Ce, Cr>>...>
81  static std::true_type test(int);
82  template<typename...>
83  static std::false_type test(...);
84 };
85 
86 struct is_allocator_aware {
87  template<typename C,
88  typename A = typename Bare<C>::allocator_type,
89  typename G = decltype(std::declval<LRef<C>>().get_allocator()),
90  TrueIf<std::is_same<A, G>>...>
91  static std::true_type test(int);
92  template<typename...>
93  static std::false_type test(...);
94 };
95 
96 struct is_sequence_container {
97  template<typename C,
98  typename B = Bare<C>,
99  typename T = typename B::value_type,
100  typename St = typename B::size_type,
101  typename It = typename B::iterator,
102  typename C1 = decltype(B(St(), std::declval<LRef<T>>())),
103  typename C2 = decltype(B(std::declval<It&>(), std::declval<It&>())),
104  typename E1 = decltype(std::declval<B&>().emplace(std::declval<It&>())),
105  typename E2 = decltype(std::declval<B&>().emplace(std::declval<It&>(), std::declval<LRef<T>>())),
106  typename I = decltype(std::declval<B&>().insert(std::declval<It&>(), St(), std::declval<LRef<T>>())),
107  typename I2 = decltype(std::declval<B&>().insert(std::declval<It&>(), std::declval<It&>(), std::declval<It&>())),
108  typename E3 = decltype(std::declval<B&>().erase(std::declval<It&>())),
109  typename E4 = decltype(std::declval<B&>().erase(std::declval<It&>(), std::declval<It&>())),
110  typename Cl = decltype(std::declval<B&>().clear()),
111  typename A1 = decltype(std::declval<B&>().assign(std::declval<It&>(), std::declval<It&>())),
112  typename A2 = decltype(std::declval<B&>().assign(St(), std::declval<LRef<T>>()))>
113  static std::true_type test(int);
114  template<typename...>
115  static std::false_type test(...);
116 };
117 
118 struct is_array_sequence {
119  template<typename C>
120  static auto test(int) -> decltype(std::declval<LRef<C>>().fill(0), std::true_type{}) {}
121  template<typename>
122  static std::false_type test(...);
123 };
124 
125 struct is_associative_container {
126  template<typename C,
127  typename B = Bare<C>,
128  typename Kt = typename B::key_type,
129  typename T = typename B::value_type,
130  typename It = typename B::iterator,
131  typename Kc = typename B::key_compare,
132  typename Vc = typename B::value_compare,
133  typename St = typename B::size_type,
134  typename KC = decltype(std::declval<B&>().key_comp()),
135  typename VC = decltype(std::declval<B&>().value_comp()),
136  typename Em = decltype(std::declval<B&>().emplace()),
137  typename Eh = decltype(std::declval<B&>().emplace_hint(std::declval<It&>())),
138  typename I1 = decltype(std::declval<B&>().insert(std::declval<T&>())),
139  typename I2 = decltype(std::declval<B&>().insert(std::declval<It&>(), std::declval<T&>())),
140  typename I3 = decltype(std::declval<B&>().insert(std::declval<It&>(), std::declval<It&>())),
141  typename E1 = decltype(std::declval<B&>().erase(std::declval<Kt&>())),
142  typename E2 = decltype(std::declval<B&>().erase(std::declval<It&>())),
143  typename E3 = decltype(std::declval<B&>().erase(std::declval<It&>(), std::declval<It&>())),
144  typename Cl = decltype(std::declval<B&>().clear()),
145  typename Fi = decltype(std::declval<B&>().find(std::declval<Kt>())),
146  typename Co = decltype(std::declval<B&>().count(std::declval<Kt>())),
147  typename Lb = decltype(std::declval<B&>().lower_bound(std::declval<Kt>())),
148  typename Ub = decltype(std::declval<B&>().upper_bound(std::declval<Kt>())),
149  typename Er = decltype(std::declval<B&>().equal_range(std::declval<Kt>())),
150  TrueIf<std::is_constructible<B, It, It, Kc>,
151  std::is_constructible<B, It, It>,
152  std::is_convertible<I2, It>,
153  std::is_convertible<E1, St>,
154  std::is_convertible<E2, It>,
155  std::is_convertible<E3, It>,
156  std::is_convertible<Fi, It>,
157  std::is_convertible<Co, St>,
158  std::is_convertible<Lb, It>,
159  std::is_convertible<Ub, It>>...>
160  static std::true_type test(int);
161  template<typename...>
162  static std::false_type test(...);
163 };
164 } // detail
165 
220 template<typename T>
221 struct Container : And<Or<TraitOf<detail::is_container, T>,
222  TraitOf<detail::is_forward_list, T>>,
223  Regular<T>,
225  Copyable<T>,
226  Destructible<T>> {};
227 
252 template<typename T>
253 struct ReversibleContainer : And<Container<T>, TraitOf<detail::is_reversible, T>> {};
254 
271 template<typename T>
272 struct AllocatorAwareContainer : And<Container<T>, TraitOf<detail::is_allocator_aware, T>> {};
273 
298 template<typename T>
299 struct SequenceContainer : And<Container<T>, Or<TraitOf<detail::is_sequence_container, T>,
300  TraitOf<detail::is_array_sequence, T>,
301  TraitOf<detail::is_forward_list, T>>> {};
302 
339 template<typename T>
340 struct AssociativeContainer : And<Container<T>, TraitOf<detail::is_associative_container, T>> {};
341 } // concepts
342 } // gears
343 
344 #endif // GEARS_CONCEPTS_CONTAINER_HPP