]> git.ipfire.org Git - thirdparty/squid.git/blob - src/base/Optional.h
Source Format Enforcement (#745)
[thirdparty/squid.git] / src / base / Optional.h
1 /*
2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #ifndef SQUID__SRC_BASE_OPTIONAL_H
10 #define SQUID__SRC_BASE_OPTIONAL_H
11
12 #include <exception>
13
14 /// std::bad_optional_access replacement (until we upgrade to C++17)
15 class BadOptionalAccess: public std::exception
16 {
17 public:
18 BadOptionalAccess() {}
19 /* std::exception API */
20 virtual const char* what() const noexcept override { return "bad-optional-access"; }
21 virtual ~BadOptionalAccess() noexcept = default;
22 };
23
24 /// (limited) std::optional replacement (until we upgrade to C++17)
25 template <typename Value>
26 class Optional
27 {
28 public:
29 // std::optional supports non-trivial types as well, but we
30 // do not want to fiddle with unions to disable default Value constructor
31 // until that work becomes necessary
32 static_assert(std::is_trivial<Value>::value, "Value is trivial");
33
34 constexpr Optional() noexcept {}
35 constexpr explicit Optional(const Value &v): value_(v), hasValue_(true) {}
36
37 constexpr explicit operator bool() const noexcept { return hasValue_; }
38 constexpr bool has_value() const noexcept { return hasValue_; }
39
40 const Value &value() const &
41 {
42 if (!hasValue_)
43 throw BadOptionalAccess();
44 return value_;
45 }
46
47 template <class Other>
48 constexpr Value value_or(Other &&defaultValue) const &
49 {
50 return hasValue_ ? value_ : static_cast<Value>(std::forward<Other>(defaultValue));
51 }
52
53 private:
54 Value value_; // stored value; inaccessible/uninitialized unless hasValue_
55 bool hasValue_ = false;
56 };
57
58 #endif /* SQUID__SRC_BASE_OPTIONAL_H */
59