SigUtil  0.95
Utility modules for modern C++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
container_traits.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, Daniel Park
3  * All rights reserved.
4  *
5  * Permission to modify and redistribute this software is granted to
6  * anyone provided the above copyright notice, this condition and the
7  * following disclaimer are retained.
8  *
9  * This software is provided "as is", without and express or implied
10  * warranty. In no event shall the author be liable for damages arising
11  * from the use of this software.
12  */
13 
14 /*
15 Copyright© 2014 Akihiro Nishimura
16 
17 This software is released under the MIT License.
18 http://opensource.org/licenses/mit-license.php
19 */
20 
21 #ifndef SIG_CONTAINER_TRAITS_H
22 #define SIG_CONTAINER_TRAITS_H
23 
24 #include <vector>
25 #include <deque>
26 #include <list>
27 #include <set>
28 #include <map>
29 #include <unordered_set>
30 #include <unordered_map>
31 #include <initializer_list>
32 
33 #include "../array.hpp"
34 
35 
67 namespace sig
68 {
69 namespace impl
70 {
71 
72 template <class C>
74 {
75  static const bool exist = false;
76 };
77 
78 
80 
81 template<class C>
83 {
84  static const bool exist = false;
85 };
86 
87 template<template<class, size_t> class C, class T, size_t N>
88 struct static_container_traits<C<T, N>>
89 {
90  static const bool exist = true;
91 
92  using value_type = T;
93 
94  static const size_t size = N; // only static_container
95 
96  template<class U>
97  using rebind = C<U, N>;
98 
99  template<class U, size_t M>
100  using rebind_t = C<U, M>; // only static_container
101 
102  template<size_t M>
103  using rebind_n = C<T, M>; // only static_container
104 
105 
106  static C<T, N> make(size_t n){ return C<T, N>(); }
107 
108  static void add_element(C<T, N>& c, T const& t)
109  {
110  c.push_back(t);
111  }
112  static void add_element(C<T, N>& c, T&& t)
113  {
114  c.push_back(std::move(t));
115  }
116 };
117 
118 template<class T, size_t N>
119 struct container_traits<std::array<T, N>> : public static_container_traits<std::array<T, N>>
120 {};
121 
122 template<class T, size_t N>
123 struct container_traits<sig::array<T, N>> : public static_container_traits<sig::array<T, N>>
124 {};
125 
126 /*
128 
129 template<class C>
130 struct temp_container_traits;
131 
132 template<template<class> class C, class T>
133 struct temp_container_traits<C<T>>
134 {
135  static const bool exist = true;
136 
137  using value_type = T;
138 
139  template<class U>
140  using rebind = C<U>;
141 };
142 
143 template<class T>
144 struct container_traits<std::initializer_list<T>> : public temp_container_traits<std::initializer_list<T>>
145 {};
146 */
147 
149 
150 template<class C>
152 
153 template<template<class, class> class C, class T, class A>
155 {
156  static const bool exist = true;
157 
158  using value_type = T;
159 
160  template<class U>
161  using rebind = C<U, typename A::template rebind<U>::other>;
162 
163 
164  static C<T, A> make(size_t n){ return C<T, A>(); } // default implementation
165 
166  static void add_element(C<T, A>& c, T const& t)
167  {
168  c.push_back(t);
169  }
170  static void add_element(C<T, A>& c, T&& t)
171  {
172  c.push_back(std::move(t));
173  }
174 
175  static void concat(C<T, A>& lhs, C<T, A> const& rhs)
176  {
177  lhs.insert(lhs.end(), rhs.begin(), rhs.end());
178  }
179  static void concat(C<T, A>& lhs, C<T, A>&& rhs)
180  {
181  lhs.insert(lhs.end(), std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end()));
182  }
183 };
184 
185 template<class... Args>
186 struct container_traits<std::vector<Args...>> : public sequence_container_traits<std::vector<Args...>>
187 {
188  static std::vector<Args...> make(size_t n){ std::vector<Args...> tmp; tmp.reserve(n); return tmp; }
189 };
190 
191 template<class... Args>
192 struct container_traits<std::deque<Args...>> : public sequence_container_traits<std::deque<Args...>>
193 {};
194 
195 template<class... Args>
196 struct container_traits<std::list<Args...>> : public sequence_container_traits<std::list<Args...>>
197 {};
198 
199 
201 
202 template<class C>
204 
205 // for set
206 template<template<class, class, class> class C, class T, template<class> class O, class A>
207 struct associative_container_traits<C<T, O<T>, A>>
208 {
209  static const bool exist = true;
210 
211  using value_type = T;
212 
213  template<class U>
214  using rebind = C<U, O<U>, typename A::template rebind<U>::other>;
215 
216 
217  static C<T, O<T>, A> make(size_t n){ return C<T, O<T>, A>(); } // default implementation
218 
219  static void add_element(C<T, O<T>, A>& c, T const& t)
220  {
221  c.insert(t);
222  }
223  static void add_element(C<T, O<T>, A>& c, T&& t)
224  {
225  c.insert(std::move(t));
226  }
227 
228  static void concat(C<T, O<T>, A>& lhs, C<T, O<T>, A> const& rhs)
229  {
230  lhs.insert(rhs.begin(), rhs.end());
231  }
232  static void concat(C<T, O<T>, A>& lhs, C<T, O<T>, A>&& rhs)
233  {
234  lhs.insert(std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end()));
235  }
236 };
237 
238 // for map
239 template<template<class, class, class, class> class C, class K, class T, template<class> class O, class A>
240 struct associative_container_traits<C<K, T, O<K>, A>>
241 {
242  static const bool exist = true;
243 
244  using value_type = std::pair<const K, T>;
245 
246  template<class U, class V>
247  using rebind = C<U, V, O<U>, typename A::template rebind<std::pair<U, V>>::other>;
248 
249 
250  static C<K, T, O<K>, A> make(size_t n){ return C<K, T, O<K>, A>(); } // default implementation
251 
252  template<class P>
253  static void add_element(C<K, T, O<K>, A>& c, P&& pair)
254  {
255  c.insert(std::forward<P>(pair));
256  }
257 
258  static void concat(C<K, T, O<K>, A>& lhs, C<K, T, O<K>, A> const& rhs)
259  {
260  lhs.insert(rhs.begin(), rhs.end());
261  }
262  static void concat(C<K, T, O<K>, A>& lhs, C<K, T, O<K>, A>&& rhs)
263  {
264  lhs.insert(std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end()));
265  }
266 };
267 
268 template<class... Args>
269 struct container_traits<std::multiset<Args...>> : public associative_container_traits<std::multiset<Args...>>
270 {};
271 
272 template<class... Args>
273 struct container_traits<std::set<Args...>> : public associative_container_traits<std::set<Args...>>
274 {};
275 
276 #if SIG_MSVC_ENV
277 template<class K, class T, class... Args>
278 struct container_traits<std::map<K, T, Args...>> : public associative_container_traits<std::map<K, T, Args...>>
279 {};
280 
281 template<class K, class T, class... Args>
282 struct container_traits<std::multimap<K, T, Args...>> : public associative_container_traits<std::multimap<K, T, Args...>>
283 {};
284 
285 #else
286 template<class... Args>
287 struct container_traits<std::map<Args...>> : public associative_container_traits<std::map<Args...>>
288 {};
289 
290 template<class... Args>
291 struct container_traits<std::multimap<Args...>> : public associative_container_traits<std::multimap<Args...>>
292 {};
293 #endif
294 
295 
297 
298 template<class C>
300 
301 // for set
302 template<template<class, class, class, class> class C, class T, template<class> class H, template<class> class O, class A>
303 struct hash_container_traits<C<T, H<T>, O<T>, A>>
304 {
305  static const bool exist = true;
306 
307  using value_type = T;
308 
309  template<class U>
310  using rebind = C<U, H<U>, O<U>, typename A::template rebind<U>::other>;
311 
312 
313  static C<T, H<T>, O<T>, A> make(size_t n){
314  //C<T, H<T>, O<T>, A> tmp; tmp.reserve(n); return tmp; // performace varies by value condition (added value distribution)
315  return C<T, H<T>, O<T>, A>();
316  }
317 
318  static void add_element(C<T, H<T>, O<T>, A>& c, T const& t)
319  {
320  c.insert(t);
321  }
322  static void add_element(C<T, H<T>, O<T>, A>& c, T&& t)
323  {
324  c.insert(std::move(t));
325  }
326 
327  static void concat(C<T, H<T>, O<T>, A>& lhs, C<T, H<T>, O<T>, A> const& rhs)
328  {
329  lhs.insert(rhs.begin(), rhs.end());
330  }
331  static void concat(C<T, H<T>, O<T>, A>& lhs, C<T, H<T>, O<T>, A>&& rhs)
332  {
333  lhs.insert(std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end()));
334  }
335 };
336 
337 template<template<class, class, class, class, class> class C, class K, class T, template<class> class H, template<class> class O, class A>
338 struct hash_container_traits<C<K, T, H<K>, O<K>, A>>
339 {
340  static const bool exist = true;
341 
342  using value_type = std::pair<const K, T>;
343 
344  template<class U, class V>
345  using rebind = C<U, V, H<U>, O<U>, typename A::template rebind<std::pair<U, V>>::other>;
346 
347 
348  static C<K, T, H<K>, O<K>, A> make(size_t n){
349  //C<K, T, H<K>, O<K>, A> tmp; tmp.reserve(n); return tmp; // performace varies by value condition (added value distribution)
350  return C<K, T, H<K>, O<K>, A>();
351  }
352 
353  template<class P>
354  static void add_element(C<K, T, H<K>, O<K>, A>& c, P&& pair)
355  {
356  c.insert(std::forward<P>(pair));
357  }
358 
359  static void concat(C<K, T, H<K>, O<K>, A>& lhs, C<K, T, H<K>, O<K>, A> const& rhs)
360  {
361  lhs.insert(rhs.begin(), rhs.end());
362  }
363  static void concat(C<K, T, H<K>, O<K>, A>& lhs, C<K, T, H<K>, O<K>, A>&& rhs)
364  {
365  lhs.insert(std::make_move_iterator(rhs.begin()), std::make_move_iterator(rhs.end()));
366  }
367 };
368 
369 template<class... Args>
370 struct container_traits<std::unordered_set<Args...>> : public hash_container_traits<std::unordered_set<Args...>>
371 {};
372 
373 template<class... Args>
374 struct container_traits<std::unordered_multiset<Args...>> : public hash_container_traits<std::unordered_multiset<Args...>>
375 {};
376 
377 #if SIG_MSVC_ENV
378 template<class K, class T, class... Args>
379 struct container_traits<std::unordered_map<K, T, Args...>> : public hash_container_traits<std::unordered_map<K, T, Args...>>
380 {};
381 
382 template<class K, class T, class... Args>
383 struct container_traits<std::unordered_multimap<K, T, Args...>> : public hash_container_traits<std::unordered_multimap<K, T, Args...>>
384 {};
385 
386 #else
387 template<class... Args>
388 struct container_traits<std::unordered_map<Args...>> : public hash_container_traits<std::unordered_map<Args...>>
389 {};
390 
391 template<class... Args>
392 struct container_traits<std::unordered_multimap<Args...>> : public hash_container_traits<std::unordered_multimap<Args...>>
393 {};
394 #endif
395 
396 
397 /*
398 // basic_string
399 template<class T, template<class> class K, class A>
400 struct container_traits<std::basic_string<T,K<T>,A>>
401 {
402  static const bool exist = true;
403 
404  using value_type = T;
405 
406  template<class U>
407  using rebind = std::basic_string<U,K<U>,typename A::template rebind<U>::other>;
408 
409  static void add_element(std::basic_string<T,K<T>,A>& c, const T& t)
410  {
411  c.push_back(t);
412  }
413 
414  static void concat(std::basic_string<T,K<T>,A>& lhs, const std::basic_string<T,K<T>,A>& rhs)
415  {
416  lhs+=rhs;
417  }
418 };
419 */
420 
421 }
422 }
423 #endif
C< U, O< U >, typename A::template rebind< U >::other > rebind
static void add_element(C< T, N > &c, T &&t)
static void add_element(C< T, A > &c, T const &t)
static void concat(C< K, T, H< K >, O< K >, A > &lhs, C< K, T, H< K >, O< K >, A > &&rhs)
static void add_element(C< T, N > &c, T const &t)
C< U, V, H< U >, O< U >, typename A::template rebind< std::pair< U, V >>::other > rebind
static std::vector< Args...> make(size_t n)
C< U, H< U >, O< U >, typename A::template rebind< U >::other > rebind
static void concat(C< K, T, O< K >, A > &lhs, C< K, T, O< K >, A > const &rhs)
static void add_element(C< K, T, O< K >, A > &c, P &&pair)
static void concat(C< T, A > &lhs, C< T, A > const &rhs)
static void concat(C< T, H< T >, O< T >, A > &lhs, C< T, H< T >, O< T >, A > const &rhs)
static void concat(C< T, H< T >, O< T >, A > &lhs, C< T, H< T >, O< T >, A > &&rhs)
static void concat(C< K, T, H< K >, O< K >, A > &lhs, C< K, T, H< K >, O< K >, A > const &rhs)
STLライクな静的配列
Definition: array.hpp:27
static void add_element(C< T, O< T >, A > &c, T const &t)
C< U, V, O< U >, typename A::template rebind< std::pair< U, V >>::other > rebind
C< U, typename A::template rebind< U >::other > rebind
static void concat(C< T, A > &lhs, C< T, A > &&rhs)
static void concat(C< T, O< T >, A > &lhs, C< T, O< T >, A > &&rhs)
static void add_element(C< K, T, H< K >, O< K >, A > &c, P &&pair)
static void concat(C< T, O< T >, A > &lhs, C< T, O< T >, A > const &rhs)
static void concat(C< K, T, O< K >, A > &lhs, C< K, T, O< K >, A > &&rhs)
static void add_element(C< T, H< T >, O< T >, A > &c, T &&t)
auto map(F &&func, C &&list)
1引数高階関数
Definition: high_order.hpp:62
static void add_element(C< T, H< T >, O< T >, A > &c, T const &t)
Definition: array.hpp:15