| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library.
 -    Copyright (c) 2022 - Raw Material Software Limited
 - 
 -    JUCE is an open source library subject to commercial or open-source
 -    licensing.
 - 
 -    The code included in this file is provided under the terms of the ISC license
 -    http://www.isc.org/downloads/software-support-policy/isc-license. Permission
 -    To use, copy, modify, and/or distribute this software for any purpose with or
 -    without fee is hereby granted provided that the above copyright notice and
 -    this permission notice appear in all copies.
 - 
 -    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 -    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 -    DISCLAIMED.
 - 
 -   ==============================================================================
 - */
 - 
 - namespace juce
 - {
 - 
 - namespace detail
 - {
 - namespace adlSwap
 - {
 - using std::swap;
 - 
 - template <typename T>
 - constexpr auto isNothrowSwappable = noexcept (swap (std::declval<T&>(), std::declval<T&>()));
 - } // namespace adlSwap
 - } // namespace detail
 - 
 - /** A type representing the null state of an Optional.
 -     Similar to std::nullopt_t.
 - */
 - struct Nullopt
 - {
 -     explicit constexpr Nullopt (int) {}
 - };
 - 
 - /** An object that can be used when constructing and comparing Optional instances.
 -     Similar to std::nullopt.
 - */
 - constexpr Nullopt nullopt { 0 };
 - 
 - // Without this, our tests can emit "unreachable code" warnings during
 - // link time code generation.
 - JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4702)
 - 
 - /**
 -     A simple optional type.
 - 
 -     Has similar (not necessarily identical!) semantics to std::optional.
 - 
 -     This is intended to stand-in for std::optional while JUCE's minimum
 -     supported language standard is lower than C++17. When the minimum language
 -     standard moves to C++17, this class will probably be deprecated, in much
 -     the same way that juce::ScopedPointer was deprecated in favour of
 -     std::unique_ptr after C++11.
 - 
 -     This isn't really intended to be used by JUCE clients. Instead, it's to be
 -     used internally in JUCE code, with an API close-enough to std::optional
 -     that the types can be swapped with fairly minor disruption at some point in
 -     the future, but *without breaking any public APIs*.
 - 
 -     @tags{Core}
 - */
 - template <typename Value>
 - class Optional
 - {
 -     template <typename T, typename U>
 -     struct NotConstructibleFromSimilarType
 -     {
 -         static constexpr auto value = ! std::is_constructible<T, Optional<U>&>::value
 -                                    && ! std::is_constructible<T, const Optional<U>&>::value
 -                                    && ! std::is_constructible<T, Optional<U>&&>::value
 -                                    && ! std::is_constructible<T, const Optional<U>&&>::value
 -                                    && ! std::is_convertible<Optional<U>&, T>::value
 -                                    && ! std::is_convertible<const Optional<U>&, T>::value
 -                                    && ! std::is_convertible<Optional<U>&&, T>::value
 -                                    && ! std::is_convertible<const Optional<U>&&, T>::value;
 -     };
 - 
 -     template <typename T, typename U>
 -     using OptionalCopyConstructorEnabled = std::enable_if_t<std::is_constructible<T, const U&>::value && NotConstructibleFromSimilarType<T, U>::value>;
 - 
 -     template <typename T, typename U>
 -     using OptionalMoveConstructorEnabled = std::enable_if_t<std::is_constructible<T, U&&>::value && NotConstructibleFromSimilarType<T, U>::value>;
 - 
 -     template <typename T, typename U>
 -     static auto notAssignableFromSimilarType = NotConstructibleFromSimilarType<T, U>::value
 -                                                && ! std::is_assignable<T&, Optional<U>&>::value
 -                                                && ! std::is_assignable<T&, const Optional<U>&>::value
 -                                                && ! std::is_assignable<T&, Optional<U>&&>::value
 -                                                && ! std::is_assignable<T&, const Optional<U>&&>::value;
 - 
 -     template <typename T, typename U>
 -     using OptionalCopyAssignmentEnabled = std::enable_if_t<std::is_constructible<T, const U&>::value
 -                                                            && std::is_assignable<T&, const U&>::value
 -                                                            && NotConstructibleFromSimilarType<T, U>::value>;
 - 
 -     template <typename T, typename U>
 -     using OptionalMoveAssignmentEnabled = std::enable_if_t<std::is_constructible<T, U>::value
 -                                                            && std::is_nothrow_assignable<T&, U>::value
 -                                                            && NotConstructibleFromSimilarType<T, U>::value>;
 - 
 - public:
 -     Optional() : placeholder() {}
 - 
 -     Optional (Nullopt) noexcept : placeholder() {}
 - 
 -     template <typename U = Value,
 -               typename = std::enable_if_t<std::is_constructible<Value, U&&>::value
 -                                           && ! std::is_same<std::decay_t<U>, Optional>::value>>
 -     Optional (U&& value) noexcept (noexcept (Value (std::forward<U> (value))))
 -         : storage (std::forward<U> (value)), valid (true)
 -     {
 -     }
 - 
 -     Optional (Optional&& other) noexcept (noexcept (std::declval<Optional>().constructFrom (other)))
 -         : placeholder()
 -     {
 -         constructFrom (other);
 -     }
 - 
 -     Optional (const Optional& other)
 -         : placeholder(), valid (other.valid)
 -     {
 -         if (valid)
 -             new (&storage) Value (*other);
 -     }
 - 
 -     template <typename Other, typename = OptionalMoveConstructorEnabled<Value, Other>>
 -     Optional (Optional<Other>&& other) noexcept (noexcept (std::declval<Optional>().constructFrom (other)))
 -         : placeholder()
 -     {
 -         constructFrom (other);
 -     }
 - 
 -     template <typename Other, typename = OptionalCopyConstructorEnabled<Value, Other>>
 -     Optional (const Optional<Other>& other)
 -         : placeholder(), valid (other.hasValue())
 -     {
 -         if (valid)
 -             new (&storage) Value (*other);
 -     }
 - 
 -     Optional& operator= (Nullopt) noexcept
 -     {
 -         reset();
 -         return *this;
 -     }
 - 
 -     template <typename U = Value,
 -               typename = std::enable_if_t<std::is_nothrow_move_constructible<U>::value
 -                                           && std::is_nothrow_move_assignable<U>::value>>
 -     Optional& operator= (Optional&& other) noexcept (noexcept (std::declval<Optional>().assign (std::declval<Optional&>())))
 -     {
 -         assign (other);
 -         return *this;
 -     }
 - 
 -     template <typename U = Value,
 -               typename = std::enable_if_t<! std::is_same<std::decay_t<U>, Optional>::value
 -                                           && std::is_constructible<Value, U>::value
 -                                           && std::is_assignable<Value&, U>::value
 -                                           && (! std::is_scalar<Value>::value || ! std::is_same<std::decay_t<U>, Value>::value)>>
 -     Optional& operator= (U&& value)
 -     {
 -         if (valid)
 -             **this = std::forward<U> (value);
 -         else
 -             new (&storage) Value (std::forward<U> (value));
 - 
 -         valid = true;
 -         return *this;
 -     }
 - 
 -     /** Maintains the strong exception safety guarantee. */
 -     Optional& operator= (const Optional& other)
 -     {
 -         auto copy = other;
 -         assign (copy);
 -         return *this;
 -     }
 - 
 -     template <typename Other, typename = OptionalMoveAssignmentEnabled<Value, Other>>
 -     Optional& operator= (Optional<Other>&& other) noexcept (noexcept (std::declval<Optional>().assign (other)))
 -     {
 -         assign (other);
 -         return *this;
 -     }
 - 
 -     /** Maintains the strong exception safety guarantee. */
 -     template <typename Other, typename = OptionalCopyAssignmentEnabled<Value, Other>>
 -     Optional& operator= (const Optional<Other>& other)
 -     {
 -         auto copy = other;
 -         assign (copy);
 -         return *this;
 -     }
 - 
 -     ~Optional() noexcept
 -     {
 -         reset();
 -     }
 - 
 -           Value* operator->()       noexcept { return reinterpret_cast<      Value*> (&storage); }
 -     const Value* operator->() const noexcept { return reinterpret_cast<const Value*> (&storage); }
 - 
 -           Value& operator*()       noexcept { return *operator->(); }
 -     const Value& operator*() const noexcept { return *operator->(); }
 - 
 -     explicit operator bool() const noexcept { return valid; }
 -     bool hasValue() const noexcept { return valid; }
 - 
 -     void reset()
 -     {
 -         if (std::exchange (valid, false))
 -             operator*().~Value();
 -     }
 - 
 -     /** Like std::optional::value_or */
 -     template <typename U>
 -     Value orFallback (U&& fallback) const { return *this ? **this : std::forward<U> (fallback); }
 - 
 -     template <typename... Args>
 -     Value& emplace (Args&&... args)
 -     {
 -         reset();
 -         new (&storage) Value (std::forward<Args> (args)...);
 -         valid = true;
 -         return **this;
 -     }
 - 
 -     void swap (Optional& other) noexcept (std::is_nothrow_move_constructible<Value>::value
 -                                           && detail::adlSwap::isNothrowSwappable<Value>)
 -     {
 -         if (hasValue() && other.hasValue())
 -         {
 -             using std::swap;
 -             swap (**this, *other);
 -         }
 -         else if (hasValue() || other.hasValue())
 -         {
 -             (hasValue() ? other : *this).constructFrom (hasValue() ? *this : other);
 -         }
 -     }
 - 
 - private:
 -     template <typename Other>
 -     void constructFrom (Optional<Other>& other) noexcept (noexcept (Value (std::move (*other))))
 -     {
 -         if (! other.hasValue())
 -             return;
 - 
 -         new (&storage) Value (std::move (*other));
 -         valid = true;
 -         other.reset();
 -     }
 - 
 -     template <typename Other>
 -     void assign (Optional<Other>& other) noexcept (noexcept (std::declval<Value&>() = std::move (*other)) && noexcept (std::declval<Optional>().constructFrom (other)))
 -     {
 -         if (valid)
 -         {
 -             if (other.hasValue())
 -             {
 -                 **this = std::move (*other);
 -                 other.reset();
 -             }
 -             else
 -             {
 -                 reset();
 -             }
 -         }
 -         else
 -         {
 -             constructFrom (other);
 -         }
 -     }
 - 
 -     union
 -     {
 -         char placeholder;
 -         Value storage;
 -     };
 -     bool valid = false;
 - };
 - 
 - JUCE_END_IGNORE_WARNINGS_MSVC
 - 
 - template <typename Value>
 - Optional<std::decay_t<Value>> makeOptional (Value&& v)
 - {
 -     return std::forward<Value> (v);
 - }
 - 
 - template <class T, class U>
 - bool operator== (const Optional<T>& lhs, const Optional<U>& rhs)
 - {
 -     if (lhs.hasValue() != rhs.hasValue()) return false;
 -     if (! lhs.hasValue()) return true;
 -     return *lhs == *rhs;
 - }
 - 
 - template <class T, class U>
 - bool operator!= (const Optional<T>& lhs, const Optional<U>& rhs)
 - {
 -     if (lhs.hasValue() != rhs.hasValue()) return true;
 -     if (! lhs.hasValue()) return false;
 -     return *lhs != *rhs;
 - }
 - 
 - template <class T, class U>
 - bool operator< (const Optional<T>& lhs, const Optional<U>& rhs)
 - {
 -     if (! rhs.hasValue()) return false;
 -     if (! lhs.hasValue()) return true;
 -     return *lhs < *rhs;
 - }
 - 
 - template <class T, class U>
 - bool operator<= (const Optional<T>& lhs, const Optional<U>& rhs)
 - {
 -     if (! lhs.hasValue()) return true;
 -     if (! rhs.hasValue()) return false;
 -     return *lhs <= *rhs;
 - }
 - 
 - template <class T, class U>
 - bool operator> (const Optional<T>& lhs, const Optional<U>& rhs)
 - {
 -     if (! lhs.hasValue()) return false;
 -     if (! rhs.hasValue()) return true;
 -     return *lhs > *rhs;
 - }
 - 
 - template <class T, class U>
 - bool operator>= (const Optional<T>& lhs, const Optional<U>& rhs)
 - {
 -     if (! rhs.hasValue()) return true;
 -     if (! lhs.hasValue()) return false;
 -     return *lhs >= *rhs;
 - }
 - 
 - template <class T>
 - bool operator== (const Optional<T>& opt, Nullopt) noexcept { return ! opt.hasValue(); }
 - template <class T>
 - bool operator== (Nullopt, const Optional<T>& opt) noexcept { return ! opt.hasValue(); }
 - template <class T>
 - bool operator!= (const Optional<T>& opt, Nullopt) noexcept { return opt.hasValue(); }
 - template <class T>
 - bool operator!= (Nullopt, const Optional<T>& opt) noexcept { return opt.hasValue(); }
 - template <class T>
 - bool operator< (const Optional<T>&, Nullopt) noexcept { return false; }
 - template <class T>
 - bool operator< (Nullopt, const Optional<T>& opt) noexcept { return opt.hasValue(); }
 - template <class T>
 - bool operator<= (const Optional<T>& opt, Nullopt) noexcept { return ! opt.hasValue(); }
 - template <class T>
 - bool operator<= (Nullopt, const Optional<T>&) noexcept { return true; }
 - template <class T>
 - bool operator> (const Optional<T>& opt, Nullopt) noexcept { return opt.hasValue(); }
 - template <class T>
 - bool operator> (Nullopt, const Optional<T>&) noexcept { return false; }
 - template <class T>
 - bool operator>= (const Optional<T>&, Nullopt) noexcept { return true; }
 - template <class T>
 - bool operator>= (Nullopt, const Optional<T>& opt) noexcept { return ! opt.hasValue(); }
 - 
 - template <class T, class U>
 - bool operator== (const Optional<T>& opt, const U& value) { return opt.hasValue() ? *opt == value : false; }
 - template <class T, class U>
 - bool operator== (const T& value, const Optional<U>& opt) { return opt.hasValue() ? value == *opt : false; }
 - template <class T, class U>
 - bool operator!= (const Optional<T>& opt, const U& value) { return opt.hasValue() ? *opt != value : true; }
 - template <class T, class U>
 - bool operator!= (const T& value, const Optional<U>& opt) { return opt.hasValue() ? value != *opt : true; }
 - template <class T, class U>
 - bool operator< (const Optional<T>& opt, const U& value) { return opt.hasValue() ? *opt < value : true; }
 - template <class T, class U>
 - bool operator< (const T& value, const Optional<U>& opt) { return opt.hasValue() ? value < *opt : false; }
 - template <class T, class U>
 - bool operator<= (const Optional<T>& opt, const U& value) { return opt.hasValue() ? *opt <= value : true; }
 - template <class T, class U>
 - bool operator<= (const T& value, const Optional<U>& opt) { return opt.hasValue() ? value <= *opt : false; }
 - template <class T, class U>
 - bool operator> (const Optional<T>& opt, const U& value) { return opt.hasValue() ? *opt > value : false; }
 - template <class T, class U>
 - bool operator> (const T& value, const Optional<U>& opt) { return opt.hasValue() ? value > *opt : true; }
 - template <class T, class U>
 - bool operator>= (const Optional<T>& opt, const U& value) { return opt.hasValue() ? *opt >= value : false; }
 - template <class T, class U>
 - bool operator>= (const T& value, const Optional<U>& opt) { return opt.hasValue() ? value >= *opt : true; }
 - 
 - } // namespace juce
 
 
  |