OpenShot Audio Library | OpenShotAudio 0.4.0
 
Loading...
Searching...
No Matches
juce_Optional.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
15
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
26using Nullopt = std::nullopt_t;
27constexpr auto nullopt = std::nullopt;
28
29// Without this, our tests can emit "unreachable code" warnings during
30// link time code generation.
31JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4702)
32
33#ifndef DOXYGEN
34#define JUCE_OPTIONAL_OPERATORS X(==) X(!=) X(<) X(<=) X(>) X(>=)
35#endif
36
55template <typename Value>
56class Optional
57{
58 template <typename> struct IsOptional : std::false_type {};
59 template <typename T> struct IsOptional<Optional<T>> : std::true_type {};
60
61public:
62 Optional() = default;
63 Optional (const Optional&) = default;
64 Optional (Optional&&) = default;
65 Optional& operator= (const Optional&) = default;
66 Optional& operator= (Optional&&) = default;
67
68 Optional (Nullopt) noexcept {}
69
70 template <typename Head, typename... Tail, std::enable_if_t<! IsOptional<std::decay_t<Head>>::value, int> = 0>
71 Optional (Head&& head, Tail&&... tail)
72 noexcept (std::is_nothrow_constructible_v<std::optional<Value>, Head, Tail...>)
73 : opt (std::forward<Head> (head), std::forward<Tail> (tail)...) {}
74
75 template <typename Other>
76 Optional (const Optional<Other>& other)
77 noexcept (std::is_nothrow_constructible_v<std::optional<Value>, const std::optional<Other>&>)
78 : opt (other.opt) {}
79
80 template <typename Other>
81 Optional (Optional<Other>&& other)
82 noexcept (std::is_nothrow_constructible_v<std::optional<Value>, std::optional<Other>&&>)
83 : opt (std::move (other.opt)) {}
84
85 template <typename Other, std::enable_if_t<! IsOptional<std::decay_t<Other>>::value, int> = 0>
86 Optional& operator= (Other&& other)
87 noexcept (std::is_nothrow_assignable_v<std::optional<Value>, Other>)
88 {
89 opt = std::forward<Other> (other);
90 return *this;
91 }
92
93 template <typename Other>
94 Optional& operator= (const Optional<Other>& other)
95 noexcept (std::is_nothrow_assignable_v<std::optional<Value>, const std::optional<Other>&>)
96 {
97 opt = other.opt;
98 return *this;
99 }
100
101 template <typename Other>
102 Optional& operator= (Optional<Other>&& other)
103 noexcept (std::is_nothrow_assignable_v<std::optional<Value>, std::optional<Other>&&>)
104 {
105 opt = std::move (other.opt);
106 return *this;
107 }
108
109 template <typename... Other>
110 auto& emplace (Other&&... other)
111 {
112 return opt.emplace (std::forward<Other> (other)...);
113 }
114
115 void reset() noexcept
116 {
117 opt.reset();
118 }
119
120 void swap (Optional& other)
121 noexcept (std::is_nothrow_swappable_v<std::optional<Value>>)
122 {
123 opt.swap (other.opt);
124 }
125
126 decltype (auto) operator->() { return opt.operator->(); }
127 decltype (auto) operator->() const { return opt.operator->(); }
128 decltype (auto) operator* () { return opt.operator* (); }
129 decltype (auto) operator* () const { return opt.operator* (); }
130
131 explicit operator bool() const noexcept { return opt.has_value(); }
132 bool hasValue() const noexcept { return opt.has_value(); }
133
134 template <typename U>
135 decltype (auto) orFallback (U&& fallback) const& { return opt.value_or (std::forward<U> (fallback)); }
136
137 template <typename U>
138 decltype (auto) orFallback (U&& fallback) & { return opt.value_or (std::forward<U> (fallback)); }
139
140 #define X(op) \
141 template <typename T, typename U> friend bool operator op (const Optional<T>&, const Optional<U>&); \
142 template <typename T> friend bool operator op (const Optional<T>&, Nullopt); \
143 template <typename T> friend bool operator op (Nullopt, const Optional<T>&); \
144 template <typename T, typename U> friend bool operator op (const Optional<T>&, const U&); \
145 template <typename T, typename U> friend bool operator op (const T&, const Optional<U>&);
146
147 JUCE_OPTIONAL_OPERATORS
148
149 #undef X
150
151private:
152 template <typename Other>
153 friend class Optional;
154
155 std::optional<Value> opt;
156};
157
158JUCE_END_IGNORE_WARNINGS_MSVC
159
160template <typename Value>
161Optional<std::decay_t<Value>> makeOptional (Value&& v)
162{
163 return std::forward<Value> (v);
164}
165
166#ifndef DOXYGEN
167#define X(op) \
168 template <typename T, typename U> bool operator op (const Optional<T>& lhs, const Optional<U>& rhs) { return lhs.opt op rhs.opt; } \
169 template <typename T> bool operator op (const Optional<T>& lhs, Nullopt rhs) { return lhs.opt op rhs; } \
170 template <typename T> bool operator op (Nullopt lhs, const Optional<T>& rhs) { return lhs op rhs.opt; } \
171 template <typename T, typename U> bool operator op (const Optional<T>& lhs, const U& rhs) { return lhs.opt op rhs; } \
172 template <typename T, typename U> bool operator op (const T& lhs, const Optional<U>& rhs) { return lhs op rhs.opt; }
173
174JUCE_OPTIONAL_OPERATORS
175
176#undef X
177#undef JUCE_OPTIONAL_OPERATORS
178#endif
179
180} // namespace juce