Bitcoin Core 32.99.0
P2P Digital Currency
not_null.h
Go to the documentation of this file.
1// Copyright (c) The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or https://opensource.org/license/mit/.
4
5#ifndef BITCOIN_UTIL_NOT_NULL_H
6#define BITCOIN_UTIL_NOT_NULL_H
7
8#include <attributes.h>
9#include <util/check.h>
10
11#include <compare>
12#include <concepts>
13#include <cstddef>
14#include <functional>
15#include <memory>
16#include <type_traits>
17#include <utility>
18
19namespace util {
20
42template <class T>
43 requires std::is_class_v<T> && requires(T t) { { t != nullptr } -> std::convertible_to<bool>; }
45{
46public:
47 template <std::convertible_to<T> U>
48 requires(!std::same_as<std::remove_cvref_t<U>, NotNull>)
49 constexpr explicit NotNull(U&& u) noexcept(std::is_nothrow_constructible_v<T, U&&>)
50 : m_ptr(std::forward<U>(u))
51 {
52 Assert(m_ptr != nullptr);
53 }
54
55 template <class U>
56 requires std::move_constructible<U> && std::constructible_from<T, U&&>
57 constexpr explicit(!std::convertible_to<U, T>)
58 NotNull(NotNull<U>&& other) noexcept(std::is_nothrow_move_constructible_v<U> && std::is_nothrow_constructible_v<T, U&&>)
59 : m_ptr(std::move(other).get())
60 {
61 Assume(m_ptr != nullptr);
62 }
63
64 template <class U>
65 requires std::convertible_to<const U&, T>
66 constexpr NotNull(const NotNull<U>& other) noexcept(std::is_nothrow_constructible_v<T, const U&>)
67 : m_ptr(other.get())
68 {
69 Assume(m_ptr != nullptr);
70 }
71
72 NotNull(std::nullptr_t) = delete;
73 NotNull& operator=(std::nullptr_t) = delete;
74
75 constexpr NotNull(NotNull&&) = default;
76 constexpr NotNull& operator=(NotNull&&) = default;
77 constexpr NotNull(const NotNull&) = default;
78 constexpr NotNull& operator=(const NotNull&) = default;
79
80 constexpr const T& get() const& noexcept LIFETIMEBOUND { return Assume(m_ptr); }
81 constexpr T get() && noexcept(std::is_nothrow_move_constructible_v<T>)
82 requires std::move_constructible<T>
83 {
84 return std::move(Assume(m_ptr));
85 }
86
87 constexpr decltype(auto) operator->() const LIFETIMEBOUND { return get(); }
88 constexpr decltype(auto) operator*() const LIFETIMEBOUND { return *get(); }
89
90 constexpr operator T() const& noexcept(std::is_nothrow_copy_constructible_v<T>)
91 requires std::copy_constructible<T>
92 {
93 return get();
94 }
95 constexpr operator T() && noexcept(std::is_nothrow_move_constructible_v<T>)
96 requires std::move_constructible<T>
97 {
98 return std::move(*this).get();
99 }
100
101 template <class U>
102 constexpr auto operator<=>(const NotNull<U>& other) const
103 {
104 return std::compare_three_way{}(get(), other.get());
105 }
106 template <class U>
107 constexpr bool operator==(const NotNull<U>& other) const
108 {
109 return get() == other.get();
110 }
111
112private:
114};
115
116template <class T>
118
119template <typename T, typename Deleter = std::default_delete<T>>
121
122template <typename T>
124
125} // namespace util
126
127template <class T>
128struct std::hash<util::NotNull<T>> {
129 std::size_t operator()(const util::NotNull<T>& v) const noexcept
130 {
131 return std::hash<T>{}(v.get());
132 }
133};
134
135#endif // BITCOIN_UTIL_NOT_NULL_H
#define LIFETIMEBOUND
Definition: attributes.h:16
#define Assert(val)
Identity function.
Definition: check.h:116
#define Assume(val)
Assume is the identity function.
Definition: check.h:128
NotNull is intended to be used to denote that a smart pointer type can not hold a nullptr value.
Definition: not_null.h:45
constexpr auto operator<=>(const NotNull< U > &other) const
Definition: not_null.h:102
constexpr NotNull(U &&u) noexcept(std::is_nothrow_constructible_v< T, U && >)
Definition: not_null.h:49
constexpr NotNull(const NotNull &)=default
constexpr const T & get() const &noexcept LIFETIMEBOUND
Definition: not_null.h:80
constexpr NotNull(NotNull &&)=default
NotNull(std::nullptr_t)=delete
constexpr NotNull & operator=(NotNull &&)=default
constexpr bool operator==(const NotNull< U > &other) const
Definition: not_null.h:107
constexpr NotNull(const NotNull< U > &other) noexcept(std::is_nothrow_constructible_v< T, const U & >)
Definition: not_null.h:66
NotNull & operator=(std::nullptr_t)=delete
constexpr T get() &&noexcept(std::is_nothrow_move_constructible_v< T >)
Definition: not_null.h:81
constexpr NotNull & operator=(const NotNull &)=default
#define T(expected, seed, data)
NotNull(T) -> NotNull< T >
std::size_t operator()(const util::NotNull< T > &v) const noexcept
Definition: not_null.h:129