3131#include < __type_traits/remove_cvref.h>
3232#include < __utility/exchange.h>
3333#include < __utility/forward.h>
34+ #include < __utility/forward_like.h>
3435#include < __utility/in_place.h>
3536#include < __utility/move.h>
3637#include < __utility/swap.h>
@@ -56,13 +57,15 @@ class _LIBCPP_NO_SPECIALIZATIONS indirect {
5657 using const_pointer = allocator_traits<_Allocator>::const_pointer;
5758
5859 static_assert (__check_valid_allocator<allocator_type>::value);
59- static_assert (is_same_v<typename allocator_type::value_type, value_type>);
60- static_assert (is_object_v<value_type>);
61- static_assert (!is_array_v<value_type>);
62- static_assert (!is_same_v<value_type, in_place_t >);
63- static_assert (!__is_inplace_type<value_type>::value);
60+ static_assert (is_same_v<typename allocator_type::value_type, value_type>,
61+ " allocator's value_type type must match std::indirect's held type" );
62+ static_assert (is_object_v<value_type>, " std::indirect cannot hold void or a reference or function type" );
63+ static_assert (!is_array_v<value_type>, " std::indirect cannot hold an array type" );
64+ static_assert (!is_same_v<value_type, in_place_t >, " std::indirect cannot hold std::in_place_t" );
65+ static_assert (!__is_inplace_type<value_type>::value,
66+ " std::indirect cannot hold a specialization of std::in_place_type_t" );
6467 static_assert (std::is_same_v<value_type, remove_cv_t <value_type>>,
65- " value_type must not be const or volatile qualified" );
68+ " std::indirect cannot hold a const or volatile qualified type " );
6669
6770 // [indirect.ctor], constructors
6871 _LIBCPP_HIDE_FROM_ABI constexpr explicit indirect ()
@@ -206,28 +209,12 @@ class _LIBCPP_NO_SPECIALIZATIONS indirect {
206209 }
207210
208211 // [indirect.obs], observers
209- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp& operator *() const & noexcept {
210- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
211- !valueless_after_move (), " operator* called on a valueless std::indirect object" );
212- return *__ptr_;
213- }
214-
215- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp& operator *() & noexcept {
216- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
217- !valueless_after_move (), " operator* called on a valueless std::indirect object" );
218- return *__ptr_;
219- }
220-
221- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& operator *() const && noexcept {
222- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
223- !valueless_after_move (), " operator* called on a valueless std::indirect object" );
224- return std::move (*__ptr_);
225- }
226-
227- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr _Tp&& operator *() && noexcept {
228- _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS (
229- !valueless_after_move (), " operator* called on a valueless std::indirect object" );
230- return std::move (*__ptr_);
212+ template <class _Self >
213+ requires (!is_volatile_v<_Self>)
214+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto && operator *(this _Self&& __self) noexcept {
215+ _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS ((!std::__forward_as<_Self, indirect>(__self).valueless_after_move ()),
216+ " operator* called on a valueless std::indirect object" );
217+ return std::forward_like<_Self>(*__self.__ptr_ );
231218 }
232219
233220 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr const_pointer operator ->() const noexcept {
0 commit comments