YSTest: optional.h 源文件

YSTest PreAlpha_b900_20201012 The YSLib Test Project

optional.h
浏览该文件的文档.
1 /*
2 © 2015-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
47 #ifndef YB_INC_ystdex_optional_h_
48 #define YB_INC_ystdex_optional_h_ 1
49
50 #include "placement.hpp" // for <optional> conditionally, tagged_value;
51 #if YB_Has_optional != 1
52 # include "operators.hpp" // for or_, is_trivially_destructible, is_cv,
53 // std::move, empty_base, is_nothrow_moveable, and_, nullptr_t, remove_cv_t,
54 // totally_ordered, not_, nand_, is_reference, is_same,
55 // is_nothrow_destructible, is_object, enable_if_t, is_constructible, decay_t,
56 // is_nothrow_swappable, ystdex::addressof, is_copyable;
57 # include <initializer_list> // for std::initializer_list;
58 # include <stdexcept> // for std::logic_error;
59 #endif
60 #include "functional.hpp" // for ystdex::swap_dependent, default_last_value,
61 // std::accumulate, std::hash;
62
63 namespace ystdex
64 {
65
72 template<typename _type>
73 using optional_relop_t = enable_if_t<is_convertible<_type, bool>::value, bool>;
74
75 #if YB_Has_optional != 1
76 inline namespace cpp2017
78 {
79
80 template<typename>
81 class optional;
82
83 } // inline namespace 2017;
84
86
87 namespace details
88 {
89
91
92 template<typename _type, typename _tOther>
93 using converts_from_optional = or_<is_constructible<_type,
94 const optional<_tOther>&>, is_constructible<_type, optional<_tOther>&>,
95 is_constructible<_type, const optional<_tOther>>, is_constructible<_type,
96 optional<_tOther>>, is_convertible<const optional<_tOther>&, _type>,
97 is_convertible<optional<_tOther>&, _type>, is_convertible<const
98 optional<_tOther>&&, _type>, is_convertible<optional<_tOther>&&, _type>>;
99
100 template<typename _type, typename _tOther>
101 using assigns_from_optional = or_<is_assignable<_type&, const
102 optional<_tOther>&>, is_assignable<_type&, optional<_tOther>&>,
103 is_assignable<_type&, const optional<_tOther>&&>,
104 is_assignable<_type&, optional<_tOther>&&>>;
106
107 template<typename _type, bool = is_trivially_destructible<_type>::value>
108 class optional_base : public optional_base<_type, true>
109 {
110 public:
111 #if __cpp_inheriting_constructors < 201511L \
112 || (YB_IMPL_GNUCPP >= 80000 && YB_IMPL_GNUCPP < 80200)
113 // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85792.
114 yconstfn
115 optional_base() = default;
116 #endif
117 using optional_base<_type, true>::optional_base;
120 yconstfn
121 optional_base(const optional_base&) = default;
123 yconstfn
124 optional_base(optional_base&&) = default;
125 ~optional_base()
126 {
127 if(this->has_value())
128 this->destroy_nothrow();
129 }
130
131 optional_base&
132 operator=(const optional_base& s)
133 {
134 return this->assign(s.value);
135 }
136 optional_base&
137 operator=(optional_base&& s)
138 {
139 return this->assign(std::move(s.value));
140 }
141 };
142
143 template<typename _type>
144 class optional_base<_type, true> : protected tagged_value<bool, _type>
145 {
146 // NOTE: See WG21 N3770 comment FI 15, also CWG 1776.
147 static_assert(!is_cv<_type>(), "Cv-qualified type found.");
148
149 protected:
151 using base = tagged_value<bool, _type>;
152
154 using base::value;
155
156 public:
157 yconstfn
158 optional_base() = default;
159 template<typename... _tParams>
160 explicit yconstfn
161 optional_base(in_place_t, _tParams&&... args)
162 : base(true, in_place, yforward(args)...)
163 {}
164 yconstfn_relaxed
165 optional_base(const optional_base& s)
166 : base(s)
167 {
168 if(has_value())
169 base::construct(s.value);
170 }
172 yconstfn_relaxed
173 optional_base(optional_base&& s)
174 : base(s)
175 {
176 if(has_value())
177 base::construct(std::move(s.value));
178 }
183 ~optional_base() = default;
184
185 optional_base&
186 operator=(const optional_base& s)
187 {
188 return assign(s.value);
189 }
191 optional_base&
192 operator=(optional_base&& s) ynoexcept(is_nothrow_moveable<_type>())
193 {
194 return assign(std::move(s.value));
195 }
196
198 template<typename _tParam>
199 optional_base&
200 assign(_tParam&& arg) ynoexcept(and_<is_rvalue_reference<_tParam&&>,
201 is_nothrow_moveable<_type>>())
202 {
203 if(has_value() && arg.has_value())
204 value = yforward(arg);
205 else if(arg.has_value())
206 construct(yforward(arg));
207 else
208 reset();
209 return *this;
210 }
211
212 template<typename... _tParams>
213 void
214 construct(_tParams&&... args)
215 {
216 base::construct(yforward(args)...);
217 base::token = true;
218 }
219
220 void
221 destroy() ynothrow
222 {
223 base::token = {};
224 base::destroy_nothrow();
225 }
226
227 yconstfn_relaxed _type&
228 get() ynothrow
229 {
230 return value;
231 }
233 yconstfn const _type&
234 get() const ynothrow
235 {
236 return value;
237 }
238
240 bool
241 has_value() const ynothrow
242 {
243 return base::token;
244 }
245
246 void
247 reset() ynothrow
248 {
249 if(has_value())
250 destroy();
251 }
252 };
253
254 } // namespace details;
255 #endif
256
257
259 inline namespace cpp2017
260 {
261
262 #if YB_Has_optional == 1
263
265 using std::optional;
266 using std::bad_optional_access;
267 using std::nullopt_t;
268 using std::nullopt;
269 using std::make_optional;
271 #elif YB_Has_optional == 2
272
274 using std::experimental::optional;
275 using std::experimental::bad_optional_access;
276 using std::experimental::nullopt_t;
277 using std::experimental::nullopt;
278 using std::experimental::make_optional;
280 #else
281
283
285
290 #if YB_IMPL_MSCPP
291 struct nullopt_t
292 #else
293 yconstexpr_inline const struct nullopt_t
294 #endif
295 {
300 yimpl(explicit yconstfn
301 nullopt_t(nullptr_t)
302 {})
303 #if YB_IMPL_MSCPP
304 };
305
306 yconstexpr_inline const nullopt_t nullopt{yimpl(nullptr)};
307 #else
308 } nullopt{yimpl(nullptr)};
309 #endif
310
311
312
320 class YB_API bad_optional_access : public std::exception
321 {
322 public:
323 bad_optional_access()
324 : exception()
325 {}
327 bad_optional_access(const bad_optional_access&) = default;
328 ~bad_optional_access() override;
329
334 YB_ATTR_returns_nonnull yimpl(YB_STATELESS) virtual const char*
335 what() const ynothrow override;
336 };
338
339
350 template<typename _type>
351 class optional : private details::optional_base<remove_cv_t<_type>>, yimpl(
352 private totally_ordered<optional<_type>, nullopt_t>)
353 {
355 static_assert(!or_<is_reference<_type>, is_same<remove_cv_t<_type>,
356 in_place_t>, is_same<remove_cv_t<_type>, in_place_t>,
357 is_same<remove_cv_t<_type>, nullopt_t>>(), "Invalid type found.");
359 static_assert(and_<is_nothrow_destructible<_type>, is_object<_type>>(),
360 "Invalid type found.");
361
362 public:
363 using value_type = _type;
364
365 private:
366 using base = details::optional_base<_type>;
367
368 public:
369 yconstfn
370 optional() ynothrow
371 {}
372 yconstfn
373 optional(nullopt_t) ynothrow
374 {}
380 template<typename _tOther = _type, yimpl(enable_if_t<and_<not_<is_same<
381 optional<_type>, decay_t<_tOther>>>, not_<is_same<in_place_t,
382 decay_t<_tOther>>>, is_constructible<_type, _tOther>,
383 is_convertible<_tOther&&, _type>>::value, bool> = true)>
384 yconstfn
385 optional(_tOther&& v)
386 : base(in_place, yforward(v))
387 {}
388 template<typename _tOther = _type, yimpl(enable_if_t<and_<not_<is_same<
389 optional<_type>, decay_t<_tOther>>>, not_<is_same<in_place_t,
390 decay_t<_tOther>>>, is_constructible<_type, _tOther>, not_<
391 is_convertible<_tOther&&, _type>>>::value, bool> = false)>
392 explicit yconstfn
393 optional(_tOther&& v)
394 : base(in_place, yforward(v))
395 {}
396 template<typename _tOther, yimpl(enable_if_t<and_<not_<is_same<_type,
397 _tOther>>, is_constructible<_type, const _tOther&>, is_convertible<const
398 _tOther&, _type>, not_<
399 details::converts_from_optional<_type, _tOther>>>::value, bool> = true)>
400 yconstfn_relaxed
401 optional(const optional<_tOther>& t)
402 {
403 // XXX: Need to support non copyable and movable objects before mandated
404 // copy ellision available in ISO C++17.
405 if(t)
406 emplace(*t);
407 }
408 template<typename _tOther, yimpl(enable_if_t<and_<not_<is_same<_type,
409 _tOther>>, is_constructible<_type, const _tOther&>, not_<is_convertible<
410 const _tOther&, _type>>, not_<details::converts_from_optional<_type,
411 _tOther>>>::value, bool> = false)>
412 explicit yconstfn_relaxed
413 optional(const optional<_tOther>& t)
414 {
415 // XXX: Ditto.
416 if(t)
417 emplace(*t);
418 }
419 template<typename _tOther, yimpl(enable_if_t<and_<not_<is_same<_type,
420 _tOther>>, is_constructible<_type, _tOther>, is_convertible<_tOther&&,
421 _type>, not_<details::converts_from_optional<_type, _tOther>>>::value,
422 bool> = true)>
423 yconstfn_relaxed
424 optional(optional<_tOther>&& t)
425 {
426 // XXX: Ditto.
427 if(t)
428 emplace(std::move(*t));
429 }
430 template<typename _tOther, yimpl(enable_if_t<and_<not_<is_same<_type,
431 _tOther>>, is_constructible<_type, _tOther>, not_<is_convertible<
432 _tOther&&, _type>>, not_<details::converts_from_optional<_type,
433 _tOther>>>::value, bool> = false)>
434 explicit yconstfn_relaxed
435 optional(optional<_tOther>&& t)
436 {
437 // XXX: Ditto.
438 if(t)
439 emplace(std::move(*t));
440 }
442 template<typename... _tParams, yimpl(
443 typename = enable_if_t<is_constructible<_type, _tParams...>::value>)>
444 explicit yconstfn
445 optional(in_place_t, _tParams&&... args)
446 : base(in_place, yforward(args)...)
447 {}
448 template<typename _tOther, typename... _tParams,
449 yimpl(typename = enable_if_t<is_constructible<_type,
450 std::initializer_list<_tOther>&, _tParams&&...>::value>)>
451 explicit yconstfn
452 optional(in_place_t, std::initializer_list<_tOther> il, _tParams&&... args)
453 : base(in_place, il, yforward(args)...)
454 {}
455 yconstfn
456 optional(const optional&) yimpl(= default);
457 yconstfn
458 optional(optional&& o) ynoexcept(is_nothrow_move_constructible<_type>())
459 : base(std::move(o))
460 {}
461 ~optional() yimpl(= default);
462
463 optional&
464 operator=(nullopt_t) ynothrow
465 {
466 reset();
467 return *this;
468 }
469 optional&
470 operator=(const optional& o)
471 {
472 get_base() = o.get_base();
473 return *this;
474 }
476 optional&
477 operator=(optional&& o) ynoexcept(is_nothrow_moveable<_type>())
478 {
479 get_base() = std::move(o.get_base());
480 return *this;
481 }
487 template<typename _tOther = _type>
488 enable_if_t<and_<not_<is_same<optional<_type>, decay_t<_tOther>>>,
489 is_constructible<_type, _tOther>, nand_<is_scalar<_type>,
490 is_same<_type, decay_t<_tOther>>>,
491 is_assignable<_type&, _tOther>>::value, optional&>
492 operator=(_tOther&& v)
493 {
494 if(has_value())
495 this->get() = yforward(v);
496 else
497 this->construct(yforward(v));
498 return *this;
499 }
500 template<typename _tOther>
501 yimpl(enable_if_t)<and_<not_<is_same<_type, _tOther>>,
502 is_constructible<_type, const _tOther&>, is_assignable<_type&, _tOther>,
503 not_<details::converts_from_optional<_type, _tOther>>,
504 not_<details::assigns_from_optional<_type, _tOther>>>::value, optional&>
505 operator=(const optional<_tOther>& u)
506 {
507 if(u)
508 {
509 if(this->has_value())
510 this->get() = *u;
511 else
512 this->construct(*u);
513 }
514 else
515 this->reset();
516 return *this;
517 }
518 template<typename _tOther>
519 enable_if_t<and_<not_<is_same<_type, _tOther>>,
520 is_constructible<_type, _tOther>, is_assignable<_type&, _tOther>,
521 not_<details::converts_from_optional< _type, _tOther>>,
522 not_<details::assigns_from_optional<_type, _tOther>>>::value, optional&>
523 operator=(optional<_tOther>&& u)
524 {
525 if(u)
526 {
527 if(this->has_value())
528 this->get() = std::move(*u);
529 else
530 this->construct(std::move(*u));
531 }
532 else
533 this->reset();
534 return *this;
535 }
537
542 //{@
543 template<typename... _tParams>
544 _type&
545 emplace(_tParams&&... args)
546 {
547 reset();
548 this->construct(yforward(args)...);
549 return this->get();
550 }
551 template<typename _tOther, typename... _tParams>
552 _type&
553 emplace(std::initializer_list<_tOther> il, _tParams&&... args)
554 {
555 reset();
556 this->construct(il, yforward(args)...);
557 return this->get();
558 }
560
561 private:
562 base&
563 get_base() ynothrow
564 {
565 return static_cast< base&>(*this);
566 }
567 const base&
568 get_base() const ynothrow
569 {
570 return static_cast<const base&>(*this);
571 }
572
573 public:
574 void
575 swap(optional& o) ynoexcept(and_<is_nothrow_move_constructible<value_type>,
576 is_nothrow_swappable<value_type>>())
577 {
578 if(has_value() && o.has_value())
579 ystdex::swap_dependent(this->get(), o.get());
580 else if(has_value())
581 {
582 o.construct(std::move(this->get()));
583 this->destroy();
584 }
585 else if(o.has_value())
586 {
587 this->construct(std::move(this->get()));
588 o.destroy();
589 }
590 }
591
597 yconstfn_relaxed _type*
598 operator->()
599 {
600 return ystdex::addressof(this->get());
601 }
602 yconstfn const _type*
603 operator->() const
604 {
605 return ystdex::addressof(this->get());
606 }
608
609 yconstfn_relaxed _type&
610 operator*() &
611 {
612 return this->get();
613 }
614 yconstfn const _type&
615 operator*() const&
616 {
617 return this->get();
618 }
620 yconstfn_relaxed _type&&
621 operator*() &&
622 {
623 return std::move(this->get());
624 }
626 yconstfn const _type&&
627 operator*() const&&
628 {
629 return std::move(this->get());
630 }
631
632 explicit yconstfn
633 operator bool() const ynothrow
634 {
635 return has_value();
636 }
637
639 using base::has_value;
640
641 yconstfn_relaxed _type&
642 value() &
643 {
644 return has_value() ? this->get()
645 : (throw bad_optional_access(), this->get());
646 }
647 yconstfn const _type&
648 value() const&
649 {
650 return has_value() ? this->get()
651 : (throw bad_optional_access(), this->get());
652 }
654 yconstfn_relaxed _type&&
655 value() &&
656 {
657 return has_value() ? std::move(this->get())
658 : (throw bad_optional_access(), std::move(this->get()));
659 }
661 yconstfn _type&&
662 value() const&&
663 {
664 return has_value() ? std::move(this->get())
665 : (throw bad_optional_access(), std::move(this->get()));
666 }
667
668 template<typename _tOther>
669 yconstfn _type
670 value_or(_tOther&& other) const&
671 {
672 static_assert(is_copyable<_type>(), "Invalid type found.");
673
674 return has_value() ? this->get() : static_cast<_type>(yforward(other));
675 }
676 template<typename _tOther>
677 yconstfn_relaxed _type
678 value_or(_tOther&& other) &&
679 {
680 static_assert(is_copyable<_type>(), "Invalid type found.");
681
682 return has_value() ? std::move(this->get())
683 : static_cast<_type>(yforward(other));
684 }
685
687 using base::reset;
688 };
689
695
697
699 template<typename _type, typename _tOther>
700 yconstfn auto
701 operator==(const optional<_type>& x, const optional<_tOther>& y)
702 -> optional_relop_t<decltype(
703 std::declval<_type>() == std::declval<_tOther>())>
704 {
705 return bool(x) == bool(y) && (!x || *x == *y);
706 }
707
708 template<typename _type, typename _tOther>
709 yconstfn auto
710 operator!=(const optional<_type>& x, const optional<_tOther>& y)
711 -> optional_relop_t<decltype(
712 std::declval<_type>() != std::declval<_tOther>())>
713 {
714 return bool(x) != bool(y) || (bool(x) && *x != *y);
715 }
716
717 template<typename _type, typename _tOther>
718 yconstfn auto
719 operator<(const optional<_type>& x, const optional<_tOther>& y)
720 -> optional_relop_t<decltype(
721 std::declval<_type>() < std::declval<_tOther>())>
722 {
723 return bool(y) && (!x || *x < *y);
724 }
725
726 template<typename _type, typename _tOther>
727 yconstfn auto
728 operator>(const optional<_type>& x, const optional<_tOther>& y)
729 -> optional_relop_t<decltype(
730 std::declval<_type>() > std::declval<_tOther>())>
731 {
732 return bool(x) && (!y || *x > *y);
733 }
734
735 template<typename _type, typename _tOther>
736 yconstfn auto
737 operator<=(const optional<_type>& x, const optional<_tOther>& y)
738 -> optional_relop_t<decltype(
739 std::declval<_type>() <= std::declval<_tOther>())>
740 {
741 return !x || (bool(y) && *x <= *y);
742 }
743
744 template<typename _type, typename _tOther>
745 yconstfn auto
746 operator>=(const optional<_type>& x, const optional<_tOther>& y)
747 -> optional_relop_t<decltype(
748 std::declval<_type>() >= std::declval<_tOther>())>
749 {
750 return !y || (bool(x) && *x >= *y);
751 }
753
759 template<typename _type>
760 yconstfn bool
761 operator==(const optional<_type>& x, nullopt_t) ynothrow
762 {
763 return !x;
764 }
765
766 template<typename _type>
767 yconstfn bool
768 operator<(const optional<_type>&, nullopt_t) ynothrow
769 {
770 return {};
771 }
772 template<typename _type>
773 yconstfn bool
774 operator<(nullopt_t, const optional<_type>& y) ynothrow
775 {
776 return bool(y);
777 }
779
781
782 template<typename _type, typename _tOther>
783 yconstfn auto
784 operator==(const optional<_type>& x, const _tOther& y)
785 -> optional_relop_t<decltype(
786 std::declval<_type>() == std::declval<_tOther>())>
787 {
788 return x && *x == y;
789 }
790 template<typename _type, typename _tOther>
791 yconstfn auto
792 operator==(const _tOther& x, const optional<_type>& y)
793 -> optional_relop_t<decltype(
794 std::declval<_tOther>() == std::declval<_type>())>
795 {
796 return y && x == *y;
797 }
798
799 template<typename _type, typename _tOther>
800 yconstfn auto
801 operator!=(const optional<_type>& x, const _tOther& y)
802 -> optional_relop_t<decltype(
803 std::declval<_type>() != std::declval<_tOther>())>
804 {
805 return !x || *x != y;
806 }
807 template<typename _type, typename _tOther>
808 yconstfn auto
809 operator!=(const _tOther& x, const optional<_type>& y)
810 -> optional_relop_t<decltype(
811 std::declval<_tOther>() != std::declval<_type>())>
812 {
813 return !y || x != *y;
814 }
815
816 template<typename _type, typename _tOther>
817 yconstfn auto
818 operator<(const optional<_type>& x, const _tOther& y)
819 -> optional_relop_t<decltype(
820 std::declval<_type>() < std::declval<_tOther>())>
821 {
822 return !x || *x < y;
823 }
824 template<typename _type, typename _tOther>
825 yconstfn auto
826 operator<(const _tOther& x, const optional<_type>& y)
827 -> optional_relop_t<decltype(
828 std::declval<_tOther>() < std::declval<_type>())>
829 {
830 return y && x < *y;
831 }
832
833 template<typename _type, typename _tOther>
834 yconstfn auto
835 operator>(const optional<_type>& x, const _tOther& y)
836 -> optional_relop_t<decltype(
837 std::declval<_type>() > std::declval<_tOther>())>
838 {
839 return x && *x > y;
840 }
841 template<typename _type, typename _tOther>
842 yconstfn auto
843 operator>(const _tOther& x, const optional<_type>& y)
844 -> optional_relop_t<decltype(
845 std::declval<_tOther>() > std::declval<_type>())>
846 {
847 return !y || x > *y;
848 }
849
850 template<typename _type, typename _tOther>
851 yconstfn auto
852 operator<=(const optional<_type>& x, const _tOther& y)
853 -> optional_relop_t<decltype(
854 std::declval<_type>() <= std::declval<_tOther>())>
855 {
856 return !x || *x <= y;
857 }
858 template<typename _type, typename _tOther>
859 yconstfn auto
860 operator<=(const _tOther& x, const optional<_type>& y)
861 -> optional_relop_t<decltype(
862 std::declval<_tOther>() <= std::declval<_type>())>
863 {
864 return y && x <= *y;
865 }
866
867 template<typename _type, typename _tOther>
868 yconstfn auto
869 operator>=(const optional<_type>& x, const _tOther& y)
870 -> optional_relop_t<decltype(
871 std::declval<_type>() >= std::declval<_tOther>())>
872 {
873 return x && *x >= y;
874 }
875 template<typename _type, typename _tOther>
876 yconstfn auto
877 operator>=(const _tOther& x, const optional<_type>& y)
878 -> optional_relop_t<decltype(
879 std::declval<_tOther>() >= std::declval<_type>())>
880 {
881 return !y || x >= *y;
882 }
884
886
887 template<typename _type> void
888 swap(optional<_type>& x, optional<_type>& y) ynoexcept_spec(x.swap(y))
889 {
890 return x.swap(y);
891 }
892
900 template<typename _type, typename... _tParams>
901 optional<_type>
902 make_optional(_tParams&&... args)
903 {
904 return optional<_type>(in_place, yforward(args)...);
905 }
906 template<typename _type, typename _tOther, typename... _tParams>
907 optional<_type>
908 make_optional(std::initializer_list<_tOther> il, _tParams&&... args)
909 {
910 return optional<_type>(in_place, il, yforward(args)...);
911 }
913
914 #endif
915
921 template<typename _type, typename... _tParams>
923 yconstfn optional<_type>
924 make_optional_inplace(_tParams&&... args)
925 {
926 return optional<_type>(in_place, yforward(args)...);
927 }
928
934 template<typename _type>
935 yconstfn _type&
936 ref_opt(optional<_type>&& o) ynothrowv
937 {
938 return *o.operator->();
939 }
940 template<typename _type>
941 yconstfn _type&
942 ref_opt() ynothrowv
943 {
944 return ref_opt(make_optional_inplace<_type>());
945 }
947
948
956 template<typename _type>
957 struct optional_last_value
958 {
959 template<typename _tIn>
960 optional<_type>
961 operator()(_tIn first, _tIn last) const
962 {
963 return std::accumulate(first, last, optional<_type>(),
964 [](optional<_type>&, decltype(*first) val){
965 return yforward(val);
966 });
967 }
968 };
969
970 template<>
971 struct optional_last_value<void> : default_last_value<void>
972 {};
974
975
976 } // inline namespace cpp2017;
977
978 } // namespace ystdex;
979
980 #if YB_Has_optional != 1
981 namespace std
982 {
983
989 template<typename _type>
990 struct hash<ystdex::optional<_type>>
991 {
992 size_t
993 operator()(const ystdex::optional<_type>& k) const
994 yimpl(ynoexcept_spec(hash<_type>{}(*k)))
995 {
996 // NOTE: The unspecified value is randomly picked.
997 return k ? hash<_type>{}(*k) : yimpl(-4242);
998 }
999 };
1000
1001 } // namespace std;
1002 #endif
1003
1004 #endif
1005
ystdex::cpp2017::optional::operator=
optional & operator=(const optional &o)
Definition: optional.h:470
ystdex::cpp2017::optional::operator->
const _type * operator->() const
Definition: optional.h:603
ystdex::cpp2017::is_nothrow_swappable
Definition: swap.hpp:77
x
const EncapsulationBase & x
Definition: NPLA1Forms.cpp:1536
ystdex::cpp2017::swap
void swap(optional< _type > &x, optional< _type > &y)
Definition: optional.h:888
ystdex::details::optional_base< _type, true >::optional_base
optional_base()=default
ystdex::details::optional_base< _type, true >::assign
optional_base & assign(_tParam &&arg)
Definition: optional.h:200
ystdex::cpp2017::optional::~optional
~optional()=default
placement.hpp
放置对象管理操作。
ystdex::cpp2017::bad_optional_access::~bad_optional_access
~bad_optional_access() override
ystdex::is_copyable
Definition: meta.hpp:616
ystdex::cpp2017::optional::swap
void swap(optional &o)
Definition: optional.h:575
ystdex::cpp2017::optional::value_or
_type value_or(_tOther &&other) &&
Definition: optional.h:678
ystdex::cpp2017::optional::value
const _type & value() const &
Definition: optional.h:648
ystdex::cpp2014::enable_if_t
typename enable_if< _bCond, _type >::type enable_if_t
Definition: meta.hpp:199
ystdex::details::optional_base< _type, true >::has_value
bool has_value() const
Definition: optional.h:241
ystdex::details::optional_base::operator=
optional_base & operator=(optional_base &&s)
Definition: optional.h:137
ystdex::cpp2017::optional::emplace
_type & emplace(_tParams &&... args)
Definition: optional.h:545
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::details::optional_base
Definition: optional.h:109
ystdex::cpp2017::make_optional
optional< _type > make_optional(std::initializer_list< _tOther > il, _tParams &&... args)
Definition: optional.h:908
ynoexcept_spec
#define ynoexcept_spec(...)
表达式 noexcept 异常规范。
Definition: ydef.h:1181
ystdex::cpp2017::optional::optional
optional(in_place_t, _tParams &&... args)
Definition: optional.h:445
ystdex::nullptr_t
空指针类。
Definition: ydef.h:1321
ystdex::is_cv
判断指定类型是否为 const 或 volatile 类型。
Definition: meta.hpp:588
ystdex::cpp2017::operator<=
auto operator<=(const optional< _type > &x, const optional< _tOther > &y) -> optional_relop_t< decltype(std::declval< _type >()<=std::declval< _tOther >())>
Definition: optional.h:737
ystdex::details::optional_base< _type, true >::operator=
optional_base & operator=(optional_base &&s)
Definition: optional.h:192
ystdex::cpp2017::optional::optional
optional(const optional &)=default
ystdex::cpp2017::operator!=
auto operator!=(const optional< _type > &x, const optional< _tOther > &y) -> optional_relop_t< decltype(std::declval< _type >() !=std::declval< _tOther >())>
Definition: optional.h:710
ystdex::details::optional_base< _type, true >::construct
void construct(_tParams &&... args)
Definition: optional.h:214
ystdex::cpp2017::optional::get_base
const base & get_base() const
Definition: optional.h:568
ystdex::cpp2017::nullopt_t
无值状态指示。
Definition: optional.h:295
yconstfn_relaxed
#define yconstfn_relaxed
指定编译时没有 C++11 限制和隐式成员 const 的常量函数。
Definition: ydef.h:1097
ystdex::cpp2017::optional::operator*
const _type & operator*() const &
Definition: optional.h:615
ystdex::swap_dependent
void swap_dependent(_type &x, _type &y)(is_nothrow_swappable< _type >())
支持基于 ystdex_swap::swap 的 ADL 的左值交换。
Definition: swap.hpp:371
ystdex::uniformed_tags::in_place_t
in_place_tag(*)(empty_base<>) in_place_t
原地空标记类型。
Definition: placement.hpp:187
ystdex::details::optional_base::optional_base
optional_base(const optional_base &)=default
ystdex::uniformed_tags::in_place
in_place_tag in_place(empty_base<>)
原地标记函数。
Definition: placement.hpp:205
CHRLib::args
YB_ATTR_nodiscard _tParams && args
Definition: CharacterProcessing.h:649
ystdex::cpp2017::optional::optional
optional(optional< _tOther > &&t)
Definition: optional.h:424
ystdex::cpp2017::optional< _tNodeAlloc >::value_type
_tNodeAlloc value_type
Definition: optional.h:363
ystdex::cpp2014::decay_t
typename decay< _type >::type decay_t
Definition: meta.hpp:196
ystdex::details::optional_base< _type, true >::destroy
void destroy()
Definition: optional.h:221
ystdex::cpp2017::optional
可选值对象包装。
Definition: optional.h:81
YB_ATTR_returns_nonnull
#define YB_ATTR_returns_nonnull
指示返回非空属性。
Definition: ydef.h:761
ystdex::cpp2017::optional_last_value
合并可选值序列。
Definition: optional.h:958
CHRLib::CharSet::other
@ other
Definition: Encoding.h:65
ystdex::cpp2017::optional::optional
optional(in_place_t, std::initializer_list< _tOther > il, _tParams &&... args)
Definition: optional.h:452
ystdex::or_
逻辑或。
Definition: integral_constant.hpp:172
yforward
#define yforward(_expr)
根据参数类型使用 std::forward 转发对应参数。
Definition: ydef.h:1508
ystdex::nand_
逻辑与非。
Definition: integral_constant.hpp:202
ystdex::cpp2017::nullopt_t::nullopt_t
nullopt_t(nullptr_t)
Definition: optional.h:302
ystdex::tagged_value
带记号标记的可选值。
Definition: placement.hpp:784
ystdex::details::optional_base::~optional_base
~optional_base()
Definition: optional.h:125
ystdex::cpp2017::optional::optional
optional(optional &&o)
Definition: optional.h:458
ystdex::cpp2017::make_optional
optional< _type > make_optional(_tParams &&... args)
创建 optional 对象。
Definition: optional.h:902
ystdex::cpp2017::operator<
auto operator<(const optional< _type > &x, const optional< _tOther > &y) -> optional_relop_t< decltype(std::declval< _type >()< std::declval< _tOther >())>
Definition: optional.h:719
YB_STATELESS
#define YB_STATELESS
指示函数或函数模板实例为无状态函数。
Definition: ydef.h:941
ystdex::details::optional_base< _type, true >::~optional_base
~optional_base()=default
析构：空实现。
std
Definition: optional.h:982
ystdex::reset
bool reset(std::unique_ptr< _type, _tDeleter > &p)
Definition: memory.hpp:613
functional.hpp
函数和可调用对象。
ystdex::details::optional_base< _type, true >::operator=
optional_base & operator=(const optional_base &s)
Definition: optional.h:186
ystdex::cpp2017::optional::optional
optional()
Definition: optional.h:370
operators.hpp
重载操作符。
ystdex::cpp2017::optional::optional
optional(_tOther &&v)
Definition: optional.h:385
ystdex::cpp2014::remove_cv_t
typename remove_cv< _type >::type remove_cv_t
Definition: meta.hpp:142
ystdex::dep_ops::totally_ordered
details::flat_ops< _type, _type2, _tOpt, less_than_comparable, equality_comparable > totally_ordered
Definition: operators.hpp:389
ystdex::cpp2017::optional::operator*
const _type && operator*() const &&
Definition: optional.h:627
yconstexpr_inline
#define yconstexpr_inline
可选的内联 constexpr 变量。
Definition: ydef.h:1085
ystdex::cpp2017::optional::get_base
base & get_base()
Definition: optional.h:563
ystdex::details::optional_base::optional_base
optional_base()=default
YSLib::UI::y
SPos SPos y
Definition: YWidget.cpp:44
ystdex::cpp2017::operator>
auto operator>(const optional< _type > &x, const optional< _tOther > &y) -> optional_relop_t< decltype(std::declval< _type >() > std::declval< _tOther >())>
Definition: optional.h:728
CHRLib::s
_tDst const _tSrc * s
Definition: CharacterProcessing.h:143
ystdex::details::optional_base< _type, true >::get
const _type & get() const
Definition: optional.h:234
ystdex::cpp2017::optional::operator*
_type && operator*() &&
Definition: optional.h:621
ystdex::cpp2017::optional::operator=
enable_if_t< and_< not_< is_same< _type, _tOther > >, is_constructible< _type, _tOther >, is_assignable< _type &, _tOther >, not_< details::converts_from_optional< _type, _tOther > >, not_< details::assigns_from_optional< _type, _tOther > > >::value, optional & > operator=(optional< _tOther > &&u)
Definition: optional.h:523
ystdex::cpp2017::optional::optional
optional(nullopt_t)
Definition: optional.h:373
YB_API
#define YB_API
YBase 应用程序编程接口：用于向库文件约定链接。
Definition: ydef.h:985
ystdex::cpp2017::optional::operator->
_type * operator->()
Definition: optional.h:598
ystdex::details::optional_base< _type, true >::reset
void reset()
Definition: optional.h:247
v
byte v
Definition: CharRenderer.cpp:76
ystdex::cpp2017::make_optional_inplace
optional< _type > make_optional_inplace(_tParams &&... args)
使用指定参数构造指定 optional 实例的值。
Definition: optional.h:924
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:1219
ystdex
<memory> 特性测试宏。
Definition: ydef.h:1262
ystdex::details::optional_base< _type, true >::optional_base
optional_base(optional_base &&s)
Definition: optional.h:173
ystdex::details::optional_base< _type, true >::optional_base
optional_base(in_place_t, _tParams &&... args)
Definition: optional.h:161
ystdex::assign
void assign(_tCon &con, _tParams &&... args)
插入参数指定的元素到容器。
Definition: container.hpp:150
YSLib::_tParams
YB_ATTR_nodiscard YB_PURE typename _tParams
Definition: ValueNode.h:1294
ystdex::cpp2017::bad_optional_access::bad_optional_access
bad_optional_access(const bad_optional_access &)=default
ystdex::optional_relop_t
enable_if_t< is_convertible< _type, bool >::value, bool > optional_relop_t
保留可选的比较操作对象类型的比较操作结果类型。
Definition: optional.h:73
ystdex::cpp2017::optional::operator=
enable_if_t< and_< not_< is_same< _type, _tOther > >, is_constructible< _type, const _tOther & >, is_assignable< _type &, _tOther >, not_< details::converts_from_optional< _type, _tOther > >, not_< details::assigns_from_optional< _type, _tOther > > >::value, optional & > operator=(const optional< _tOther > &u)
Definition: optional.h:505
ystdex::construct
void construct(_tIter i, _tParams &&... args)
使用指定参数在迭代器指定的位置以指定参数初始化构造对象。
Definition: placement.hpp:376
ystdex::cpp2017::optional::emplace
_type & emplace(std::initializer_list< _tOther > il, _tParams &&... args)
Definition: optional.h:553
ystdex::addressof
enable_if_t< has_no_overloaded_addressof< _type >::value, _type * > addressof(_type &r)
尝试对非重载 operator& 提供 constexpr 的 std::addressof 替代。
Definition: addressof.hpp:131
ystdex::cpp2017::optional::operator=
enable_if_t< and_< not_< is_same< optional< _type >, decay_t< _tOther > > >, is_constructible< _type, _tOther >, nand_< is_scalar< _type >, is_same< _type, decay_t< _tOther > > >, is_assignable< _type &, _tOther > >::value, optional & > operator=(_tOther &&v)
Definition: optional.h:492
ystdex::details::optional_base< _type, true >::get
_type & get()
Definition: optional.h:228
ystdex::cpp2017::optional::value_or
_type value_or(_tOther &&other) const &
Definition: optional.h:670
ystdex::details::optional_base::optional_base
optional_base(optional_base &&)=default
ystdex::cpp2017::optional::value
_type && value() &&
Definition: optional.h:655
ystdex::cpp2017::bad_optional_access::bad_optional_access
bad_optional_access()
Definition: optional.h:323
ystdex::cpp2017::operator==
bool operator==(const optional< _type > &x, nullopt_t)
Definition: optional.h:761
ystdex::cpp2017::optional::value
_type & value() &
Definition: optional.h:642
ystdex::cpp2017::bad_optional_access
可选值操作失败异常。
Definition: optional.h:321
ystdex::cpp2017::optional::value
_type && value() const &&
Definition: optional.h:662
ystdex::default_last_value
合并值序列。
Definition: functional.hpp:851
ystdex::is_nothrow_moveable
Definition: meta.hpp:634
const
const Decapsulate const Decapsulate &y ynothrow ContextNode &ctx const
Definition: NPLA1Forms.cpp:1629
yimpl
#define yimpl(...)
实现标签。
Definition: ydef.h:413
platform::bool
YB_ATTR_nodiscard std::FILE *fp bool
Definition: FileIO.h:1271
ystdex::not_
逻辑非。
Definition: integral_constant.hpp:193
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:1199
ystdex::cpp2017::optional::operator=
optional & operator=(optional &&o)
Definition: optional.h:477
ystdex::details::optional_base::operator=
optional_base & operator=(const optional_base &s)
Definition: optional.h:132
ynoexcept
#define ynoexcept(...)
YSLib 无异常抛出保证：指定特定的异常规范。
Definition: ydef.h:1151
std::hash< ystdex::optional< _type > >::operator()
size_t operator()(const ystdex::optional< _type > &k) const
Definition: optional.h:993
ystdex::cpp2017::ref_opt
_type & ref_opt(optional< _type > &&o)
从 optional 实例的临时对象取左值引用。
Definition: optional.h:936
ystdex::cpp2017::optional::operator==
auto operator==(const optional< _type > &x, const optional< _tOther > &y) -> optional_relop_t< decltype(std::declval< _type >()==std::declval< _tOther >())>
关系和比较操作。
Definition: optional.h:701
NPL::get
PDefH(void, LiftTermRef, TermNode &term, const TermNode &tm) ImplExpr(NPL ref get()
Definition: NPLA.h:1737
ystdex::cpp2017::destroy
void destroy(_tFwd first, _tFwd last)
Definition: placement.hpp:451
ystdex::cpp2017::optional::optional
optional(const optional< _tOther > &t)
Definition: optional.h:401
yconstfn
#define yconstfn
指定编译时常量函数。
Definition: ydef.h:1073
ystdex::cpp2017::operator>=
auto operator>=(const optional< _type > &x, const optional< _tOther > &y) -> optional_relop_t< decltype(std::declval< _type >() >=std::declval< _tOther >())>
Definition: optional.h:746
ystdex::cpp2017::optional_last_value::operator()
optional< _type > operator()(_tIn first, _tIn last) const
Definition: optional.h:961
NPL::_tParam
_tParam
Definition: NPLA.h:2367
ystdex::cpp2017::optional::operator*
_type & operator*() &
Definition: optional.h:610
ystdex::details::optional_base< _type, true >::optional_base
optional_base(const optional_base &s)
Definition: optional.h:165
ystdex::and_
逻辑操作元函数。
Definition: integral_constant.hpp:151