Simple-Utility v2.3.1
Loading...
Searching...
No Matches
base.hpp
Go to the documentation of this file.
1// Copyright Dominic Koepke 2019 - 2023.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef SL_UTILITY_NULLABLES_BASE_HPP
7#define SL_UTILITY_NULLABLES_BASE_HPP
8
9#pragma once
10
14
15#include <cstddef>
16#include <functional>
17#include <type_traits>
18
19namespace sl::nullables
20{
96 template <class T>
97 struct traits;
98
103 template <class T>
104 using value_t = typename traits<std::remove_cvref_t<T>>::value_type;
105
110 template <class T>
111 constexpr static auto null_v{traits<std::remove_cvref_t<T>>::null};
112
117 template <class T>
118 requires std::is_pointer_v<T>
119 struct traits<T>
120 {
121 using value_type = std::remove_pointer_t<T>;
122 static constexpr std::nullptr_t null{nullptr};
123 };
124
127 namespace detail
128 {
129 template <class TNullable>
131 [[nodiscard]]
132 constexpr decltype(auto) unwrap(
133 TNullable&& na
134 )
135 noexcept
136 {
137 return *std::forward<TNullable>(na);
138 }
139
140 struct unwrap_fn
141 {
142 template <class TNullable>
143 requires requires { { unwrap(std::declval<TNullable>()) } -> std::convertible_to<value_t<TNullable>>; }
144 [[nodiscard]]
145 constexpr decltype(auto) operator()(TNullable&& na) const noexcept
146 {
147 return unwrap(std::forward<TNullable>(na));
148 }
149 };
150 }
151
160 inline constexpr detail::unwrap_fn unwrap{};
161
169 template <class T>
170 concept input_nullable = requires
171 {
172 typename value_t<T>;
173 null_v<T>;
174 }
175 && concepts::weakly_equality_comparable_with<T, decltype(null_v<T>)>;
176
185 template <class T>
187 && concepts::initializes<decltype(null_v<T>), std::remove_cvref_t<T>>
188 && std::is_assignable_v<std::remove_cvref_t<T>&, decltype(null_v<T>)>;
189}
190
191namespace sl::nullables::detail
192{
193 struct algorithm_tag
194 {
195 };
196}
197
198namespace sl::nullables
199{
214 template <concepts::unqualified Operation>
216 {
217 public:
218 [[nodiscard]]
219 explicit Algorithm(Operation operation) noexcept(std::is_nothrow_move_constructible_v<Operation>)
220 : m_Operation{std::move(operation)}
221 {
222 }
223
224 template <input_nullable Nullable>
225 requires std::regular_invocable<Operation, Nullable>
226 && std::is_void_v<std::invoke_result_t<Operation, Nullable>>
227 friend constexpr auto operator |(
228 Nullable&& input,
229 const Algorithm& algorithm
230 ) noexcept(std::is_nothrow_invocable_v<Operation, Nullable>)
231 {
232 return std::invoke(algorithm.m_Operation, std::forward<Nullable>(input));
233 }
234
235 template <input_nullable Nullable>
236 requires std::regular_invocable<Operation, Nullable>
237 [[nodiscard]]
238 friend constexpr auto operator |(
239 Nullable&& input,
240 const Algorithm& algorithm
241 ) noexcept(std::is_nothrow_invocable_v<Operation, Nullable>)
242 {
243 return std::invoke(algorithm.m_Operation, std::forward<Nullable>(input));
244 }
245
246 private:
248 Operation m_Operation{};
249 };
250
254}
255
256namespace sl::nullables::detail
257{
258 template <class T>
259 using dereference_result_t = decltype(nullables::unwrap(std::declval<T>()));
260}
261
262#endif
#define SL_UTILITY_NO_UNIQUE_ADDRESS
Definition: Config.hpp:21
The core algorithm helper, which executes the held operation when used as the right-hand-side of oper...
Definition: base.hpp:216
friend constexpr auto operator|(Nullable &&input, const Algorithm &algorithm) noexcept(std::is_nothrow_invocable_v< Operation, Nullable >)
Definition: base.hpp:227
Algorithm(Operation operation) noexcept(std::is_nothrow_move_constructible_v< Operation >)
Definition: base.hpp:219
Determines whether a type can be used in unary operator * expressions and if the return type is conve...
Definition: operators.hpp:734
Checks whether the target type is constructible from the source type.
Definition: stl_extensions.hpp:78
Checks whether a symmetrical set of operators == and != to compare both types with each other exists.
Definition: stl_extensions.hpp:124
Checks whether a type is an input_nullable.
Definition: base.hpp:170
Checks whether a type is nullable.
Definition: base.hpp:186
constexpr detail::unwrap_fn unwrap
Retrieves the value of the given input_nullable.
Definition: base.hpp:160
static constexpr auto null_v
Convenience constant retrieving the null object of a nullable type.
Definition: base.hpp:111
typename traits< std::remove_cvref_t< T > >::value_type value_t
Convenience alias retrieving the value type of a nullable type.
Definition: base.hpp:104
std::remove_pointer_t< T > value_type
Definition: base.hpp:121
Definition: adapter.hpp:19
The main trait, which may be specialized from.
Definition: base.hpp:97