26using Nullopt = std::nullopt_t;
27constexpr auto nullopt = std::nullopt;
31JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4702)
34#define JUCE_OPTIONAL_OPERATORS X(==) X(!=) X(<) X(<=) X(>) X(>=)
55template <
typename Value>
58 template <
typename>
struct IsOptional : std::false_type {};
59 template <
typename T>
struct IsOptional<
Optional<T>> : std::true_type {};
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)...) {}
75 template <
typename Other>
77 noexcept (std::is_nothrow_constructible_v<std::optional<Value>,
const std::optional<Other>&>)
80 template <
typename Other>
82 noexcept (std::is_nothrow_constructible_v<std::optional<Value>, std::optional<Other>&&>)
83 : opt (std::move (other.opt)) {}
85 template <
typename Other, std::enable_if_t<! IsOptional<std::decay_t<Other>>::value,
int> = 0>
87 noexcept (std::is_nothrow_assignable_v<std::optional<Value>, Other>)
89 opt = std::forward<Other> (other);
93 template <
typename Other>
95 noexcept (std::is_nothrow_assignable_v<std::optional<Value>,
const std::optional<Other>&>)
101 template <
typename Other>
103 noexcept (std::is_nothrow_assignable_v<std::optional<Value>, std::optional<Other>&&>)
105 opt = std::move (other.opt);
109 template <
typename... Other>
110 auto& emplace (Other&&... other)
112 return opt.emplace (std::forward<Other> (other)...);
115 void reset()
noexcept
121 noexcept (std::is_nothrow_swappable_v<std::optional<Value>>)
123 opt.swap (other.opt);
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* (); }
131 explicit operator bool()
const noexcept {
return opt.has_value(); }
132 bool hasValue()
const noexcept {
return opt.has_value(); }
134 template <
typename U>
135 decltype (
auto) orFallback (U&& fallback)
const& {
return opt.value_or (std::forward<U> (fallback)); }
137 template <
typename U>
138 decltype (
auto) orFallback (U&& fallback) & {
return opt.value_or (std::forward<U> (fallback)); }
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>&);
147 JUCE_OPTIONAL_OPERATORS
152 template <
typename Other>
155 std::optional<Value> opt;
158JUCE_END_IGNORE_WARNINGS_MSVC
160template <
typename Value>
163 return std::forward<Value> (v);
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; }
174JUCE_OPTIONAL_OPERATORS
177#undef JUCE_OPTIONAL_OPERATORS