Skip to content

Commit 71e224f

Browse files
committed
Add error messages, deduplicate operator*
1 parent 9474baf commit 71e224f

File tree

1 file changed

+15
-28
lines changed

1 file changed

+15
-28
lines changed

libcxx/include/__memory/indirect.h

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
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

Comments
 (0)