File indexing completed on 2026-05-03 08:13:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef _LIBCPP___CXX03___RANGES_MOVABLE_BOX_H
0011 #define _LIBCPP___CXX03___RANGES_MOVABLE_BOX_H
0012
0013 #include <__cxx03/__concepts/constructible.h>
0014 #include <__cxx03/__concepts/copyable.h>
0015 #include <__cxx03/__concepts/movable.h>
0016 #include <__cxx03/__config>
0017 #include <__cxx03/__memory/addressof.h>
0018 #include <__cxx03/__memory/construct_at.h>
0019 #include <__cxx03/__type_traits/is_nothrow_constructible.h>
0020 #include <__cxx03/__utility/move.h>
0021 #include <__cxx03/optional>
0022
0023 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
0024 # pragma GCC system_header
0025 #endif
0026
0027 _LIBCPP_PUSH_MACROS
0028 #include <__cxx03/__undef_macros>
0029
0030 _LIBCPP_BEGIN_NAMESPACE_STD
0031
0032 #if _LIBCPP_STD_VER >= 20
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 template <class _Tp>
0045 concept __movable_box_object =
0046 # if _LIBCPP_STD_VER >= 23
0047 move_constructible<_Tp>
0048 # else
0049 copy_constructible<_Tp>
0050 # endif
0051 && is_object_v<_Tp>;
0052
0053 namespace ranges {
0054
0055 template <__movable_box_object _Tp>
0056 class __movable_box {
0057 _LIBCPP_NO_UNIQUE_ADDRESS optional<_Tp> __val_;
0058
0059 public:
0060 template <class... _Args>
0061 requires is_constructible_v<_Tp, _Args...>
0062 _LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box(in_place_t, _Args&&... __args) noexcept(
0063 is_nothrow_constructible_v<_Tp, _Args...>)
0064 : __val_(in_place, std::forward<_Args>(__args)...) {}
0065
0066 _LIBCPP_HIDE_FROM_ABI constexpr __movable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
0067 requires default_initializable<_Tp>
0068 : __val_(in_place) {}
0069
0070 _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box const&) = default;
0071 _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box&&) = default;
0072
0073 _LIBCPP_HIDE_FROM_ABI constexpr __movable_box&
0074 operator=(__movable_box const& __other) noexcept(is_nothrow_copy_constructible_v<_Tp>)
0075 # if _LIBCPP_STD_VER >= 23
0076 requires copy_constructible<_Tp>
0077 # endif
0078 {
0079 if (this != std::addressof(__other)) {
0080 if (__other.__has_value())
0081 __val_.emplace(*__other);
0082 else
0083 __val_.reset();
0084 }
0085 return *this;
0086 }
0087
0088 _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box&&)
0089 requires movable<_Tp>
0090 = default;
0091
0092 _LIBCPP_HIDE_FROM_ABI constexpr __movable_box&
0093 operator=(__movable_box&& __other) noexcept(is_nothrow_move_constructible_v<_Tp>) {
0094 if (this != std::addressof(__other)) {
0095 if (__other.__has_value())
0096 __val_.emplace(std::move(*__other));
0097 else
0098 __val_.reset();
0099 }
0100 return *this;
0101 }
0102
0103 _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return *__val_; }
0104 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return *__val_; }
0105
0106 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { return __val_.operator->(); }
0107 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { return __val_.operator->(); }
0108
0109 _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return __val_.has_value(); }
0110 };
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125 # if _LIBCPP_STD_VER >= 23
0126 template <class _Tp>
0127 concept __doesnt_need_empty_state =
0128 (copy_constructible<_Tp>
0129
0130
0131 ? copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp> && is_nothrow_copy_constructible_v<_Tp>)
0132
0133
0134 : movable<_Tp> || is_nothrow_move_constructible_v<_Tp>);
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146 template <class _Tp>
0147 concept __can_use_no_unique_address = (copy_constructible<_Tp> ? copyable<_Tp> : movable<_Tp>);
0148
0149 # else
0150
0151 template <class _Tp>
0152 concept __doesnt_need_empty_state_for_copy = copyable<_Tp> || is_nothrow_copy_constructible_v<_Tp>;
0153
0154 template <class _Tp>
0155 concept __doesnt_need_empty_state_for_move = movable<_Tp> || is_nothrow_move_constructible_v<_Tp>;
0156
0157 template <class _Tp>
0158 concept __doesnt_need_empty_state = __doesnt_need_empty_state_for_copy<_Tp> && __doesnt_need_empty_state_for_move<_Tp>;
0159
0160 template <class _Tp>
0161 concept __can_use_no_unique_address = copyable<_Tp>;
0162 # endif
0163
0164 template <class _Tp>
0165 struct __movable_box_holder {
0166 _Tp __val_;
0167
0168 template <class... _Args>
0169 _LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box_holder(in_place_t, _Args&&... __args)
0170 : __val_(std::forward<_Args>(__args)...) {}
0171 };
0172
0173 template <class _Tp>
0174 requires __can_use_no_unique_address<_Tp>
0175 struct __movable_box_holder<_Tp> {
0176 _LIBCPP_NO_UNIQUE_ADDRESS _Tp __val_;
0177
0178 template <class... _Args>
0179 _LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box_holder(in_place_t, _Args&&... __args)
0180 : __val_(std::forward<_Args>(__args)...) {}
0181 };
0182
0183 template <__movable_box_object _Tp>
0184 requires __doesnt_need_empty_state<_Tp>
0185 class __movable_box<_Tp> {
0186 _LIBCPP_NO_UNIQUE_ADDRESS __movable_box_holder<_Tp> __holder_;
0187
0188 public:
0189 template <class... _Args>
0190 requires is_constructible_v<_Tp, _Args...>
0191 _LIBCPP_HIDE_FROM_ABI constexpr explicit __movable_box(in_place_t __inplace, _Args&&... __args) noexcept(
0192 is_nothrow_constructible_v<_Tp, _Args...>)
0193 : __holder_(__inplace, std::forward<_Args>(__args)...) {}
0194
0195 _LIBCPP_HIDE_FROM_ABI constexpr __movable_box() noexcept(is_nothrow_default_constructible_v<_Tp>)
0196 requires default_initializable<_Tp>
0197 : __holder_(in_place_t{}) {}
0198
0199 _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box const&) = default;
0200 _LIBCPP_HIDE_FROM_ABI __movable_box(__movable_box&&) = default;
0201
0202
0203 _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box const&)
0204 requires copyable<_Tp>
0205 = default;
0206 _LIBCPP_HIDE_FROM_ABI __movable_box& operator=(__movable_box&&)
0207 requires movable<_Tp>
0208 = default;
0209
0210
0211 _LIBCPP_HIDE_FROM_ABI constexpr __movable_box& operator=(__movable_box const& __other) noexcept {
0212 static_assert(is_nothrow_copy_constructible_v<_Tp>);
0213 static_assert(!__can_use_no_unique_address<_Tp>);
0214 if (this != std::addressof(__other)) {
0215 std::destroy_at(std::addressof(__holder_.__val_));
0216 std::construct_at(std::addressof(__holder_.__val_), __other.__holder_.__val_);
0217 }
0218 return *this;
0219 }
0220
0221 _LIBCPP_HIDE_FROM_ABI constexpr __movable_box& operator=(__movable_box&& __other) noexcept {
0222 static_assert(is_nothrow_move_constructible_v<_Tp>);
0223 static_assert(!__can_use_no_unique_address<_Tp>);
0224 if (this != std::addressof(__other)) {
0225 std::destroy_at(std::addressof(__holder_.__val_));
0226 std::construct_at(std::addressof(__holder_.__val_), std::move(__other.__holder_.__val_));
0227 }
0228 return *this;
0229 }
0230
0231 _LIBCPP_HIDE_FROM_ABI constexpr _Tp const& operator*() const noexcept { return __holder_.__val_; }
0232 _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator*() noexcept { return __holder_.__val_; }
0233
0234 _LIBCPP_HIDE_FROM_ABI constexpr const _Tp* operator->() const noexcept { return std::addressof(__holder_.__val_); }
0235 _LIBCPP_HIDE_FROM_ABI constexpr _Tp* operator->() noexcept { return std::addressof(__holder_.__val_); }
0236
0237 _LIBCPP_HIDE_FROM_ABI constexpr bool __has_value() const noexcept { return true; }
0238 };
0239 }
0240
0241 #endif
0242
0243 _LIBCPP_END_NAMESPACE_STD
0244
0245 _LIBCPP_POP_MACROS
0246
0247 #endif