YSTest: memory.hpp 源文件

YSTest PreAlpha_b800_20170810 The YSLib Test Project

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

- 文件列表
- 文件成员

memory.hpp
浏览该文件的文档.
1 /*
2 © 2011-2017 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_memory_hpp_
31 #define YB_INC_ystdex_memory_hpp_ 1
32
33 #include "placement.hpp" // for "placement.hpp", <memory>, and_,
34 // is_copy_constructible, is_class_type, cond_t, is_detected, vdefer,
35 // std::declval, detected_t, conditional, indirect_element_t,
36 // remove_reference_t, detected_or_t, not_, is_void, remove_pointer_t,
37 // yconstraint, is_pointer, enable_if_t, is_array, extent, remove_extent_t,
38 // ystdex::construct_within, is_polymorphic;
39 #include "pointer.hpp" // for "pointer.hpp";
40 #include "type_op.hpp" // for has_mem_value_type, cond_or;
41 #include "exception.h" // for throw_invalid_construction;
42 #include "ref.hpp" // for is_reference_wrapper;
43
44 #if YB_IMPL_MSCPP >= 1800
45
50 # ifndef __cpp_lib_make_unique
51 # define __cpp_lib_make_unique 201304
52 # endif
53 #endif
54
61 namespace ystdex
62 {
63
65
66 namespace details
67 {
68
69 template<typename _type>
70 using is_copy_constructible_class
71 = and_<is_copy_constructible<_type>, is_class_type<_type>>;
72
73
75 template<class _tAlloc, typename _type>
76 using rebind_t = typename _tAlloc::template rebind<_type>::other;
77
78 // XXX: Details member across headers?
80 template<typename _type>
81 using check_allocator = and_<cond_t<has_mem_value_type<_type>,
82 is_detected<rebind_t, _type, vdefer<details::mem_value_type_t, _type>>>,
83 is_copy_constructible_class<_type>>;
84
86 template<typename _type>
87 using nested_allocator_t = typename _type::allocator_type;
88
89
91
92 template<typename _type, typename... _tParams>
93 using mem_new_t
94 = decltype(_type::operator new(std::declval<_tParams>()...));
95
96 template<typename _type, typename... _tParams>
97 using mem_delete_t
98 = decltype(_type::operator delete(std::declval<_tParams>()...));
100
101 } // namespace details;
102
103
109 template<typename _type, typename... _tParams>
110 struct has_mem_new : is_detected<details::mem_new_t, _type, _tParams...>
111 {};
112
113 template<typename _type, typename... _tParams>
114 struct has_mem_delete : is_detected<details::mem_delete_t, _type, _tParams...>
115 {};
117
118
124 template<typename _type>
125 struct is_allocatable : is_nonconst_object<_type>
126 {};
127
128
133 template<typename _type>
134 struct has_nested_allocator
135 : details::check_allocator<detected_t<details::nested_allocator_t, _type>>
136 {};
137
138
143 template<typename _type, class _tDefault = std::allocator<_type>>
144 struct nested_allocator : conditional<has_nested_allocator<_type>::value,
145 detected_t<details::nested_allocator_t, _type>, _tDefault>
146 {};
148
149
154 template<class _tAlloc>
155 class allocator_delete
156 {
157 private:
158 using traits = std::allocator_traits<_tAlloc>;
159
160 public:
161 using pointer = typename traits::pointer;
162 using size_type = typename traits::size_type;
163
164 private:
165 _tAlloc& alloc_ref;
166 size_type size;
167
168 public:
169 allocator_delete(_tAlloc& alloc, size_type s)
170 : alloc_ref(alloc), size(s)
171 {}
172
173 void
174 operator()(pointer p) const ynothrowv
175 {
176 traits::deallocate(alloc_ref, p, size);
177 }
178 };
179
180
185 template<typename _tAlloc>
186 std::unique_ptr<_tAlloc, allocator_delete<_tAlloc>>
187 make_allocator_guard(_tAlloc& a,
188 typename std::allocator_traits<_tAlloc>::size_type n = 1)
189 {
190 using del_t = allocator_delete<_tAlloc>;
191
192 return std::unique_ptr<_tAlloc, del_t>(
193 std::allocator_traits<_tAlloc>::allocate(a, n), del_t(a, n));
194 }
195
196
198
199 template<typename _type, class _tAlloc, typename... _tParams>
201 auto
202 create_with_allocator(_tAlloc&& a, _tParams&&... args)
203 -> decltype(ystdex::make_allocator_guard(a).release())
204 {
205 auto gd(ystdex::make_allocator_guard(a));
206
207 ystdex::construct_within<typename std::allocator_traits<decay_t<_tAlloc>>
208 ::value_type>(*gd.get(), yforward(args)...);
209 return gd.release();
210 }
211
212
214
215
221 template<class _type>
222 struct class_allocator : std::allocator<_type>
223 {
224 class_allocator() = default;
225 using std::allocator<_type>::allocator;
226 class_allocator(const class_allocator&) = default;
227
228 _type*
229 allocate(size_t n)
230 {
231 return _type::operator new(n * sizeof(_type));
232 }
233
235 void
236 deallocate(_type* p, size_t) ynothrow
237 {
238 // TODO: What if the size hint is supported by %_type?
239 return _type::operator delete(p);
240 }
241 };
242
243
249 template<typename _type>
250 using local_allocator = cond_t<and_<has_mem_new<_type, size_t>,
251 has_mem_delete<_type*>>, class_allocator<_type>, std::allocator<_type>>;
253
254
255
256 namespace details
257 {
258
260 template<typename _type, typename... _tParams>
261 YB_NORETURN _type*
262 try_new_impl(void*, _tParams&&...)
263 {
264 throw_invalid_construction();
265 }
267 template<typename _type, typename... _tParams>
268 auto
269 try_new_impl(nullptr_t, _tParams&&... args)
270 -> decltype(new _type(yforward(args)...))
271 {
272 return new _type(yforward(args)...);
273 }
274
276 template<typename _type, class _tAlloc, typename... _tParams>
277 YB_NORETURN _type*
278 try_create_with_allocator_impl(void*, _tAlloc&, _tParams&&...)
279 {
280 throw_invalid_construction();
281 }
283 template<typename _type, class _tAlloc, typename... _tParams>
284 auto
285 try_create_with_allocator_impl(nullptr_t, _tAlloc& a, _tParams&&... args)
286 -> decltype(ystdex::create_with_allocator<_type>(a, yforward(args)...))
287 {
288 return ystdex::create_with_allocator<_type>(a, yforward(args)...);
289 }
290
292
293 template<typename _type>
294 struct pack_obj_impl
295 {
296 template<typename... _tParams>
297 static _type
298 pack(_tParams&&... args)
299 {
300 return _type(yforward(args)...);
301 }
302 };
303
304 template<typename _type, class _tDeleter>
305 struct pack_obj_impl<std::unique_ptr<_type, _tDeleter>>
306 {
307 template<typename... _tParams>
308 static std::unique_ptr<_type>
309 pack(_tParams&&... args)
310 {
311 return std::unique_ptr<_type>(yforward(args)...);
312 }
313 };
314
315 template<typename _type>
316 struct pack_obj_impl<std::shared_ptr<_type>>
317 {
318 template<typename... _tParams>
319 static std::shared_ptr<_type>
320 pack(_tParams&&... args)
321 {
322 return std::shared_ptr<_type>(yforward(args)...);
323 }
324 };
326
327 } // namespace details;
328
329
331
332
336 template<typename _type, typename... _tParams>
337 _type*
338 try_new(_tParams&&... args)
339 {
340 return details::try_new_impl<_type>(nullptr, yforward(args)...);
341 }
342
347 template<typename _type, class _tAlloc, typename... _tParams>
348 _type*
349 try_create_with_allocator(_tAlloc&& a, _tParams&&... args)
350 {
351 return details::try_create_with_allocator_impl<_type>(nullptr, a,
352 yforward(args)...);
353 }
355
356
365 template<typename _type>
366 struct is_sharing : false_
367 {};
368
369 template<typename _type>
370 struct is_sharing<std::shared_ptr<_type>> : true_
371 {};
372
373 template<typename _type>
374 struct is_sharing<std::weak_ptr<_type>> : true_
375 {};
377
378
388 template<typename _type>
390 struct free_delete
391 {
392 yconstfn free_delete() ynothrow = default;
393 template<typename _type2,
394 yimpl(typename = enable_if_convertible_t<_type2*, _type*>)>
395 free_delete(const free_delete<_type2>&) ynothrow
396 {}
397
399 void
400 operator()(_type* p) const ynothrowv
401 {
402 p->~_type();
403 std::free(p);
404 }
405 };
406
407 template<typename _type>
408 struct free_delete<_type[]>
409 {
411
412 static_assert(is_trivially_destructible<_type>(), "Invalid type found");
413
414 yconstfn free_delete() ynothrow = default;
415 template<typename _type2,
416 yimpl(typename = enable_if_convertible_t<_type2(*)[], _type(*)[]>)>
417 free_delete(const free_delete<_type2[]>&) ynothrow
418 {}
419
420 template<typename _type2,
421 yimpl(typename = enable_if_convertible_t<_type2(*)[], _type(*)[]>)>
422 void
423 operator()(_type2* p) const ynothrowv
424 {
425 std::free(p);
426 }
428 };
430
431
438 template<typename>
439 struct temporary_buffer_delete;
440
441 template<typename _type>
442 struct temporary_buffer_delete<_type[]>
443 {
444 yconstfn temporary_buffer_delete() ynothrow = default;
445
446 void
447 operator()(_type* p) const ynothrowv
448 {
449 std::return_temporary_buffer(p);
450 }
451 };
453
454
460 template<typename _type>
461 class temporary_buffer
462 {
463 public:
464 using array_type = _type[];
465 using element_type = _type;
466 using deleter = temporary_buffer_delete<array_type>;
467 using pointer = std::unique_ptr<_type, deleter>;
468
469 private:
470 std::pair<pointer, size_t> buf;
471
472 public:
474 temporary_buffer(size_t n)
475 : buf([n]{
476 // NOTE: See LWG 2072.
477 const auto pr(std::get_temporary_buffer<_type>(ptrdiff_t(n)));
478
479 if(pr.first)
480 return std::pair<pointer, size_t>(pointer(pr.first),
481 size_t(pr.second));
482 throw std::bad_cast();
483 }())
484 {}
485 temporary_buffer(temporary_buffer&&) = default;
486 temporary_buffer&
487 operator=(temporary_buffer&&) = default;
488
490 yconstfn const pointer&
491 get() const ynothrow
492 {
493 return buf.first;
494 }
495
496 pointer&
497 get_pointer_ref() ynothrow
498 {
499 return buf.first;
500 }
501
502 size_t
503 size() const ynothrow
504 {
505 return buf.second;
506 }
507 };
509
510
516 template<class _tDeleter>
518 using deleter_member_pointer_t
519 = typename remove_reference_t<_tDeleter>::pointer;
520
522 template<typename _type, class _tDeleter>
523 using unique_ptr_pointer
524 = detected_or_t<_type*, deleter_member_pointer_t, _tDeleter>;
525
531 template<typename _tPointer, typename _tDefault = void>
532 using defer_element = cond_or<not_<is_void<remove_pointer_t<_tPointer>>>,
533 _tDefault, indirect_element_t, _tPointer>;
535
536
542 template<typename _type>
543 yconstfn _type*
544 get_raw(_type* const& p) ynothrow
545 {
546 return p;
547 }
549 template<typename _type, typename _fDeleter>
550 yconstfn auto
551 get_raw(const std::unique_ptr<_type, _fDeleter>& p) ynothrow
552 -> decltype(p.get())
553 {
554 return p.get();
555 }
556 template<typename _type>
557 yconstfn _type*
558 get_raw(const std::shared_ptr<_type>& p) ynothrow
559 {
560 return p.get();
561 }
562 template<typename _type>
563 yconstfn _type*
564 get_raw(const std::weak_ptr<_type>& p) ynothrow
565 {
566 return p.lock().get();
567 }
569
575 template<typename _type>
576 yconstfn bool
577 owns_any(_type* const& p) ynothrow
578 {
579 return {};
580 }
582 template<typename _type, typename _fDeleter>
583 yconstfn bool
584 owns_any(const std::unique_ptr<_type, _fDeleter>& p) ynothrow
585 {
586 return bool(p);
587 }
588 template<typename _type>
589 yconstfn bool
590 owns_any(const std::shared_ptr<_type>& p) ynothrow
591 {
592 return p.use_count() > 0;
593 }
594 template<typename _type>
595 yconstfn bool
596 owns_any(const std::weak_ptr<_type>& p) ynothrow
597 {
598 return !p.expired();
599 }
601
607 template<typename _type>
608 yconstfn bool
609 owns_nonnull(_type* const& p) ynothrow
610 {
611 return {};
612 }
614 template<typename _type, typename _fDeleter>
615 yconstfn bool
616 owns_nonnull(const std::unique_ptr<_type, _fDeleter>& p) ynothrow
617 {
618 return bool(p);
619 }
620 template<typename _type>
621 yconstfn bool
622 owns_nonnull(const std::shared_ptr<_type>& p) ynothrow
623 {
624 return bool(p);
625 }
626 template<typename _type>
627 yconstfn bool
628 owns_nonnull(const std::weak_ptr<_type>& p) ynothrow
629 {
630 return bool(p.lock());
631 }
633
639 template<typename _type>
640 yconstfn bool
641 owns_unique(const _type&) ynothrow
642 {
643 return !is_reference_wrapper<_type>();
644 }
645 template<typename _type, class _tDeleter>
646 inline bool
647 owns_unique(const std::unique_ptr<_type, _tDeleter>& p) ynothrow
648 {
649 return bool(p);
650 }
652 template<typename _type>
653 inline bool
654 owns_unique(const std::shared_ptr<_type>& p) ynothrow
655 {
656 return p.unique();
657 }
659 template<typename _type>
660 inline bool
661 owns_unique(const std::weak_ptr<_type>& p) ynothrow
662 {
663 return p.use_count() == 1;
664 }
665
666 template<typename _type>
667 yconstfn bool
668 owns_unique_nonnull(const _type&) ynothrow
669 {
670 return !is_reference_wrapper<_type>();
671 }
673
674 template<typename _type, class _tDeleter>
675 inline bool
676 owns_unique_nonnull(const std::unique_ptr<_type, _tDeleter>& p) ynothrow
677 {
678 yconstraint(p);
679 return true;
680 }
681 template<typename _type>
682 inline bool
683 owns_unique_nonnull(const std::shared_ptr<_type>& p) ynothrow
684 {
685 yconstraint(p);
686 return p.unique();
687 }
689 template<typename _type>
690 inline bool
691 owns_unique_nonnull(const std::weak_ptr<_type>& p) ynothrow
692 {
693 yconstraint(!p.expired());
694 return p.use_count() == 1;
695 }
697
698
705 template<typename _type, class _tDeleter>
707 inline bool
708 reset(std::unique_ptr<_type, _tDeleter>& p) ynothrow
709 {
710 if(p.get())
711 {
712 p.reset();
713 return true;
714 }
715 return {};
716 }
717 template<typename _type>
718 inline bool
719 reset(std::shared_ptr<_type>& p) ynothrow
720 {
721 if(p.get())
722 {
723 p.reset();
724 return true;
725 }
726 return {};
727 }
729
738 template<typename _type, typename _pSrc>
739 yconstfn std::unique_ptr<_type>
740 unique_raw(_pSrc* p) ynothrow
741 {
742 return std::unique_ptr<_type>(p);
743 }
744 template<typename _type>
745 yconstfn std::unique_ptr<_type>
746 unique_raw(_type* p) ynothrow
747 {
748 return std::unique_ptr<_type>(p);
749 }
750 template<typename _type, typename _tDeleter, typename _pSrc>
751 yconstfn std::unique_ptr<_type, _tDeleter>
752 unique_raw(_pSrc* p, _tDeleter&& d) ynothrow
753 {
754 return std::unique_ptr<_type, _tDeleter>(p, yforward(d));
755 }
756 template<typename _type, typename _tDeleter>
757 yconstfn std::unique_ptr<_type, _tDeleter>
758 unique_raw(_type* p, _tDeleter&& d) ynothrow
759 {
760 return std::unique_ptr<_type, _tDeleter>(p, yforward(d));
761 }
766 template<typename _type>
767 yconstfn std::unique_ptr<_type>
768 unique_raw(nullptr_t) ynothrow
769 {
770 return std::unique_ptr<_type>();
771 }
773
774
783
785 template<typename _type, typename... _tParams>
786 yconstfn std::shared_ptr<_type>
787 share_raw(_type* p, _tParams&&... args)
788 {
789 return std::shared_ptr<_type>(p, yforward(args)...);
790 }
795 template<typename _type, typename _pSrc, typename... _tParams>
796 yconstfn std::shared_ptr<_type>
797 share_raw(_pSrc&& p, _tParams&&... args)
798 {
799 static_assert(is_pointer<remove_reference_t<_pSrc>>(),
800 "Invalid type found.");
801
802 return std::shared_ptr<_type>(p, yforward(args)...);
803 }
805
809 template<typename _type>
810 yconstfn std::shared_ptr<_type>
811 share_raw(nullptr_t) ynothrow
812 {
813 return std::shared_ptr<_type>();
814 }
820 template<typename _type, class... _tParams>
821 yconstfn yimpl(enable_if_t)<sizeof...(_tParams) != 0, std::shared_ptr<_type>>
822 share_raw(nullptr_t, _tParams&&... args) ynothrow
823 {
824 return std::shared_ptr<_type>(nullptr, yforward(args)...);
825 }
827
828
829 inline namespace cpp2014
830 {
831
832 #if __cpp_lib_make_unique >= 201304 || __cplusplus > 201103L
833 using std::make_unique;
835 #else
836
850 template<typename _type, typename... _tParams>
851 yconstfn yimpl(enable_if_t<!is_array<_type>::value, std::unique_ptr<_type>>)
852 make_unique(_tParams&&... args)
853 {
854 return std::unique_ptr<_type>(new _type(yforward(args)...));
855 }
856 template<typename _type, typename... _tParams>
857 yconstfn yimpl(enable_if_t<is_array<_type>::value && extent<_type>::value == 0,
858 std::unique_ptr<_type>>)
859 make_unique(size_t size)
860 {
861 return std::unique_ptr<_type>(new remove_extent_t<_type>[size]());
862 }
863 template<typename _type, typename... _tParams>
864 yimpl(enable_if_t<extent<_type>::value != 0>)
865 make_unique(_tParams&&...) = delete;
867 #endif
868
869 } // inline namespace cpp2014;
870
877 template<typename _type, typename... _tParams>
878 yconstfn yimpl(enable_if_t<!is_array<_type>::value, std::unique_ptr<_type>>)
879 make_unique_default_init()
880 {
881 return std::unique_ptr<_type>(new _type);
882 }
883 template<typename _type, typename... _tParams>
884 yconstfn yimpl(enable_if_t<is_array<_type>::value && extent<_type>::value == 0,
885 std::unique_ptr<_type>>)
886 make_unique_default_init(size_t size)
887 {
888 return std::unique_ptr<_type>(new remove_extent_t<_type>[size]);
889 }
890 template<typename _type, typename... _tParams>
891 yimpl(enable_if_t<extent<_type>::value != 0>)
892 make_unique_default_init(_tParams&&...) = delete;
894
901 template<typename _type, typename _tValue>
902 yconstfn std::unique_ptr<_type>
903 make_unique(std::initializer_list<_tValue> il)
904 {
905 return ystdex::make_unique<_type>(il);
906 }
907
913 template<typename _type, typename _tDeleter, typename... _tParams>
914 yconstfn yimpl(enable_if_t<!is_array<_type>::value, std::unique_ptr<_type>>)
915 make_unique_with(_tDeleter&& d)
916 {
917 return std::unique_ptr<_type, _tDeleter>(new _type, yforward(d));
918 }
919 template<typename _type, typename _tDeleter, typename... _tParams>
920 yconstfn yimpl(enable_if_t<is_array<_type>::value && extent<_type>::value == 0,
921 std::unique_ptr<_type>>)
922 make_unique_with(_tDeleter&& d, size_t size)
923 {
924 return std::unique_ptr<_type, _tDeleter>(new remove_extent_t<_type>[size],
925 yforward(d));
926 }
927 template<typename _type, typename _tDeleter, typename... _tParams>
928 yimpl(enable_if_t<extent<_type>::value != 0>)
929 make_unique_with(_tDeleter&&, _tParams&&...) = delete;
931
932
943 template<typename _type, typename _tValue>
944 yconstfn std::shared_ptr<_type>
945 make_shared(std::initializer_list<_tValue> il)
946 {
947 return std::make_shared<_type>(il);
948 }
949
954 template<typename _type>
955 inline std::weak_ptr<_type>
956 make_weak(const std::shared_ptr<_type>& p) ynothrow
957 {
958 return p;
959 }
961
962
968 template<typename _tValue, typename _type = _tValue>
970 yconstfn std::shared_ptr<decay_t<_type>>
971 share_copy(const _tValue& v)
972 {
973 using std::make_shared;
974
975 return make_shared<decay_t<_type>>(yforward(v));
976 }
977
979 template<typename _tValue, typename _type = _tValue>
980 yconstfn std::shared_ptr<decay_t<_type>>
981 share_forward(_tValue&& v)
982 {
983 using std::make_shared;
984
985 return make_shared<decay_t<_type>>(yforward(v));
986 }
987
989 template<typename _tValue, typename _type = _tValue>
990 yconstfn std::shared_ptr<decay_t<_type>>
991 share_move(_tValue&& v)
992 {
993 using std::make_shared;
994
995 return make_shared<decay_t<_type>>(std::move(v));
996 }
998
999
1005 template<typename _tDst, typename _type>
1006 std::unique_ptr<_tDst>
1007 static_pointer_cast(std::unique_ptr<_type> p) ynothrow
1008 {
1009 return std::unique_ptr<_tDst>(static_cast<_tDst*>(p.release()));
1010 }
1011 template<typename _tDst, typename _type, typename _tDeleter>
1012 std::unique_ptr<_tDst, _tDeleter>
1013 static_pointer_cast(std::unique_ptr<_type, _tDeleter> p) ynothrow
1014 {
1015 return std::unique_ptr<_tDst, _tDeleter>(static_cast<_tDst*>(p.release()),
1016 std::move(p.get_deleter()));
1017 }
1018
1019 template<typename _tDst, typename _type>
1020 std::unique_ptr<_tDst>
1021 dynamic_pointer_cast(std::unique_ptr<_type>& p) ynothrow
1022 {
1023 if(auto p_res = dynamic_cast<_tDst*>(p.get()))
1024 {
1025 p.release();
1026 return std::unique_ptr<_tDst>(p_res);
1027 }
1028 return std::unique_ptr<_tDst>();
1029 }
1030 template<typename _tDst, typename _type>
1031 std::unique_ptr<_tDst>
1032 dynamic_pointer_cast(std::unique_ptr<_type>&& p) ynothrow
1033 {
1034 return ystdex::dynamic_pointer_cast<_tDst, _type>(p);
1035 }
1036 template<typename _tDst, typename _type, typename _tDeleter>
1037 std::unique_ptr<_tDst, _tDeleter>
1038 dynamic_pointer_cast(std::unique_ptr<_type, _tDeleter>& p) ynothrow
1039 {
1040 if(auto p_res = dynamic_cast<_tDst*>(p.get()))
1041 {
1042 p.release();
1043 return std::unique_ptr<_tDst, _tDeleter>(p_res);
1044 }
1045 return std::unique_ptr<_tDst, _tDeleter>(nullptr);
1046 }
1047 template<typename _tDst, typename _type, typename _tDeleter>
1048 std::unique_ptr<_tDst, _tDeleter>
1049 dynamic_pointer_cast(std::unique_ptr<_type, _tDeleter>&& p) ynothrow
1050 {
1051 return ystdex::dynamic_pointer_cast<_tDst, _type, _tDeleter>(p);
1052 }
1053
1054 template<typename _tDst, typename _type>
1055 std::unique_ptr<_tDst>
1056 const_pointer_cast(std::unique_ptr<_type> p) ynothrow
1057 {
1058 return std::unique_ptr<_tDst>(const_cast<_tDst*>(p.release()));
1059 }
1060 template<typename _tDst, typename _type, typename _tDeleter>
1061 std::unique_ptr<_tDst, _tDeleter>
1062 const_pointer_cast(std::unique_ptr<_type, _tDeleter> p) ynothrow
1063 {
1064 return std::unique_ptr<_tDst, _tDeleter>(const_cast<_tDst*>(p.release()),
1065 std::move(p.get_deleter()));
1066 }
1068
1069
1071
1072 template<typename _type>
1074 inline _type*
1075 clone_monomorphic(const _type& v)
1076 {
1077 return new _type(v);
1078 }
1080 template<typename _type, class _tAlloc>
1081 inline auto
1082 clone_monomorphic(const _type& v, _tAlloc&& a)
1083 -> decltype(ystdex::create_with_allocator<_type>(yforward(a), v))
1084 {
1085 return ystdex::create_with_allocator<_type>(yforward(a), v);
1086 }
1087
1089 template<typename _tPointer>
1090 inline auto
1091 clone_monomorphic_ptr(const _tPointer& p)
1092 -> decltype(ystdex::clone_monomorphic(*p))
1093 {
1094 using ptr_t = decltype(ystdex::clone_monomorphic(*p));
1095
1096 return p ? ystdex::clone_monomorphic(*p) : ptr_t();
1097 }
1099 template<typename _tPointer, class _tAlloc>
1100 inline auto
1101 clone_monomorphic_ptr(const _tPointer& p, _tAlloc&& a)
1102 -> decltype(ystdex::clone_monomorphic(*p, yforward(a)))
1103 {
1104 using ptr_t = decltype(ystdex::clone_monomorphic(*p, yforward(a)));
1105
1106 return p ? ystdex::clone_monomorphic(*p, yforward(a)) : ptr_t();
1107 }
1108
1113 template<class _type>
1114 inline auto
1115 clone_polymorphic(const _type& v) -> decltype(v.clone())
1116 {
1117 static_assert(is_polymorphic<_type>(), "Non-polymorphic class type found.");
1118
1119 return v.clone();
1120 }
1121
1123 template<class _tPointer>
1124 inline auto
1125 clone_polymorphic_ptr(const _tPointer& p) -> decltype(clone_polymorphic(*p))
1126 {
1127 return
1128 p ? ystdex::clone_polymorphic(*p) : decltype(clone_polymorphic(*p))();
1129 }
1131
1132
1134
1135
1142 template<typename _type, typename... _tParams>
1143 auto
1144 pack_object(_tParams&&... args)
1145 -> decltype(yimpl(details::pack_obj_impl<_type>::pack(yforward(args)...)))
1146 {
1147 return details::pack_obj_impl<_type>::pack(yforward(args)...);
1148 }
1149
1150
1152 template<typename _type, typename _tPack = std::unique_ptr<_type>>
1153 struct object_pack
1154 {
1155 public:
1156 using value_type = _type;
1157 using pack_type = _tPack;
1158
1159 private:
1160 pack_type pack;
1161
1162 public:
1164 template<typename... _tParams>
1165 object_pack(_tParams&&... args)
1166 : pack(pack_object<_tPack>(yforward(args)...))
1167 {}
1168
1169 operator pack_type&() ynothrow
1170 {
1171 return pack;
1172 }
1173 operator const pack_type&() const ynothrow
1174 {
1175 return pack;
1176 }
1177 };
1179
1180 } // namespace ystdex;
1181
1182
1183 namespace std
1184 {
1185
1192 template<typename>
1193 struct hash;
1194
1195 template<typename _type>
1196 struct hash<ystdex::observer_ptr<_type>>
1197 {
1198 size_t
1199 operator()(const ystdex::observer_ptr<_type>& p) const yimpl(ynothrow)
1200 {
1201 return hash<_type*>(p.get());
1202 }
1203 };
1205
1206 } // namespace std;
1207
1208 #endif
1209
ystdex::class_allocator::allocate
_type * allocate(size_t n)
Definition: memory.hpp:229
ystdex::temporary_buffer::pointer
std::unique_ptr< _type, deleter > pointer
Definition: memory.hpp:467
ystdex::details::rebind_t
typename _tAlloc::template rebind< _type >::other rebind_t
Definition: memory.hpp:76
ystdex::temporary_buffer_delete
使用显式 std::return_temporary_buffer 的删除器。
Definition: memory.hpp:439
ystdex::details::mem_delete_t
decltype(_type::operator delete(std::declval< _tParams >()...)) mem_delete_t
Definition: memory.hpp:98
ystdex::free_delete< _type[]>::operator()
void operator()(_type2 *p) const
Definition: memory.hpp:423
ystdex::class_allocator
类分配器。
Definition: memory.hpp:222
ystdex::reset
bool reset(std::unique_ptr< _type, _tDeleter > &p)
Definition: memory.hpp:708
ystdex::details::mem_new_t
decltype(_type::operator new(std::declval< _tParams >()...)) mem_new_t
Definition: memory.hpp:94
ystdex::true_
bool_< true > true_
Definition: type_traits.hpp:391
ystdex::has_mem_new
Definition: memory.hpp:110
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:680
ystdex::share_forward
std::shared_ptr< decay_t< _type > > share_forward(_tValue &&v)
传递值创建对应的 std::shared_ptr 实例的对象。
Definition: memory.hpp:981
v
byte v
Definition: CharRenderer.cpp:75
ystdex::share_copy
std::shared_ptr< decay_t< _type > > share_copy(const _tValue &v)
复制值创建对应的 std::shared_ptr 实例的对象。
Definition: memory.hpp:971
ystdex::temporary_buffer::get_pointer_ref
pointer & get_pointer_ref()
Definition: memory.hpp:497
ystdex::deleter_member_pointer_t
typename remove_reference_t< _tDeleter >::pointer deleter_member_pointer_t
取删除器的 pointer 成员类型。
Definition: memory.hpp:519
ystdex::owns_unique_nonnull
bool owns_unique_nonnull(const _type &)
Definition: memory.hpp:668
ystdex::has_mem_delete
Definition: memory.hpp:114
platform::size_t
YF_API size_t
Definition: FileIO.h:1353
ystdex::details::pack_obj_impl< std::shared_ptr< _type > >::pack
static std::shared_ptr< _type > pack(_tParams &&...args)
Definition: memory.hpp:320
ystdex::nested_allocator
取嵌套成员分配器类型，若不存在则使用第二模板参数指定的默认类型。
Definition: memory.hpp:144
ystdex::make_weak
std::weak_ptr< _type > make_weak(const std::shared_ptr< _type > &p)
使用指定的 std::shared_ptr 实例的对象创建对应的 std::weak_ptr 实例的对象。
Definition: memory.hpp:956
ystdex::object_pack::pack
pack_type pack
Definition: memory.hpp:1160
ystdex::false_
bool_< false > false_
Definition: type_traits.hpp:392
ystdex::clone_polymorphic
auto clone_polymorphic(const _type &v) -> decltype(v.clone())
使用 clone 成员函数复制多态类类型对象。
Definition: memory.hpp:1115
platform::bool
std::FILE *fp bool
Definition: FileIO.h:1280
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:262
ystdex::is_class_type
判断指定类型是否是类类型。
Definition: type_traits.hpp:795
ystdex::details::try_create_with_allocator_impl
_type * try_create_with_allocator_impl(void *, _tAlloc &, _tParams &&...)
Definition: memory.hpp:278
ystdex::cpp2014::enable_if_t
typename enable_if< _bCond, _type >::type enable_if_t
Definition: type_traits.hpp:343
ystdex::cpp2014::make_unique
enable_if_t<!is_array< _type >::value, std::unique_ptr< _type > > make_unique(_tParams &&...args)
使用 new 和指定参数构造指定类型的 std::unique_ptr 对象。
Definition: memory.hpp:852
ystdex::make_shared
std::shared_ptr< _type > make_shared(std::initializer_list< _tValue > il)
使用指定类型的初始化列表构造指定类型的 std::shared_ptr 对象。
Definition: memory.hpp:945
CHRLib::args
_tParams && args
Definition: CharacterProcessing.h:538
ystdex::unique_raw
std::unique_ptr< _type > unique_raw(_pSrc *p)
Definition: memory.hpp:740
ystdex::cpp2014::remove_extent_t
typename remove_extent< _type >::type remove_extent_t
Definition: type_traits.hpp:316
ystdex::owns_nonnull
bool owns_nonnull(_type *const &p)
Definition: memory.hpp:609
ystdex::is_reference_wrapper
判断模板参数指定的类型是否。
Definition: ref.hpp:161
ystdex::details::pack_obj_impl::pack
static _type pack(_tParams &&...args)
Definition: memory.hpp:298
ystdex::make_unique
std::unique_ptr< _type > make_unique(std::initializer_list< _tValue > il)
使用指定类型的初始化列表构造指定类型的 std::unique_ptr 对象。
Definition: memory.hpp:903
ystdex::details::is_copy_constructible_class
and_< is_copy_constructible< _type >, is_class_type< _type >> is_copy_constructible_class
Definition: memory.hpp:71
ystdex::temporary_buffer::element_type
_type element_type
Definition: memory.hpp:465
std::hash< ystdex::observer_ptr< _type > >::operator()
size_t operator()(const ystdex::observer_ptr< _type > &p) const
Definition: memory.hpp:1199
ystdex::unique_ptr_pointer
detected_or_t< _type *, deleter_member_pointer_t, _tDeleter > unique_ptr_pointer
取 unique_ptr 包装的指针类型。
Definition: memory.hpp:524
ystdex::dynamic_pointer_cast
std::unique_ptr< _tDst > dynamic_pointer_cast(std::unique_ptr< _type > &p)
Definition: memory.hpp:1021
ystdex::temporary_buffer::array_type
_type[] array_type
Definition: memory.hpp:464
ystdex::class_allocator::deallocate
void deallocate(_type *p, size_t)
Definition: memory.hpp:236
YSLib::a
YB_PURE const _type * a
Definition: YCoreUtilities.h:167
ystdex::detected_or_t
_t< detected_or< _tDefault, _gOp, _tParams... >> detected_or_t
Definition: type_traits.hpp:719
ystdex::allocator_delete::pointer
typename traits::pointer pointer
Definition: memory.hpp:161
ystdex::indirect_element_t
remove_reference_t< indirect_t< _type >> indirect_element_t
Definition: type_traits.hpp:1042
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:766
ystdex::object_pack::pack_type
_tPack pack_type
Definition: memory.hpp:1157
ystdex::free_delete::operator()
void operator()(_type *p) const
Definition: memory.hpp:400
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:140
ystdex
特性测试宏。
Definition: ydef.h:822
ystdex::object_pack::object_pack
object_pack(_tParams &&...args)
Definition: memory.hpp:1165
ystdex::free_delete< _type[]>::free_delete
free_delete(const free_delete< _type2[]> &)
Definition: memory.hpp:417
ystdex::cond_or
cond_t< _tCond, vdefer< _gOp, _tParams... >, _tDefault > cond_or
条件判断，若失败使用默认类型。
Definition: type_op.hpp:319
std::hash
ystdex::observer_ptr 散列支持。
Definition: memory.hpp:1193
ystdex::free_delete
使用显式析构函数调用和 std::free 的删除器。
Definition: memory.hpp:390
ystdex::details::nested_allocator_t
typename _type::allocator_type nested_allocator_t
Definition: memory.hpp:87
ref.hpp
引用包装。
type_op.hpp
C++ 类型操作。
ystdex::static_pointer_cast
std::unique_ptr< _tDst > static_pointer_cast(std::unique_ptr< _type > p)
智能指针转换。
Definition: memory.hpp:1007
ystdex::defer_element
cond_or< not_< is_void< remove_pointer_t< _tPointer >>>, _tDefault, indirect_element_t, _tPointer > defer_element
取指针对应的元素类型。
Definition: memory.hpp:533
ystdex::allocator_delete::size
size_type size
Definition: memory.hpp:166
exception.h
ystdex::is_allocatable
判断类型是否符合分配器要求的目标类型。
Definition: memory.hpp:125
pointer.hpp
通用指针。
ystdex::try_create_with_allocator
_type * try_create_with_allocator(_tAlloc &&a, _tParams &&...args)
尝试调用 ystdex::create_with_allocator 表达式创建对象。
Definition: memory.hpp:349
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:786
ystdex::details::pack_obj_impl
Definition: memory.hpp:294
ystdex::has_nested_allocator
判断类型具有嵌套的成员 allocator_type 指称一个可复制构造的类类型。
Definition: memory.hpp:134
ystdex::clone_monomorphic_ptr
auto clone_monomorphic_ptr(const _tPointer &p) -> decltype(ystdex::clone_monomorphic(*p))
若指针非空，使用 new 复制指针指向的对象。
Definition: memory.hpp:1091
CHRLib::CharSet::other
Definition: Encoding.h:65
ystdex::nullptr_t
空指针类。
Definition: ydef.h:861
ystdex::allocator_delete::traits
std::allocator_traits< _tAlloc > traits
Definition: memory.hpp:158
ystdex::local_allocator
cond_t< and_< has_mem_new< _type, size_t >, has_mem_delete< _type * >>, class_allocator< _type >, std::allocator< _type >> local_allocator
局部分配器。
Definition: memory.hpp:251
std
Definition: memory.hpp:1183
ystdex::is_nonconst_object
判断类型是否为非 const 对象类型。
Definition: type_traits.hpp:805
ystdex::make_unique_with
enable_if_t<!is_array< _type >::value, std::unique_ptr< _type > > make_unique_with(_tDeleter &&d)
Definition: memory.hpp:915
ystdex::allocator_delete::alloc_ref
_tAlloc & alloc_ref
Definition: memory.hpp:165
placement.hpp
放置对象管理操作。
ystdex::owns_unique
bool owns_unique(const _type &)
Definition: memory.hpp:641
ystdex::class_allocator::class_allocator
class_allocator()=default
ystdex::allocator_delete::allocator_delete
allocator_delete(_tAlloc &alloc, size_type s)
Definition: memory.hpp:169
ystdex::object_pack
打包的对象：使用 pack_object 得到的对象包装。
Definition: memory.hpp:1153
YB_NORETURN
#define YB_NORETURN
指定无返回值函数。
Definition: ydef.h:504
ystdex::make_allocator_guard
std::unique_ptr< _tAlloc, allocator_delete< _tAlloc > > make_allocator_guard(_tAlloc &a, typename std::allocator_traits< _tAlloc >::size_type n=1)
构造分配器守护。
Definition: memory.hpp:187
ystdex::allocator_delete::operator()
void operator()(pointer p) const
Definition: memory.hpp:174
ystdex::throw_invalid_construction
void throw_invalid_construction()
Definition: ystdex/exception.cpp:49
ystdex::temporary_buffer::operator=
temporary_buffer & operator=(temporary_buffer &&)=default
ystdex::get_raw
_type * get_raw(_type *const &p)
Definition: memory.hpp:544
ystdex::pack_object
auto pack_object(_tParams &&...args) -> decltype(details::pack_obj_impl< _type >::pack(std::forward< decltype(args)>(args)...))
打包对象：通过指定参数构造对象。
Definition: memory.hpp:1144
ystdex::owns_any
bool owns_any(_type *const &p)
Definition: memory.hpp:577
ystdex::const_pointer_cast
std::unique_ptr< _tDst > const_pointer_cast(std::unique_ptr< _type > p)
Definition: memory.hpp:1056
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 传递对应参数。
Definition: ydef.h:995
ystdex::share_raw
std::shared_ptr< _type > share_raw(_type *p, _tParams &&...args)
Definition: memory.hpp:787
ystdex::clone_polymorphic_ptr
auto clone_polymorphic_ptr(const _tPointer &p) -> decltype(clone_polymorphic(*p))
若指针非空，使用 clone 成员函数复制指针指向的多态类类型对象。
Definition: memory.hpp:1125
ystdex::temporary_buffer::buf
std::pair< pointer, size_t > buf
Definition: memory.hpp:470
ystdex::enable_if_convertible_t
enable_if_t< is_convertible< _tFrom, _tTo >::value, _type > enable_if_convertible_t
Definition: type_traits.hpp:1052
ystdex::is_detected
typename details::detector< nonesuch, void, _gOp, _tParams... >::value_t is_detected
Definition: type_traits.hpp:708
ystdex::is_sharing
判断指定类型是否为已知的持有共享所有权的对象类型。
Definition: memory.hpp:366
CHRLib::d
_tDst * d
Definition: CharacterProcessing.h:139
ystdex::observer_ptr
观察者指针：无所有权的智能指针。
Definition: pointer.hpp:201
ystdex::clone_monomorphic
_type * clone_monomorphic(const _type &v)
使用 new 复制对象。
Definition: memory.hpp:1075
ystdex::create_with_allocator
auto create_with_allocator(_tAlloc &&a, _tParams &&...args) -> decltype(ystdex::make_allocator_guard(a).release())
使用分配器创建对象。
Definition: memory.hpp:202
ystdex::size
auto size(const _tRange &c) -> decltype(c.size())
类容器访问。
Definition: range.hpp:233
ystdex::make_unique_default_init
enable_if_t<!is_array< _type >::value, std::unique_ptr< _type > > make_unique_default_init()
Definition: memory.hpp:879
ystdex::temporary_buffer::temporary_buffer
temporary_buffer(size_t n)
Definition: memory.hpp:474
ystdex::allocator_delete::size_type
typename traits::size_type size_type
Definition: memory.hpp:162
ystdex::temporary_buffer
临时缓冲区。
Definition: memory.hpp:461
yconstraint
#define yconstraint(_expr)
约束：接口语义。
Definition: cassert.h:88
ystdex::and_
逻辑操作元函数。
Definition: type_traits.hpp:420
ystdex::free_delete::free_delete
free_delete()=default
ystdex::object_pack::value_type
_type value_type
Definition: memory.hpp:1156
ystdex::details::pack_obj_impl< std::unique_ptr< _type, _tDeleter > >::pack
static std::unique_ptr< _type > pack(_tParams &&...args)
Definition: memory.hpp:309
ystdex::temporary_buffer::size
size_t size() const
Definition: memory.hpp:503
ystdex::share_move
std::shared_ptr< decay_t< _type > > share_move(_tValue &&v)
转移值创建对应的 std::shared_ptr 实例的对象。
Definition: memory.hpp:991
ystdex::details::try_new_impl
_type * try_new_impl(void *, _tParams &&...)
Definition: memory.hpp:262
ystdex::try_new
_type * try_new(_tParams &&...args)
尝试调用 new 表达式创建对象。
Definition: memory.hpp:338
ystdex::allocator_delete
释放分配器的删除器。
Definition: memory.hpp:155
ystdex::temporary_buffer_delete< _type[]>::operator()
void operator()(_type *p) const
Definition: memory.hpp:447
CHRLib::p
const auto p(d)
ystdex::free_delete::free_delete
free_delete(const free_delete< _type2 > &)
Definition: memory.hpp:395