YSTest: placement.hpp 源文件

YSTest PreAlpha_b800_20170810 The YSLib Test Project

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

- 文件列表
- 文件成员

placement.hpp
浏览该文件的文档.
1 /*
2 © 2015-2016 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
30 #ifndef YB_INC_ystdex_placement_hpp_
31 #define YB_INC_ystdex_placement_hpp_ 1
32
33 #include "addressof.hpp" // for "addressof.hpp", empty_base, size_t_,
34 // YB_ASSUME, ystdex::constfn_addressof, yforward, is_lvalue_reference,
35 // std::pair, std::unique_ptr;
36 #include <new> // for placement ::operator new from standard library;
37 #include <iterator> // for std::iterator_traits;
38 #include "deref_op.hpp" // for is_undereferenceable;
39 #include "cassert.h" // for yconstraint;
40
41 namespace ystdex
42 {
43
48 yconstexpr const struct default_init_t{} default_init{};
49
54 yconstexpr const struct value_init_t{} value_init{};
55
56
62 struct in_place_tag
64 {
65 in_place_tag() = delete;
66 };
67
69 using in_place_t = in_place_tag(&)(yimpl(empty_base<>));
70
72 template<typename _type>
73 using in_place_type_t = in_place_tag(&)(yimpl(empty_base<_type>));
74
76 template<size_t _vIdx>
77 using in_place_index_t = in_place_tag(&)(yimpl(size_t_<_vIdx>));
78
84 yimpl(YB_NORETURN) inline in_place_tag
85 in_place(yimpl(empty_base<>))
86 {
87 YB_ASSUME(false);
88 }
89 template<typename _type>
90 yimpl(YB_NORETURN) in_place_tag
91 in_place(yimpl(empty_base<_type>))
92 {
93 YB_ASSUME(false);
94 }
95 template<size_t _vIdx>
96 yimpl(YB_NORETURN) in_place_tag
97 in_place(yimpl(size_t_<_vIdx>))
98 {
99 YB_ASSUME(false);
100 }
102
103
110 template<typename _type, typename _tObj>
112 inline _type*
113 construct_default_within(_tObj& obj)
114 {
115 return ::new(static_cast<void*>(static_cast<_tObj*>(
116 ystdex::constfn_addressof(obj)))) _type;
117 }
118
124 template<typename _type, typename _tObj, typename... _tParams>
125 inline _type*
126 construct_within(_tObj& obj, _tParams&&... args)
127 {
128 return ::new(static_cast<void*>(static_cast<_tObj*>(
129 ystdex::constfn_addressof(obj)))) _type(yforward(args)...);
130 }
132
139 template<typename _type>
140 inline void
141 construct_default_in(_type& obj)
142 {
143 ystdex::construct_default_within<_type>(obj);
144 }
145
152 template<typename _type, typename... _tParams>
153 inline void
154 construct_in(_type& obj, _tParams&&... args)
155 {
156 ystdex::construct_within<_type>(obj, yforward(args)...);
157 }
158
160
161
163
176 template<typename _tIter, typename... _tParams>
177 void
178 construct(_tIter i, _tParams&&... args)
179 {
180 using value_type = typename std::iterator_traits<_tIter>::value_type;
181
182 yconstraint(!is_undereferenceable(i));
183 ystdex::construct_within<value_type>(*i, yforward(args)...);
184 }
185
191 template<typename _tIter>
192 void
193 construct_default(_tIter i)
194 {
195 using value_type = typename std::iterator_traits<_tIter>::value_type;
196
197 yconstraint(!is_undereferenceable(i));
198 ystdex::construct_default_within<value_type>(*i);
199 }
200
205 template<typename _tIter, typename... _tParams>
206 void
207 construct_range(_tIter first, _tIter last, _tParams&&... args)
208 {
209 for(; first != last; ++first)
210 ystdex::construct(first, yforward(args)...);
211 }
213
214
224 template<typename _type>
225 inline void
226 destroy_at(_type* location)
227 {
228 yconstraint(location);
229 location->~_type();
230 }
231
233 template<typename _tFwd>
234 inline void
235 destroy(_tFwd first, _tFwd last)
236 {
237 for(; first != last; ++first)
238 ystdex::destroy_at(std::addressof(*first));
239 }
240
241 template<typename _tFwd, typename _tSize>
242 inline _tFwd
243 destroy_n(_tFwd first, _tSize n)
244 {
245 // XXX: To reduce dependency on resolution of LWG 2598.
246 static_assert(is_lvalue_reference<decltype(*first)>(),
247 "Invalid iterator reference type found.");
248
249 // XXX: Excessive order refinment by ','?
250 for(; n > 0; static_cast<void>(++first), --n)
251 ystdex::destroy_at(std::addressof(*first));
252 return first;
253 }
255
256
257
265 template<typename _type>
266 inline void
267 destruct_in(_type& obj)
268 {
269 obj.~_type();
270 }
271
278 template<typename _tIter>
279 void
280 destruct(_tIter i)
281 {
282 using value_type = typename std::iterator_traits<_tIter>::value_type;
283
284 yconstraint(!is_undereferenceable(i));
285 ystdex::destruct_in<value_type>(*i);
286 }
287
293 template<typename _tIter>
294 void
295 destruct_range(_tIter first, _tIter last)
296 {
297 for(; first != last; ++first)
298 ystdex::destruct(first);
299 }
301
302
303 #define YB_Impl_UninitGuard_Begin \
304 auto i = first; \
305 \
306 try \
307 {
308
309 // NOTE: The order of destruction is unspecified.
310 #define YB_Impl_UninitGuard_End \
311 } \
312 catch(...) \
313 { \
314 ystdex::destruct_range(first, i); \
315 throw; \
316 }
317
319
320
322
324 template<typename _tFwd>
325 inline void
326 uninitialized_default_construct(_tFwd first, _tFwd last)
327 {
328 YB_Impl_UninitGuard_Begin
329 for(; first != last; ++first)
330 ystdex::construct_default(first);
331 YB_Impl_UninitGuard_End
332 }
333
334 template<typename _tFwd, typename _tSize>
335 _tFwd
336 uninitialized_default_construct_n(_tFwd first, _tSize n)
337 {
338 YB_Impl_UninitGuard_Begin
339 // XXX: Excessive order refinment by ','?
340 for(; n > 0; static_cast<void>(++first), --n)
341 ystdex::construct_default(first);
342 YB_Impl_UninitGuard_End
343 }
345
347 template<typename _tFwd>
348 inline void
349 uninitialized_value_construct(_tFwd first, _tFwd last)
350 {
351 YB_Impl_UninitGuard_Begin
352 ystdex::construct_range(first, last);
353 YB_Impl_UninitGuard_End
354 }
355
356 template<typename _tFwd, typename _tSize>
357 _tFwd
358 uninitialized_value_construct_n(_tFwd first, _tSize n)
359 {
360 YB_Impl_UninitGuard_Begin
361 // XXX: Excessive order refinment by ','?
362 for(; n > 0; static_cast<void>(++first), --n)
363 ystdex::construct(first);
364 YB_Impl_UninitGuard_End
365 return first;
366 }
368
369
376 template<typename _tIn, class _tFwd>
377 _tFwd
378 uninitialized_move(_tIn first, _tIn last, _tFwd result)
379 {
380 YB_Impl_UninitGuard_Begin
381 for(; first != last; static_cast<void>(++result), ++first)
382 ystdex::construct(result, std::move(*first));
383 YB_Impl_UninitGuard_End
384 return result;
385 }
386
387 template<typename _tIn, typename _tSize, class _tFwd>
388 std::pair<_tIn, _tFwd>
389 uninitialized_move_n(_tIn first, _tSize n, _tFwd result)
390 {
391 YB_Impl_UninitGuard_Begin
392 // XXX: Excessive order refinment by ','?
393 for(; n > 0; ++result, static_cast<void>(++first), --n)
394 ystdex::construct(result, std::move(*first));
395 YB_Impl_UninitGuard_End
396 return {first, result};
397 }
399
400
416 template<typename _tFwd, typename... _tParams>
417 void
418 uninitialized_construct(_tFwd first, _tFwd last, _tParams&&... args)
419 {
420 YB_Impl_UninitGuard_Begin
421 for(; i != last; ++i)
422 ystdex::construct(i, yforward(args)...);
423 YB_Impl_UninitGuard_End
424 }
425
432 template<typename _tFwd, typename _tSize, typename... _tParams>
433 void
434 uninitialized_construct_n(_tFwd first, _tSize n, _tParams&&... args)
435 {
436 YB_Impl_UninitGuard_Begin
437 // NOTE: This form is by specification (WG21 N4431) of
438 // 'std::unitialized_fill' literally.
439 for(; n--; ++i)
440 ystdex::construct(i, yforward(args)...);
441 YB_Impl_UninitGuard_End
442 }
444
445
446 #undef YB_Impl_UninitGuard_End
447 #undef YB_Impl_UninitGuard_Begin
448
449
451
452 template<typename _type, class _tAlloc = std::allocator<_type>>
454 class default_init_allocator : public _tAlloc
455 {
456 public:
457 using allocator_type = _tAlloc;
458 using traits_type = std::allocator_traits<allocator_type>;
459 template<typename _tOther>
460 struct rebind
461 {
462 using other = default_init_allocator<_tOther,
463 typename traits_type::template rebind_alloc<_tOther>>;
464 };
465
466 using allocator_type::allocator_type;
467
468 template<typename _tOther>
469 void
470 construct(_tOther* p)
471 ynoexcept(std::is_nothrow_default_constructible<_tOther>::value)
472 {
473 ::new(static_cast<void*>(p)) _tOther;
474 }
475 template<typename _tOther, typename... _tParams>
476 void
477 construct(_type* p, _tParams&&... args)
478 {
479 traits_type::construct(static_cast<allocator_type&>(*this), p,
480 yforward(args)...);
481 }
482 };
483
484
490 template<typename _type, typename _tPointer = _type*>
491 struct placement_delete
492 {
493 using pointer = _tPointer;
494
495 yconstfn placement_delete() ynothrow = default;
496 template<typename _type2,
497 yimpl(typename = enable_if_convertible_t<_type2*, _type*>)>
498 placement_delete(const placement_delete<_type2>&) ynothrow
499 {}
500
502 void
503 operator()(pointer p) const ynothrowv
504 {
505 destroy_at(p);
506 }
507 };
508
509
511 template<typename _type, typename _tPointer = _type*>
512 using placement_ptr
513 = std::unique_ptr<_type, placement_delete<_type, _tPointer>>;
515
516
522 template<typename _tToken, typename _type>
523 struct tagged_value
524 {
525 using token_type = _tToken;
526 using value_type = _type;
527
528 token_type token;
529 union
530 {
531 empty_base<> empty;
532 mutable _type value;
533 };
534
535 yconstfn
536 tagged_value()
537 ynoexcept_spec(is_nothrow_default_constructible<token_type>())
538 : token(), empty()
539 {}
540 tagged_value(default_init_t)
541 {}
542 tagged_value(token_type t)
543 : token(t), empty()
544 {}
545 template<typename... _tParams>
546 explicit yconstfn
547 tagged_value(token_type t, in_place_t, _tParams&&... args)
548 : token(t), value(yforward(args)...)
549 {}
550 tagged_value(const tagged_value& v)
551 : token(v.token)
552 {}
557 ~tagged_value()
558 {}
559
560 template<typename... _tParams>
561 void
562 construct(_tParams&&... args)
563 {
564 ystdex::construct_in(value, yforward(args)...);
565 }
566
567 void
568 destroy() ynoexcept(is_nothrow_destructible<value_type>())
569 {
570 ystdex::destruct_in(value);
571 }
572
573 void
574 destroy_nothrow() ynothrow
575 {
576 ynoexcept_assert("Invalid type found.", value.~value_type());
577
578 destroy();
579 }
580 };
581
582 } // namespace ystdex;
583
584 #endif
585
ystdex::uninitialized_value_construct
void uninitialized_value_construct(_tFwd first, _tFwd last)
Definition: placement.hpp:349
ystdex::in_place_index_t
in_place_tag(&)(size_t_< _vIdx >) in_place_index_t
原地索引标记模板。
Definition: placement.hpp:77
ystdex::value_init_t
值初始化标记。
Definition: placement.hpp:54
ystdex::uninitialized_construct
void uninitialized_construct(_tFwd first, _tFwd last, _tParams &&...args)
在迭代器指定的未初始化的范围上构造对象。
Definition: placement.hpp:418
ystdex::tagged_value::~tagged_value
~tagged_value()
析构：空实现。
Definition: placement.hpp:557
ystdex::placement_delete::operator()
void operator()(pointer p) const
Definition: placement.hpp:503
ystdex::tagged_value::destroy_nothrow
void destroy_nothrow()
Definition: placement.hpp:574
ystdex::default_init_t
默认初始化标记。
Definition: placement.hpp:48
ystdex::tagged_value::empty
empty_base empty
Definition: placement.hpp:531
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:680
ystdex::constfn_addressof
enable_if_t<!has_overloaded_addressof< _type >::value, _type * > constfn_addressof(_type &r)
尝试对非重载 operator& 提供 constexpr 的 std::addressof 替代。
Definition: addressof.hpp:78
ystdex::default_init_allocator::traits_type
std::allocator_traits< allocator_type > traits_type
Definition: placement.hpp:458
v
byte v
Definition: CharRenderer.cpp:75
ystdex::tagged_value::tagged_value
tagged_value(token_type t, in_place_t, _tParams &&...args)
Definition: placement.hpp:547
ystdex::placement_delete::pointer
_tPointer pointer
Definition: placement.hpp:493
ystdex::tagged_value< bool, _type >::value_type
_type value_type
Definition: placement.hpp:526
ystdex::placement_delete::placement_delete
placement_delete()=default
ynoexcept_assert
#define ynoexcept_assert(_msg,...)
表达式 noexcept 静态断言。
Definition: ydef.h:747
ynoexcept_spec
#define ynoexcept_spec(...)
表达式 noexcept 异常规范。
Definition: ydef.h:794
ystdex::tagged_value::tagged_value
tagged_value(default_init_t)
Definition: placement.hpp:540
ystdex::placement_ptr
std::unique_ptr< _type, placement_delete< _type, _tPointer >> placement_ptr
独占放置存储的对象所有权的指针。
Definition: placement.hpp:513
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:262
ystdex::uninitialized_value_construct_n
_tFwd uninitialized_value_construct_n(_tFwd first, _tSize n)
Definition: placement.hpp:358
deref_op.hpp
解引用操作。
ystdex::construct_default_in
void construct_default_in(_type &obj)
以默认初始化原地构造。
Definition: placement.hpp:141
ystdex::destroy_n
_tFwd destroy_n(_tFwd first, _tSize n)
Definition: placement.hpp:243
CHRLib::args
_tParams && args
Definition: CharacterProcessing.h:538
ystdex::destruct
void destruct(_tIter i)
析构迭代器指向的对象。
Definition: placement.hpp:280
yconstexpr
#define yconstexpr
指定编译时常量表达式。
Definition: ydef.h:679
ystdex::is_undereferenceable
bool is_undereferenceable(const _tIter &)
Definition: deref_op.hpp:45
ystdex::default_init_allocator::construct
void construct(_type *p, _tParams &&...args)
Definition: placement.hpp:477
ystdex::tagged_value
带记号标记的可选值。
Definition: placement.hpp:523
ystdex::default_init_allocator::allocator_type
_tAlloc allocator_type
Definition: placement.hpp:457
ystdex::in_place_t
in_place_tag(&)(empty_base<>) in_place_t
原地空标记类型。
Definition: placement.hpp:69
ystdex::default_init_allocator::construct
void construct(_tOther *p)
Definition: placement.hpp:470
ystdex::tagged_value::construct
void construct(_tParams &&...args)
Definition: placement.hpp:562
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:766
ystdex::uninitialized_construct_n
void uninitialized_construct_n(_tFwd first, _tSize n, _tParams &&...args)
Definition: placement.hpp:434
YB_Impl_UninitGuard_Begin
#define YB_Impl_UninitGuard_Begin
Definition: placement.hpp:303
ystdex
特性测试宏。
Definition: ydef.h:822
YSLib::i
return i
Definition: YCoreUtilities.h:176
ystdex::size_t_
std::integral_constant< size_t, _vInt > size_t_
Definition: type_traits.hpp:385
YB_Impl_UninitGuard_End
#define YB_Impl_UninitGuard_End
Definition: placement.hpp:310
ystdex::in_place
in_place_tag in_place(empty_base<>)
原地标记函数。
Definition: placement.hpp:85
cassert.h
ISO C 断言/调试跟踪扩展。
ystdex::value_init
const struct ystdex::value_init_t value_init
ystdex::tagged_value::destroy
void destroy()
Definition: placement.hpp:568
ystdex::construct_default_within
_type * construct_default_within(_tObj &obj)
以默认初始化在对象中构造。
Definition: placement.hpp:113
ystdex::construct_default
void construct_default(_tIter i)
使用指定参数在迭代器指定的位置以默认初始化构造对象。
Definition: placement.hpp:193
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:786
addressof.hpp
一元操作符 & 和取指针的相关接口。
ystdex::destruct_range
void destruct_range(_tIter first, _tIter last)
析构d迭代器范围内的对象序列。
Definition: placement.hpp:295
ystdex::uninitialized_move_n
std::pair< _tIn, _tFwd > uninitialized_move_n(_tIn first, _tSize n, _tFwd result)
Definition: placement.hpp:389
ystdex::destroy
void destroy(_tFwd first, _tFwd last)
Definition: placement.hpp:235
ystdex::default_init_allocator
默认初始化构造分配器。
Definition: placement.hpp:454
ystdex::empty_base
空基类模板。
Definition: ydef.h:928
ystdex::in_place_type_t
in_place_tag(&)(empty_base< _type >) in_place_type_t
原地类型标记模板。
Definition: placement.hpp:73
ystdex::tagged_value< bool, _type >::token_type
bool token_type
Definition: placement.hpp:525
YB_NORETURN
#define YB_NORETURN
指定无返回值函数。
Definition: ydef.h:504
ystdex::default_init_allocator::rebind
Definition: placement.hpp:460
ystdex::tagged_value::tagged_value
tagged_value(const tagged_value &v)
Definition: placement.hpp:550
ystdex::uninitialized_default_construct
void uninitialized_default_construct(_tFwd first, _tFwd last)
在范围内未初始化放置构造。
Definition: placement.hpp:326
ystdex::placement_delete
放置存储的对象删除器：释放时调用伪析构函数。
Definition: placement.hpp:491
ystdex::construct
void construct(_tIter i, _tParams &&...args)
使用指定参数在迭代器指定的位置以指定参数初始化构造对象。
Definition: placement.hpp:178
ystdex::tagged_value::token
token_type token
Definition: placement.hpp:528
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:995
ystdex::destroy_at
void destroy_at(_type *location)
原地销毁。
Definition: placement.hpp:226
ystdex::enable_if_convertible_t
enable_if_t< is_convertible< _tFrom, _tTo >::value, _type > enable_if_convertible_t
Definition: type_traits.hpp:1052
ystdex::in_place_tag
原地标记类型。
Definition: placement.hpp:63
ystdex::construct_in
void construct_in(_type &obj, _tParams &&...args)
以值初始化原地构造。
Definition: placement.hpp:154
ystdex::tagged_value::tagged_value
tagged_value()
Definition: placement.hpp:536
ystdex::default_init
const struct ystdex::default_init_t default_init
ystdex::in_place_tag::in_place_tag
in_place_tag()=delete
yconstraint
#define yconstraint(_expr)
约束：接口语义。
Definition: cassert.h:88
ystdex::construct_within
_type * construct_within(_tObj &obj, _tParams &&...args)
以值初始化在对象中构造。
Definition: placement.hpp:126
ystdex::uninitialized_move
_tFwd uninitialized_move(_tIn first, _tIn last, _tFwd result)
转移初始化范围。
Definition: placement.hpp:378
ystdex::construct_range
void construct_range(_tIter first, _tIter last, _tParams &&...args)
使用指定的参数重复构造迭代器范围内的对象序列。
Definition: placement.hpp:207
ystdex::tagged_value::tagged_value
tagged_value(token_type t)
Definition: placement.hpp:542
ystdex::uninitialized_default_construct_n
_tFwd uninitialized_default_construct_n(_tFwd first, _tSize n)
Definition: placement.hpp:336
ystdex::tagged_value::value
_type value
Definition: placement.hpp:532
YB_ASSUME
#define YB_ASSUME(_expr)
假定表达式总是成立。
Definition: ydef.h:447
ynoexcept
#define ynoexcept(...)
YSLib 无异常抛出保证：指定特定的异常规范。
Definition: ydef.h:746
CHRLib::p
const auto p(d)
ystdex::destruct_in
void destruct_in(_type &obj)
原地析构。
Definition: placement.hpp:267