OpenVPN 3 Core Library
Loading...
Searching...
No Matches
optional_ref.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2024- OpenVPN Inc.
8//
9// This program is free software: you can redistribute it and/or modify
10// it under the terms of the GNU Affero General Public License Version 3
11// as published by the Free Software Foundation.
12//
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU Affero General Public License for more details.
17//
18// You should have received a copy of the GNU Affero General Public License
19// along with this program in the COPYING file.
20// If not, see <http://www.gnu.org/licenses/>.
21
22#pragma once
23
24#include <optional> // std::nullopt_t
25#include <stdexcept>
26#include <type_traits>
27
28namespace openvpn {
29
78template <typename T>
79 requires std::is_reference_v<T>
81{
82 using value_type = std::remove_reference_t<T>;
83 value_type *mRef = nullptr;
84 static constexpr char errorMsg[] = "optional<T &>: access error";
85
86 public:
90 constexpr optional() noexcept = default;
91
96 constexpr optional(std::nullopt_t noOption) noexcept;
97
102 constexpr optional(T r) noexcept;
103
108 constexpr optional(value_type *r) noexcept;
109
113 constexpr optional(const optional &) noexcept = default;
114
118 constexpr optional(optional &&) noexcept = default;
119
124 optional &operator=(const optional &) noexcept = default;
125
130 optional &operator=(optional &&) noexcept = default;
131
137 optional &operator=(std::nullopt_t noOption) noexcept;
138
142 void reset() noexcept;
143
148 [[nodiscard]] constexpr bool has_value() const noexcept;
149
154 [[nodiscard]] constexpr explicit operator bool() const noexcept;
155
161 constexpr value_type value() const;
162
170 constexpr value_type value_or(const value_type &default_value) const noexcept;
171
177 const T operator*() const;
178
184 T operator*();
185
191 const value_type *operator->() const;
192
198 value_type *operator->();
199};
200
201// Implementations below
202
203template <typename T>
204 requires std::is_reference_v<T>
205inline constexpr optional<T>::optional(std::nullopt_t) noexcept
206 : optional()
207{
208}
209
210template <typename T>
211 requires std::is_reference_v<T>
212inline constexpr optional<T>::optional(T r) noexcept
213 : mRef(&r)
214{
215}
216
217template <typename T>
218 requires std::is_reference_v<T>
219inline constexpr optional<T>::optional(value_type *r) noexcept
220 : mRef(r)
221{
222}
223
224template <typename T>
225 requires std::is_reference_v<T>
226inline optional<T> &optional<T>::operator=(std::nullopt_t) noexcept
227{
228 reset();
229 return *this;
230}
231
232template <typename T>
233 requires std::is_reference_v<T>
234inline void optional<T>::reset() noexcept
235{
236 mRef = nullptr;
237}
238
239template <typename T>
240 requires std::is_reference_v<T>
241inline constexpr bool optional<T>::has_value() const noexcept
242{
243 return mRef != nullptr;
244}
245
246template <typename T>
247 requires std::is_reference_v<T>
248inline constexpr optional<T>::operator bool() const noexcept
249{
250 return has_value();
251}
252
253template <typename T>
254 requires std::is_reference_v<T>
255inline constexpr auto optional<T>::value() const -> value_type
256{
257 if (!bool(*this))
258 throw std::runtime_error(errorMsg);
259 return *mRef;
260}
261
262template <typename T>
263 requires std::is_reference_v<T>
264inline constexpr auto optional<T>::value_or(const value_type &default_value) const noexcept -> value_type
265{
266 return bool(*this) ? *mRef : default_value;
267}
268
269template <typename T>
270 requires std::is_reference_v<T>
271inline const T optional<T>::operator*() const
272{
273 if (!bool(*this))
274 throw std::runtime_error(errorMsg);
275 return *mRef;
276}
277
278template <typename T>
279 requires std::is_reference_v<T>
281{
282 return const_cast<T &>(*(std::as_const(*this)));
283}
284
285template <typename T>
286 requires std::is_reference_v<T>
287inline auto optional<T>::operator->() const -> const value_type *
288{
289 if (!bool(*this))
290 throw std::runtime_error(errorMsg);
291 return mRef;
292}
293
294template <typename T>
295 requires std::is_reference_v<T>
297{
298 return const_cast<value_type *>(std::as_const(*this).operator->());
299}
300
301} // namespace openvpn
designed to represent an optional reference to an object of type T
optional & operator=(const optional &) noexcept=default
Copy assignment operator.
const T operator*() const
Dereference operator.
void reset() noexcept
Resets the optional, making it empty.
std::remove_reference_t< T > value_type
constexpr value_type value() const
Gets the contained value.
constexpr bool has_value() const noexcept
Checks whether the optional contains a value.
value_type * mRef
constexpr optional() noexcept=default
Default constructor. Creates an empty optional.
const value_type * operator->() const
Arrow operator.
static constexpr char errorMsg[]
constexpr value_type value_or(const value_type &default_value) const noexcept
Returns the contained value if the optional is not empty, otherwise returns the provided default valu...