104class non_null : generic_ordering_from_three_way_compare_and_equals<non_null<P>> {
105 static_assert(pointer::detail::is_pointer_like_v<P>,
"non_null is only defined for pointer-like types.");
108 using ordering_base = generic_ordering_from_three_way_compare_and_equals<non_null<P>>;
112 using held_pointer = P;
114 using element_type =
typename std::pointer_traits<held_pointer>::element_type;
117 using pointer =
decltype(::arene::base::pointer::detail::to_address(std::declval<held_pointer>()));
123 constexpr explicit non_null(std::nullptr_t) =
delete;
133 constexpr auto operator=(non_null
const&) -> non_null& =
default;
135 constexpr auto operator=(non_null&&) -> non_null& =
default;
152 std::enable_if_t<!is_non_null_v<U>, std::enable_if_t<std::is_constructible<held_pointer, U>::value>>> =
155 constexpr explicit non_null(U&& ptr_value)
noexcept(std::is_nothrow_constructible<held_pointer, U>::value)
157 ptr_(std::forward<U>(ptr_value)) {
158 ARENE_PRECONDITION(ptr_ !=
nullptr);
169 typename U = held_pointer,
170 constraints<std::enable_if_t<std::is_constructible<held_pointer, U
const&>::value>> =
nullptr>
172 constexpr non_null(non_null<U>
const& copy_from)
noexcept(std::is_nothrow_constructible<held_pointer, U
const&>::value
175 ptr_(copy_from.unwrap()) {}
185 typename U = held_pointer,
186 constraints<std::enable_if_t<std::is_constructible<held_pointer, U&&>::value>> =
nullptr>
188 constexpr non_null(non_null<U>&& move_from)
noexcept(std::is_nothrow_constructible<held_pointer, U&&>::value)
190 ptr_(std::move(move_from).unwrap()) {}
200 typename U = held_pointer,
201 constraints<std::enable_if_t<!is_non_null_v<U>>, std::enable_if_t<std::is_assignable<held_pointer&, U>::value>> =
203 constexpr auto operator=(U&& new_ptr)
noexcept(std::is_nothrow_assignable<held_pointer&, U>::value) -> non_null& {
204 ARENE_PRECONDITION(new_ptr !=
nullptr);
205 ptr_ = std::forward<U>(new_ptr);
217 typename U = held_pointer,
218 constraints<std::enable_if_t<std::is_assignable<held_pointer&, U
const&>::value>> =
nullptr>
219 constexpr auto operator=(non_null<U>
const& copy_from
220 )
noexcept(std::is_nothrow_assignable<held_pointer&, U
const&>::value) -> non_null& {
221 ptr_ = copy_from.unwrap();
233 typename U = held_pointer,
234 constraints<std::enable_if_t<std::is_assignable<held_pointer&, U&&>::value>> =
nullptr>
235 constexpr auto operator=(non_null<U>&& move_from)
noexcept(std::is_nothrow_assignable<held_pointer&, U&&>::value)
237 ptr_ = std::move(move_from.unwrap());
260 template <
typename U = held_pointer, constraints<std::enable_if_t<std::is_pointer<U>::value>> =
nullptr>
261 ARENE_NODISCARD
constexpr auto get()
const noexcept -> held_pointer {
265 template <
typename U = held_pointer, constraints<std::enable_if_t<!std::is_pointer<U>::value>> =
nullptr>
266 ARENE_NODISCARD
constexpr auto get()
const noexcept ->
decltype(
auto) {
268 ARENE_INVARIANT(ptr_ !=
nullptr);
269 return ::arene::base::pointer::detail::to_address(ptr_);
284 ARENE_NODISCARD
constexpr auto unwrap()
const&
noexcept -> held_pointer
const& {
return ptr_; }
288 template <
typename U = held_pointer, constraints<std::enable_if_t<!std::is_pointer<U>::value>> =
nullptr>
289 ARENE_NODISCARD
constexpr auto unwrap() &&
noexcept -> held_pointer&& {
290 return std::move(ptr_);
308 typename U = held_pointer,
309 constraints<std::enable_if_t<arene::base::pointer::detail::has_reset<held_pointer&, U>>> =
nullptr>
310 constexpr void reset(U&& reset_to)
noexcept(
noexcept(std::declval<held_pointer>().reset(std::declval<U>()))) {
311 ARENE_PRECONDITION(reset_to !=
nullptr);
312 ptr_.reset(std::forward<U>(reset_to));
327 typename U = held_pointer,
329 std::enable_if_t<!arene::base::pointer::detail::has_reset<held_pointer&, U>>,
330 std::enable_if_t<std::is_assignable<held_pointer&, U>::value>> =
nullptr>
331 constexpr void reset(U&& reset_to)
noexcept(std::is_nothrow_assignable<held_pointer&, U>::value) {
332 ARENE_PRECONDITION(reset_to !=
nullptr);
333 ptr_ = std::forward<U>(reset_to);
337 constexpr void reset(std::nullptr_t)
noexcept =
delete;
346 template <
typename U = P, constraints<std::enable_if_t<is_swappable_v<P>>> =
nullptr>
347 constexpr void swap(non_null& swap_with)
noexcept(is_nothrow_swappable_v<P>) {
348 ::arene::base::swap(ptr_, swap_with.ptr_);
361 template <
typename U = P, constraints<std::enable_if_t<is_swappable_v<P>>> =
nullptr>
362 friend constexpr void swap(non_null& lhs, non_null& rhs)
noexcept(
noexcept(lhs.swap(rhs))) {
375 template <
typename U = element_type,
typename = std::enable_if_t<!std::is_same<std::remove_cv_t<U>,
void>::value>>
376 ARENE_NODISCARD
constexpr auto operator->()
const noexcept -> pointer {
387 template <
typename U = element_type,
typename = std::enable_if_t<!std::is_same<std::remove_cv_t<U>,
void>::value>>
388 ARENE_NODISCARD
constexpr auto operator*()
const noexcept ->
decltype(
auto) {
399 template <
typename U = held_pointer, constraints<std::enable_if_t<!std::is_pointer<U>::value>> =
nullptr>
400 ARENE_NODISCARD
explicit constexpr operator
bool()
const noexcept {
401 return ptr_ !=
nullptr;
403 template <
typename U = held_pointer, constraints<std::enable_if_t<std::is_pointer<U>::value>> =
nullptr>
404 ARENE_NODISCARD
explicit constexpr operator
bool()
const noexcept {
415 ARENE_NODISCARD
constexpr auto operator!()
const noexcept ->
bool {
return !(
static_cast<
bool>(*
this)); }
429 ARENE_NODISCARD
constexpr operator held_pointer
const&()
const&
noexcept {
return ptr_; }
433 template <
typename U = held_pointer, constraints<std::enable_if_t<!std::is_pointer<U>::value>> =
nullptr>
435 ARENE_NODISCARD
constexpr operator held_pointer&&() &&
noexcept {
436 return std::move(ptr_);
455 std::enable_if_t<!is_non_null_v<U>>,
456 std::enable_if_t<std::is_constructible<U, held_pointer
const&>::value>> =
nullptr>
457 ARENE_NODISCARD
explicit constexpr operator U(
458 )
const&
noexcept(std::is_nothrow_constructible<U, held_pointer
const&>::value) {
459 return static_cast<U>(ptr_);
466 std::enable_if_t<!is_non_null_v<U>>,
467 std::enable_if_t<!std::is_pointer<U>::value>,
468 std::enable_if_t<std::is_constructible<U, held_pointer&&>::value>> =
nullptr>
469 ARENE_NODISCARD
explicit constexpr operator U() &&
noexcept(std::is_nothrow_constructible<U, held_pointer&&>::value) {
470 return static_cast<U>(std::move(ptr_));
488 constraints<std::enable_if_t<is_equality_comparable_v<held_pointer
const&, OtherType
const&>>> =
nullptr>
489 ARENE_NODISCARD
friend constexpr auto operator==(non_null
const& lhs, non_null<OtherType>
const& rhs)
noexcept
491 return lhs.unwrap() == rhs.unwrap();
509 typename NonNullType,
512 std::enable_if_t<std::is_same<NonNullType, non_null>::value>,
513 std::enable_if_t<!is_non_null_v<OtherType>>,
514 std::enable_if_t<is_equality_comparable_v<held_pointer
const&, OtherType
const&>>> =
nullptr>
515 ARENE_NODISCARD
friend constexpr auto operator==(NonNullType
const& lhs, OtherType
const& rhs)
noexcept ->
bool {
516 return lhs.unwrap() == rhs;
529 ARENE_NODISCARD
friend constexpr auto operator==(non_null
const& lhs, std::nullptr_t
const rhs)
noexcept ->
bool {
546 constraints<std::enable_if_t<compare_three_way_supported_v<held_pointer
const&, OtherType
const&>>> =
nullptr>
547 ARENE_NODISCARD
static constexpr auto three_way_compare(non_null
const& lhs, non_null<OtherType>
const& rhs)
noexcept
549 return compare_three_way{}(lhs.unwrap(), rhs.unwrap());
562 std::enable_if_t<compare_three_way_supported_v<held_pointer
const&, OtherType
const&>>,
563 std::enable_if_t<!is_non_null_v<OtherType>>> =
nullptr>
564 ARENE_NODISCARD
static constexpr auto three_way_compare(non_null
const& lhs, OtherType
const& rhs)
noexcept
566 return compare_three_way{}(lhs.unwrap(), rhs);
574 template <
typename Dummy = held_pointer, constraints<std::enable_if_t<!std::is_pointer<Dummy>::value>> =
nullptr>
575 ARENE_NODISCARD
static constexpr auto three_way_compare(non_null
const& lhs, std::nullptr_t
const)
noexcept
578 return strong_ordering::equal;
580 return strong_ordering::greater;
586 template <
typename Dummy = held_pointer, constraints<std::enable_if_t<std::is_pointer<Dummy>::value>> =
nullptr>
587 ARENE_NODISCARD
static constexpr auto three_way_compare(non_null
const&, std::nullptr_t
const)
noexcept
589 return strong_ordering::greater;
595 template <
typename I>
596 constexpr auto operator[](I) =
delete;
597 template <
typename I>
599 template <
typename I>
600 constexpr auto operator+(I
const&)
const -> non_null =
delete;
601 template <
typename I>
602 constexpr auto operator-(I
const&)
const -> non_null =
delete;
605 constexpr auto operator++(
int) -> non_null& =
delete;
609 constexpr auto operator--(
int) -> non_null& =
delete;