YSTest: container.hpp 源文件

YSTest PreAlpha_b500_20140530 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

全部 类 命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义 组 页
container.hpp
浏览该文件的文档.
1 /*
2 © 2012-2014 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #ifndef YB_INC_ystdex_container_hpp_
29 #define YB_INC_ystdex_container_hpp_ 1
30
31 #include "functional.hpp"
32 #include "cassert.h"
33 #include <array> // for std::array;
34 #include <algorithm> // for std::copy_n;
35
36 namespace ystdex
37 {
38
48 template<class _tSeqCon>
49 class container_adaptor : protected _tSeqCon
50 {
51 protected:
52 using container_type = _tSeqCon;
53
54 private:
55 using base = container_type;
56
57 public:
59
60 using value_type = typename container_type::value_type;
61 using reference = typename container_type::reference;
62 using const_reference = typename container_type::const_reference;
63 using iterator = typename container_type::iterator;
64 using const_iterator = typename container_type::const_iterator;
65 using difference_type = typename container_type::difference_type;
66 using size_type = typename container_type::size_type;
67
68 container_adaptor() = default;
69 explicit
70 container_adaptor(size_type n)
71 : base(n)
72 {}
73 container_adaptor(size_type n, const value_type& value)
74 : base(n, value)
75 {}
76 template<class _tIn>
77 container_adaptor(_tIn first, _tIn last)
78 : base(std::move(first), std::move(last))
79 {}
80 container_adaptor(const container_adaptor&) = default;
81 #if YB_IMPL_MSCPP
82 container_adaptor(container_adaptor&& con)
84 : base(static_cast<base&&>(con))
85 {}
86 #else
87 container_adaptor(container_adaptor&&) = default;
88 #endif
89
90 container_adaptor(std::initializer_list<value_type> il)
91 : base(il)
92 {};
93
95
96 container_adaptor&
97 operator=(const container_adaptor&) = default;
98 container_adaptor&
99 #if YB_IMPL_MSCPP
100 operator=(container_adaptor&& con)
102 {
103 static_cast< base&>(*this) = static_cast< base&&>(con);
104 return *this;
105 }
106 #else
107 operator=(container_adaptor&&) = default;
108 #endif
109
110 container_adaptor&
111 operator=(std::initializer_list<value_type> il)
112 {
113 base::operator=(il);
114 }
115
117 friend bool
118 operator==(const container_adaptor& x, const container_adaptor& y)
119 {
120 return static_cast<const container_type&>(x)
121 == static_cast<const container_type&>(y);
122 }
123
125
126 using container_type::begin;
127
128 using container_type::end;
129
130 using container_type::cbegin;
131
132 using container_type::cend;
133
134 void
135 swap(container_adaptor& c) ynothrow
136 {
137 return base::swap(static_cast<container_type&>(c));
138 }
139
140 using base::size;
141
142 using base::max_size;
143
144 using base::empty;
146 };
147
153 template<class _tSeqCon>
154 inline bool
155 operator!=(const container_adaptor<_tSeqCon>& x,
156 const container_adaptor<_tSeqCon>& y)
157 {
158 return !(x == y);
159 }
160
161 template<class _tSeqCon>
162 void
163 swap(container_adaptor<_tSeqCon>& x,
164 container_adaptor<_tSeqCon>& y) ynothrow
165 {
166 x.swap(y);
167 }
169
170
180 template<class _tSeqCon>
181 class sequence_container_adaptor : protected container_adaptor<_tSeqCon>
182 {
183 private:
184 using base = container_adaptor<_tSeqCon>;
185
186 public:
187 using container_type = typename base::container_type;
188 using value_type = typename container_type::value_type;
189 using size_type = typename container_type::size_type;
190
192
193 sequence_container_adaptor() = default;
194 explicit
195 sequence_container_adaptor(size_type n)
196 : base(n)
197 {}
198 sequence_container_adaptor(size_type n, const value_type& value)
199 : base(n, value)
200 {}
201 template<class _tIn>
202 sequence_container_adaptor(_tIn first, _tIn last)
203 : base(std::move(first), std::move(last))
204 {}
205 sequence_container_adaptor(const sequence_container_adaptor&) = default;
206 #if YB_IMPL_MSCPP
207 sequence_container_adaptor(sequence_container_adaptor&& con)
209 : base(static_cast<base&&>(con))
210 {}
211 #else
212 sequence_container_adaptor(sequence_container_adaptor&&) = default;
213 #endif
214 sequence_container_adaptor(std::initializer_list<value_type> il)
215 : base(il)
216 {};
217
218 sequence_container_adaptor&
219 operator=(const sequence_container_adaptor&) = default;
220 sequence_container_adaptor&
221 #if YB_IMPL_MSCPP
222 operator=(sequence_container_adaptor&& con)
224 {
225 static_cast< base&>(*this) = static_cast< base&&>(con);
226 return *this;
227 }
228 #else
229 operator=(sequence_container_adaptor&&) = default;
230 #endif
231 sequence_container_adaptor&
232 operator=(std::initializer_list<value_type> il)
233 {
234 base::operator=(il);
235 }
236
238 friend bool
239 operator==(const sequence_container_adaptor& x,
240 const sequence_container_adaptor& y)
241 {
242 return static_cast<const container_type&>(x)
243 == static_cast<const container_type&>(y);
244 }
245
246 // using container_type::emplace;
247
248 using container_type::insert;
249
250 using container_type::erase;
251
252 using container_type::clear;
253
254 using container_type::assign;
256 };
257
263 template<class _tSeqCon>
264 inline bool
265 operator!=(const sequence_container_adaptor<_tSeqCon>& x,
266 const sequence_container_adaptor<_tSeqCon>& y)
267 {
268 return !(x == y);
269 }
270
271 template<class _tSeqCon>
272 void
273 swap(sequence_container_adaptor<_tSeqCon>& x,
274 sequence_container_adaptor<_tSeqCon>& y) ynothrow
275 {
276 x.swap(y);
277 }
279
280
287 template<class _tCon, typename... _tParams>
288 inline void
289 assign(_tCon& c, _tParams&&... args)
290 {
291 c.assign(yforward(args)...);
292 }
293 template<class _tCon, typename _type, size_t _vN>
294 inline void
295 assign(_tCon& c, const _type(&arr)[_vN])
296 {
297 c.assign(arr, arr + _vN);
298 }
300
301
307 template<typename _tCon>
308 class container_inserter
309 {
310 public:
311 using container_type = _tCon;
312
313 protected:
314 _tCon* container;
315
316 public:
317 container_inserter(_tCon& c)
318 : container(&c)
319 {}
320
321 template<typename... _tParams>
322 auto
323 operator()(_tParams&&... args)
324 -> decltype(container->insert(std::forward<_tParams>(args)...))
325 // NOTE: Nested %decltype could cause crashing of devkitPro G++ 4.7.1.
326 {
327 yassume(container);
328 return container->insert(yforward(args)...);
329 }
330 };
331
336 template<typename _tCon, typename... _tParams>
337 inline void
338 seq_insert(_tCon& c, _tParams&&... args)
339 {
340 ystdex::seq_apply(container_inserter<_tCon>(c), yforward(args)...);
341 }
342
343
345 namespace details
346 {
347
348 template<class _tCon, typename _tKey>
349 bool
350 exists(const _tCon& con, const _tKey& key,
351 decltype(std::declval<_tCon>().count()) = 1U)
352 {
353 return con.count(key) != 0;
354 }
355 template<class _tCon, typename _tKey>
356 bool
357 exists(const _tCon& con, const _tKey& key, ...)
358 {
359 return con.find(key) != end(con);
360 }
361
362 } // namespace details;
363
371 template<class _tCon, typename _tKey>
372 inline bool
373 exists(const _tCon& con, const _tKey& key)
374 {
375 return details::exists(con, key);
376 }
377
378
385 template<typename _tRange>
386 void
387 erase_all(_tRange& c, const typename _tRange::value_type& val)
388 {
389 c.erase(std::remove(begin(c), end(c), val), end(c));
390 }
397 template<typename _tCon, typename _tFwd, typename _tValue>
398 void
399 erase_all(_tCon& c, _tFwd first, _tFwd last, const _tValue& value)
400 {
401 while(first != last)
402 if(*first == value)
403 c.erase(first++);
404 else
405 ++first;
406 }
407
414 template<typename _tRange, typename _fPred>
415 void
416 erase_all_if(_tRange& c, _fPred pred)
417 {
418 c.erase(std::remove_if(begin(c), end(c), pred), end(c));
419 }
426 template<typename _tCon, typename _tFwd, typename _fPred>
427 void
428 erase_all_if(_tCon& c, _tFwd first, _tFwd last, _fPred pred)
429 {
430 while(first != last)
431 if(pred(*first))
432 c.erase(first++);
433 else
434 ++first;
435 }
436
437
443 template<typename _tRandom>
444 inline _tRandom
445 sort_unique(_tRandom first, _tRandom last)
446 {
447 std::sort(first, last);
448 return std::unique(first, last);
449 }
450
456 template<class _tCon>
457 void
458 sort_unique(_tCon& c)
459 {
460 ystdex::sort_unique(begin(c), last(c));
461 c.erase(ystdex::sort_unique(begin(c), last(c)), end(c));
462 }
463
464
473 template<class _tMap>
474 std::pair<typename _tMap::iterator, bool>
475 search_map(_tMap& m, const typename _tMap::key_type& k)
476 {
477 const auto i(m.lower_bound(k));
478
479 return std::make_pair(i, (i == m.end() || m.key_comp()(k, i->first)));
480 }
481
482
487 template<typename _type, typename... _tParams>
488 inline std::array<_type, sizeof...(_tParams)>
489 make_array(_tParams&&... args)
490 {
491 // TODO: Use one pair of braces (depending on G++).
492 return {{decay_copy(args)...}};
493 }
494
499 template<typename _type, typename... _tParams>
500 inline std::array<_type, sizeof...(_tParams)>
501 forward_as_array(_tParams&&... args)
502 {
503 // TODO: Use one pair of braces (depending on G++).
504 return {{yforward(args)...}};
505 }
506
512 template<typename _type, size_t _vN, typename _tSrc>
513 yconstfn std::array<_type, _vN>
514 to_array(const _tSrc& src)
515 {
516 return std::array<_type, _vN>(src);
517 }
518 template<typename _type, size_t _vN>
519 yconstfn std::array<_type, _vN>
520 to_array(const std::array<_type, _vN>& src)
521 {
522 return src;
523 }
524 template<typename _type, size_t _vN, typename _tSrcElement>
525 inline std::array<_type, _vN>
526 to_array(const _tSrcElement(&src)[_vN])
527 {
528 std::array<_type, _vN> arr;
529
530 std::copy_n(std::addressof(src[0]), _vN, std::addressof(arr[0]));
531 return arr;
532 }
533 template<typename _type, size_t _vN, typename _tSrcElement>
534 inline std::array<_type, _vN>
535 to_array(_tSrcElement(&&src)[_vN])
536 {
537 std::array<_type, _vN> arr;
538
539 std::copy_n(std::make_move_iterator(std::addressof(src[0])), _vN,
540 std::addressof(arr[0]));
541 return arr;
542 }
544
545 } // namespace ystdex;
546
547 #endif
548
ystdex::assign
void assign(_tCon &c, _tParams &&...args)
插入参数指定的元素到容器。
Definition: container.hpp:289
ystdex::container_adaptor::container_adaptor
container_adaptor(size_type n)
Definition: container.hpp:70
ystdex::container_adaptor::const_reference
typename container_type::const_reference const_reference
Definition: container.hpp:62
ystdex::iterator_transformation::first
static auto first(const _tIterator &i) -> decltype((i->first))
Definition: iterator.hpp:759
ystdex::container_adaptor::operator=
container_adaptor & operator=(const container_adaptor &)=default
满足容器要求。
ystdex::container_inserter::container_inserter
container_inserter(_tCon &c)
Definition: container.hpp:317
ystdex::operator!=
bool operator!=(nullptr_t lhs, const _type &rhs)
Definition: ydef.h:638
ystdex::seq_insert
void seq_insert(_tCon &c, _tParams &&...args)
顺序插入值至指定容器。
Definition: container.hpp:338
ystdex::swap
void swap(sequence_container_adaptor< _tSeqCon > &x, sequence_container_adaptor< _tSeqCon > &y)
Definition: container.hpp:273
YSLib::UI::args
yconstfn const string _tParams && args
Definition: Loader.h:111
ystdex::to_array
std::array< _type, _vN > to_array(const _tSrc &src)
取指定参数转换为 std::array 对象。
Definition: container.hpp:514
ystdex::sequence_container_adaptor::operator=
sequence_container_adaptor & operator=(std::initializer_list< value_type > il)
Definition: container.hpp:232
ystdex::sequence_container_adaptor::container_type
typename base::container_type container_type
Definition: container.hpp:187
ystdex::container_adaptor::base
container_type base
Definition: container.hpp:55
cassert.h
ISO C 断言/调试跟踪扩展。
ystdex::sequence_container_adaptor::operator=
sequence_container_adaptor & operator=(const sequence_container_adaptor &)=default
ystdex::container_adaptor
容器适配器。
Definition: container.hpp:49
ystdex::container_adaptor::size_type
typename container_type::size_type size_type
Definition: container.hpp:66
ystdex::container_adaptor::const_iterator
typename container_type::const_iterator const_iterator
Definition: container.hpp:64
ystdex::container_adaptor::difference_type
typename container_type::difference_type difference_type
Definition: container.hpp:65
ystdex::sequence_container_adaptor::sequence_container_adaptor
sequence_container_adaptor(size_type n)
Definition: container.hpp:195
ystdex::sequence_container_adaptor::sequence_container_adaptor
sequence_container_adaptor(size_type n, const value_type &value)
Definition: container.hpp:198
ystdex::search_map
std::pair< typename _tMap::iterator, bool > search_map(_tMap &m, const typename _tMap::key_type &k)
按指定键值搜索指定映射。
Definition: container.hpp:475
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:722
ystdex::seq_apply
void seq_apply(_fCallable &&)
顺序递归调用。
Definition: functional.hpp:125
ystdex::container_inserter::container_type
_tCon container_type
Definition: container.hpp:311
YSLib::Drawing::operator=
CompactPixmapEx & operator=(const CompactPixmapEx &buf)
Definition: ygdi.h:328
ystdex::sequence_container_adaptor::sequence_container_adaptor
sequence_container_adaptor(_tIn first, _tIn last)
Definition: container.hpp:202
ystdex::container_adaptor::value_type
typename container_type::value_type value_type
满足容器要求。
Definition: container.hpp:60
ystdex::swap
void swap(any &x, any &y)
交换对象。
Definition: any.h:729
yassume
#define yassume
假定：环境语义。
Definition: cassert.h:58
ystdex::container_adaptor::container_type
_tSeqCon container_type
Definition: container.hpp:52
ystdex::assign
void assign(_tCon &c, const _type(&arr)[_vN])
Definition: container.hpp:295
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:514
ystdex::details::exists
bool exists(const _tCon &con, const _tKey &key, decltype(std::declval< _tCon >().count())=1U)
Definition: container.hpp:350
ystdex::container_inserter::operator()
auto operator()(_tParams &&...args) -> decltype(container->insert(std::forward< _tParams >(args)...))
Definition: container.hpp:323
ystdex::container_adaptor::iterator
typename container_type::iterator iterator
Definition: container.hpp:63
ystdex::sequence_container_adaptor
序列容器适配器。
Definition: container.hpp:181
ystdex::forward_as_array
std::array< _type, sizeof...(_tParams)> forward_as_array(_tParams &&...args)
取指定参数转移至 std::array 对象。
Definition: container.hpp:501
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:463
ystdex::container_adaptor::reference
typename container_type::reference reference
Definition: container.hpp:61
ystdex::container_adaptor::swap
void swap(container_adaptor &c)
Definition: container.hpp:135
ystdex::container_adaptor::container_adaptor
container_adaptor(_tIn first, _tIn last)
Definition: container.hpp:77
ystdex::sort_unique
_tRandom sort_unique(_tRandom first, _tRandom last)
排序指定序列范围，保留不重复元素的区间。
Definition: container.hpp:445
ystdex::sequence_container_adaptor::sequence_container_adaptor
sequence_container_adaptor(std::initializer_list< value_type > il)
Definition: container.hpp:214
ystdex::sequence_container_adaptor::operator==
friend bool operator==(const sequence_container_adaptor &x, const sequence_container_adaptor &y)
满足容器要求。
Definition: container.hpp:239
ystdex::make_array
std::array< _type, sizeof...(_tParams)> make_array(_tParams &&...args)
取指定参数初始化的 std::array 对象。
Definition: container.hpp:489
ystdex::container_adaptor::container_adaptor
container_adaptor(size_type n, const value_type &value)
Definition: container.hpp:73
ystdex::erase_all_if
void erase_all_if(_tRange &c, _fPred pred)
删除指定序列范围中满足条件的元素。
Definition: container.hpp:416
ystdex::exists
bool exists(const _tCon &con, const _tKey &key)
判断指定的容器中存在指定的键。
Definition: container.hpp:373
ystdex::container_adaptor::operator==
friend bool operator==(const container_adaptor &x, const container_adaptor &y)
满足容器要求。
Definition: container.hpp:118
CHRLib::c
c
Definition: chrproc.h:76
ystdex::container_adaptor::container_adaptor
container_adaptor()=default
ystdex::container_inserter
容器插入函数对象。
Definition: container.hpp:308
ystdex::sequence_container_adaptor::sequence_container_adaptor
sequence_container_adaptor()=default
满足序列容器要求。
ystdex::container_inserter::container
_tCon * container
Definition: container.hpp:314
ystdex::container_adaptor::operator=
container_adaptor & operator=(std::initializer_list< value_type > il)
Definition: container.hpp:111
ystdex::container_adaptor::container_adaptor
container_adaptor(std::initializer_list< value_type > il)
Definition: container.hpp:90
ystdex::sequence_container_adaptor::base
container_adaptor< _tSeqCon > base
Definition: container.hpp:184
functional.hpp
函数和可调用对象。
ystdex::erase_all
void erase_all(_tRange &c, const typename _tRange::value_type &val)
删除指定序列范围中和指定值的相等的元素。
Definition: container.hpp:387
ystdex::decay_copy
decay_t< _type > decay_copy(_type &&arg)
退化复制。
Definition: utility.hpp:168