2016-10-12 15:46:20 +08:00
|
|
|
// -*- C++ -*-
|
2021-11-18 05:25:01 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2016-10-12 15:46:20 +08:00
|
|
|
//
|
2019-01-19 18:56:40 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2016-10-12 15:46:20 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef _LIBCPP_OPTIONAL
|
|
|
|
#define _LIBCPP_OPTIONAL
|
|
|
|
|
|
|
|
/*
|
|
|
|
optional synopsis
|
|
|
|
|
|
|
|
// C++1z
|
|
|
|
|
|
|
|
namespace std {
|
2017-04-18 04:15:16 +08:00
|
|
|
// 23.6.3, optional for object types
|
2016-10-12 15:46:20 +08:00
|
|
|
template <class T> class optional;
|
|
|
|
|
2017-04-18 04:15:16 +08:00
|
|
|
// 23.6.4, no-value state indicator
|
2016-10-12 15:46:20 +08:00
|
|
|
struct nullopt_t{see below };
|
2018-01-03 01:17:01 +08:00
|
|
|
inline constexpr nullopt_t nullopt(unspecified );
|
2016-10-12 15:46:20 +08:00
|
|
|
|
2017-04-18 04:15:16 +08:00
|
|
|
// 23.6.5, class bad_optional_access
|
2016-10-12 15:46:20 +08:00
|
|
|
class bad_optional_access;
|
|
|
|
|
2017-04-18 04:15:16 +08:00
|
|
|
// 23.6.6, relational operators
|
|
|
|
template <class T, class U>
|
|
|
|
constexpr bool operator==(const optional<T>&, const optional<U>&);
|
|
|
|
template <class T, class U>
|
|
|
|
constexpr bool operator!=(const optional<T>&, const optional<U>&);
|
|
|
|
template <class T, class U>
|
|
|
|
constexpr bool operator<(const optional<T>&, const optional<U>&);
|
|
|
|
template <class T, class U>
|
|
|
|
constexpr bool operator>(const optional<T>&, const optional<U>&);
|
|
|
|
template <class T, class U>
|
|
|
|
constexpr bool operator<=(const optional<T>&, const optional<U>&);
|
|
|
|
template <class T, class U>
|
|
|
|
constexpr bool operator>=(const optional<T>&, const optional<U>&);
|
|
|
|
|
|
|
|
// 23.6.7 comparison with nullopt
|
2016-10-12 15:46:20 +08:00
|
|
|
template <class T> constexpr bool operator==(const optional<T>&, nullopt_t) noexcept;
|
|
|
|
template <class T> constexpr bool operator==(nullopt_t, const optional<T>&) noexcept;
|
|
|
|
template <class T> constexpr bool operator!=(const optional<T>&, nullopt_t) noexcept;
|
|
|
|
template <class T> constexpr bool operator!=(nullopt_t, const optional<T>&) noexcept;
|
|
|
|
template <class T> constexpr bool operator<(const optional<T>&, nullopt_t) noexcept;
|
|
|
|
template <class T> constexpr bool operator<(nullopt_t, const optional<T>&) noexcept;
|
|
|
|
template <class T> constexpr bool operator<=(const optional<T>&, nullopt_t) noexcept;
|
|
|
|
template <class T> constexpr bool operator<=(nullopt_t, const optional<T>&) noexcept;
|
|
|
|
template <class T> constexpr bool operator>(const optional<T>&, nullopt_t) noexcept;
|
|
|
|
template <class T> constexpr bool operator>(nullopt_t, const optional<T>&) noexcept;
|
|
|
|
template <class T> constexpr bool operator>=(const optional<T>&, nullopt_t) noexcept;
|
|
|
|
template <class T> constexpr bool operator>=(nullopt_t, const optional<T>&) noexcept;
|
|
|
|
|
2017-04-18 04:15:16 +08:00
|
|
|
// 23.6.8, comparison with T
|
|
|
|
template <class T, class U> constexpr bool operator==(const optional<T>&, const U&);
|
2017-11-01 09:27:25 +08:00
|
|
|
template <class T, class U> constexpr bool operator==(const T&, const optional<U>&);
|
2017-04-18 04:15:16 +08:00
|
|
|
template <class T, class U> constexpr bool operator!=(const optional<T>&, const U&);
|
2017-11-01 09:27:25 +08:00
|
|
|
template <class T, class U> constexpr bool operator!=(const T&, const optional<U>&);
|
2017-04-18 04:15:16 +08:00
|
|
|
template <class T, class U> constexpr bool operator<(const optional<T>&, const U&);
|
2017-11-01 09:27:25 +08:00
|
|
|
template <class T, class U> constexpr bool operator<(const T&, const optional<U>&);
|
2017-04-18 04:15:16 +08:00
|
|
|
template <class T, class U> constexpr bool operator<=(const optional<T>&, const U&);
|
2017-11-01 09:27:25 +08:00
|
|
|
template <class T, class U> constexpr bool operator<=(const T&, const optional<U>&);
|
2017-04-18 04:15:16 +08:00
|
|
|
template <class T, class U> constexpr bool operator>(const optional<T>&, const U&);
|
2017-11-01 09:27:25 +08:00
|
|
|
template <class T, class U> constexpr bool operator>(const T&, const optional<U>&);
|
2017-04-18 04:15:16 +08:00
|
|
|
template <class T, class U> constexpr bool operator>=(const optional<T>&, const U&);
|
2017-11-01 09:27:25 +08:00
|
|
|
template <class T, class U> constexpr bool operator>=(const T&, const optional<U>&);
|
2017-04-18 04:15:16 +08:00
|
|
|
|
|
|
|
// 23.6.9, specialized algorithms
|
2021-05-09 09:30:32 +08:00
|
|
|
template <class T> void swap(optional<T>&, optional<T>&) noexcept(see below ); // constexpr in C++20
|
2016-10-12 15:46:20 +08:00
|
|
|
template <class T> constexpr optional<see below > make_optional(T&&);
|
|
|
|
template <class T, class... Args>
|
|
|
|
constexpr optional<T> make_optional(Args&&... args);
|
|
|
|
template <class T, class U, class... Args>
|
|
|
|
constexpr optional<T> make_optional(initializer_list<U> il, Args&&... args);
|
|
|
|
|
2017-04-18 04:15:16 +08:00
|
|
|
// 23.6.10, hash support
|
2016-10-12 15:46:20 +08:00
|
|
|
template <class T> struct hash;
|
|
|
|
template <class T> struct hash<optional<T>>;
|
|
|
|
|
|
|
|
template <class T> class optional {
|
|
|
|
public:
|
|
|
|
using value_type = T;
|
|
|
|
|
2017-04-18 04:15:16 +08:00
|
|
|
// 23.6.3.1, constructors
|
2016-10-12 15:46:20 +08:00
|
|
|
constexpr optional() noexcept;
|
|
|
|
constexpr optional(nullopt_t) noexcept;
|
|
|
|
optional(const optional &);
|
2017-04-13 06:51:27 +08:00
|
|
|
optional(optional &&) noexcept(see below);
|
2016-10-12 15:46:20 +08:00
|
|
|
template <class... Args> constexpr explicit optional(in_place_t, Args &&...);
|
|
|
|
template <class U, class... Args>
|
|
|
|
constexpr explicit optional(in_place_t, initializer_list<U>, Args &&...);
|
|
|
|
template <class U = T>
|
2022-05-18 01:15:18 +08:00
|
|
|
constexpr explicit(see-below) optional(U &&);
|
2016-10-12 15:46:20 +08:00
|
|
|
template <class U>
|
2022-05-18 01:15:18 +08:00
|
|
|
explicit(see-below) optional(const optional<U> &); // constexpr in C++20
|
2016-10-12 15:46:20 +08:00
|
|
|
template <class U>
|
2022-05-18 01:15:18 +08:00
|
|
|
explicit(see-below) optional(optional<U> &&); // constexpr in C++20
|
2016-10-12 15:46:20 +08:00
|
|
|
|
2017-04-18 04:15:16 +08:00
|
|
|
// 23.6.3.2, destructor
|
2021-05-09 09:30:32 +08:00
|
|
|
~optional(); // constexpr in C++20
|
2016-10-12 15:46:20 +08:00
|
|
|
|
2017-04-18 04:15:16 +08:00
|
|
|
// 23.6.3.3, assignment
|
2021-05-09 09:30:32 +08:00
|
|
|
optional &operator=(nullopt_t) noexcept; // constexpr in C++20
|
|
|
|
optional &operator=(const optional &); // constexpr in C++20
|
|
|
|
optional &operator=(optional &&) noexcept(see below); // constexpr in C++20
|
|
|
|
template <class U = T> optional &operator=(U &&); // constexpr in C++20
|
|
|
|
template <class U> optional &operator=(const optional<U> &); // constexpr in C++20
|
|
|
|
template <class U> optional &operator=(optional<U> &&); // constexpr in C++20
|
|
|
|
template <class... Args> T& emplace(Args &&...); // constexpr in C++20
|
2016-10-12 15:46:20 +08:00
|
|
|
template <class U, class... Args>
|
2021-05-09 09:30:32 +08:00
|
|
|
T& emplace(initializer_list<U>, Args &&...); // constexpr in C++20
|
2016-10-12 15:46:20 +08:00
|
|
|
|
2017-04-18 04:15:16 +08:00
|
|
|
// 23.6.3.4, swap
|
2021-05-09 09:30:32 +08:00
|
|
|
void swap(optional &) noexcept(see below ); // constexpr in C++20
|
2016-10-12 15:46:20 +08:00
|
|
|
|
2017-04-18 04:15:16 +08:00
|
|
|
// 23.6.3.5, observers
|
2016-10-12 15:46:20 +08:00
|
|
|
constexpr T const *operator->() const;
|
|
|
|
constexpr T *operator->();
|
|
|
|
constexpr T const &operator*() const &;
|
|
|
|
constexpr T &operator*() &;
|
|
|
|
constexpr T &&operator*() &&;
|
|
|
|
constexpr const T &&operator*() const &&;
|
|
|
|
constexpr explicit operator bool() const noexcept;
|
|
|
|
constexpr bool has_value() const noexcept;
|
|
|
|
constexpr T const &value() const &;
|
|
|
|
constexpr T &value() &;
|
|
|
|
constexpr T &&value() &&;
|
|
|
|
constexpr const T &&value() const &&;
|
|
|
|
template <class U> constexpr T value_or(U &&) const &;
|
|
|
|
template <class U> constexpr T value_or(U &&) &&;
|
|
|
|
|
2021-12-16 03:54:24 +08:00
|
|
|
// [optional.monadic], monadic operations
|
|
|
|
template<class F> constexpr auto and_then(F&& f) &; // since C++23
|
|
|
|
template<class F> constexpr auto and_then(F&& f) &&; // since C++23
|
|
|
|
template<class F> constexpr auto and_then(F&& f) const&; // since C++23
|
|
|
|
template<class F> constexpr auto and_then(F&& f) const&&; // since C++23
|
|
|
|
template<class F> constexpr auto transform(F&& f) &; // since C++23
|
|
|
|
template<class F> constexpr auto transform(F&& f) &&; // since C++23
|
|
|
|
template<class F> constexpr auto transform(F&& f) const&; // since C++23
|
|
|
|
template<class F> constexpr auto transform(F&& f) const&&; // since C++23
|
|
|
|
template<class F> constexpr optional or_else(F&& f) &&; // since C++23
|
|
|
|
template<class F> constexpr optional or_else(F&& f) const&; // since C++23
|
|
|
|
|
2017-04-18 04:15:16 +08:00
|
|
|
// 23.6.3.6, modifiers
|
2021-05-09 09:30:32 +08:00
|
|
|
void reset() noexcept; // constexpr in C++20
|
2016-10-12 15:46:20 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
T *val; // exposition only
|
|
|
|
};
|
2018-05-25 10:08:49 +08:00
|
|
|
|
|
|
|
template<class T>
|
|
|
|
optional(T) -> optional<T>;
|
|
|
|
|
2016-10-12 15:46:20 +08:00
|
|
|
} // namespace std
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2022-03-26 00:55:36 +08:00
|
|
|
#include <__assert> // all public C++ headers provide the assertion handler
|
2020-11-05 04:01:25 +08:00
|
|
|
#include <__availability>
|
2021-12-16 03:54:24 +08:00
|
|
|
#include <__concepts/invocable.h>
|
2021-05-19 23:57:04 +08:00
|
|
|
#include <__config>
|
2022-04-17 22:01:38 +08:00
|
|
|
#include <__functional/hash.h>
|
|
|
|
#include <__functional/invoke.h>
|
|
|
|
#include <__functional/unary_function.h>
|
|
|
|
#include <__memory/construct_at.h>
|
|
|
|
#include <__tuple>
|
|
|
|
#include <__utility/forward.h>
|
2022-03-06 02:17:07 +08:00
|
|
|
#include <__utility/in_place.h>
|
2022-04-17 22:01:38 +08:00
|
|
|
#include <__utility/move.h>
|
2022-03-06 02:17:07 +08:00
|
|
|
#include <__utility/swap.h>
|
2016-10-12 15:46:20 +08:00
|
|
|
#include <initializer_list>
|
|
|
|
#include <new>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <type_traits>
|
2018-09-13 03:41:40 +08:00
|
|
|
#include <version>
|
2016-10-12 15:46:20 +08:00
|
|
|
|
[libc++] Re-add transitive includes that had been removed since LLVM 14
This commit re-adds transitive includes that had been removed by
4cd04d1687f1, c36870c8e79c, a83f4b9cda57, 1458458b558d, 2e2f3158c604,
and 489637e66dd3. This should cover almost all the includes that had
been removed since LLVM 14 and that would contribute to breaking user
code when releasing LLVM 15.
It is possible to disable the inclusion of these headers by defining
_LIBCPP_REMOVE_TRANSITIVE_INCLUDES. The intent is that vendors will
enable that macro and start fixing downstream issues immediately. We
can then remove the macro (and the transitive includes) by default in
a future release. That way, we will break users only once by removing
transitive includes in bulk instead of doing it bit by bit a every
release, which is more disruptive for users.
Note 1: The set of headers to re-add was found by re-generating the
transitive include test on a checkout of release/14.x, which
provided the list of all transitive includes we used to provide.
Note 2: Several includes of <vector>, <optional>, <array> and <unordered_map>
have been added in this commit. These transitive inclusions were
added when we implemented boyer_moore_searcher in <functional>.
Note 3: This is a best effort patch to try and resolve downstream breakage
caused since branching LLVM 14. I wasn't able to perfectly mirror
transitive includes in LLVM 14 for a few headers, so I added a
release note explaining it. To summarize, adding boyer_moore_searcher
created a bunch of circular dependencies, so we have to break
backwards compatibility in a few cases.
Differential Revision: https://reviews.llvm.org/D128661
2022-06-28 03:53:41 +08:00
|
|
|
#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
|
|
|
|
# include <atomic>
|
|
|
|
# include <chrono>
|
|
|
|
# include <climits>
|
|
|
|
# include <concepts>
|
|
|
|
# include <ctime>
|
|
|
|
# include <iterator>
|
|
|
|
# include <memory>
|
|
|
|
# include <ratio>
|
|
|
|
# include <tuple>
|
|
|
|
# include <typeinfo>
|
|
|
|
# include <utility>
|
|
|
|
# include <variant>
|
|
|
|
#endif
|
|
|
|
|
2022-06-17 04:43:46 +08:00
|
|
|
// standard-mandated includes
|
|
|
|
#include <compare>
|
|
|
|
|
2016-10-12 15:46:20 +08:00
|
|
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
2022-02-02 09:16:40 +08:00
|
|
|
# pragma GCC system_header
|
2016-10-12 15:46:20 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
namespace std // purposefully not using versioning namespace
|
|
|
|
{
|
|
|
|
|
2018-11-19 23:37:04 +08:00
|
|
|
class _LIBCPP_EXCEPTION_ABI _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS bad_optional_access
|
2017-02-06 04:06:38 +08:00
|
|
|
: public exception
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
// Get the key function ~bad_optional_access() into the dylib
|
2017-02-06 04:52:32 +08:00
|
|
|
virtual ~bad_optional_access() _NOEXCEPT;
|
2017-02-06 04:06:38 +08:00
|
|
|
virtual const char* what() const _NOEXCEPT;
|
2016-10-12 15:46:20 +08:00
|
|
|
};
|
|
|
|
|
2021-12-02 21:12:51 +08:00
|
|
|
} // namespace std
|
2016-10-12 15:46:20 +08:00
|
|
|
|
|
|
|
#if _LIBCPP_STD_VER > 14
|
|
|
|
|
|
|
|
_LIBCPP_BEGIN_NAMESPACE_STD
|
|
|
|
|
|
|
|
_LIBCPP_NORETURN
|
|
|
|
inline _LIBCPP_INLINE_VISIBILITY
|
2018-11-19 23:37:04 +08:00
|
|
|
_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
|
2016-10-12 15:46:20 +08:00
|
|
|
void __throw_bad_optional_access() {
|
|
|
|
#ifndef _LIBCPP_NO_EXCEPTIONS
|
|
|
|
throw bad_optional_access();
|
|
|
|
#else
|
|
|
|
_VSTD::abort();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
struct nullopt_t
|
|
|
|
{
|
|
|
|
struct __secret_tag { _LIBCPP_INLINE_VISIBILITY explicit __secret_tag() = default; };
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
|
|
|
|
};
|
|
|
|
|
2021-09-22 21:35:32 +08:00
|
|
|
inline constexpr nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
|
2016-10-12 15:46:20 +08:00
|
|
|
|
2021-12-16 03:54:24 +08:00
|
|
|
struct __optional_construct_from_invoke_tag {};
|
|
|
|
|
2016-10-12 15:46:20 +08:00
|
|
|
template <class _Tp, bool = is_trivially_destructible<_Tp>::value>
|
|
|
|
struct __optional_destruct_base;
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
struct __optional_destruct_base<_Tp, false>
|
|
|
|
{
|
|
|
|
typedef _Tp value_type;
|
|
|
|
static_assert(is_object_v<value_type>,
|
|
|
|
"instantiation of optional with a non-object type is undefined behavior");
|
|
|
|
union
|
|
|
|
{
|
|
|
|
char __null_state_;
|
|
|
|
value_type __val_;
|
|
|
|
};
|
|
|
|
bool __engaged_;
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 ~__optional_destruct_base()
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
if (__engaged_)
|
|
|
|
__val_.~value_type();
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr __optional_destruct_base() noexcept
|
|
|
|
: __null_state_(),
|
|
|
|
__engaged_(false) {}
|
|
|
|
|
|
|
|
template <class... _Args>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
|
|
|
|
: __val_(_VSTD::forward<_Args>(__args)...),
|
|
|
|
__engaged_(true) {}
|
|
|
|
|
2021-12-16 03:54:24 +08:00
|
|
|
#if _LIBCPP_STD_VER > 20
|
|
|
|
template <class _Fp, class... _Args>
|
|
|
|
_LIBCPP_HIDE_FROM_ABI
|
|
|
|
constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
|
|
|
|
: __val_(_VSTD::invoke(_VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...)), __engaged_(true) {}
|
|
|
|
#endif
|
|
|
|
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 void reset() noexcept
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
if (__engaged_)
|
|
|
|
{
|
|
|
|
__val_.~value_type();
|
|
|
|
__engaged_ = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
struct __optional_destruct_base<_Tp, true>
|
|
|
|
{
|
|
|
|
typedef _Tp value_type;
|
|
|
|
static_assert(is_object_v<value_type>,
|
|
|
|
"instantiation of optional with a non-object type is undefined behavior");
|
|
|
|
union
|
|
|
|
{
|
|
|
|
char __null_state_;
|
|
|
|
value_type __val_;
|
|
|
|
};
|
|
|
|
bool __engaged_;
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr __optional_destruct_base() noexcept
|
|
|
|
: __null_state_(),
|
|
|
|
__engaged_(false) {}
|
|
|
|
|
|
|
|
template <class... _Args>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
|
|
|
|
: __val_(_VSTD::forward<_Args>(__args)...),
|
|
|
|
__engaged_(true) {}
|
|
|
|
|
2021-12-16 03:54:24 +08:00
|
|
|
#if _LIBCPP_STD_VER > 20
|
|
|
|
template <class _Fp, class... _Args>
|
|
|
|
_LIBCPP_HIDE_FROM_ABI
|
|
|
|
constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
|
|
|
|
: __val_(_VSTD::invoke(_VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...)), __engaged_(true) {}
|
|
|
|
#endif
|
|
|
|
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 void reset() noexcept
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
if (__engaged_)
|
|
|
|
{
|
|
|
|
__engaged_ = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp, bool = is_reference<_Tp>::value>
|
|
|
|
struct __optional_storage_base : __optional_destruct_base<_Tp>
|
|
|
|
{
|
|
|
|
using __base = __optional_destruct_base<_Tp>;
|
|
|
|
using value_type = _Tp;
|
|
|
|
using __base::__base;
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr bool has_value() const noexcept
|
|
|
|
{
|
|
|
|
return this->__engaged_;
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr value_type& __get() & noexcept
|
|
|
|
{
|
|
|
|
return this->__val_;
|
|
|
|
}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr const value_type& __get() const& noexcept
|
|
|
|
{
|
|
|
|
return this->__val_;
|
|
|
|
}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr value_type&& __get() && noexcept
|
|
|
|
{
|
|
|
|
return _VSTD::move(this->__val_);
|
|
|
|
}
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr const value_type&& __get() const&& noexcept
|
|
|
|
{
|
|
|
|
return _VSTD::move(this->__val_);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... _Args>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct(_Args&&... __args)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
_LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
|
2021-05-09 09:30:32 +08:00
|
|
|
#if _LIBCPP_STD_VER > 17
|
|
|
|
_VSTD::construct_at(_VSTD::addressof(this->__val_), _VSTD::forward<_Args>(__args)...);
|
|
|
|
#else
|
2020-12-12 09:30:28 +08:00
|
|
|
::new ((void*)_VSTD::addressof(this->__val_)) value_type(_VSTD::forward<_Args>(__args)...);
|
2021-05-09 09:30:32 +08:00
|
|
|
#endif
|
2016-10-12 15:46:20 +08:00
|
|
|
this->__engaged_ = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _That>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct_from(_That&& __opt)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
if (__opt.has_value())
|
|
|
|
__construct(_VSTD::forward<_That>(__opt).__get());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _That>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 void __assign_from(_That&& __opt)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
if (this->__engaged_ == __opt.has_value())
|
|
|
|
{
|
|
|
|
if (this->__engaged_)
|
|
|
|
this->__val_ = _VSTD::forward<_That>(__opt).__get();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (this->__engaged_)
|
|
|
|
this->reset();
|
|
|
|
else
|
|
|
|
__construct(_VSTD::forward<_That>(__opt).__get());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-06-03 01:43:11 +08:00
|
|
|
// optional<T&> is currently required to be ill-formed. However, it may
|
|
|
|
// be allowed in the future. For this reason, it has already been implemented
|
|
|
|
// to ensure we can make the change in an ABI-compatible manner.
|
2016-10-12 15:46:20 +08:00
|
|
|
template <class _Tp>
|
|
|
|
struct __optional_storage_base<_Tp, true>
|
|
|
|
{
|
|
|
|
using value_type = _Tp;
|
|
|
|
using __raw_type = remove_reference_t<_Tp>;
|
|
|
|
__raw_type* __value_;
|
|
|
|
|
|
|
|
template <class _Up>
|
|
|
|
static constexpr bool __can_bind_reference() {
|
|
|
|
using _RawUp = typename remove_reference<_Up>::type;
|
|
|
|
using _UpPtr = _RawUp*;
|
|
|
|
using _RawTp = typename remove_reference<_Tp>::type;
|
|
|
|
using _TpPtr = _RawTp*;
|
|
|
|
using _CheckLValueArg = integral_constant<bool,
|
|
|
|
(is_lvalue_reference<_Up>::value && is_convertible<_UpPtr, _TpPtr>::value)
|
|
|
|
|| is_same<_RawUp, reference_wrapper<_RawTp>>::value
|
|
|
|
|| is_same<_RawUp, reference_wrapper<typename remove_const<_RawTp>::type>>::value
|
|
|
|
>;
|
|
|
|
return (is_lvalue_reference<_Tp>::value && _CheckLValueArg::value)
|
|
|
|
|| (is_rvalue_reference<_Tp>::value && !is_lvalue_reference<_Up>::value &&
|
|
|
|
is_convertible<_UpPtr, _TpPtr>::value);
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr __optional_storage_base() noexcept
|
|
|
|
: __value_(nullptr) {}
|
|
|
|
|
|
|
|
template <class _UArg>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr explicit __optional_storage_base(in_place_t, _UArg&& __uarg)
|
|
|
|
: __value_(_VSTD::addressof(__uarg))
|
|
|
|
{
|
|
|
|
static_assert(__can_bind_reference<_UArg>(),
|
|
|
|
"Attempted to construct a reference element in tuple from a "
|
|
|
|
"possible temporary");
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 void reset() noexcept { __value_ = nullptr; }
|
2016-10-12 15:46:20 +08:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr bool has_value() const noexcept
|
|
|
|
{ return __value_ != nullptr; }
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr value_type& __get() const& noexcept
|
|
|
|
{ return *__value_; }
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr value_type&& __get() const&& noexcept
|
|
|
|
{ return _VSTD::forward<value_type>(*__value_); }
|
|
|
|
|
|
|
|
template <class _UArg>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct(_UArg&& __val)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
_LIBCPP_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
|
|
|
|
static_assert(__can_bind_reference<_UArg>(),
|
|
|
|
"Attempted to construct a reference element in tuple from a "
|
|
|
|
"possible temporary");
|
|
|
|
__value_ = _VSTD::addressof(__val);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _That>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 void __construct_from(_That&& __opt)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
if (__opt.has_value())
|
|
|
|
__construct(_VSTD::forward<_That>(__opt).__get());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _That>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 void __assign_from(_That&& __opt)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
if (has_value() == __opt.has_value())
|
|
|
|
{
|
|
|
|
if (has_value())
|
|
|
|
*__value_ = _VSTD::forward<_That>(__opt).__get();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (has_value())
|
|
|
|
reset();
|
|
|
|
else
|
|
|
|
__construct(_VSTD::forward<_That>(__opt).__get());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-07-10 01:15:49 +08:00
|
|
|
template <class _Tp, bool = is_trivially_copy_constructible<_Tp>::value>
|
|
|
|
struct __optional_copy_base : __optional_storage_base<_Tp>
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
using __optional_storage_base<_Tp>::__optional_storage_base;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp>
|
2017-07-10 01:15:49 +08:00
|
|
|
struct __optional_copy_base<_Tp, false> : __optional_storage_base<_Tp>
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
using __optional_storage_base<_Tp>::__optional_storage_base;
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-07-10 01:15:49 +08:00
|
|
|
__optional_copy_base() = default;
|
2016-10-12 15:46:20 +08:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_copy_base(const __optional_copy_base& __opt)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
this->__construct_from(__opt);
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-07-10 01:15:49 +08:00
|
|
|
__optional_copy_base(__optional_copy_base&&) = default;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__optional_copy_base& operator=(const __optional_copy_base&) = default;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__optional_copy_base& operator=(__optional_copy_base&&) = default;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp, bool = is_trivially_move_constructible<_Tp>::value>
|
|
|
|
struct __optional_move_base : __optional_copy_base<_Tp>
|
|
|
|
{
|
|
|
|
using __optional_copy_base<_Tp>::__optional_copy_base;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
struct __optional_move_base<_Tp, false> : __optional_copy_base<_Tp>
|
|
|
|
{
|
|
|
|
using value_type = _Tp;
|
|
|
|
using __optional_copy_base<_Tp>::__optional_copy_base;
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__optional_move_base() = default;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__optional_move_base(const __optional_move_base&) = default;
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_move_base(__optional_move_base&& __opt)
|
2016-10-12 15:46:20 +08:00
|
|
|
noexcept(is_nothrow_move_constructible_v<value_type>)
|
|
|
|
{
|
|
|
|
this->__construct_from(_VSTD::move(__opt));
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-07-10 01:15:49 +08:00
|
|
|
__optional_move_base& operator=(const __optional_move_base&) = default;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__optional_move_base& operator=(__optional_move_base&&) = default;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp, bool =
|
|
|
|
is_trivially_destructible<_Tp>::value &&
|
|
|
|
is_trivially_copy_constructible<_Tp>::value &&
|
|
|
|
is_trivially_copy_assignable<_Tp>::value>
|
|
|
|
struct __optional_copy_assign_base : __optional_move_base<_Tp>
|
|
|
|
{
|
|
|
|
using __optional_move_base<_Tp>::__optional_move_base;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
struct __optional_copy_assign_base<_Tp, false> : __optional_move_base<_Tp>
|
|
|
|
{
|
|
|
|
using __optional_move_base<_Tp>::__optional_move_base;
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__optional_copy_assign_base() = default;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__optional_copy_assign_base(const __optional_copy_assign_base&) = default;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__optional_copy_assign_base(__optional_copy_assign_base&&) = default;
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
this->__assign_from(__opt);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-07-10 01:15:49 +08:00
|
|
|
__optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp, bool =
|
|
|
|
is_trivially_destructible<_Tp>::value &&
|
|
|
|
is_trivially_move_constructible<_Tp>::value &&
|
|
|
|
is_trivially_move_assignable<_Tp>::value>
|
|
|
|
struct __optional_move_assign_base : __optional_copy_assign_base<_Tp>
|
|
|
|
{
|
|
|
|
using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
struct __optional_move_assign_base<_Tp, false> : __optional_copy_assign_base<_Tp>
|
|
|
|
{
|
|
|
|
using value_type = _Tp;
|
|
|
|
using __optional_copy_assign_base<_Tp>::__optional_copy_assign_base;
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__optional_move_assign_base() = default;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__optional_move_assign_base(const __optional_move_assign_base& __opt) = default;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__optional_move_assign_base(__optional_move_assign_base&&) = default;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
__optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt)
|
2016-10-12 15:46:20 +08:00
|
|
|
noexcept(is_nothrow_move_assignable_v<value_type> &&
|
|
|
|
is_nothrow_move_constructible_v<value_type>)
|
|
|
|
{
|
|
|
|
this->__assign_from(_VSTD::move(__opt));
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
using __optional_sfinae_ctor_base_t = __sfinae_ctor_base<
|
|
|
|
is_copy_constructible<_Tp>::value,
|
|
|
|
is_move_constructible<_Tp>::value
|
|
|
|
>;
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
using __optional_sfinae_assign_base_t = __sfinae_assign_base<
|
|
|
|
(is_copy_constructible<_Tp>::value && is_copy_assignable<_Tp>::value),
|
|
|
|
(is_move_constructible<_Tp>::value && is_move_assignable<_Tp>::value)
|
|
|
|
>;
|
|
|
|
|
2021-12-16 03:54:24 +08:00
|
|
|
template<class _Tp>
|
|
|
|
class optional;
|
|
|
|
template <class _Tp>
|
|
|
|
struct __is_std_optional : false_type {};
|
|
|
|
template <class _Tp> struct __is_std_optional<optional<_Tp>> : true_type {};
|
|
|
|
|
2016-10-12 15:46:20 +08:00
|
|
|
template <class _Tp>
|
|
|
|
class optional
|
2017-07-10 01:15:49 +08:00
|
|
|
: private __optional_move_assign_base<_Tp>
|
2016-10-12 15:46:20 +08:00
|
|
|
, private __optional_sfinae_ctor_base_t<_Tp>
|
|
|
|
, private __optional_sfinae_assign_base_t<_Tp>
|
|
|
|
{
|
2017-07-10 01:15:49 +08:00
|
|
|
using __base = __optional_move_assign_base<_Tp>;
|
2016-10-12 15:46:20 +08:00
|
|
|
public:
|
|
|
|
using value_type = _Tp;
|
|
|
|
|
|
|
|
private:
|
|
|
|
// Disable the reference extension using this static assert.
|
2019-03-26 00:35:59 +08:00
|
|
|
static_assert(!is_same_v<__uncvref_t<value_type>, in_place_t>,
|
2016-10-12 15:46:20 +08:00
|
|
|
"instantiation of optional with in_place_t is ill-formed");
|
|
|
|
static_assert(!is_same_v<__uncvref_t<value_type>, nullopt_t>,
|
|
|
|
"instantiation of optional with nullopt_t is ill-formed");
|
|
|
|
static_assert(!is_reference_v<value_type>,
|
|
|
|
"instantiation of optional with a reference type is ill-formed");
|
|
|
|
static_assert(is_destructible_v<value_type>,
|
|
|
|
"instantiation of optional with a non-destructible type is ill-formed");
|
2019-03-26 00:35:59 +08:00
|
|
|
static_assert(!is_array_v<value_type>,
|
|
|
|
"instantiation of optional with an array type is ill-formed");
|
2016-10-12 15:46:20 +08:00
|
|
|
|
|
|
|
// LWG2756: conditionally explicit conversion from _Up
|
|
|
|
struct _CheckOptionalArgsConstructor {
|
|
|
|
template <class _Up>
|
|
|
|
static constexpr bool __enable_implicit() {
|
|
|
|
return is_constructible_v<_Tp, _Up&&> &&
|
|
|
|
is_convertible_v<_Up&&, _Tp>;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Up>
|
|
|
|
static constexpr bool __enable_explicit() {
|
|
|
|
return is_constructible_v<_Tp, _Up&&> &&
|
|
|
|
!is_convertible_v<_Up&&, _Tp>;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
template <class _Up>
|
2019-06-24 04:28:29 +08:00
|
|
|
using _CheckOptionalArgsCtor = _If<
|
|
|
|
_IsNotSame<__uncvref_t<_Up>, in_place_t>::value &&
|
|
|
|
_IsNotSame<__uncvref_t<_Up>, optional>::value,
|
2016-10-12 15:46:20 +08:00
|
|
|
_CheckOptionalArgsConstructor,
|
|
|
|
__check_tuple_constructor_fail
|
|
|
|
>;
|
|
|
|
template <class _QualUp>
|
|
|
|
struct _CheckOptionalLikeConstructor {
|
|
|
|
template <class _Up, class _Opt = optional<_Up>>
|
2019-06-24 04:28:29 +08:00
|
|
|
using __check_constructible_from_opt = _Or<
|
2016-10-12 15:46:20 +08:00
|
|
|
is_constructible<_Tp, _Opt&>,
|
|
|
|
is_constructible<_Tp, _Opt const&>,
|
|
|
|
is_constructible<_Tp, _Opt&&>,
|
|
|
|
is_constructible<_Tp, _Opt const&&>,
|
|
|
|
is_convertible<_Opt&, _Tp>,
|
|
|
|
is_convertible<_Opt const&, _Tp>,
|
|
|
|
is_convertible<_Opt&&, _Tp>,
|
|
|
|
is_convertible<_Opt const&&, _Tp>
|
|
|
|
>;
|
|
|
|
template <class _Up, class _Opt = optional<_Up>>
|
2019-06-24 04:28:29 +08:00
|
|
|
using __check_assignable_from_opt = _Or<
|
2016-10-12 15:46:20 +08:00
|
|
|
is_assignable<_Tp&, _Opt&>,
|
|
|
|
is_assignable<_Tp&, _Opt const&>,
|
|
|
|
is_assignable<_Tp&, _Opt&&>,
|
|
|
|
is_assignable<_Tp&, _Opt const&&>
|
|
|
|
>;
|
|
|
|
template <class _Up, class _QUp = _QualUp>
|
|
|
|
static constexpr bool __enable_implicit() {
|
|
|
|
return is_convertible<_QUp, _Tp>::value &&
|
|
|
|
!__check_constructible_from_opt<_Up>::value;
|
|
|
|
}
|
|
|
|
template <class _Up, class _QUp = _QualUp>
|
|
|
|
static constexpr bool __enable_explicit() {
|
|
|
|
return !is_convertible<_QUp, _Tp>::value &&
|
|
|
|
!__check_constructible_from_opt<_Up>::value;
|
|
|
|
}
|
|
|
|
template <class _Up, class _QUp = _QualUp>
|
|
|
|
static constexpr bool __enable_assign() {
|
2020-12-13 00:57:32 +08:00
|
|
|
// Construction and assignability of _QUp to _Tp has already been
|
2016-10-12 15:46:20 +08:00
|
|
|
// checked.
|
|
|
|
return !__check_constructible_from_opt<_Up>::value &&
|
|
|
|
!__check_assignable_from_opt<_Up>::value;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <class _Up, class _QualUp>
|
2019-06-24 04:28:29 +08:00
|
|
|
using _CheckOptionalLikeCtor = _If<
|
|
|
|
_And<
|
|
|
|
_IsNotSame<_Up, _Tp>,
|
2016-10-12 15:46:20 +08:00
|
|
|
is_constructible<_Tp, _QualUp>
|
|
|
|
>::value,
|
|
|
|
_CheckOptionalLikeConstructor<_QualUp>,
|
|
|
|
__check_tuple_constructor_fail
|
|
|
|
>;
|
|
|
|
template <class _Up, class _QualUp>
|
2019-06-24 04:28:29 +08:00
|
|
|
using _CheckOptionalLikeAssign = _If<
|
|
|
|
_And<
|
|
|
|
_IsNotSame<_Up, _Tp>,
|
2016-10-12 15:46:20 +08:00
|
|
|
is_constructible<_Tp, _QualUp>,
|
|
|
|
is_assignable<_Tp&, _QualUp>
|
|
|
|
>::value,
|
|
|
|
_CheckOptionalLikeConstructor<_QualUp>,
|
|
|
|
__check_tuple_constructor_fail
|
|
|
|
>;
|
2021-12-16 03:54:24 +08:00
|
|
|
|
2016-10-12 15:46:20 +08:00
|
|
|
public:
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr optional() noexcept {}
|
2017-05-17 23:30:01 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr optional(const optional&) = default;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr optional(optional&&) = default;
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr optional(nullopt_t) noexcept {}
|
|
|
|
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
template <class _InPlaceT, class... _Args, class = enable_if_t<
|
2019-06-24 04:28:29 +08:00
|
|
|
_And<
|
|
|
|
_IsSame<_InPlaceT, in_place_t>,
|
|
|
|
is_constructible<value_type, _Args...>
|
2019-03-12 06:55:21 +08:00
|
|
|
>::value
|
|
|
|
>
|
2016-10-12 15:46:20 +08:00
|
|
|
>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2019-03-12 06:55:21 +08:00
|
|
|
constexpr explicit optional(_InPlaceT, _Args&&... __args)
|
2016-10-12 15:46:20 +08:00
|
|
|
: __base(in_place, _VSTD::forward<_Args>(__args)...) {}
|
|
|
|
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
template <class _Up, class... _Args, class = enable_if_t<
|
2016-10-12 15:46:20 +08:00
|
|
|
is_constructible_v<value_type, initializer_list<_Up>&, _Args...>>
|
|
|
|
>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
|
|
|
|
: __base(in_place, __il, _VSTD::forward<_Args>(__args)...) {}
|
|
|
|
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
template <class _Up = value_type, enable_if_t<
|
2016-10-12 15:46:20 +08:00
|
|
|
_CheckOptionalArgsCtor<_Up>::template __enable_implicit<_Up>()
|
|
|
|
, int> = 0>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr optional(_Up&& __v)
|
|
|
|
: __base(in_place, _VSTD::forward<_Up>(__v)) {}
|
|
|
|
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
template <class _Up, enable_if_t<
|
2016-10-12 15:46:20 +08:00
|
|
|
_CheckOptionalArgsCtor<_Up>::template __enable_explicit<_Up>()
|
|
|
|
, int> = 0>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr explicit optional(_Up&& __v)
|
|
|
|
: __base(in_place, _VSTD::forward<_Up>(__v)) {}
|
|
|
|
|
|
|
|
// LWG2756: conditionally explicit conversion from const optional<_Up>&
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
template <class _Up, enable_if_t<
|
2016-10-12 15:46:20 +08:00
|
|
|
_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_implicit<_Up>()
|
|
|
|
, int> = 0>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 optional(const optional<_Up>& __v)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
this->__construct_from(__v);
|
|
|
|
}
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
template <class _Up, enable_if_t<
|
2016-10-12 15:46:20 +08:00
|
|
|
_CheckOptionalLikeCtor<_Up, _Up const&>::template __enable_explicit<_Up>()
|
|
|
|
, int> = 0>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 explicit optional(const optional<_Up>& __v)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
this->__construct_from(__v);
|
|
|
|
}
|
|
|
|
|
|
|
|
// LWG2756: conditionally explicit conversion from optional<_Up>&&
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
template <class _Up, enable_if_t<
|
2016-10-12 15:46:20 +08:00
|
|
|
_CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_implicit<_Up>()
|
|
|
|
, int> = 0>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 optional(optional<_Up>&& __v)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
this->__construct_from(_VSTD::move(__v));
|
|
|
|
}
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
template <class _Up, enable_if_t<
|
2016-10-12 15:46:20 +08:00
|
|
|
_CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_explicit<_Up>()
|
|
|
|
, int> = 0>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 explicit optional(optional<_Up>&& __v)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
this->__construct_from(_VSTD::move(__v));
|
|
|
|
}
|
|
|
|
|
2021-12-16 03:54:24 +08:00
|
|
|
#if _LIBCPP_STD_VER > 20
|
|
|
|
template<class _Fp, class... _Args>
|
|
|
|
_LIBCPP_HIDE_FROM_ABI
|
|
|
|
constexpr explicit optional(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
|
|
|
|
: __base(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Fp>(__f), _VSTD::forward<_Args>(__args)...) {
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 optional& operator=(nullopt_t) noexcept
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
reset();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY optional& operator=(const optional&) = default;
|
|
|
|
_LIBCPP_INLINE_VISIBILITY optional& operator=(optional&&) = default;
|
|
|
|
|
|
|
|
// LWG2756
|
|
|
|
template <class _Up = value_type,
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
class = enable_if_t<
|
2019-06-24 04:28:29 +08:00
|
|
|
_And<
|
|
|
|
_IsNotSame<__uncvref_t<_Up>, optional>,
|
|
|
|
_Or<
|
2019-06-28 02:40:55 +08:00
|
|
|
_IsNotSame<__uncvref_t<_Up>, value_type>,
|
2019-06-24 04:28:29 +08:00
|
|
|
_Not<is_scalar<value_type>>
|
2016-10-16 11:21:35 +08:00
|
|
|
>,
|
|
|
|
is_constructible<value_type, _Up>,
|
|
|
|
is_assignable<value_type&, _Up>
|
|
|
|
>::value>
|
2016-10-12 15:46:20 +08:00
|
|
|
>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 optional&
|
2016-10-12 15:46:20 +08:00
|
|
|
operator=(_Up&& __v)
|
|
|
|
{
|
|
|
|
if (this->has_value())
|
|
|
|
this->__get() = _VSTD::forward<_Up>(__v);
|
|
|
|
else
|
|
|
|
this->__construct(_VSTD::forward<_Up>(__v));
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// LWG2756
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
template <class _Up, enable_if_t<
|
2016-10-12 15:46:20 +08:00
|
|
|
_CheckOptionalLikeAssign<_Up, _Up const&>::template __enable_assign<_Up>()
|
|
|
|
, int> = 0>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 optional&
|
2016-10-12 15:46:20 +08:00
|
|
|
operator=(const optional<_Up>& __v)
|
|
|
|
{
|
|
|
|
this->__assign_from(__v);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// LWG2756
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
template <class _Up, enable_if_t<
|
2016-10-12 15:46:20 +08:00
|
|
|
_CheckOptionalLikeCtor<_Up, _Up &&>::template __enable_assign<_Up>()
|
|
|
|
, int> = 0>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 optional&
|
2016-10-12 15:46:20 +08:00
|
|
|
operator=(optional<_Up>&& __v)
|
|
|
|
{
|
|
|
|
this->__assign_from(_VSTD::move(__v));
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class... _Args,
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
class = enable_if_t
|
2016-10-12 15:46:20 +08:00
|
|
|
<
|
|
|
|
is_constructible_v<value_type, _Args...>
|
|
|
|
>
|
|
|
|
>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp &
|
2016-10-12 15:46:20 +08:00
|
|
|
emplace(_Args&&... __args)
|
|
|
|
{
|
|
|
|
reset();
|
|
|
|
this->__construct(_VSTD::forward<_Args>(__args)...);
|
2017-04-13 06:51:27 +08:00
|
|
|
return this->__get();
|
2016-10-12 15:46:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Up, class... _Args,
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
class = enable_if_t
|
2016-10-12 15:46:20 +08:00
|
|
|
<
|
|
|
|
is_constructible_v<value_type, initializer_list<_Up>&, _Args...>
|
|
|
|
>
|
|
|
|
>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 _Tp &
|
2016-10-12 15:46:20 +08:00
|
|
|
emplace(initializer_list<_Up> __il, _Args&&... __args)
|
|
|
|
{
|
|
|
|
reset();
|
|
|
|
this->__construct(__il, _VSTD::forward<_Args>(__args)...);
|
2017-04-13 06:51:27 +08:00
|
|
|
return this->__get();
|
2016-10-12 15:46:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-09 09:30:32 +08:00
|
|
|
_LIBCPP_CONSTEXPR_AFTER_CXX17 void swap(optional& __opt)
|
2016-10-12 15:46:20 +08:00
|
|
|
noexcept(is_nothrow_move_constructible_v<value_type> &&
|
|
|
|
is_nothrow_swappable_v<value_type>)
|
|
|
|
{
|
|
|
|
if (this->has_value() == __opt.has_value())
|
|
|
|
{
|
|
|
|
using _VSTD::swap;
|
|
|
|
if (this->has_value())
|
|
|
|
swap(this->__get(), __opt.__get());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (this->has_value())
|
|
|
|
{
|
|
|
|
__opt.__construct(_VSTD::move(this->__get()));
|
|
|
|
reset();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->__construct(_VSTD::move(__opt.__get()));
|
|
|
|
__opt.reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr
|
|
|
|
add_pointer_t<value_type const>
|
|
|
|
operator->() const
|
|
|
|
{
|
2021-05-10 01:29:56 +08:00
|
|
|
_LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value");
|
2016-10-12 15:46:20 +08:00
|
|
|
return _VSTD::addressof(this->__get());
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr
|
|
|
|
add_pointer_t<value_type>
|
|
|
|
operator->()
|
|
|
|
{
|
2021-05-10 01:29:56 +08:00
|
|
|
_LIBCPP_ASSERT(this->has_value(), "optional operator-> called on a disengaged value");
|
2016-10-12 15:46:20 +08:00
|
|
|
return _VSTD::addressof(this->__get());
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr
|
|
|
|
const value_type&
|
2021-07-02 01:18:27 +08:00
|
|
|
operator*() const& noexcept
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
2021-05-10 01:29:56 +08:00
|
|
|
_LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
|
2016-10-12 15:46:20 +08:00
|
|
|
return this->__get();
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr
|
|
|
|
value_type&
|
2021-07-02 01:18:27 +08:00
|
|
|
operator*() & noexcept
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
2021-05-10 01:29:56 +08:00
|
|
|
_LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
|
2016-10-12 15:46:20 +08:00
|
|
|
return this->__get();
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr
|
|
|
|
value_type&&
|
2021-07-02 01:18:27 +08:00
|
|
|
operator*() && noexcept
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
2021-05-10 01:29:56 +08:00
|
|
|
_LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
|
2016-10-12 15:46:20 +08:00
|
|
|
return _VSTD::move(this->__get());
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr
|
|
|
|
const value_type&&
|
2021-07-02 01:18:27 +08:00
|
|
|
operator*() const&& noexcept
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
2021-05-10 01:29:56 +08:00
|
|
|
_LIBCPP_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
|
2016-10-12 15:46:20 +08:00
|
|
|
return _VSTD::move(this->__get());
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr explicit operator bool() const noexcept { return has_value(); }
|
|
|
|
|
|
|
|
using __base::has_value;
|
|
|
|
using __base::__get;
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2018-11-19 23:37:04 +08:00
|
|
|
_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
|
2016-10-12 15:46:20 +08:00
|
|
|
constexpr value_type const& value() const&
|
|
|
|
{
|
|
|
|
if (!this->has_value())
|
|
|
|
__throw_bad_optional_access();
|
|
|
|
return this->__get();
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2018-11-19 23:37:04 +08:00
|
|
|
_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
|
2016-10-12 15:46:20 +08:00
|
|
|
constexpr value_type& value() &
|
|
|
|
{
|
|
|
|
if (!this->has_value())
|
|
|
|
__throw_bad_optional_access();
|
|
|
|
return this->__get();
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2018-11-19 23:37:04 +08:00
|
|
|
_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
|
2016-10-12 15:46:20 +08:00
|
|
|
constexpr value_type&& value() &&
|
|
|
|
{
|
|
|
|
if (!this->has_value())
|
|
|
|
__throw_bad_optional_access();
|
|
|
|
return _VSTD::move(this->__get());
|
|
|
|
}
|
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2018-11-19 23:37:04 +08:00
|
|
|
_LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
|
2016-10-12 15:46:20 +08:00
|
|
|
constexpr value_type const&& value() const&&
|
|
|
|
{
|
|
|
|
if (!this->has_value())
|
|
|
|
__throw_bad_optional_access();
|
|
|
|
return _VSTD::move(this->__get());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Up>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
|
|
|
constexpr value_type value_or(_Up&& __v) const&
|
|
|
|
{
|
|
|
|
static_assert(is_copy_constructible_v<value_type>,
|
|
|
|
"optional<T>::value_or: T must be copy constructible");
|
|
|
|
static_assert(is_convertible_v<_Up, value_type>,
|
|
|
|
"optional<T>::value_or: U must be convertible to T");
|
|
|
|
return this->has_value() ? this->__get() :
|
|
|
|
static_cast<value_type>(_VSTD::forward<_Up>(__v));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Up>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2017-06-07 02:47:26 +08:00
|
|
|
constexpr value_type value_or(_Up&& __v) &&
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
static_assert(is_move_constructible_v<value_type>,
|
|
|
|
"optional<T>::value_or: T must be move constructible");
|
|
|
|
static_assert(is_convertible_v<_Up, value_type>,
|
|
|
|
"optional<T>::value_or: U must be convertible to T");
|
|
|
|
return this->has_value() ? _VSTD::move(this->__get()) :
|
|
|
|
static_cast<value_type>(_VSTD::forward<_Up>(__v));
|
|
|
|
}
|
|
|
|
|
2021-12-16 03:54:24 +08:00
|
|
|
#if _LIBCPP_STD_VER > 20
|
|
|
|
template<class _Func>
|
2022-02-15 22:34:04 +08:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
|
2021-12-16 03:54:24 +08:00
|
|
|
constexpr auto and_then(_Func&& __f) & {
|
|
|
|
using _Up = invoke_result_t<_Func, value_type&>;
|
|
|
|
static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
|
|
|
|
"Result of f(value()) must be a specialization of std::optional");
|
|
|
|
if (*this)
|
|
|
|
return _VSTD::invoke(_VSTD::forward<_Func>(__f), value());
|
|
|
|
return remove_cvref_t<_Up>();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _Func>
|
2022-02-15 22:34:04 +08:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
|
2021-12-16 03:54:24 +08:00
|
|
|
constexpr auto and_then(_Func&& __f) const& {
|
|
|
|
using _Up = invoke_result_t<_Func, const value_type&>;
|
|
|
|
static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
|
|
|
|
"Result of f(value()) must be a specialization of std::optional");
|
|
|
|
if (*this)
|
|
|
|
return _VSTD::invoke(_VSTD::forward<_Func>(__f), value());
|
|
|
|
return remove_cvref_t<_Up>();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _Func>
|
2022-02-15 22:34:04 +08:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
|
2021-12-16 03:54:24 +08:00
|
|
|
constexpr auto and_then(_Func&& __f) && {
|
|
|
|
using _Up = invoke_result_t<_Func, value_type&&>;
|
|
|
|
static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
|
|
|
|
"Result of f(std::move(value())) must be a specialization of std::optional");
|
|
|
|
if (*this)
|
|
|
|
return _VSTD::invoke(_VSTD::forward<_Func>(__f), _VSTD::move(value()));
|
|
|
|
return remove_cvref_t<_Up>();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _Func>
|
|
|
|
_LIBCPP_HIDE_FROM_ABI
|
|
|
|
constexpr auto and_then(_Func&& __f) const&& {
|
|
|
|
using _Up = invoke_result_t<_Func, const value_type&&>;
|
|
|
|
static_assert(__is_std_optional<remove_cvref_t<_Up>>::value,
|
|
|
|
"Result of f(std::move(value())) must be a specialization of std::optional");
|
|
|
|
if (*this)
|
|
|
|
return _VSTD::invoke(_VSTD::forward<_Func>(__f), _VSTD::move(value()));
|
|
|
|
return remove_cvref_t<_Up>();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _Func>
|
2022-02-15 22:34:04 +08:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
|
2021-12-16 03:54:24 +08:00
|
|
|
constexpr auto transform(_Func&& __f) & {
|
|
|
|
using _Up = remove_cv_t<invoke_result_t<_Func, value_type&>>;
|
|
|
|
static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
|
|
|
|
static_assert(!is_same_v<_Up, in_place_t>,
|
|
|
|
"Result of f(value()) should not be std::in_place_t");
|
|
|
|
static_assert(!is_same_v<_Up, nullopt_t>,
|
|
|
|
"Result of f(value()) should not be std::nullopt_t");
|
|
|
|
static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
|
|
|
|
if (*this)
|
|
|
|
return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), value());
|
|
|
|
return optional<_Up>();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _Func>
|
2022-02-15 22:34:04 +08:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
|
2021-12-16 03:54:24 +08:00
|
|
|
constexpr auto transform(_Func&& __f) const& {
|
|
|
|
using _Up = remove_cv_t<invoke_result_t<_Func, const value_type&>>;
|
|
|
|
static_assert(!is_array_v<_Up>, "Result of f(value()) should not be an Array");
|
|
|
|
static_assert(!is_same_v<_Up, in_place_t>,
|
|
|
|
"Result of f(value()) should not be std::in_place_t");
|
|
|
|
static_assert(!is_same_v<_Up, nullopt_t>,
|
|
|
|
"Result of f(value()) should not be std::nullopt_t");
|
|
|
|
static_assert(is_object_v<_Up>, "Result of f(value()) should be an object type");
|
|
|
|
if (*this)
|
|
|
|
return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), value());
|
|
|
|
return optional<_Up>();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _Func>
|
2022-02-15 22:34:04 +08:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
|
2021-12-16 03:54:24 +08:00
|
|
|
constexpr auto transform(_Func&& __f) && {
|
|
|
|
using _Up = remove_cv_t<invoke_result_t<_Func, value_type&&>>;
|
|
|
|
static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
|
|
|
|
static_assert(!is_same_v<_Up, in_place_t>,
|
|
|
|
"Result of f(std::move(value())) should not be std::in_place_t");
|
|
|
|
static_assert(!is_same_v<_Up, nullopt_t>,
|
|
|
|
"Result of f(std::move(value())) should not be std::nullopt_t");
|
|
|
|
static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
|
|
|
|
if (*this)
|
|
|
|
return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), _VSTD::move(value()));
|
|
|
|
return optional<_Up>();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class _Func>
|
2022-02-15 22:34:04 +08:00
|
|
|
_LIBCPP_HIDE_FROM_ABI _LIBCPP_AVAILABILITY_THROW_BAD_OPTIONAL_ACCESS
|
2021-12-16 03:54:24 +08:00
|
|
|
constexpr auto transform(_Func&& __f) const&& {
|
|
|
|
using _Up = remove_cvref_t<invoke_result_t<_Func, const value_type&&>>;
|
|
|
|
static_assert(!is_array_v<_Up>, "Result of f(std::move(value())) should not be an Array");
|
|
|
|
static_assert(!is_same_v<_Up, in_place_t>,
|
|
|
|
"Result of f(std::move(value())) should not be std::in_place_t");
|
|
|
|
static_assert(!is_same_v<_Up, nullopt_t>,
|
|
|
|
"Result of f(std::move(value())) should not be std::nullopt_t");
|
|
|
|
static_assert(is_object_v<_Up>, "Result of f(std::move(value())) should be an object type");
|
|
|
|
if (*this)
|
|
|
|
return optional<_Up>(__optional_construct_from_invoke_tag{}, _VSTD::forward<_Func>(__f), _VSTD::move(value()));
|
|
|
|
return optional<_Up>();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<invocable _Func>
|
|
|
|
_LIBCPP_HIDE_FROM_ABI
|
|
|
|
constexpr optional or_else(_Func&& __f) const& requires is_copy_constructible_v<value_type> {
|
|
|
|
static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
|
|
|
|
"Result of f() should be the same type as this optional");
|
|
|
|
if (*this)
|
|
|
|
return *this;
|
|
|
|
return _VSTD::forward<_Func>(__f)();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<invocable _Func>
|
|
|
|
_LIBCPP_HIDE_FROM_ABI
|
|
|
|
constexpr optional or_else(_Func&& __f) && requires is_move_constructible_v<value_type> {
|
|
|
|
static_assert(is_same_v<remove_cvref_t<invoke_result_t<_Func>>, optional>,
|
|
|
|
"Result of f() should be the same type as this optional");
|
|
|
|
if (*this)
|
|
|
|
return _VSTD::move(*this);
|
|
|
|
return _VSTD::forward<_Func>(__f)();
|
|
|
|
}
|
|
|
|
#endif // _LIBCPP_STD_VER > 20
|
|
|
|
|
2016-10-12 15:46:20 +08:00
|
|
|
using __base::reset;
|
|
|
|
};
|
|
|
|
|
2021-08-17 23:59:07 +08:00
|
|
|
#if _LIBCPP_STD_VER >= 17
|
2022-01-11 01:00:10 +08:00
|
|
|
template<class _Tp>
|
|
|
|
optional(_Tp) -> optional<_Tp>;
|
2018-05-25 10:08:49 +08:00
|
|
|
#endif
|
|
|
|
|
2016-10-12 15:46:20 +08:00
|
|
|
// Comparisons between optionals
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() ==
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
if (static_cast<bool>(__x) != static_cast<bool>(__y))
|
|
|
|
return false;
|
|
|
|
if (!static_cast<bool>(__x))
|
|
|
|
return true;
|
|
|
|
return *__x == *__y;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() !=
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
if (static_cast<bool>(__x) != static_cast<bool>(__y))
|
|
|
|
return true;
|
|
|
|
if (!static_cast<bool>(__x))
|
|
|
|
return false;
|
|
|
|
return *__x != *__y;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() <
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
if (!static_cast<bool>(__y))
|
|
|
|
return false;
|
|
|
|
if (!static_cast<bool>(__x))
|
|
|
|
return true;
|
|
|
|
return *__x < *__y;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() >
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
if (!static_cast<bool>(__x))
|
|
|
|
return false;
|
|
|
|
if (!static_cast<bool>(__y))
|
|
|
|
return true;
|
|
|
|
return *__x > *__y;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() <=
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
if (!static_cast<bool>(__x))
|
|
|
|
return true;
|
|
|
|
if (!static_cast<bool>(__y))
|
|
|
|
return false;
|
|
|
|
return *__x <= *__y;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() >=
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
if (!static_cast<bool>(__y))
|
|
|
|
return true;
|
|
|
|
if (!static_cast<bool>(__x))
|
|
|
|
return false;
|
|
|
|
return *__x >= *__y;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Comparisons with nullopt
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
bool
|
|
|
|
operator==(const optional<_Tp>& __x, nullopt_t) noexcept
|
|
|
|
{
|
|
|
|
return !static_cast<bool>(__x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
bool
|
|
|
|
operator==(nullopt_t, const optional<_Tp>& __x) noexcept
|
|
|
|
{
|
|
|
|
return !static_cast<bool>(__x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
bool
|
|
|
|
operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
|
|
|
|
{
|
|
|
|
return static_cast<bool>(__x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
bool
|
|
|
|
operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
|
|
|
|
{
|
|
|
|
return static_cast<bool>(__x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
bool
|
|
|
|
operator<(const optional<_Tp>&, nullopt_t) noexcept
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
bool
|
|
|
|
operator<(nullopt_t, const optional<_Tp>& __x) noexcept
|
|
|
|
{
|
|
|
|
return static_cast<bool>(__x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
bool
|
|
|
|
operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
|
|
|
|
{
|
|
|
|
return !static_cast<bool>(__x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
bool
|
2016-12-24 07:37:52 +08:00
|
|
|
operator<=(nullopt_t, const optional<_Tp>&) noexcept
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
bool
|
|
|
|
operator>(const optional<_Tp>& __x, nullopt_t) noexcept
|
|
|
|
{
|
|
|
|
return static_cast<bool>(__x);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
bool
|
2016-12-24 07:37:52 +08:00
|
|
|
operator>(nullopt_t, const optional<_Tp>&) noexcept
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
bool
|
|
|
|
operator>=(const optional<_Tp>&, nullopt_t) noexcept
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
bool
|
|
|
|
operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
|
|
|
|
{
|
|
|
|
return !static_cast<bool>(__x);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Comparisons with T
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() ==
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator==(const optional<_Tp>& __x, const _Up& __v)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
return static_cast<bool>(__x) ? *__x == __v : false;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() ==
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator==(const _Tp& __v, const optional<_Up>& __x)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
return static_cast<bool>(__x) ? __v == *__x : false;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() !=
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator!=(const optional<_Tp>& __x, const _Up& __v)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
return static_cast<bool>(__x) ? *__x != __v : true;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() !=
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator!=(const _Tp& __v, const optional<_Up>& __x)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
return static_cast<bool>(__x) ? __v != *__x : true;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() <
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator<(const optional<_Tp>& __x, const _Up& __v)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
return static_cast<bool>(__x) ? *__x < __v : true;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() <
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator<(const _Tp& __v, const optional<_Up>& __x)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
return static_cast<bool>(__x) ? __v < *__x : false;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() <=
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator<=(const optional<_Tp>& __x, const _Up& __v)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
return static_cast<bool>(__x) ? *__x <= __v : true;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() <=
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator<=(const _Tp& __v, const optional<_Up>& __x)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
return static_cast<bool>(__x) ? __v <= *__x : false;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() >
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator>(const optional<_Tp>& __x, const _Up& __v)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
return static_cast<bool>(__x) ? *__x > __v : false;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() >
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator>(const _Tp& __v, const optional<_Up>& __x)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
return static_cast<bool>(__x) ? __v > *__x : true;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() >=
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator>=(const optional<_Tp>& __x, const _Up& __v)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
return static_cast<bool>(__x) ? *__x >= __v : false;
|
|
|
|
}
|
|
|
|
|
2017-03-31 04:06:52 +08:00
|
|
|
template <class _Tp, class _Up>
|
2016-10-12 15:46:20 +08:00
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2021-05-11 01:04:16 +08:00
|
|
|
is_convertible_v<decltype(declval<const _Tp&>() >=
|
|
|
|
declval<const _Up&>()), bool>,
|
2016-10-12 15:46:20 +08:00
|
|
|
bool
|
|
|
|
>
|
2017-03-31 04:06:52 +08:00
|
|
|
operator>=(const _Tp& __v, const optional<_Up>& __x)
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
|
|
|
return static_cast<bool>(__x) ? __v >= *__x : true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <class _Tp>
|
2021-05-09 09:30:32 +08:00
|
|
|
inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
|
[libc++] Use enable_if_t instead of _EnableIf
I just ran into a compiler error involving __bind_back and some overloads
that were being disabled with _EnableIf. I noticed that the error message
was quite bad and did not mention the reason for the overload being
excluded. Specifically, the error looked like this:
candidate template ignored: substitution failure [with _Args =
<ContiguousView>]: no member named '_EnableIfImpl' in 'std::_MetaBase<false>'
Instead, when using enable_if or enable_if_t, the compiler is clever and
can produce better diagnostics, like so:
candidate template ignored: requirement 'is_invocable_v<
std::__bind_back_op<1, std::integer_sequence<unsigned long, 0>>,
std::ranges::views::__transform::__fn &, std::tuple<PlusOne> &,
ContiguousView>' was not satisfied [with _Args = <ContiguousView>]
Basically, it tries to do a poor man's implementation of concepts, which
is already a lot better than simply complaining about substitution failure.
Hence, this commit uses enable_if_t instead of _EnableIf whenever
possible. That is both more straightforward than using the internal
helper, and also leads to better error messages in those cases.
I understand the motivation for _EnableIf's implementation was to improve
compile-time performance, however I believe striving to improve error
messages is even more important for our QOI, hence this patch. Furthermore,
it is unclear that _EnableIf actually improved compile-time performance
in any noticeable way (see discussion in the review for details).
Differential Revision: https://reviews.llvm.org/D108216
2021-08-18 00:26:09 +08:00
|
|
|
enable_if_t<
|
2016-10-12 15:46:20 +08:00
|
|
|
is_move_constructible_v<_Tp> && is_swappable_v<_Tp>,
|
|
|
|
void
|
|
|
|
>
|
|
|
|
swap(optional<_Tp>& __x, optional<_Tp>& __y) noexcept(noexcept(__x.swap(__y)))
|
|
|
|
{
|
|
|
|
__x.swap(__y);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
optional<decay_t<_Tp>> make_optional(_Tp&& __v)
|
|
|
|
{
|
|
|
|
return optional<decay_t<_Tp>>(_VSTD::forward<_Tp>(__v));
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class... _Args>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
optional<_Tp> make_optional(_Args&&... __args)
|
|
|
|
{
|
|
|
|
return optional<_Tp>(in_place, _VSTD::forward<_Args>(__args)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp, class _Up, class... _Args>
|
|
|
|
_LIBCPP_INLINE_VISIBILITY constexpr
|
|
|
|
optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args)
|
|
|
|
{
|
|
|
|
return optional<_Tp>(in_place, __il, _VSTD::forward<_Args>(__args)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class _Tp>
|
2017-01-21 08:02:12 +08:00
|
|
|
struct _LIBCPP_TEMPLATE_VIS hash<
|
|
|
|
__enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>
|
|
|
|
>
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
2021-05-26 02:34:18 +08:00
|
|
|
#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
|
|
|
|
_LIBCPP_DEPRECATED_IN_CXX17 typedef optional<_Tp> argument_type;
|
|
|
|
_LIBCPP_DEPRECATED_IN_CXX17 typedef size_t result_type;
|
|
|
|
#endif
|
2016-10-12 15:46:20 +08:00
|
|
|
|
|
|
|
_LIBCPP_INLINE_VISIBILITY
|
2021-05-26 02:34:18 +08:00
|
|
|
size_t operator()(const optional<_Tp>& __opt) const
|
2016-10-12 15:46:20 +08:00
|
|
|
{
|
2017-01-21 08:02:12 +08:00
|
|
|
return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
|
2016-10-12 15:46:20 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
_LIBCPP_END_NAMESPACE_STD
|
|
|
|
|
2021-04-21 00:03:32 +08:00
|
|
|
#endif // _LIBCPP_STD_VER > 14
|
2016-10-12 15:46:20 +08:00
|
|
|
|
2021-04-21 00:03:32 +08:00
|
|
|
#endif // _LIBCPP_OPTIONAL
|