YSTest: allocator.hpp 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

allocator.hpp
浏览该文件的文档.
1 /*
2 © 2014-2020 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_allocator_hpp_
31 #define YB_INC_ystdex_allocator_hpp_ 1
32
33 #include "placement.hpp" // for internal "placement.hpp", <memory>,
34 // std::pair, false_, true_, std::allocator_arg, is_constructible, not_, and_,
35 // is_explicitly_constructible, is_implicitly_constructible, enable_if_t,
36 // detected_or_t, is_unqualified_object, is_copy_constructible, is_class_type,
37 // is_same, std::pointer_traits, std::declval, is_detected, detected_t,
38 // is_detected_exact, cond, remove_cvref_t, bool_, is_lvalue_reference,
39 // exclude_self_t;
40 #include "apply.hpp" // for std::tuple, std::forward_as_tuple,
41 // std::piecewise_construct_t, std::piecewise_construct, std::make_tuple,
42 // ystdex::apply;
43 #include "type_op.hpp" // for internal "type_op.hpp", cond_or_t;
44 #include "pointer.hpp" // for ystdex::swap_dependent, ystdex::to_address;
45 #include "exception.h" // for throw_invalid_construction;
46
56 #ifndef __cpp_lib_allocator_traits_is_always_equal
57 # if YB_IMPL_MSCPP >= 1900 || __cplusplus >= 201411L
58 # define __cpp_lib_allocator_traits_is_always_equal 201411L
59 # endif
60 #endif
61
62
69 namespace ystdex
70 {
71
73 #if __cpp_lib_allocator_traits_is_always_equal >= 201411L \
74 || __cplusplus >= 201411L
75 # define YB_Impl_Has_allocator_traits_is_always_equal true
76 #else
77 # define YB_Impl_Has_allocator_traits_is_always_equal false
78 #endif
79
80
81 #if __cplusplus > 201703L && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20190731)
82 // XXX: See https://github.com/cplusplus/draft/issues/3111.
83 // XXX: See https://gcc.gnu.org/viewcvs/gcc/trunk/libstdc++-v3/include/std/memory?r1=273515&r2=273945.
85
86 using std::uses_allocator_construction_args;
87 using std::make_obj_using_allocator;
88 using std::uninitialized_construct_using_allocator;
90 #else
91
96 namespace details
97 {
98
99 template<typename _type>
100 struct is_pair : false_
101 {};
102
103 template<typename _type1, typename _type2>
104 struct is_pair<std::pair<_type1, _type2>> : true_
105 {};
106
107
108 template<typename _type, class _tAlloc>
109 struct pair_has_allocator : std::uses_allocator<_type, _tAlloc>
110 {};
111
112 template<typename _type1, typename _type2, class _tAlloc>
113 struct pair_has_allocator<std::pair<_type1, _type2>, _tAlloc>
114 : or_<pair_has_allocator<_type1, _tAlloc>,
115 pair_has_allocator<_type2, _tAlloc>>
116 {};
117
118 template<typename, class, typename...>
119 struct uaca_res;
120
121 template<typename _type, class _tAlloc, typename... _tParams>
122 using uaca_res_t = _t<uaca_res<_type, _tAlloc, _tParams...>>;
123
124 template<typename _type, class _tAlloc>
125 struct uaa_func
126 {
127 const _tAlloc& a;
128
129 template<typename... _tParams>
130 YB_ATTR_nodiscard YB_FLATTEN inline auto
131 operator()(_tParams&&...) const -> uaca_res_t<_type, _tAlloc, _tParams...>;
132 };
133
134
135 template<typename, class _bPair, class _bPfx, class _tAlloc,
136 typename... _tParams>
137 YB_ATTR_nodiscard YB_FLATTEN inline std::tuple<_tParams&&...>
138 uses_allocator_args(_bPair, false_, _bPfx, const _tAlloc&, _tParams&&... args)
139 {
140 return std::forward_as_tuple(yforward(args)...);
141 }
142 template<typename, class _tAlloc, typename... _tParams>
143 YB_ATTR_nodiscard YB_FLATTEN inline
144 std::tuple<const std::allocator_arg_t&, const _tAlloc&, _tParams&&...>
145 uses_allocator_args(false_, true_, true_, const _tAlloc& a, _tParams&&... args)
146 {
147 return std::forward_as_tuple(std::allocator_arg, a, yforward(args)...);
148 }
149 template<typename, class _tAlloc, typename... _tParams>
150 YB_ATTR_nodiscard YB_FLATTEN inline
151 std::tuple<_tParams&&..., const _tAlloc&>
152 uses_allocator_args(false_, true_, false_, const _tAlloc& a, _tParams&&... args)
153 {
154 return std::forward_as_tuple(yforward(args)..., a);
155 }
156 template<class _type, class _tAlloc>
157 YB_ATTR_nodiscard YB_FLATTEN inline auto
158 uses_allocator_args(true_, true_, false_, const _tAlloc&)
159 -> uaca_res_t<_type, _tAlloc, const std::piecewise_construct_t&,
160 std::tuple<>, std::tuple<>>;
161 template<typename _type, class _tAlloc, typename _type1, typename _type2>
162 YB_ATTR_nodiscard YB_FLATTEN inline auto
163 uses_allocator_args(true_, true_, false_, const _tAlloc&,
164 const std::pair<_type1, _type2>&)
165 -> uaca_res_t<_type, _tAlloc, const std::piecewise_construct_t&,
166 std::tuple<const _type1&>, std::tuple<const _type2&>>;
167 template<typename _type, class _tAlloc, typename _type1, typename _type2>
168 YB_ATTR_nodiscard YB_FLATTEN inline auto
169 uses_allocator_args(true_, true_, false_, const _tAlloc& a,
170 std::pair<_type1, _type2>&&)
171 -> uaca_res_t<_type, _tAlloc, const std::piecewise_construct_t&,
172 std::tuple<_type1&&>, std::tuple<_type2&&>>;
173 template<typename _type, class _tAlloc, typename _type1, typename _type2>
174 YB_ATTR_nodiscard YB_FLATTEN inline auto
175 uses_allocator_args(true_, true_, false_, const _tAlloc& a, _type1&&, _type2&&)
176 -> uaca_res_t<_type, _tAlloc, const std::piecewise_construct_t&,
177 std::tuple<_type1&&>, std::tuple<_type2&&>>;
179 template<typename _type, class _tAlloc, class _tTuple1, class _tTuple2>
180 YB_ATTR_nodiscard YB_FLATTEN inline auto
181 uses_allocator_args(true_, true_, false_, const _tAlloc& a,
182 std::piecewise_construct_t, _tTuple1&& x, _tTuple2&& y) -> decltype(
183 std::make_tuple(std::piecewise_construct, ystdex::apply(
184 uaa_func<remove_cv_t<typename _type::first_type>, _tAlloc>{a}, yforward(x)),
185 ystdex::apply(uaa_func<remove_cv_t<typename _type::second_type>,
186 _tAlloc>{a}, yforward(y))))
187 {
188 return std::make_tuple(std::piecewise_construct, ystdex::apply(uaa_func<
189 remove_cv_t<typename _type::first_type>, _tAlloc>{a}, yforward(x)),
190 ystdex::apply(uaa_func<remove_cv_t<typename _type::second_type>,
191 _tAlloc>{a}, yforward(y)));
192 }
193
194 } // unnamed namespace details;
195
196 // XXX: Blocked. 'yforward' in the trailing-return-type cause G++ 5.3 20151204
197 // crash: internal compiler error: Segmentation fault.
198 template<typename _type, class _tAlloc, typename... _tParams>
199 YB_ATTR_nodiscard YB_FLATTEN inline auto
200 uses_allocator_construction_args(const _tAlloc& a, _tParams&&... args) -> yimpl(
201 decltype(details::uses_allocator_args<_type>(details::is_pair<_type>(),
202 details::pair_has_allocator<_type, _tAlloc>(), is_constructible<_type,
203 std::allocator_arg_t, _tAlloc, _tParams...>(), a,
204 std::forward<_tParams&&>(args)...)))
205 {
206 return details::uses_allocator_args<_type>(details::is_pair<_type>(),
207 details::pair_has_allocator<_type, _tAlloc>(), is_constructible<_type,
208 std::allocator_arg_t, _tAlloc, _tParams...>(), a, yforward(args)...);
209 }
210
211 namespace details
212 {
213
214 template<typename _type, class _tAlloc, typename... _tParams>
215 struct uaca_res
216 {
217 using type = decltype(ystdex::uses_allocator_construction_args<_type>(
218 std::declval<const _tAlloc&>(), std::declval<_tParams>()...));
219 };
220
221 template<typename _type, class _tAlloc>
222 template<typename... _tParams>
223 YB_ATTR_nodiscard YB_FLATTEN inline auto
224 uaa_func<_type, _tAlloc>::operator()(_tParams&&... args) const
225 -> uaca_res_t<_type, _tAlloc, _tParams...>
226 {
227 return
228 ystdex::uses_allocator_construction_args<_type>(a, yforward(args)...);
229 }
230
231 template<class _type, class _tAlloc>
232 YB_ATTR_nodiscard YB_FLATTEN inline auto
233 uses_allocator_args(true_, true_, false_, const _tAlloc& a) -> uaca_res_t<_type,
234 _tAlloc, const std::piecewise_construct_t&, std::tuple<>, std::tuple<>>
235 {
236 return ystdex::uses_allocator_construction_args<_type>(a,
237 std::piecewise_construct, std::tuple<>(), std::tuple<>());
238 }
239 template<typename _type, class _tAlloc, typename _type1, typename _type2>
240 YB_ATTR_nodiscard YB_FLATTEN inline auto
241 uses_allocator_args(true_, true_, false_, const _tAlloc& a,
242 const std::pair<_type1, _type2>& arg)
243 -> uaca_res_t<_type, _tAlloc, const std::piecewise_construct_t&,
244 std::tuple<const _type1&>, std::tuple<const _type2&>>
245 {
246 return ystdex::uses_allocator_construction_args<_type>(a,
247 std::piecewise_construct, std::forward_as_tuple(arg.first),
248 std::forward_as_tuple(arg.second));
249 }
250 template<typename _type, class _tAlloc, typename _type1, typename _type2>
251 YB_ATTR_nodiscard YB_FLATTEN inline auto
252 uses_allocator_args(true_, true_, false_, const _tAlloc& a,
253 std::pair<_type1, _type2>&& arg)
254 -> uaca_res_t<_type, _tAlloc, const std::piecewise_construct_t&,
255 std::tuple<_type1&&>, std::tuple<_type2&&>>
256 {
257 return ystdex::uses_allocator_construction_args<_type>(a,
258 std::piecewise_construct, std::forward_as_tuple(yforward(arg.first)),
259 std::forward_as_tuple(yforward(arg.second)));
260 }
261 template<typename _type, class _tAlloc, typename _type1, typename _type2>
262 YB_ATTR_nodiscard YB_FLATTEN inline auto
263 uses_allocator_args(true_, true_, false_, const _tAlloc& a, _type1&& arg1,
264 _type2&& arg2)
265 -> uaca_res_t<_type, _tAlloc, const std::piecewise_construct_t&,
266 std::tuple<_type1&&>, std::tuple<_type2&&>>
267 {
268 return ystdex::uses_allocator_construction_args<_type>(a,
269 std::piecewise_construct, std::forward_as_tuple(yforward(arg1)),
270 std::forward_as_tuple(yforward(arg2)));
271 }
272
273 template<typename _type, class _tAlloc>
274 struct ucua_func
275 {
276 void* pv;
277
278 template<typename... _tParams>
279 _type*
280 operator()(_tParams&&... args) const
281 ynoexcept(is_nothrow_constructible<_type, _tParams...>())
282 {
283 return ::new(pv) _type(yforward(args)...);
284 }
285 };
286
287 // TODO: Detect more implemenations?
288 // XXX: This is a workaround to implementation without support of WG21 N4387.
289 # if (defined(__GLIBCXX__) && (__GLIBCXX__ <= 20150630 \
290 || YB_IMPL_GNUCPP < 60000)) && !(_LIBCPP_VERSION > 4000 \
291 || __cplusplus >= 201703L)
292 // NOTE: See See https://gcc.gnu.org/viewcvs/gcc/trunk/libstdc++-v3/include/bits/stl_pair.h?r1=225189&r2=225188&pathrev=225189,
293 // and https://reviews.llvm.org/rL276605.
294 template<typename _type1, typename _type2, class _tAlloc>
295 struct ucua_func<std::pair<_type1, _type2>, _tAlloc>
296 {
297 void* pv;
298
299 template<typename... _tParams>
300 auto
301 operator()(_tParams&&... args) const
302 -> decltype(::new(pv) std::pair<_type1, _type2>(yforward(args)...))
303 {
304 return ::new(pv) std::pair<_type1, _type2>(yforward(args)...);
305 }
306 template<typename _tParam1, typename _tParam2>
307 enable_if_t<and_<not_<is_constructible<_tParam1, _tParam2>>,
308 is_explicitly_constructible<_type1, _tParam1>,
309 is_implicitly_constructible<_type2, _tParam2>>::value,
310 std::pair<_type1, _type2>*>
311 operator()(_tParam1&& arg1, _tParam2&& arg2) const
312 {
313 return ::new(pv)
314 std::pair<_type1, _type2>(_type1(arg1), yforward(arg2));
315 }
316 template<typename _tParam1, typename _tParam2>
317 enable_if_t<and_<not_<is_constructible<_tParam1, _tParam2>>,
318 is_implicitly_constructible<_type1, _tParam1>,
319 is_explicitly_constructible<_type2, _tParam2>>::value,
320 std::pair<_type1, _type2>*>
321 operator()(_tParam1&& arg1, _tParam2&& arg2) const
322 {
323 return ::new(pv)
324 std::pair<_type1, _type2>(yforward(arg1), _type2(arg2));
325 }
326 template<typename _tParam1, typename _tParam2>
327 enable_if_t<and_<not_<is_constructible<_tParam1, _tParam2>>,
328 is_explicitly_constructible<_type1, _tParam1>,
329 is_explicitly_constructible<_type2, _tParam2>>::value,
330 std::pair<_type1, _type2>*>
331 operator()(_tParam1&& arg1, _tParam2&& arg2) const
332 {
333 return ::new(pv)
334 std::pair<_type1, _type2>(_type1(arg1), _type2(arg2));
335 }
336 };
337 # endif
338
339 } // namespace details;
340
341 template<typename _type, class _tAlloc, typename... _tParams>
342 YB_ATTR_nodiscard _type
343 make_obj_using_allocator(const _tAlloc& a, _tParams&&... args)
344 {
345 return ystdex::make_from_tuple<_type>(
346 ystdex::uses_allocator_construction_args<_type>(a, yforward(args)...));
347 }
348
349 template<typename _type, class _tAlloc, typename... _tParams>
350 _type*
351 uninitialized_construct_using_allocator(_type* p, const _tAlloc& a,
352 _tParams&&... args)
353 {
354 return ystdex::apply(details::ucua_func<_type, _tAlloc>{p},
355 ystdex::uses_allocator_construction_args<_type>(a, yforward(args)...));
356 }
358 #endif
359
360
362 namespace details
363 {
364
366
367 #if !YB_Impl_Has_allocator_traits_is_always_equal
368 template<typename _type, typename... _tParams>
369 using mem_is_always_equal_t = typename _type::is_always_equal;
370 #endif
371
372
373 } // namespace details;
374
376 inline namespace cpp2017
377 {
378
379 #if YB_Impl_Has_allocator_traits_is_always_equal
380 using std::allocator_traits;
381 #else
382 template<class _tAlloc>
383 struct allocator_traits : std::allocator_traits<_tAlloc>
384 {
385 using is_always_equal = detected_or_t<is_empty<_tAlloc>,
386 details::mem_is_always_equal_t, _tAlloc>;
387 };
388 #endif
389
390 } // inline namespace cpp2017;
391
392
397 template<class _tAlloc>
398 using alloc_value_t = typename allocator_traits<_tAlloc>::value_type;
399
401
402 template<class _tAlloc>
403 using alloc_pointer_t = typename allocator_traits<_tAlloc>::pointer;
404
405 template<class _tAlloc>
406 using alloc_const_pointer_t = typename allocator_traits<_tAlloc>::const_pointer;
407
408 template<class _tAlloc>
409 using alloc_size_type_t = typename allocator_traits<_tAlloc>::size_type;
410
411 template<class _tAlloc>
412 using alloc_difference_type_t
413 = typename allocator_traits<_tAlloc>::difference_type;
415
421 template<class _tAlloc, typename _type>
422 using rebind_alloc_t
423 = typename allocator_traits<_tAlloc>::template rebind_alloc<_type>;
424
425 template<class _tAlloc, typename _type>
426 using rebind_traits_t
427 = typename allocator_traits<_tAlloc>::template rebind_traits<_type>;
429
430
438 template<typename _type>
439 struct is_allocatable : is_unqualified_object<_type>
440 {};
441
442
444 namespace details
445 {
446
448
449 template<typename _type, typename... _tParams>
450 using mem_new_t
451 = decltype(_type::operator new(std::declval<_tParams>()...));
452
453 template<typename _type, typename... _tParams>
454 using mem_delete_t
455 = decltype(_type::operator delete(std::declval<_tParams>()...));
457
458 template<typename _type>
459 using is_copy_constructible_class
460 = and_<is_copy_constructible<_type>, is_class_type<_type>>;
461
463
464 template<class _tAlloc>
465 using mem_pointer_t = typename _tAlloc::pointer;
466
467 template<class _tAlloc>
468 using mem_const_pointer_t = typename _tAlloc::const_pointer;
469
470 template<class _tAlloc>
471 using mem_const_pointer_conv_t = is_convertible<mem_pointer_t<_tAlloc>,
472 mem_const_pointer_t<_tAlloc>>;
473
474 template<class _tAlloc>
475 using mem_void_pointer_t = typename _tAlloc::void_pointer;
476
477 template<class _tAlloc>
478 using mem_void_pointer_conv_t = is_convertible<mem_pointer_t<_tAlloc>,
479 mem_void_pointer_t<_tAlloc>>;
480
481 template<class _tAlloc>
482 using mem_const_void_pointer_t = typename _tAlloc::const_void_pointer;
483
484 template<class _tAlloc>
485 using mem_const_void_pointer_conv_t = and_<is_convertible<mem_pointer_t<
486 _tAlloc>, mem_const_void_pointer_t<_tAlloc>>,
487 is_convertible<mem_const_pointer_t<_tAlloc>,
488 mem_const_void_pointer_t<_tAlloc>>, is_convertible<
489 mem_void_pointer_t<_tAlloc>, mem_const_void_pointer_t<_tAlloc>>>;
490
491 template<class _tAlloc>
492 using same_pointer_to_test_t
493 = is_same<decltype(std::pointer_traits<mem_pointer_t<_tAlloc>>::pointer_to(
494 *std::declval<mem_pointer_t<_tAlloc>>())), mem_pointer_t<_tAlloc>>;
495
496 template<class _tAlloc>
497 using same_pointer_to_t = cond_or_t<is_detected<mem_pointer_t, _tAlloc>, true_,
498 same_pointer_to_test_t, _tAlloc>;
499
500 template<class _tAlloc>
501 using mem_allocate_t = decltype(std::declval<_tAlloc&>().allocate(size_t(0)));
502
503 template<class _tAlloc, typename _tPointer = decltype(
504 std::declval<typename allocator_traits<_tAlloc>::const_void_pointer>())>
505 using ator_allocate_hint_t = decltype(allocator_traits<_tAlloc>::allocate(
506 std::declval<_tAlloc&>(), size_t(0), std::declval<_tPointer>()));
507
508 template<class _tAlloc>
509 using mem_deallocate_t = decltype(std::declval<_tAlloc&>().deallocate(
510 std::declval<mem_allocate_t<_tAlloc>>(), size_t(0)));
511
512 template<class _tAlloc>
513 using ator_max_size_t
514 = decltype(allocator_traits<_tAlloc>::max_size(std::declval<_tAlloc&>()));
515
516 // XXX: The member %details::mem_value_type_t is in %type_op.hpp.
517 template<class _type, typename _tPointer = detected_t<alloc_pointer_t,
518 _type>, typename _tSize = detected_t<alloc_size_type_t, _type>,
519 typename _tDifference = detected_t<alloc_difference_type_t, _type>>
520 struct check_allocator_members : and_<cond_or_t<is_detected<
521 mem_const_pointer_t, _type>, true_, mem_const_pointer_conv_t, _type>,
522 cond_or_t<is_detected<mem_void_pointer_t, _type>, true_,
523 mem_void_pointer_conv_t, _type>, cond_or_t<is_detected<
524 mem_const_void_pointer_t, _type>, true_, mem_const_void_pointer_conv_t,
525 _type>, is_unsigned<_tSize>, is_signed<_tDifference>,
526 same_pointer_to_t<_type>,
527 is_detected_exact<_tPointer, mem_allocate_t, _type>,
528 is_detected_exact<_tPointer, ator_allocate_hint_t, _type>,
529 is_detected<mem_deallocate_t, _type>,
530 is_detected_exact<_tSize, ator_max_size_t, _type>>
531 {};
532
533 template<typename _type,
534 typename _tValue = detected_or_t<void, mem_value_type_t, _type>>
535 struct is_allocator
536 : cond_or_t<is_allocatable<_tValue>, false_, check_allocator_members, _type>
537 {};
538
539 template<typename _type, typename _tValue>
540 using same_alloc_value_t = is_same<alloc_value_t<_type>, _tValue>;
542
544 template<typename _type>
545 using nested_allocator_t = typename _type::allocator_type;
546
548
549 template<typename _type>
550 using mem_get_allocator_t
551 = decltype(std::declval<const _type&>().get_allocator());
552
553 template<typename _type,
554 typename _tAlloc = remove_cvref_t<mem_get_allocator_t<_type>>>
555 struct check_get_allocator : bool_<is_allocator<_tAlloc>::value
556 && noexcept(std::declval<const _type&>().get_allocator())>
557 {};
559
560 } // namespace details;
561
567 template<typename _type, typename... _tParams>
568 struct has_mem_new : is_detected<details::mem_new_t, _type, _tParams...>
569 {};
570
571 template<typename _type, typename... _tParams>
572 struct has_mem_delete : is_detected<details::mem_delete_t, _type, _tParams...>
573 {};
575
576
594 template<typename _type>
595 struct is_allocator : details::is_allocator<_type>
596 {};
597
598
604 template<typename _type, typename _tValue>
605 struct is_allocator_for : cond_or_t<is_allocator<_type>, false_,
606 details::same_alloc_value_t, _type, _tValue>
607 {};
608
609
614 template<typename _type>
615 struct is_byte_allocator : is_allocator_for<_type, byte>
616 {};
618
619
621
622
627 template<typename _type>
628 struct has_nested_allocator
629 : is_allocator<detected_t<details::nested_allocator_t, _type>>
630 {};
631
632
637 template<typename _type, class _tDefault = std::allocator<_type>>
638 struct nested_allocator : cond<has_nested_allocator<_type>,
639 detected_t<details::nested_allocator_t, _type>, _tDefault>
640 {};
642
643
650 template<class _tCon, bool = has_nested_allocator<_tCon>::value>
651 struct nested_allocator_base
652 {
653 using allocator_type = typename _tCon::allocator_type;
654 };
655
656 template<class _tCon>
657 struct nested_allocator_base<_tCon, false>
658 {};
660
661
667 template<typename _type>
668 struct has_get_allocator : cond_or_t<is_detected<details::mem_get_allocator_t>,
669 false_, details::check_get_allocator, _type>
670 {};
671
672
673 namespace details
674 {
675
677 template<class _tAlloc>
678 class allocator_delete_base
679 {
680 protected:
681 using ator_traits = allocator_traits<remove_cvref_t<_tAlloc>>;
682 using stored_ator_t
683 = cond_t<is_lvalue_reference<_tAlloc>, lref<_tAlloc>, _tAlloc>;
684
686 mutable stored_ator_t alloc;
687
688 template<class _tParam,
689 yimpl(typename = exclude_self_t<allocator_delete_base, _tParam>)>
690 allocator_delete_base(_tParam&& a) ynothrow
691 : alloc(yforward(a))
692 {}
693 allocator_delete_base(const allocator_delete_base&) = default;
694 allocator_delete_base(allocator_delete_base&&) = default;
695
696 allocator_delete_base&
697 operator=(const allocator_delete_base&) = default;
698 allocator_delete_base&
699 operator=(allocator_delete_base&&) = default;
700
702 YB_ATTR_nodiscard YB_PURE _tAlloc&
703 get_allocator() const ynothrow
704 {
705 return alloc;
706 }
707 };
708
709
711
712 template<typename _tAlloc>
713 yconstfn_relaxed void
714 do_alloc_on_copy(_tAlloc&, const _tAlloc&, false_) ynothrow
715 {}
716 template<typename _tAlloc>
717 yconstfn_relaxed void
718 do_alloc_on_copy(_tAlloc& x, const _tAlloc& y, true_) ynoexcept_spec(x = y)
719 {
720 x = y;
721 }
722
723 template<typename _tAlloc>
724 yconstfn_relaxed void
725 do_alloc_on_move(_tAlloc&, _tAlloc&, false_) ynothrow
726 {}
731 template<typename _tAlloc>
732 yconstfn_relaxed void
733 do_alloc_on_move(_tAlloc& x, _tAlloc& y, true_) ynothrow
734 {
735 // NOTE: As per ISO C++17 [allocator.requirements], this shall exit via
736 // an exception.
737 x = std::move(y);
738 }
739
740 template<typename _tAlloc>
741 yconstfn_relaxed void
742 do_alloc_on_swap(_tAlloc&, _tAlloc&, false_) ynothrow
743 {}
744 template<typename _tAlloc>
745 yconstfn_relaxed void
746 do_alloc_on_swap(_tAlloc& x, _tAlloc& y, true_)
747 ynoexcept_spec(ystdex::swap_dependent(x, y))
748 {
749 ystdex::swap_dependent(x, y);
750 }
752
753 } // namespace details;
754
755
765 template<class _tAlloc>
766 class allocator_guard_delete : private details::allocator_delete_base<_tAlloc>
767 {
768 private:
770 using base = details::allocator_delete_base<_tAlloc>;
772 using typename base::ator_traits;
773
774 public:
776 using pointer = typename ator_traits::pointer;
778 using size_type = typename ator_traits::size_type;
779
780 private:
782 size_type count;
783
784 public:
786 allocator_guard_delete(_tAlloc a, size_type n = 1) ynothrow
787 : base(yforward(a)), count(n)
788 {}
789 allocator_guard_delete(const allocator_guard_delete&) = default;
790 allocator_guard_delete(allocator_guard_delete&&) = default;
791
792 allocator_guard_delete&
793 operator=(const allocator_guard_delete&) = default;
794 allocator_guard_delete&
795 operator=(allocator_guard_delete&&) = default;
796
798 void
799 operator()(pointer p) const ynothrowv
800 {
801 ator_traits::deallocate(base::alloc, p, count);
802 }
803
805 yimpl(using) base::get_allocator;
806
808 YB_ATTR_nodiscard YB_PURE size_type
809 get_count() const ynothrow
810 {
811 return count;
812 }
813 };
814
815
820 template<class _tAlloc>
821 class allocator_delete : private details::allocator_delete_base<_tAlloc>
822 {
823 private:
825 using base = details::allocator_delete_base<_tAlloc>;
827 using typename base::ator_traits;
828
829 public:
831 using pointer = typename ator_traits::pointer;
832
834 template<class _tParam,
835 yimpl(typename = exclude_self_t<allocator_delete, _tParam>)>
836 allocator_delete(_tParam&& a) ynothrow
837 : base(yforward(a))
838 {}
840
841 allocator_delete(const allocator_delete&) = default;
842 allocator_delete(allocator_delete&&) = default;
843
844 allocator_delete&
845 operator=(const allocator_delete&) = default;
846 allocator_delete&
847 operator=(allocator_delete&&) = default;
849
850 void
851 operator()(pointer p) const ynothrowv
852 {
853 ator_traits::destroy(base::alloc, ystdex::to_address(p));
854 ator_traits::deallocate(base::alloc, p, 1);
855 }
856
858 yimpl(using) base::get_allocator;
859 };
861
862
867 template<class _tAlloc>
868 using allocator_guard
869 = std::unique_ptr<alloc_value_t<_tAlloc>, allocator_guard_delete<_tAlloc>>;
870
871
876 template<class _tAlloc>
877 YB_ATTR_nodiscard inline allocator_guard<_tAlloc>
878 make_allocator_guard(_tAlloc& a,
879 typename allocator_traits<_tAlloc>::size_type n = 1)
880 {
881 return allocator_guard<_tAlloc>(allocator_traits<_tAlloc>::allocate(a, n),
882 allocator_guard_delete<_tAlloc>(a, n));
883 }
884
885
891 template<typename _type, class _tAlloc, typename... _tParams>
892 YB_ATTR_nodiscard auto
893 create_with_allocator(_tAlloc&& a, _tParams&&... args)
894 -> std::unique_ptr<_type, allocator_delete<remove_cvref_t<_tAlloc>>>
895 {
896 using ator_t = remove_cvref_t<_tAlloc>;
897 using ator_del_t = allocator_delete<ator_t>;
898 auto gd(ystdex::make_allocator_guard(a));
899
900 allocator_traits<ator_t>::construct(a, gd.get(), yforward(args)...);
901 return std::unique_ptr<_type, ator_del_t>(gd.release(), ator_del_t(a));
902 }
903
904
910 template<typename _type, class _tAlloc, typename... _tParams>
911 YB_ATTR_nodiscard auto
912 allocate_unique(const _tAlloc& alloc, _tParams&&... args)
913 -> std::unique_ptr<_type, allocator_delete<rebind_alloc_t<_tAlloc, _type>>>
914 {
915 rebind_alloc_t<_tAlloc, _type> a(alloc);
916
917 return ystdex::create_with_allocator<_type>(a, yforward(args)...);
918 }
923 template<typename _type, class _tAlloc, typename _tValue>
924 YB_ATTR_nodiscard auto
925 allocate_unique(const _tAlloc& alloc, std::initializer_list<_tValue> il)
926 -> std::unique_ptr<_type, allocator_delete<rebind_alloc_t<_tAlloc, _type>>>
927 {
928 rebind_alloc_t<_tAlloc, _type> a(alloc);
929
930 return ystdex::create_with_allocator<_type>(a, il);
931 }
932
942 #if __cplusplus > 201703L || (__GLIBCXX__ && !(__GLIBCXX__ <= 20111108))
943 // NOTE: See https://gcc.gnu.org/viewcvs/gcc/trunk/libstdc++-v3/include/bits/shared_ptr_base.h?r1=181171&r2=181170&pathrev=181171.
944 // NOTE: LWG 2070 is not implemented by libc++ yet.
945 using std::allocate_shared;
946 #else
947 template<typename _type, class _tAlloc, typename... _tParams>
948 YB_ATTR_nodiscard std::shared_ptr<_type>
949 allocate_shared(const _tAlloc& alloc, _tParams&&... args)
950 {
951 return std::shared_ptr<_type>(
952 ystdex::allocate_unique<_type>(alloc, yforward(args)...));
953 }
954 #endif
955
959 template<typename _type, class _tAlloc, typename _tValue>
960 YB_ATTR_nodiscard std::shared_ptr<_type>
961 allocate_shared(const _tAlloc& alloc, std::initializer_list<_tValue> il)
962 {
963 return std::shared_ptr<_type>(ystdex::allocate_unique<_type>(alloc, il));
964 }
965
966
978 template<class _type>
979 struct class_allocator : std::allocator<_type>
980 {
981 class_allocator() = default;
982 using std::allocator<_type>::allocator;
983 class_allocator(const class_allocator&) = default;
984
985 YB_ALLOCATOR YB_ATTR_returns_nonnull _type*
986 allocate(size_t n)
987 {
988 return _type::operator new(n * sizeof(_type));
989 }
990
992 void
993 deallocate(_type* p, size_t) ynothrow
994 {
995 // TODO: What if the size hint is supported by %_type?
996 return _type::operator delete(p);
997 }
998 };
999
1000
1006 template<typename _type>
1007 using local_allocator = cond_t<and_<has_mem_new<_type, size_t>,
1008 has_mem_delete<_type*>>, class_allocator<_type>, std::allocator<_type>>;
1010
1011
1013
1014 template<typename _tAlloc>
1016 yconstfn_relaxed void
1017 alloc_on_copy(_tAlloc& x, const _tAlloc& y) ynothrow
1018 {
1019 details::do_alloc_on_copy(x, y, typename allocator_traits<
1020 _tAlloc>::propagate_on_container_copy_assignment());
1021 }
1026 template<typename _tAlloc>
1027 YB_ATTR_nodiscard yconstfn _tAlloc
1028 alloc_on_copy(const _tAlloc& a)
1029 {
1030 // NOTE: As per ISO C++17 [allocator.requirements]/4, this shall not throw
1031 // exceptions.
1032 return allocator_traits<_tAlloc>::select_on_container_copy_construction(a);
1033 }
1034
1036 template<typename _tAlloc>
1037 yconstfn_relaxed void
1038 alloc_on_move(_tAlloc& x, _tAlloc& y) ynothrow
1039 {
1040 // NOTE: As per ISO C++17 [allocator.requirements]/4, this shall not throw
1041 // exceptions. Even without this requirement, it still shall not exit via an
1042 // exception. See %details::do_alloc_on_move for the rationale.
1043 details::do_alloc_on_move(x, y, typename
1044 allocator_traits<_tAlloc>::propagate_on_container_move_assignment());
1045 }
1046
1048 template<typename _tAlloc>
1049 yconstfn_relaxed void
1050 alloc_on_swap(_tAlloc& x, _tAlloc& y) ynothrow
1051 {
1052 // NOTE: As per ISO C++17 [allocator.requirements]/4, this shall not throw
1053 // exceptions.
1054 details::do_alloc_on_swap(x, y,
1055 typename allocator_traits<_tAlloc>::propagate_on_container_swap());
1056 }
1058
1059 #undef YB_Impl_Has_allocator_traits_is_always_equal
1060
1061 } // namespace ystdex;
1062
1063 #endif
1064
ystdex::cond
conditional< _tCond::value, _tThen, _tElse > cond
条件判断。
Definition: meta.hpp:787
ystdex::to_address
auto to_address(const _tPointer &p) -> decltype(details::to_address(p))
转换指针。
Definition: pointer.hpp:96
ystdex::alloc_pointer_t
typename allocator_traits< _tAlloc >::pointer alloc_pointer_t
Definition: allocator.hpp:403
ystdex::allocator_delete::allocator_delete
allocator_delete(const allocator_delete &)=default
YB_ATTR_nodiscard
#define YB_ATTR_nodiscard
标记返回值不被忽略的属性。
Definition: ydef.h:715
ystdex::cpp2017::apply
auto apply(_func &&f, _tTuple &&t) -> decltype(call_projection< _tTuple, make_index_sequence< std::tuple_size< decay_t< _tTuple >>::value >>::apply_invoke(std::forward< decltype(f)>(f), std::forward< decltype(t)>(t)))
应用函数对象和参数元组。
Definition: apply.hpp:199
x
const EncapsulationBase & x
Definition: NPLA1Forms.cpp:1536
ystdex::create_with_allocator
auto create_with_allocator(_tAlloc &&a, _tParams &&... args) -> std::unique_ptr< _type, allocator_delete< remove_cvref_t< _tAlloc >>>
使用分配器创建对象。
Definition: allocator.hpp:893
ystdex::alloc_on_swap
void alloc_on_swap(_tAlloc &x, _tAlloc &y)
按分配器特征在传播容器时交换分配器。
Definition: allocator.hpp:1050
ystdex::allocator_delete::allocator_delete
allocator_delete(_tParam &&a)
Definition: allocator.hpp:836
ystdex::details::is_allocator
Definition: allocator.hpp:537
ystdex::details::mem_const_void_pointer_t
typename _tAlloc::const_void_pointer mem_const_void_pointer_t
Definition: allocator.hpp:482
ystdex::details::is_pair
Definition: allocator.hpp:101
ystdex::details::uaa_func
Definition: allocator.hpp:126
ystdex::details::allocator_delete_base::allocator_delete_base
allocator_delete_base(allocator_delete_base &&)=default
ystdex::lref
左值引用包装。
Definition: ref.hpp:61
YB_PURE
#define YB_PURE
指示函数或函数模板实例为纯函数。
Definition: ydef.h:919
ystdex::class_allocator::deallocate
void deallocate(_type *p, size_t)
Definition: allocator.hpp:993
ystdex::allocate_unique
auto allocate_unique(const _tAlloc &alloc, _tParams &&... args) -> std::unique_ptr< _type, allocator_delete< rebind_alloc_t< _tAlloc, _type >>>
使用分配器创建 std::unique_ptr 。
Definition: allocator.hpp:912
ystdex::class_allocator::class_allocator
class_allocator()=default
ystdex::detected_or_t
_t< detected_or< _tDefault, _gOp, _tParams... > > detected_or_t
Definition: meta.hpp:407
placement.hpp
放置对象管理操作。
ystdex::allocator_delete::allocator_delete
allocator_delete(allocator_delete &&)=default
ystdex::detected_t
_t< details::detector< nonesuch, void, _gOp, _tParams... > > detected_t
Definition: meta.hpp:399
ystdex::details::pair_has_allocator
Definition: allocator.hpp:110
ystdex::cpp2017::allocator_traits
Definition: allocator.hpp:384
ystdex::details::allocator_delete_base::allocator_delete_base
allocator_delete_base(const allocator_delete_base &)=default
YB_FLATTEN
#define YB_FLATTEN
标记函数尽可能内联定义内的调用。
Definition: ydef.h:843
ystdex::details::mem_get_allocator_t
decltype(std::declval< const _type & >().get_allocator()) mem_get_allocator_t
Definition: allocator.hpp:551
ystdex::any_ops::construct
auto construct(any_storage &storage, _tParams &&... args) -> enable_if_t< is_convertible< well_formed_t< decltype(_tHandler::manage), decltype(_tHandler::init(storage, std::forward< decltype(args)>(args)...))>, any_manager >::value, any_manager >
使用指定处理器初始化存储。
Definition: any.h:418
ystdex::allocator_guard_delete::pointer
typename ator_traits::pointer pointer
Definition: allocator.hpp:776
ystdex::details::allocator_delete_base::get_allocator
_tAlloc & get_allocator() const
Definition: allocator.hpp:703
pointer.hpp
通用指针。
ynoexcept_spec
#define ynoexcept_spec(...)
表达式 noexcept 异常规范。
Definition: ydef.h:1181
ystdex::class_allocator::class_allocator
class_allocator(const class_allocator &)=default
ystdex::details::check_allocator_members
Definition: allocator.hpp:531
ystdex::details::allocator_delete_base::stored_ator_t
cond_t< is_lvalue_reference< _tAlloc >, lref< _tAlloc >, _tAlloc > stored_ator_t
Definition: allocator.hpp:683
ystdex::details::uaca_res
Definition: allocator.hpp:119
ystdex::details::mem_const_pointer_conv_t
is_convertible< mem_pointer_t< _tAlloc >, mem_const_pointer_t< _tAlloc > > mem_const_pointer_conv_t
Definition: allocator.hpp:472
ystdex::details::allocator_delete_base::operator=
allocator_delete_base & operator=(allocator_delete_base &&)=default
ystdex::has_get_allocator
判断类型具有返回分配器的无异常抛出的 get_allocator 成员函数。
Definition: allocator.hpp:670
ystdex::details::same_pointer_to_test_t
is_same< decltype(std::pointer_traits< mem_pointer_t< _tAlloc > >::pointer_to(*std::declval< mem_pointer_t< _tAlloc > >())), mem_pointer_t< _tAlloc > > same_pointer_to_test_t
Definition: allocator.hpp:494
ystdex::details::check_get_allocator
Definition: allocator.hpp:557
ystdex::is_byte_allocator
判断类型是 byte 分配器。
Definition: allocator.hpp:616
ystdex::allocator_guard_delete::operator=
allocator_guard_delete & operator=(const allocator_guard_delete &)=default
ystdex::cond_or_t
_t< cond_or< _tCond, _tDefault, _gOp, _tParams... > > cond_or_t
Definition: type_op.hpp:265
ystdex::details::mem_delete_t
decltype(_type::operator delete(std::declval< _tParams >()...)) mem_delete_t
Definition: allocator.hpp:455
ystdex::allocator_guard_delete::size_type
typename ator_traits::size_type size_type
Definition: allocator.hpp:778
yconstfn_relaxed
#define yconstfn_relaxed
指定编译时没有 C++11 限制和隐式成员 const 的常量函数。
Definition: ydef.h:1097
ystdex::swap_dependent
void swap_dependent(_type &x, _type &y)(is_nothrow_swappable< _type >())
支持基于 ystdex_swap::swap 的 ADL 的左值交换。
Definition: swap.hpp:371
ystdex::details::uaa_func::a
const _tAlloc & a
Definition: allocator.hpp:127
ystdex::allocator_guard_delete::allocator_guard_delete
allocator_guard_delete(const allocator_guard_delete &)=default
ystdex::alloc_difference_type_t
typename allocator_traits< _tAlloc >::difference_type alloc_difference_type_t
Definition: allocator.hpp:413
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: allocator.hpp:1008
CHRLib::args
YB_ATTR_nodiscard _tParams && args
Definition: CharacterProcessing.h:649
ystdex::bool_
integral_constant< bool, _vInt > bool_
Definition: integral_constant.hpp:93
ystdex::has_mem_delete
Definition: allocator.hpp:573
ystdex::allocator_delete::operator=
allocator_delete & operator=(const allocator_delete &)=default
ystdex::nested_allocator
取嵌套成员分配器类型，若不存在则使用第二模板参数指定的默认类型。
Definition: allocator.hpp:640
ystdex::details::_type2
_type2
Definition: operators.hpp:241
ystdex::class_allocator::allocate
_type * allocate(size_t n)
Definition: allocator.hpp:986
ystdex::allocator_guard_delete
释放分配器分配的存储资源的删除器。
Definition: allocator.hpp:767
ystdex::alloc_value_t
typename allocator_traits< _tAlloc >::value_type alloc_value_t
Definition: allocator.hpp:398
ystdex::details::nested_allocator_t
typename _type::allocator_type nested_allocator_t
Definition: allocator.hpp:545
ystdex::uses_allocator_construction_args
auto uses_allocator_construction_args(const _tAlloc &a, _tParams &&... args) -> decltype(details::uses_allocator_args< _type >(details::is_pair< _type >(), details::pair_has_allocator< _type, _tAlloc >(), is_constructible< _type, std::allocator_arg_t, _tAlloc, _tParams... >(), a, std::forward< _tParams && >(args)...))
Definition: allocator.hpp:200
ystdex::details::ator_allocate_hint_t
decltype(allocator_traits< _tAlloc >::allocate(std::declval< _tAlloc & >(), size_t(0), std::declval< _tPointer >())) ator_allocate_hint_t
Definition: allocator.hpp:506
YB_ATTR_returns_nonnull
#define YB_ATTR_returns_nonnull
指示返回非空属性。
Definition: ydef.h:761
ystdex::nested_allocator_base< _tSeqCon >::allocator_type
typename _tCon::allocator_type allocator_type
Definition: allocator.hpp:653
ystdex::details::allocator_delete_base::alloc
stored_ator_t alloc
Definition: allocator.hpp:686
YB_ALLOCATOR
#define YB_ALLOCATOR
指示返回指针的函数或函数模板若为非空值则对应的存储不和其它对象指针共享别名。
Definition: ydef.h:785
ystdex::is_unqualified_object
判断类型是否为非 const 对象类型。
Definition: meta.hpp:693
ystdex::or_
逻辑或。
Definition: integral_constant.hpp:172
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 转发对应参数。
Definition: ydef.h:1508
ystdex::rebind_traits_t
typename allocator_traits< _tAlloc >::template rebind_traits< _type > rebind_traits_t
Definition: allocator.hpp:427
ystdex::allocator_guard_delete::allocator_guard_delete
allocator_guard_delete(allocator_guard_delete &&)=default
std
Definition: optional.h:982
ystdex::details::do_alloc_on_swap
void do_alloc_on_swap(_tAlloc &, _tAlloc &, false_)
Definition: allocator.hpp:742
ystdex::details::mem_deallocate_t
decltype(std::declval< _tAlloc & >().deallocate(std::declval< mem_allocate_t< _tAlloc > >(), size_t(0))) mem_deallocate_t
Definition: allocator.hpp:510
ystdex::alloc_size_type_t
typename allocator_traits< _tAlloc >::size_type alloc_size_type_t
Definition: allocator.hpp:409
ystdex::details::mem_void_pointer_conv_t
is_convertible< mem_pointer_t< _tAlloc >, mem_void_pointer_t< _tAlloc > > mem_void_pointer_conv_t
Definition: allocator.hpp:479
ystdex::details::do_alloc_on_move
void do_alloc_on_move(_tAlloc &, _tAlloc &, false_)
Definition: allocator.hpp:725
type_op.hpp
C++ 类型操作。
ystdex::allocator_delete::operator=
allocator_delete & operator=(allocator_delete &&)=default
ystdex::cpp2014::remove_cv_t
typename remove_cv< _type >::type remove_cv_t
Definition: meta.hpp:142
ystdex::details::ucua_func
Definition: allocator.hpp:275
ystdex::details::uses_allocator_args
std::tuple< _tParams &&... > uses_allocator_args(_bPair, false_, _bPfx, const _tAlloc &, _tParams &&... args)
Definition: allocator.hpp:138
ystdex::details::mem_void_pointer_t
typename _tAlloc::void_pointer mem_void_pointer_t
Definition: allocator.hpp:475
ystdex::rebind_alloc_t
typename allocator_traits< _tAlloc >::template rebind_alloc< _type > rebind_alloc_t
Definition: allocator.hpp:423
ystdex::details::ucua_func::operator()
_type * operator()(_tParams &&... args) const
Definition: allocator.hpp:280
ystdex::details::uaa_func::operator()
auto operator()(_tParams &&...) const -> uaca_res_t< _type, _tAlloc, _tParams... >
ystdex::details::uaca_res_t
_t< uaca_res< _type, _tAlloc, _tParams... > > uaca_res_t
Definition: allocator.hpp:122
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
ystdex::is_class_type
判断指定类型是否是类类型。
Definition: meta.hpp:495
ystdex::allocator_delete::operator()
void operator()(pointer p) const
Definition: allocator.hpp:851
ystdex::true_
bool_< true > true_
Definition: integral_constant.hpp:109
exception.h
标准库异常扩展接口。
ystdex::allocate_shared
std::shared_ptr< _type > allocate_shared(const _tAlloc &alloc, std::initializer_list< _tValue > il)
使用分配器和初始化列表参数创建 std::shared_ptr 。
Definition: allocator.hpp:961
ystdex::is_allocatable
判断类型是否符合分配器要求的目标类型。
Definition: allocator.hpp:440
ystdex::allocator_delete::pointer
typename ator_traits::pointer pointer
Definition: allocator.hpp:831
ystdex::cond_t
_t< cond< _tCond, _tThen, _tElse > > cond_t
Definition: meta.hpp:794
ystdex::uninitialized_construct_using_allocator
_type * uninitialized_construct_using_allocator(_type *p, const _tAlloc &a, _tParams &&... args)
Definition: allocator.hpp:351
ystdex::details::do_alloc_on_copy
void do_alloc_on_copy(_tAlloc &, const _tAlloc &, false_)
Definition: allocator.hpp:714
ystdex::exclude_self_t
enable_if_t<!is_same_param< _tSelected, _tParam >::value, _type > exclude_self_t
排除选择类型的特定参数的重载。
Definition: meta.hpp:865
ystdex::make_allocator_guard
allocator_guard< _tAlloc > make_allocator_guard(_tAlloc &a, typename allocator_traits< _tAlloc >::size_type n=1)
构造分配器守卫。
Definition: allocator.hpp:878
ystdex::details::mem_pointer_t
typename _tAlloc::pointer mem_pointer_t
Definition: allocator.hpp:465
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:1219
ystdex
<memory> 特性测试宏。
Definition: ydef.h:1262
ystdex::alloc_on_move
void alloc_on_move(_tAlloc &x, _tAlloc &y)
按分配器特征在传播容器时转移分配器。
Definition: allocator.hpp:1038
ystdex::details::same_alloc_value_t
is_same< alloc_value_t< _type >, _tValue > same_alloc_value_t
Definition: allocator.hpp:540
alloc
TermPasses::allocator_type alloc
Definition: NPLA1.cpp:357
ystdex::allocator_guard_delete::count
size_type count
Definition: allocator.hpp:782
ystdex::details::allocator_delete_base::allocator_delete_base
allocator_delete_base(_tParam &&a)
Definition: allocator.hpp:690
ystdex::is_allocator_for
判断类型是指定值类型的分配器。
Definition: allocator.hpp:607
YSLib::_tParams
YB_ATTR_nodiscard YB_PURE typename _tParams
Definition: ValueNode.h:1294
ystdex::allocator_guard_delete::allocator_guard_delete
allocator_guard_delete(_tAlloc a, size_type n=1)
Definition: allocator.hpp:786
ystdex::details::mem_new_t
decltype(_type::operator new(std::declval< _tParams >()...)) mem_new_t
Definition: allocator.hpp:451
ystdex::class_allocator
类分配器。
Definition: allocator.hpp:980
ystdex::details::mem_const_pointer_t
typename _tAlloc::const_pointer mem_const_pointer_t
Definition: allocator.hpp:468
ystdex::_t
typename _type::type _t
嵌套类型别名。
Definition: meta.hpp:45
ystdex::details::mem_allocate_t
decltype(std::declval< _tAlloc & >().allocate(size_t(0))) mem_allocate_t
Definition: allocator.hpp:501
ystdex::make_obj_using_allocator
_type make_obj_using_allocator(const _tAlloc &a, _tParams &&... args)
Definition: allocator.hpp:343
ystdex::details::same_pointer_to_t
cond_or_t< is_detected< mem_pointer_t, _tAlloc >, true_, same_pointer_to_test_t, _tAlloc > same_pointer_to_t
Definition: allocator.hpp:498
ystdex::is_detected
typename details::detector< nonesuch, void, _gOp, _tParams... >::value_t is_detected
Definition: meta.hpp:396
ystdex::any_ops::destroy
@ destroy
销毁被管理的对象。
Definition: any.h:292
ystdex::cpp2017::allocator_traits::is_always_equal
detected_or_t< is_empty< _tAlloc >, details::mem_is_always_equal_t, _tAlloc > is_always_equal
Definition: allocator.hpp:386
ystdex::has_nested_allocator
判断类型具有嵌套的成员 allocator_type 指称一个构造器类型。
Definition: allocator.hpp:630
ystdex::details::allocator_delete_base
Definition: allocator.hpp:679
platform::p
return p p
Definition: YCLib/FileSystem.h:209
ystdex::alloc_on_copy
void alloc_on_copy(_tAlloc &x, const _tAlloc &y)
按分配器特征在传播容器时复制赋值分配器。
Definition: allocator.hpp:1017
ystdex::has_mem_new
Definition: allocator.hpp:569
ystdex::details::ator_max_size_t
decltype(allocator_traits< _tAlloc >::max_size(std::declval< _tAlloc & >())) ator_max_size_t
Definition: allocator.hpp:514
const
const Decapsulate const Decapsulate &y ynothrow ContextNode &ctx const
Definition: NPLA1Forms.cpp:1629
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:413
ystdex::false_
bool_< false > false_
Definition: integral_constant.hpp:110
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:1199
apply.hpp
元组应用操作。
ystdex::allocator_guard
std::unique_ptr< alloc_value_t< _tAlloc >, allocator_guard_delete< _tAlloc > > allocator_guard
分配器守卫。
Definition: allocator.hpp:869
ystdex::details::mem_is_always_equal_t
typename _type::is_always_equal mem_is_always_equal_t
Definition: allocator.hpp:369
ynoexcept
#define ynoexcept(...)
YSLib 无异常抛出保证：指定特定的异常规范。
Definition: ydef.h:1151
ystdex::allocator_guard_delete::operator()
void operator()(pointer p) const
Definition: allocator.hpp:799
ystdex::allocate_shared
std::shared_ptr< _type > allocate_shared(const _tAlloc &alloc, _tParams &&... args)
使用分配器创建 std::shared_ptr 。
Definition: allocator.hpp:949
ystdex::details::allocator_delete_base::operator=
allocator_delete_base & operator=(const allocator_delete_base &)=default
ystdex::remove_cvref_t
_t< remove_cvref< _type > > remove_cvref_t
Definition: meta.hpp:236
ystdex::is_allocator
判断类型是分配器。
Definition: allocator.hpp:596
ystdex::nested_allocator_base
启用 allocator_type 的基类。
Definition: allocator.hpp:652
ystdex::allocator_guard_delete::operator=
allocator_guard_delete & operator=(allocator_guard_delete &&)=default
ystdex::details::ucua_func::pv
void * pv
Definition: allocator.hpp:276
ystdex::details::uaca_res::type
decltype(ystdex::uses_allocator_construction_args< _type >(std::declval< const _tAlloc & >(), std::declval< _tParams >()...)) type
Definition: allocator.hpp:218
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:1073
ystdex::allocator_delete
释放分配器分配的对象的删除器。
Definition: allocator.hpp:822
YSLib::a
YB_PURE const _type * a
Definition: YCoreUtilities.h:168
NPL::_tParam
_tParam
Definition: NPLA.h:2367
ystdex::and_
逻辑操作元函数。
Definition: integral_constant.hpp:151
ystdex::alloc_const_pointer_t
typename allocator_traits< _tAlloc >::const_pointer alloc_const_pointer_t
Definition: allocator.hpp:406