[INFRA] Import NVIDIA/CCCL upstream as optimization reference library
CCCL (CUDA C++ Core Libraries) provides: - CUB: device/block/warp-level GPU primitives (reduce, scan, sort, topk) - Thrust: high-level parallel algorithms (transform_reduce, sort, scan) - libcudacxx: CUDA C++ standard library (atomics, barriers, memory) - cudax: experimental features (memory resources, allocators) - Tuning policies: per-SM hardware-specific algorithm parameters Competition optimization vectors mapped to CCCL: - Output TPS (83% weight): warp_reduce, block_reduce, device_topk - Input TPS (14% weight): device_scan, block_load, prefetch - Cache TPS (3% weight): prefix caching strategy patterns - Memory (0.9 util): pooled/cached/buddy allocators Source: https://github.com/NVIDIA/cccl (shallow clone, HEAD only) License: Apache-2.0
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of libcu++, the C++ Standard Library for your entire system,
|
||||
// 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
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___OPTIONAL_BAD_OPTIONAL_ACCESS_H
|
||||
#define _CUDA_STD___OPTIONAL_BAD_OPTIONAL_ACCESS_H
|
||||
|
||||
#include <cuda/std/detail/__config>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#if _CCCL_HAS_EXCEPTIONS()
|
||||
# if __cpp_lib_optional >= 201606L
|
||||
# include <optional>
|
||||
# else // ^^^ __cpp_lib_optional >= 201606L ^^^ / vvv __cpp_lib_optional < 201606L vvv
|
||||
# include <exception>
|
||||
# endif // ^^^ __cpp_lib_optional < 201606L ^^^
|
||||
#endif // _CCCL_HAS_EXCEPTIONS()
|
||||
|
||||
#include <cuda/std/__exception/terminate.h>
|
||||
|
||||
#include <nv/target>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
#if _CCCL_HAS_EXCEPTIONS()
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD_NOVERSION
|
||||
|
||||
# if __cpp_lib_optional >= 201606L
|
||||
|
||||
using ::std::bad_optional_access;
|
||||
|
||||
# else // ^^^ __cpp_lib_optional >= 201606L ^^^ / vvv __cpp_lib_optional < 201606L vvv
|
||||
class _CCCL_TYPE_VISIBILITY_DEFAULT bad_optional_access : public ::std::exception
|
||||
{
|
||||
public:
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return "bad access to cuda::std::optional";
|
||||
}
|
||||
};
|
||||
# endif // ^^^ __cpp_lib_optional < 201606L ^^^
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD_NOVERSION
|
||||
#endif // _CCCL_HAS_EXCEPTIONS()
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
[[noreturn]] _CCCL_API inline void __throw_bad_optional_access()
|
||||
{
|
||||
#if _CCCL_HAS_EXCEPTIONS()
|
||||
NV_IF_ELSE_TARGET(NV_IS_HOST, (throw ::cuda::std::bad_optional_access();), (::cuda::std::terminate();))
|
||||
#else // ^^^ !_CCCL_HAS_EXCEPTIONS() ^^^ / vvv _CCCL_HAS_EXCEPTIONS() vvv
|
||||
::cuda::std::terminate();
|
||||
#endif // _CCCL_HAS_EXCEPTIONS()
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___OPTIONAL_BAD_OPTIONAL_ACCESS_H
|
||||
53
cccl_upstream/libcudacxx/include/cuda/std/__optional/hash.h
Normal file
53
cccl_upstream/libcudacxx/include/cuda/std/__optional/hash.h
Normal file
@@ -0,0 +1,53 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of libcu++, the C++ Standard Library for your entire system,
|
||||
// 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
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___OPTIONAL_HASH_H
|
||||
#define _CUDA_STD___OPTIONAL_HASH_H
|
||||
|
||||
#include <cuda/std/detail/__config>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <cuda/std/__fwd/hash.h>
|
||||
#include <cuda/std/__optional/optional.h>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
#ifndef __cuda_std__
|
||||
|
||||
template <class _Tp>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT hash<__enable_hash_helper<optional<_Tp>, remove_const_t<_Tp>>>
|
||||
{
|
||||
# if _CCCL_STD_VER <= 2017 || defined(_LIBCUDACXX_ENABLE_CXX20_REMOVED_BINDER_TYPEDEFS)
|
||||
using argument_type CCCL_DEPRECATED = optional<_Tp>;
|
||||
using result_type CCCL_DEPRECATED = size_t;
|
||||
# endif
|
||||
|
||||
_CCCL_API inline size_t operator()(const optional<_Tp>& __opt) const
|
||||
{
|
||||
return static_cast<bool>(__opt) ? hash<remove_const_t<_Tp>>()(*__opt) : 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __cuda_std__
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___OPTIONAL_HASH_H
|
||||
@@ -0,0 +1,61 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of libcu++, the C++ Standard Library for your entire system,
|
||||
// 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
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___OPTIONAL_MAKE_OPTIONAL_H
|
||||
#define _CUDA_STD___OPTIONAL_MAKE_OPTIONAL_H
|
||||
|
||||
#include <cuda/std/detail/__config>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <cuda/std/__optional/optional.h>
|
||||
#include <cuda/std/__type_traits/decay.h>
|
||||
#include <cuda/std/__type_traits/is_reference.h>
|
||||
#include <cuda/std/__type_traits/is_same.h>
|
||||
#include <cuda/std/__utility/forward.h>
|
||||
#include <cuda/std/__utility/in_place.h>
|
||||
#include <cuda/std/initializer_list>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
_CCCL_TEMPLATE(class _Tp = nullopt_t::__secret_tag, class _Up)
|
||||
_CCCL_REQUIRES(is_same_v<_Tp, nullopt_t::__secret_tag>)
|
||||
_CCCL_API constexpr optional<decay_t<_Up>> make_optional(_Up&& __v)
|
||||
{
|
||||
return optional<decay_t<_Up>>(::cuda::std::forward<_Up>(__v));
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Tp, class... _Args)
|
||||
_CCCL_REQUIRES((!is_reference_v<_Tp>) )
|
||||
_CCCL_API constexpr optional<_Tp> make_optional(_Args&&... __args)
|
||||
{
|
||||
return optional<_Tp>(in_place_t{}, ::cuda::std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Tp, class _Up, class... _Args)
|
||||
_CCCL_REQUIRES((!is_reference_v<_Tp>) )
|
||||
_CCCL_API constexpr optional<_Tp> make_optional(initializer_list<_Up> __il, _Args&&... __args)
|
||||
{
|
||||
return optional<_Tp>(in_place_t{}, __il, ::cuda::std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___OPTIONAL_MAKE_OPTIONAL_H
|
||||
@@ -0,0 +1,43 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of libcu++, the C++ Standard Library for your entire system,
|
||||
// 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
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___OPTIONAL_NULLOPT_H
|
||||
#define _CUDA_STD___OPTIONAL_NULLOPT_H
|
||||
|
||||
#include <cuda/std/detail/__config>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
struct nullopt_t
|
||||
{
|
||||
struct __secret_tag
|
||||
{
|
||||
_CCCL_HIDE_FROM_ABI explicit __secret_tag() = default;
|
||||
};
|
||||
_CCCL_API constexpr explicit nullopt_t(__secret_tag, __secret_tag) noexcept {}
|
||||
};
|
||||
|
||||
_CCCL_GLOBAL_CONSTANT nullopt_t nullopt{nullopt_t::__secret_tag{}, nullopt_t::__secret_tag{}};
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___OPTIONAL_NULLOPT_H
|
||||
833
cccl_upstream/libcudacxx/include/cuda/std/__optional/optional.h
Normal file
833
cccl_upstream/libcudacxx/include/cuda/std/__optional/optional.h
Normal file
@@ -0,0 +1,833 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of libcu++, the C++ Standard Library for your entire system,
|
||||
// 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
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___OPTIONAL_OPTIONAL_H
|
||||
#define _CUDA_STD___OPTIONAL_OPTIONAL_H
|
||||
|
||||
#include <cuda/std/detail/__config>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <cuda/std/__concepts/concept_macros.h>
|
||||
#include <cuda/std/__concepts/invocable.h>
|
||||
#include <cuda/std/__functional/invoke.h>
|
||||
#include <cuda/std/__fwd/optional.h>
|
||||
#include <cuda/std/__memory/addressof.h>
|
||||
#include <cuda/std/__optional/bad_optional_access.h>
|
||||
#include <cuda/std/__optional/nullopt.h>
|
||||
#include <cuda/std/__optional/optional_base.h>
|
||||
#include <cuda/std/__type_traits/disjunction.h>
|
||||
#include <cuda/std/__type_traits/is_convertible.h>
|
||||
#include <cuda/std/__type_traits/is_copy_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_move_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_object.h>
|
||||
#include <cuda/std/__type_traits/is_reference.h>
|
||||
#include <cuda/std/__type_traits/is_same.h>
|
||||
#include <cuda/std/__type_traits/reference_constructs_from_temporary.h>
|
||||
#include <cuda/std/__type_traits/reference_converts_from_temporary.h>
|
||||
#include <cuda/std/__type_traits/remove_cv.h>
|
||||
#include <cuda/std/__type_traits/remove_cvref.h>
|
||||
#include <cuda/std/__utility/declval.h>
|
||||
#include <cuda/std/__utility/forward.h>
|
||||
#include <cuda/std/__utility/in_place.h>
|
||||
#include <cuda/std/__utility/move.h>
|
||||
#include <cuda/std/__utility/swap.h>
|
||||
#include <cuda/std/initializer_list>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_DIAG_PUSH
|
||||
_CCCL_DIAG_SUPPRESS_MSVC(4702) // suppress bogus unreachable code warning
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
// Constraints
|
||||
template <class _Tp, class _Up, class _Opt = optional<_Up>>
|
||||
using __opt_check_constructible_from_opt =
|
||||
_Or<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 _Tp, class _Up, class _Opt = optional<_Up>>
|
||||
using __opt_check_assignable_from_opt =
|
||||
_Or<is_assignable<_Tp&, _Opt&>,
|
||||
is_assignable<_Tp&, _Opt const&>,
|
||||
is_assignable<_Tp&, _Opt&&>,
|
||||
is_assignable<_Tp&, _Opt const&&>>;
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
inline constexpr bool __opt_is_implictly_constructible = is_constructible_v<_Tp, _Up> && is_convertible_v<_Up, _Tp>;
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
inline constexpr bool __opt_is_explictly_constructible = is_constructible_v<_Tp, _Up> && !is_convertible_v<_Up, _Tp>;
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
inline constexpr bool __opt_is_constructible_from_U =
|
||||
!is_same_v<remove_cvref_t<_Up>, in_place_t> && !is_same_v<remove_cvref_t<_Up>, optional<_Tp>>;
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
inline constexpr bool __opt_is_constructible_from_opt =
|
||||
!is_same_v<_Up, _Tp> && !__opt_check_constructible_from_opt<_Tp, _Up>::value;
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
inline constexpr bool __opt_is_assignable = is_constructible_v<_Tp, _Up> && is_assignable_v<_Tp&, _Up>;
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
inline constexpr bool __opt_is_assignable_from_U =
|
||||
!is_same_v<remove_cvref_t<_Up>, optional<_Tp>> && (!is_same_v<remove_cvref_t<_Up>, _Tp> || !is_scalar_v<_Tp>);
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
inline constexpr bool __opt_is_assignable_from_opt =
|
||||
!is_same_v<_Up, _Tp> && !__opt_check_constructible_from_opt<_Tp, _Up>::value
|
||||
&& !__opt_check_assignable_from_opt<_Tp, _Up>::value;
|
||||
|
||||
template <class _Tp>
|
||||
class optional : private __optional_move_assign_base<_Tp>
|
||||
{
|
||||
using __base = __optional_move_assign_base<_Tp>;
|
||||
|
||||
template <class>
|
||||
friend class optional;
|
||||
|
||||
public:
|
||||
using value_type = _Tp;
|
||||
|
||||
private:
|
||||
// Disable the reference extension using this static assert.
|
||||
static_assert(!is_same_v<remove_cvref_t<value_type>, in_place_t>,
|
||||
"instantiation of optional with in_place_t is ill-formed");
|
||||
static_assert(!is_same_v<remove_cvref_t<value_type>, nullopt_t>,
|
||||
"instantiation of optional with nullopt_t is ill-formed");
|
||||
static_assert(is_destructible_v<value_type>, "instantiation of optional with a non-destructible type is ill-formed");
|
||||
static_assert(!is_array_v<value_type>, "instantiation of optional with an array type is ill-formed");
|
||||
|
||||
public:
|
||||
// Use of {} vs = default is deliberate. = default may value-initialize, while {} is
|
||||
// guaranteed to do absolutely nothing.
|
||||
_CCCL_API constexpr optional() noexcept {} // NOLINT(modernize-use-equals-default)
|
||||
_CCCL_HIDE_FROM_ABI constexpr optional(const optional&) = default;
|
||||
_CCCL_HIDE_FROM_ABI constexpr optional(optional&&) = default;
|
||||
_CCCL_API constexpr optional(nullopt_t) noexcept {}
|
||||
|
||||
_CCCL_TEMPLATE(class _In_place_t, class... _Args)
|
||||
_CCCL_REQUIRES(is_same_v<_In_place_t, in_place_t> _CCCL_AND is_constructible_v<value_type, _Args...>)
|
||||
_CCCL_API constexpr explicit optional(_In_place_t, _Args&&... __args)
|
||||
: __base(in_place_t{}, ::cuda::std::forward<_Args>(__args)...)
|
||||
{}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up, class... _Args)
|
||||
_CCCL_REQUIRES(is_constructible_v<value_type, initializer_list<_Up>&, _Args...>)
|
||||
_CCCL_API constexpr explicit optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
|
||||
: __base(in_place_t{}, __il, ::cuda::std::forward<_Args>(__args)...)
|
||||
{}
|
||||
|
||||
// NOLINTBEGIN(bugprone-forwarding-reference-overload)
|
||||
_CCCL_TEMPLATE(class _Up = value_type)
|
||||
_CCCL_REQUIRES(__opt_is_constructible_from_U<_Tp, _Up> _CCCL_AND __opt_is_implictly_constructible<_Tp, _Up>)
|
||||
_CCCL_API constexpr optional(_Up&& __v)
|
||||
: __base(in_place_t{}, ::cuda::std::forward<_Up>(__v))
|
||||
{}
|
||||
// NOLINTEND(bugprone-forwarding-reference-overload)
|
||||
|
||||
// NOLINTBEGIN(bugprone-forwarding-reference-overload)
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__opt_is_constructible_from_U<_Tp, _Up> _CCCL_AND __opt_is_explictly_constructible<_Tp, _Up>)
|
||||
_CCCL_API constexpr explicit optional(_Up&& __v)
|
||||
: __base(in_place_t{}, ::cuda::std::forward<_Up>(__v))
|
||||
{}
|
||||
// NOLINTEND(bugprone-forwarding-reference-overload)
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__opt_is_constructible_from_opt<_Tp, _Up> _CCCL_AND __opt_is_implictly_constructible<_Tp, const _Up&>)
|
||||
_CCCL_API constexpr optional(const optional<_Up>& __v)
|
||||
{
|
||||
this->__construct_from(__v);
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__opt_is_constructible_from_opt<_Tp, _Up> _CCCL_AND __opt_is_explictly_constructible<_Tp, const _Up&>)
|
||||
_CCCL_API constexpr explicit optional(const optional<_Up>& __v)
|
||||
{
|
||||
this->__construct_from(__v);
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES((is_same_v<remove_cv_t<_Tp>, bool> || __opt_is_constructible_from_opt<_Tp, _Up>)
|
||||
_CCCL_AND __opt_is_implictly_constructible<_Tp, const _Up&>)
|
||||
_CCCL_API constexpr optional(const optional<_Up&>& __v)
|
||||
{
|
||||
this->__construct_from(__v);
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES((is_same_v<remove_cv_t<_Tp>, bool> || __opt_is_constructible_from_opt<_Tp, _Up>)
|
||||
_CCCL_AND __opt_is_explictly_constructible<_Tp, const _Up&>)
|
||||
_CCCL_API constexpr explicit optional(const optional<_Up&>& __v)
|
||||
{
|
||||
this->__construct_from(__v);
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__opt_is_constructible_from_opt<_Tp, _Up> _CCCL_AND
|
||||
__opt_is_implictly_constructible<_Tp, _Up> _CCCL_AND(!is_reference_v<_Up>))
|
||||
_CCCL_API constexpr optional(optional<_Up>&& __v)
|
||||
{
|
||||
this->__construct_from(::cuda::std::move(__v));
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__opt_is_constructible_from_opt<_Tp, _Up> _CCCL_AND
|
||||
__opt_is_explictly_constructible<_Tp, _Up> _CCCL_AND(!is_reference_v<_Up>))
|
||||
_CCCL_API constexpr explicit optional(optional<_Up>&& __v)
|
||||
{
|
||||
this->__construct_from(::cuda::std::move(__v));
|
||||
}
|
||||
|
||||
private:
|
||||
template <class _Fp, class... _Args>
|
||||
_CCCL_API constexpr explicit optional(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
|
||||
: __base(__optional_construct_from_invoke_tag{},
|
||||
::cuda::std::forward<_Fp>(__f),
|
||||
::cuda::std::forward<_Args>(__args)...)
|
||||
{}
|
||||
|
||||
public:
|
||||
_CCCL_API constexpr optional& operator=(nullopt_t) noexcept
|
||||
{
|
||||
reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr optional& operator=(const optional&) = default;
|
||||
constexpr optional& operator=(optional&&) = default;
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
_CCCL_TEMPLATE(class _Up = value_type)
|
||||
_CCCL_REQUIRES(__opt_is_assignable_from_U<_Tp, _Up> _CCCL_AND __opt_is_assignable<_Tp, _Up>)
|
||||
_CCCL_API constexpr optional& operator=(_Up&& __v)
|
||||
{
|
||||
if (this->has_value())
|
||||
{
|
||||
this->__get() = ::cuda::std::forward<_Up>(__v);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->__construct(::cuda::std::forward<_Up>(__v));
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES((!is_reference_v<_Up>)
|
||||
_CCCL_AND __opt_is_assignable_from_opt<_Tp, _Up> _CCCL_AND __opt_is_assignable<_Tp, const _Up&>)
|
||||
_CCCL_API constexpr optional& operator=(const optional<_Up>& __v)
|
||||
{
|
||||
this->__assign_from(__v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(
|
||||
is_reference_v<_Up> _CCCL_AND __opt_is_assignable_from_opt<_Tp, _Up&> _CCCL_AND __opt_is_assignable<_Tp, _Up&>)
|
||||
_CCCL_API constexpr optional& operator=(const optional<_Up>& __v)
|
||||
{
|
||||
this->__assign_from(__v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__opt_is_assignable_from_opt<_Tp, _Up> _CCCL_AND __opt_is_assignable<_Tp, _Up>)
|
||||
_CCCL_API constexpr optional& operator=(optional<_Up>&& __v)
|
||||
{
|
||||
this->__assign_from(::cuda::std::move(__v));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class... _Args, enable_if_t<is_constructible_v<value_type, _Args...>, int> = 0>
|
||||
_CCCL_API constexpr _Tp& emplace(_Args&&... __args)
|
||||
{
|
||||
reset();
|
||||
this->__construct(::cuda::std::forward<_Args>(__args)...);
|
||||
return this->__get();
|
||||
}
|
||||
|
||||
template <class _Up,
|
||||
class... _Args,
|
||||
enable_if_t<is_constructible_v<value_type, initializer_list<_Up>&, _Args...>, int> = 0>
|
||||
_CCCL_API constexpr _Tp& emplace(initializer_list<_Up> __il, _Args&&... __args)
|
||||
{
|
||||
reset();
|
||||
this->__construct(__il, ::cuda::std::forward<_Args>(__args)...);
|
||||
return this->__get();
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
_CCCL_API constexpr void
|
||||
swap(optional& __opt) noexcept(is_nothrow_move_constructible_v<value_type> && is_nothrow_swappable_v<value_type>)
|
||||
{
|
||||
if (this->has_value() == __opt.has_value())
|
||||
{
|
||||
using ::cuda::std::swap;
|
||||
if (this->has_value())
|
||||
{
|
||||
swap(this->__get(), __opt.__get());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->has_value())
|
||||
{
|
||||
__opt.__construct(::cuda::std::move(this->__get()));
|
||||
reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
this->__construct(::cuda::std::move(__opt.__get()));
|
||||
__opt.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_CCCL_API constexpr add_pointer_t<value_type const> operator->() const
|
||||
{
|
||||
_CCCL_ASSERT(this->has_value(), "optional operator-> called on a disengaged value");
|
||||
return ::cuda::std::addressof(this->__get());
|
||||
}
|
||||
|
||||
_CCCL_API constexpr add_pointer_t<value_type> operator->()
|
||||
{
|
||||
_CCCL_ASSERT(this->has_value(), "optional operator-> called on a disengaged value");
|
||||
return ::cuda::std::addressof(this->__get());
|
||||
}
|
||||
|
||||
_CCCL_API constexpr const value_type& operator*() const& noexcept
|
||||
{
|
||||
_CCCL_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
|
||||
return this->__get();
|
||||
}
|
||||
|
||||
_CCCL_API constexpr value_type& operator*() & noexcept
|
||||
{
|
||||
_CCCL_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
|
||||
return this->__get();
|
||||
}
|
||||
|
||||
_CCCL_API constexpr value_type&& operator*() && noexcept
|
||||
{
|
||||
_CCCL_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
|
||||
return ::cuda::std::move(this->__get());
|
||||
}
|
||||
|
||||
_CCCL_API constexpr const value_type&& operator*() const&& noexcept
|
||||
{
|
||||
_CCCL_ASSERT(this->has_value(), "optional operator* called on a disengaged value");
|
||||
return ::cuda::std::move(this->__get());
|
||||
}
|
||||
|
||||
_CCCL_API constexpr explicit operator bool() const noexcept
|
||||
{
|
||||
return has_value();
|
||||
}
|
||||
|
||||
using __base::__get;
|
||||
using __base::__set_engaged;
|
||||
using __base::has_value;
|
||||
|
||||
_CCCL_API constexpr value_type const& value() const&
|
||||
{
|
||||
if (!this->has_value())
|
||||
{
|
||||
__throw_bad_optional_access();
|
||||
}
|
||||
return this->__get();
|
||||
}
|
||||
|
||||
_CCCL_API constexpr value_type& value() &
|
||||
{
|
||||
if (!this->has_value())
|
||||
{
|
||||
__throw_bad_optional_access();
|
||||
}
|
||||
return this->__get();
|
||||
}
|
||||
|
||||
_CCCL_API constexpr value_type&& value() &&
|
||||
{
|
||||
if (!this->has_value())
|
||||
{
|
||||
__throw_bad_optional_access();
|
||||
}
|
||||
return ::cuda::std::move(this->__get());
|
||||
}
|
||||
|
||||
_CCCL_API constexpr value_type const&& value() const&&
|
||||
{
|
||||
if (!this->has_value())
|
||||
{
|
||||
__throw_bad_optional_access();
|
||||
}
|
||||
return ::cuda::std::move(this->__get());
|
||||
}
|
||||
|
||||
template <class _Up>
|
||||
_CCCL_API 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>(::cuda::std::forward<_Up>(__v));
|
||||
}
|
||||
|
||||
template <class _Up>
|
||||
_CCCL_API constexpr value_type value_or(_Up&& __v) &&
|
||||
{
|
||||
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() ? ::cuda::std::move(this->__get())
|
||||
: static_cast<value_type>(::cuda::std::forward<_Up>(__v));
|
||||
}
|
||||
|
||||
template <class _Func>
|
||||
_CCCL_API constexpr auto and_then(_Func&& __f) &
|
||||
{
|
||||
using _Up = invoke_result_t<_Func, value_type&>;
|
||||
static_assert(__is_cuda_std_optional_v<remove_cvref_t<_Up>>,
|
||||
"Result of f(value()) must be a specialization of std::optional");
|
||||
if (this->__engaged_)
|
||||
{
|
||||
return ::cuda::std::invoke(::cuda::std::forward<_Func>(__f), this->__get());
|
||||
}
|
||||
return remove_cvref_t<_Up>();
|
||||
}
|
||||
|
||||
template <class _Func>
|
||||
_CCCL_API constexpr auto and_then(_Func&& __f) const&
|
||||
{
|
||||
using _Up = invoke_result_t<_Func, const value_type&>;
|
||||
static_assert(__is_cuda_std_optional_v<remove_cvref_t<_Up>>,
|
||||
"Result of f(value()) must be a specialization of std::optional");
|
||||
if (this->__engaged_)
|
||||
{
|
||||
return ::cuda::std::invoke(::cuda::std::forward<_Func>(__f), this->__get());
|
||||
}
|
||||
return remove_cvref_t<_Up>();
|
||||
}
|
||||
|
||||
template <class _Func>
|
||||
_CCCL_API constexpr auto and_then(_Func&& __f) &&
|
||||
{
|
||||
using _Up = invoke_result_t<_Func, value_type&&>;
|
||||
static_assert(__is_cuda_std_optional_v<remove_cvref_t<_Up>>,
|
||||
"Result of f(std::move(value())) must be a specialization of std::optional");
|
||||
if (this->__engaged_)
|
||||
{
|
||||
return ::cuda::std::invoke(::cuda::std::forward<_Func>(__f), ::cuda::std::move(this->__get()));
|
||||
}
|
||||
return remove_cvref_t<_Up>();
|
||||
}
|
||||
|
||||
template <class _Func>
|
||||
_CCCL_API constexpr auto and_then(_Func&& __f) const&&
|
||||
{
|
||||
using _Up = invoke_result_t<_Func, const value_type&&>;
|
||||
static_assert(__is_cuda_std_optional_v<remove_cvref_t<_Up>>,
|
||||
"Result of f(std::move(value())) must be a specialization of std::optional");
|
||||
if (this->__engaged_)
|
||||
{
|
||||
return ::cuda::std::invoke(::cuda::std::forward<_Func>(__f), ::cuda::std::move(this->__get()));
|
||||
}
|
||||
return remove_cvref_t<_Up>();
|
||||
}
|
||||
|
||||
template <class _Func>
|
||||
_CCCL_API 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->__engaged_)
|
||||
{
|
||||
return optional<_Up>(__optional_construct_from_invoke_tag{}, ::cuda::std::forward<_Func>(__f), this->__get());
|
||||
}
|
||||
return optional<_Up>();
|
||||
}
|
||||
|
||||
template <class _Func>
|
||||
_CCCL_API 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->__engaged_)
|
||||
{
|
||||
return optional<_Up>(__optional_construct_from_invoke_tag{}, ::cuda::std::forward<_Func>(__f), this->__get());
|
||||
}
|
||||
return optional<_Up>();
|
||||
}
|
||||
|
||||
template <class _Func>
|
||||
_CCCL_API 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->__engaged_)
|
||||
{
|
||||
return optional<_Up>(
|
||||
__optional_construct_from_invoke_tag{}, ::cuda::std::forward<_Func>(__f), ::cuda::std::move(this->__get()));
|
||||
}
|
||||
return optional<_Up>();
|
||||
}
|
||||
|
||||
template <class _Func>
|
||||
_CCCL_API 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->__engaged_)
|
||||
{
|
||||
return optional<_Up>(
|
||||
__optional_construct_from_invoke_tag{}, ::cuda::std::forward<_Func>(__f), ::cuda::std::move(this->__get()));
|
||||
}
|
||||
return optional<_Up>();
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Func, class _Tp2 = _Tp)
|
||||
_CCCL_REQUIRES(invocable<_Func> _CCCL_AND is_copy_constructible_v<_Tp2>)
|
||||
_CCCL_API constexpr optional or_else(_Func&& __f) const&
|
||||
{
|
||||
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->__engaged_)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
return ::cuda::std::forward<_Func>(__f)();
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Func, class _Tp2 = _Tp)
|
||||
_CCCL_REQUIRES(invocable<_Func> _CCCL_AND is_move_constructible_v<_Tp2>)
|
||||
_CCCL_API constexpr optional or_else(_Func&& __f) &&
|
||||
{
|
||||
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->__engaged_)
|
||||
{
|
||||
return ::cuda::std::move(*this);
|
||||
}
|
||||
return ::cuda::std::forward<_Func>(__f)();
|
||||
}
|
||||
|
||||
using __base::reset;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_DEDUCTION_GUIDE_ATTRIBUTES optional(_Tp) -> optional<_Tp>;
|
||||
|
||||
// Comparisons between optionals
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() == declval<const _Up&>()), bool>, bool>
|
||||
operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
|
||||
{
|
||||
if (static_cast<bool>(__x) != static_cast<bool>(__y))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!static_cast<bool>(__x))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return *__x == *__y;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() != declval<const _Up&>()), bool>, bool>
|
||||
operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
|
||||
{
|
||||
if (static_cast<bool>(__x) != static_cast<bool>(__y))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!static_cast<bool>(__x))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return *__x != *__y;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() < declval<const _Up&>()), bool>, bool>
|
||||
operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
|
||||
{
|
||||
if (!static_cast<bool>(__y))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!static_cast<bool>(__x))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return *__x < *__y;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() > declval<const _Up&>()), bool>, bool>
|
||||
operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
|
||||
{
|
||||
if (!static_cast<bool>(__x))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!static_cast<bool>(__y))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return *__x > *__y;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() <= declval<const _Up&>()), bool>, bool>
|
||||
operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
|
||||
{
|
||||
if (!static_cast<bool>(__x))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!static_cast<bool>(__y))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return *__x <= *__y;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() >= declval<const _Up&>()), bool>, bool>
|
||||
operator>=(const optional<_Tp>& __x, const optional<_Up>& __y)
|
||||
{
|
||||
if (!static_cast<bool>(__y))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!static_cast<bool>(__x))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return *__x >= *__y;
|
||||
}
|
||||
|
||||
// Comparisons with nullopt
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr bool operator==(const optional<_Tp>& __x, nullopt_t) noexcept
|
||||
{
|
||||
return !static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr bool operator==(nullopt_t, const optional<_Tp>& __x) noexcept
|
||||
{
|
||||
return !static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr bool operator!=(const optional<_Tp>& __x, nullopt_t) noexcept
|
||||
{
|
||||
return static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr bool operator!=(nullopt_t, const optional<_Tp>& __x) noexcept
|
||||
{
|
||||
return static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr bool operator<(const optional<_Tp>&, nullopt_t) noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr bool operator<(nullopt_t, const optional<_Tp>& __x) noexcept
|
||||
{
|
||||
return static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr bool operator<=(const optional<_Tp>& __x, nullopt_t) noexcept
|
||||
{
|
||||
return !static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr bool operator<=(nullopt_t, const optional<_Tp>&) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr bool operator>(const optional<_Tp>& __x, nullopt_t) noexcept
|
||||
{
|
||||
return static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr bool operator>(nullopt_t, const optional<_Tp>&) noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr bool operator>=(const optional<_Tp>&, nullopt_t) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr bool operator>=(nullopt_t, const optional<_Tp>& __x) noexcept
|
||||
{
|
||||
return !static_cast<bool>(__x);
|
||||
}
|
||||
|
||||
// Comparisons with T
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() == declval<const _Up&>()), bool>, bool>
|
||||
operator==(const optional<_Tp>& __x, const _Up& __v)
|
||||
{
|
||||
return static_cast<bool>(__x) ? *__x == __v : false;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() == declval<const _Up&>()), bool>, bool>
|
||||
operator==(const _Tp& __v, const optional<_Up>& __x)
|
||||
{
|
||||
return static_cast<bool>(__x) ? __v == *__x : false;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() != declval<const _Up&>()), bool>, bool>
|
||||
operator!=(const optional<_Tp>& __x, const _Up& __v)
|
||||
{
|
||||
return static_cast<bool>(__x) ? *__x != __v : true;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() != declval<const _Up&>()), bool>, bool>
|
||||
operator!=(const _Tp& __v, const optional<_Up>& __x)
|
||||
{
|
||||
return static_cast<bool>(__x) ? __v != *__x : true;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() < declval<const _Up&>()), bool>, bool>
|
||||
operator<(const optional<_Tp>& __x, const _Up& __v)
|
||||
{
|
||||
return static_cast<bool>(__x) ? *__x < __v : true;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() < declval<const _Up&>()), bool>, bool>
|
||||
operator<(const _Tp& __v, const optional<_Up>& __x)
|
||||
{
|
||||
return static_cast<bool>(__x) ? __v < *__x : false;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() <= declval<const _Up&>()), bool>, bool>
|
||||
operator<=(const optional<_Tp>& __x, const _Up& __v)
|
||||
{
|
||||
return static_cast<bool>(__x) ? *__x <= __v : true;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() <= declval<const _Up&>()), bool>, bool>
|
||||
operator<=(const _Tp& __v, const optional<_Up>& __x)
|
||||
{
|
||||
return static_cast<bool>(__x) ? __v <= *__x : false;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() > declval<const _Up&>()), bool>, bool>
|
||||
operator>(const optional<_Tp>& __x, const _Up& __v)
|
||||
{
|
||||
return static_cast<bool>(__x) ? *__x > __v : false;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() > declval<const _Up&>()), bool>, bool>
|
||||
operator>(const _Tp& __v, const optional<_Up>& __x)
|
||||
{
|
||||
return static_cast<bool>(__x) ? __v > *__x : true;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() >= declval<const _Up&>()), bool>, bool>
|
||||
operator>=(const optional<_Tp>& __x, const _Up& __v)
|
||||
{
|
||||
return static_cast<bool>(__x) ? *__x >= __v : false;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, class _Up>
|
||||
_CCCL_API constexpr enable_if_t<is_convertible_v<decltype(declval<const _Tp&>() >= declval<const _Up&>()), bool>, bool>
|
||||
operator>=(const _Tp& __v, const optional<_Up>& __x)
|
||||
{
|
||||
return static_cast<bool>(__x) ? __v >= *__x : true;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr enable_if_t<is_reference_v<_Tp> || (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);
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
_CCCL_DIAG_POP
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___OPTIONAL_OPTIONAL_H
|
||||
@@ -0,0 +1,442 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of libcu++, the C++ Standard Library for your entire system,
|
||||
// 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
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___OPTIONAL_OPTIONAL_BASE_H
|
||||
#define _CUDA_STD___OPTIONAL_OPTIONAL_BASE_H
|
||||
|
||||
#include <cuda/std/detail/__config>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <cuda/std/__functional/invoke.h>
|
||||
#include <cuda/std/__memory/construct_at.h>
|
||||
#include <cuda/std/__tuple_dir/sfinae_helpers.h>
|
||||
#include <cuda/std/__type_traits/is_copy_assignable.h>
|
||||
#include <cuda/std/__type_traits/is_copy_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_destructible.h>
|
||||
#include <cuda/std/__type_traits/is_move_assignable.h>
|
||||
#include <cuda/std/__type_traits/is_move_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_nothrow_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_nothrow_copy_assignable.h>
|
||||
#include <cuda/std/__type_traits/is_nothrow_copy_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_nothrow_default_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_nothrow_move_assignable.h>
|
||||
#include <cuda/std/__type_traits/is_nothrow_move_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_object.h>
|
||||
#include <cuda/std/__type_traits/is_trivially_copy_assignable.h>
|
||||
#include <cuda/std/__type_traits/is_trivially_copy_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_trivially_destructible.h>
|
||||
#include <cuda/std/__type_traits/is_trivially_move_assignable.h>
|
||||
#include <cuda/std/__type_traits/is_trivially_move_constructible.h>
|
||||
#include <cuda/std/__type_traits/remove_cv.h>
|
||||
#include <cuda/std/__utility/delegate_constructors.h>
|
||||
#include <cuda/std/__utility/forward.h>
|
||||
#include <cuda/std/__utility/in_place.h>
|
||||
#include <cuda/std/__utility/move.h>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_DIAG_PUSH
|
||||
_CCCL_DIAG_SUPPRESS_MSVC(4702) // suppress bogus unreachable code warning
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
struct __optional_construct_from_invoke_tag
|
||||
{};
|
||||
|
||||
template <class _Tp, bool = is_trivially_destructible_v<_Tp>>
|
||||
struct __optional_destruct_base;
|
||||
|
||||
template <class _Tp>
|
||||
struct __optional_destruct_base<_Tp, false>
|
||||
{
|
||||
using value_type = _Tp;
|
||||
static_assert(is_object_v<value_type>, "instantiation of optional with a non-object type is undefined behavior");
|
||||
union __storage
|
||||
{
|
||||
char __null_state_;
|
||||
remove_cv_t<value_type> __val_;
|
||||
|
||||
_CCCL_API constexpr __storage() noexcept
|
||||
: __null_state_()
|
||||
{}
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class... _Args>
|
||||
_CCCL_API constexpr __storage(in_place_t,
|
||||
_Args&&... __args) noexcept(is_nothrow_constructible_v<value_type, _Args...>)
|
||||
: __val_(::cuda::std::forward<_Args>(__args)...)
|
||||
{}
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Fp, class... _Args>
|
||||
_CCCL_API constexpr __storage(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
|
||||
: __val_(::cuda::std::invoke(::cuda::std::forward<_Fp>(__f), ::cuda::std::forward<_Args>(__args)...))
|
||||
{}
|
||||
_CCCL_API _CCCL_CONSTEXPR_CXX20 ~__storage() noexcept {}
|
||||
};
|
||||
__storage __storage_;
|
||||
bool __engaged_;
|
||||
|
||||
// The held value may throw an exception, but the standard explicitly defines the destructor
|
||||
// for optional "normally", i.e. without `noexcept(false)`. We take this to mean that the
|
||||
// optional should call then call `std::terminate()` in the case of thrown exceptions.
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
_CCCL_API inline _CCCL_CONSTEXPR_CXX20 ~__optional_destruct_base() // NOLINT(bugprone-exception-escape)
|
||||
{
|
||||
if (__engaged_)
|
||||
{
|
||||
__storage_.__val_.~value_type();
|
||||
}
|
||||
}
|
||||
|
||||
_CCCL_API constexpr __optional_destruct_base() noexcept
|
||||
: __storage_()
|
||||
, __engaged_(false)
|
||||
{}
|
||||
|
||||
template <class... _Args>
|
||||
_CCCL_API constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) noexcept(
|
||||
is_nothrow_constructible_v<value_type, _Args...>)
|
||||
: __storage_(in_place_t{}, ::cuda::std::forward<_Args>(__args)...)
|
||||
, __engaged_(true)
|
||||
{}
|
||||
|
||||
template <class _Fp, class... _Args>
|
||||
_CCCL_API constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
|
||||
: __storage_(__optional_construct_from_invoke_tag{},
|
||||
::cuda::std::forward<_Fp>(__f),
|
||||
::cuda::std::forward<_Args>(__args)...)
|
||||
, __engaged_(true)
|
||||
{}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
_CCCL_API inline _CCCL_CONSTEXPR_CXX20 void reset() noexcept
|
||||
{
|
||||
if (__engaged_)
|
||||
{
|
||||
__storage_.__val_.~value_type();
|
||||
__engaged_ = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __optional_destruct_base<_Tp, true>
|
||||
{
|
||||
using value_type = _Tp;
|
||||
static_assert(is_object_v<value_type>, "instantiation of optional with a non-object type is undefined behavior");
|
||||
union __storage
|
||||
{
|
||||
char __null_state_;
|
||||
remove_cv_t<value_type> __val_;
|
||||
|
||||
_CCCL_API constexpr __storage() noexcept
|
||||
: __null_state_()
|
||||
{}
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class... _Args>
|
||||
_CCCL_API constexpr __storage(in_place_t,
|
||||
_Args&&... __args) noexcept(is_nothrow_constructible_v<value_type, _Args...>)
|
||||
: __val_(::cuda::std::forward<_Args>(__args)...)
|
||||
{}
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Fp, class... _Args>
|
||||
_CCCL_API constexpr __storage(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
|
||||
: __val_(::cuda::std::invoke(::cuda::std::forward<_Fp>(__f), ::cuda::std::forward<_Args>(__args)...))
|
||||
{}
|
||||
};
|
||||
__storage __storage_;
|
||||
bool __engaged_;
|
||||
|
||||
_CCCL_API constexpr __optional_destruct_base() noexcept
|
||||
: __storage_()
|
||||
, __engaged_(false)
|
||||
{}
|
||||
|
||||
template <class... _Args>
|
||||
_CCCL_API constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args) noexcept(
|
||||
is_nothrow_constructible_v<value_type, _Args...>)
|
||||
: __storage_(in_place_t{}, ::cuda::std::forward<_Args>(__args)...)
|
||||
, __engaged_(true)
|
||||
{}
|
||||
|
||||
template <class _Fp, class... _Args>
|
||||
_CCCL_API constexpr __optional_destruct_base(__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
|
||||
: __storage_(__optional_construct_from_invoke_tag{},
|
||||
::cuda::std::forward<_Fp>(__f),
|
||||
::cuda::std::forward<_Args>(__args)...)
|
||||
, __engaged_(true)
|
||||
{}
|
||||
|
||||
_CCCL_API constexpr void reset() noexcept
|
||||
{
|
||||
if (__engaged_)
|
||||
{
|
||||
__engaged_ = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __optional_storage_base : __optional_destruct_base<_Tp>
|
||||
{
|
||||
_CCCL_DELEGATE_CONSTRUCTORS(__optional_storage_base, __optional_destruct_base, _Tp);
|
||||
|
||||
using value_type = _Tp;
|
||||
|
||||
[[nodiscard]] _CCCL_API constexpr bool has_value() const noexcept
|
||||
{
|
||||
return this->__engaged_;
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_API constexpr value_type& __get() & noexcept
|
||||
{
|
||||
return this->__storage_.__val_;
|
||||
}
|
||||
[[nodiscard]] _CCCL_API constexpr const value_type& __get() const& noexcept
|
||||
{
|
||||
return this->__storage_.__val_;
|
||||
}
|
||||
[[nodiscard]] _CCCL_API constexpr value_type&& __get() && noexcept
|
||||
{
|
||||
return ::cuda::std::move(this->__storage_.__val_);
|
||||
}
|
||||
[[nodiscard]] _CCCL_API constexpr const value_type&& __get() const&& noexcept
|
||||
{
|
||||
return ::cuda::std::move(this->__storage_.__val_);
|
||||
}
|
||||
|
||||
_CCCL_API constexpr void __set_engaged(bool __engaged) noexcept
|
||||
{
|
||||
this->__engaged_ = __engaged;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class... _Args>
|
||||
_CCCL_API inline _CCCL_CONSTEXPR_CXX20 void __construct(_Args&&... __args)
|
||||
{
|
||||
_CCCL_ASSERT(!has_value(), "__construct called for engaged __optional_storage");
|
||||
::cuda::std::__construct_at(::cuda::std::addressof(this->__storage_.__val_), ::cuda::std::forward<_Args>(__args)...);
|
||||
this->__engaged_ = true;
|
||||
}
|
||||
|
||||
template <class _That>
|
||||
_CCCL_API constexpr void __construct_from(_That&& __opt)
|
||||
{
|
||||
if (__opt.has_value())
|
||||
{
|
||||
__construct(::cuda::std::forward<_That>(__opt).__get());
|
||||
}
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _That>
|
||||
_CCCL_API constexpr void __assign_from(_That&& __opt)
|
||||
{
|
||||
if (this->__engaged_ == __opt.has_value())
|
||||
{
|
||||
if (this->__engaged_)
|
||||
{
|
||||
this->__storage_.__val_ = ::cuda::std::forward<_That>(__opt).__get();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->__engaged_)
|
||||
{
|
||||
this->reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
__construct(::cuda::std::forward<_That>(__opt).__get());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr __smf_availability __optional_can_copy_construct =
|
||||
is_trivially_copy_constructible_v<_Tp> ? __smf_availability::__trivial
|
||||
: is_copy_constructible_v<_Tp>
|
||||
? __smf_availability::__available
|
||||
: __smf_availability::__deleted;
|
||||
|
||||
template <class _Tp, __smf_availability = __optional_can_copy_construct<_Tp>>
|
||||
struct __optional_copy_base : __optional_storage_base<_Tp>
|
||||
{
|
||||
_CCCL_DELEGATE_CONSTRUCTORS(__optional_copy_base, __optional_storage_base, _Tp);
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __optional_copy_base<_Tp, __smf_availability::__available> : __optional_storage_base<_Tp>
|
||||
{
|
||||
_CCCL_DELEGATE_CONSTRUCTORS(__optional_copy_base, __optional_storage_base, _Tp);
|
||||
|
||||
// This ctor shouldn't need to initialize the base explicitly, but g++ 9 considers it to be uninitialized
|
||||
// during constexpr evaluation if it isn't initialized explicitly. This can be replaced with the pattern
|
||||
// below, in __optional_move_base, once g++ 9 falls off our support matrix.
|
||||
_CCCL_API constexpr __optional_copy_base(const __optional_copy_base& __opt) noexcept(
|
||||
is_nothrow_copy_constructible_v<_Tp>)
|
||||
: __base()
|
||||
{
|
||||
this->__construct_from(__opt);
|
||||
}
|
||||
|
||||
_CCCL_HIDE_FROM_ABI __optional_copy_base(__optional_copy_base&&) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_copy_base& operator=(const __optional_copy_base&) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_copy_base& operator=(__optional_copy_base&&) = default;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __optional_copy_base<_Tp, __smf_availability::__deleted> : __optional_storage_base<_Tp>
|
||||
{
|
||||
_CCCL_DELEGATE_CONSTRUCTORS(__optional_copy_base, __optional_storage_base, _Tp);
|
||||
_CCCL_HIDE_FROM_ABI __optional_copy_base(const __optional_copy_base&) = delete;
|
||||
_CCCL_HIDE_FROM_ABI __optional_copy_base(__optional_copy_base&&) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_copy_base& operator=(const __optional_copy_base&) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_copy_base& operator=(__optional_copy_base&&) = default;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr __smf_availability __optional_can_move_construct =
|
||||
is_trivially_move_constructible_v<_Tp> ? __smf_availability::__trivial
|
||||
: is_move_constructible_v<_Tp>
|
||||
? __smf_availability::__available
|
||||
: __smf_availability::__deleted;
|
||||
|
||||
template <class _Tp, __smf_availability = __optional_can_move_construct<_Tp>>
|
||||
struct __optional_move_base : __optional_copy_base<_Tp>
|
||||
{
|
||||
_CCCL_DELEGATE_CONSTRUCTORS(__optional_move_base, __optional_copy_base, _Tp);
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __optional_move_base<_Tp, __smf_availability::__available> : __optional_copy_base<_Tp>
|
||||
{
|
||||
_CCCL_DELEGATE_CONSTRUCTORS(__optional_move_base, __optional_copy_base, _Tp);
|
||||
|
||||
_CCCL_HIDE_FROM_ABI __optional_move_base(const __optional_move_base&) = default;
|
||||
|
||||
_CCCL_API constexpr __optional_move_base(__optional_move_base&& __opt) noexcept(is_nothrow_move_constructible_v<_Tp>)
|
||||
{
|
||||
this->__construct_from(::cuda::std::move(__opt));
|
||||
}
|
||||
|
||||
_CCCL_HIDE_FROM_ABI __optional_move_base& operator=(const __optional_move_base&) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_move_base& operator=(__optional_move_base&&) = default;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __optional_move_base<_Tp, __smf_availability::__deleted> : __optional_copy_base<_Tp>
|
||||
{
|
||||
_CCCL_DELEGATE_CONSTRUCTORS(__optional_move_base, __optional_copy_base, _Tp);
|
||||
|
||||
_CCCL_HIDE_FROM_ABI __optional_move_base(const __optional_move_base&) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_move_base(__optional_move_base&&) = delete;
|
||||
_CCCL_HIDE_FROM_ABI __optional_move_base& operator=(const __optional_move_base&) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_move_base& operator=(__optional_move_base&&) = default;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr __smf_availability __optional_can_copy_assign =
|
||||
is_trivially_destructible_v<_Tp> && is_trivially_copy_constructible_v<_Tp> && is_trivially_copy_assignable_v<_Tp>
|
||||
? __smf_availability::__trivial
|
||||
: is_destructible_v<_Tp> && is_copy_constructible_v<_Tp> && is_copy_assignable_v<_Tp>
|
||||
? __smf_availability::__available
|
||||
: __smf_availability::__deleted;
|
||||
|
||||
template <class _Tp, __smf_availability = __optional_can_copy_assign<_Tp>>
|
||||
struct __optional_copy_assign_base : __optional_move_base<_Tp>
|
||||
{
|
||||
_CCCL_DELEGATE_CONSTRUCTORS(__optional_copy_assign_base, __optional_move_base, _Tp);
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __optional_copy_assign_base<_Tp, __smf_availability::__available> : __optional_move_base<_Tp>
|
||||
{
|
||||
_CCCL_DELEGATE_CONSTRUCTORS(__optional_copy_assign_base, __optional_move_base, _Tp);
|
||||
|
||||
_CCCL_HIDE_FROM_ABI __optional_copy_assign_base(const __optional_copy_assign_base&) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_copy_assign_base(__optional_copy_assign_base&&) = default;
|
||||
|
||||
_CCCL_API constexpr __optional_copy_assign_base& operator=(const __optional_copy_assign_base& __opt)
|
||||
{
|
||||
this->__assign_from(__opt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
__optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __optional_copy_assign_base<_Tp, __smf_availability::__deleted> : __optional_move_base<_Tp>
|
||||
{
|
||||
_CCCL_DELEGATE_CONSTRUCTORS(__optional_copy_assign_base, __optional_move_base, _Tp);
|
||||
|
||||
_CCCL_HIDE_FROM_ABI __optional_copy_assign_base(const __optional_copy_assign_base&) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_copy_assign_base(__optional_copy_assign_base&&) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_copy_assign_base& operator=(const __optional_copy_assign_base&) = delete;
|
||||
_CCCL_HIDE_FROM_ABI __optional_copy_assign_base& operator=(__optional_copy_assign_base&&) = default;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr __smf_availability __optional_can_move_assign =
|
||||
is_trivially_destructible_v<_Tp> && is_trivially_move_constructible_v<_Tp> && is_trivially_move_assignable_v<_Tp>
|
||||
? __smf_availability::__trivial
|
||||
: is_destructible_v<_Tp> && is_move_constructible_v<_Tp> && is_move_assignable_v<_Tp>
|
||||
? __smf_availability::__available
|
||||
: __smf_availability::__deleted;
|
||||
|
||||
template <class _Tp, __smf_availability = __optional_can_move_assign<_Tp>>
|
||||
struct __optional_move_assign_base : __optional_copy_assign_base<_Tp>
|
||||
{
|
||||
_CCCL_DELEGATE_CONSTRUCTORS(__optional_move_assign_base, __optional_copy_assign_base, _Tp);
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __optional_move_assign_base<_Tp, __smf_availability::__available> : __optional_copy_assign_base<_Tp>
|
||||
{
|
||||
_CCCL_DELEGATE_CONSTRUCTORS(__optional_move_assign_base, __optional_copy_assign_base, _Tp);
|
||||
|
||||
_CCCL_HIDE_FROM_ABI __optional_move_assign_base(const __optional_move_assign_base& __opt) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_move_assign_base(__optional_move_assign_base&&) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
|
||||
|
||||
_CCCL_API constexpr __optional_move_assign_base& operator=(__optional_move_assign_base&& __opt) noexcept(
|
||||
is_nothrow_move_assignable_v<_Tp> && is_nothrow_move_constructible_v<_Tp>)
|
||||
{
|
||||
this->__assign_from(::cuda::std::move(__opt));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __optional_move_assign_base<_Tp, __smf_availability::__deleted> : __optional_copy_assign_base<_Tp>
|
||||
{
|
||||
_CCCL_DELEGATE_CONSTRUCTORS(__optional_move_assign_base, __optional_copy_assign_base, _Tp);
|
||||
|
||||
_CCCL_HIDE_FROM_ABI __optional_move_assign_base(const __optional_move_assign_base& __opt) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_move_assign_base(__optional_move_assign_base&&) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_move_assign_base& operator=(const __optional_move_assign_base&) = default;
|
||||
_CCCL_HIDE_FROM_ABI __optional_move_assign_base& operator=(__optional_move_assign_base&&) = delete;
|
||||
};
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
_CCCL_DIAG_POP
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___OPTIONAL_OPTIONAL_BASE_H
|
||||
@@ -0,0 +1,351 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of libcu++, the C++ Standard Library for your entire system,
|
||||
// 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
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___OPTIONAL_OPTIONAL_REF_H
|
||||
#define _CUDA_STD___OPTIONAL_OPTIONAL_REF_H
|
||||
|
||||
#include <cuda/std/detail/__config>
|
||||
|
||||
#if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC)
|
||||
# pragma GCC system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG)
|
||||
# pragma clang system_header
|
||||
#elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC)
|
||||
# pragma system_header
|
||||
#endif // no system header
|
||||
|
||||
#include <cuda/std/__concepts/concept_macros.h>
|
||||
#include <cuda/std/__concepts/invocable.h>
|
||||
#include <cuda/std/__functional/invoke.h>
|
||||
#include <cuda/std/__fwd/optional.h>
|
||||
#include <cuda/std/__memory/addressof.h>
|
||||
#include <cuda/std/__optional/bad_optional_access.h>
|
||||
#include <cuda/std/__optional/nullopt.h>
|
||||
#include <cuda/std/__optional/optional_base.h>
|
||||
#include <cuda/std/__type_traits/decay.h>
|
||||
#include <cuda/std/__type_traits/is_array.h>
|
||||
#include <cuda/std/__type_traits/is_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_convertible.h>
|
||||
#include <cuda/std/__type_traits/is_copy_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_reference.h>
|
||||
#include <cuda/std/__type_traits/is_same.h>
|
||||
#include <cuda/std/__type_traits/reference_constructs_from_temporary.h>
|
||||
#include <cuda/std/__type_traits/reference_converts_from_temporary.h>
|
||||
#include <cuda/std/__type_traits/remove_cvref.h>
|
||||
#include <cuda/std/__type_traits/remove_reference.h>
|
||||
#include <cuda/std/__utility/declval.h>
|
||||
#include <cuda/std/__utility/forward.h>
|
||||
#include <cuda/std/__utility/in_place.h>
|
||||
#include <cuda/std/__utility/move.h>
|
||||
#include <cuda/std/__utility/swap.h>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
template <class _Tp>
|
||||
class optional<_Tp&>
|
||||
{
|
||||
private:
|
||||
using __raw_type = remove_reference_t<_Tp>;
|
||||
__raw_type* __value_ = nullptr;
|
||||
|
||||
_CCCL_TEMPLATE(class _Ref, class _Arg)
|
||||
_CCCL_REQUIRES(is_constructible_v<_Ref, _Arg>)
|
||||
[[nodiscard]] _CCCL_API static constexpr _Ref __make_reference(_Arg&& __arg) noexcept
|
||||
{
|
||||
static_assert(is_reference_v<_Ref>, "optional<T&>: make-reference requires a reference as argument");
|
||||
return _Ref(::cuda::std::forward<_Arg>(__arg));
|
||||
}
|
||||
|
||||
// Needed to interface with optional<T>
|
||||
template <class>
|
||||
friend struct __optional_storage_base;
|
||||
|
||||
[[nodiscard]] _CCCL_API constexpr _Tp& __get() noexcept
|
||||
{
|
||||
return *__value_;
|
||||
}
|
||||
[[nodiscard]] _CCCL_API constexpr const _Tp& __get() const noexcept
|
||||
{
|
||||
return *__value_;
|
||||
}
|
||||
|
||||
#if defined(_CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY)
|
||||
template <class _Up>
|
||||
static constexpr bool __from_temporary = reference_constructs_from_temporary_v<_Tp&, _Up>;
|
||||
#else
|
||||
template <class _Up>
|
||||
static constexpr bool __from_temporary = false;
|
||||
#endif // !_CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY
|
||||
|
||||
public:
|
||||
using value_type = __raw_type&;
|
||||
|
||||
// Use of {} vs = default is deliberate. = default may value-initialize, while {} is
|
||||
// guaranteed to do absolutely nothing.
|
||||
_CCCL_API constexpr optional() noexcept {} // NOLINT(modernize-use-equals-default)
|
||||
_CCCL_HIDE_FROM_ABI constexpr optional(const optional&) noexcept = default;
|
||||
_CCCL_HIDE_FROM_ABI constexpr optional(optional&&) noexcept = default;
|
||||
_CCCL_API constexpr optional(nullopt_t) noexcept {}
|
||||
|
||||
_CCCL_TEMPLATE(class _Arg)
|
||||
_CCCL_REQUIRES(is_constructible_v<_Tp&, _Arg> _CCCL_AND(!__from_temporary<_Arg>))
|
||||
_CCCL_API explicit constexpr optional(in_place_t, _Arg&& __arg) noexcept
|
||||
: __value_(::cuda::std::addressof(__make_reference<_Tp&>(::cuda::std::forward<_Arg>(__arg))))
|
||||
{}
|
||||
|
||||
// [optional.ref.ctor]-4
|
||||
template <class _Up>
|
||||
static constexpr bool __can_construct_from_rvalue =
|
||||
!__is_cuda_std_optional_v<remove_cvref_t<_Up>> && !is_same_v<remove_cvref_t<_Up>, in_place_t>
|
||||
&& is_constructible_v<_Tp&, _Up> && !__from_temporary<_Up>;
|
||||
|
||||
// NOLINTBEGIN(bugprone-forwarding-reference-overload)
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__can_construct_from_rvalue<_Up> _CCCL_AND is_convertible_v<_Up, _Tp&>)
|
||||
_CCCL_API constexpr optional(_Up&& __u) noexcept(noexcept(static_cast<_Tp&>(::cuda::std::declval<_Up>())))
|
||||
: __value_(::cuda::std::addressof(static_cast<_Tp&>(::cuda::std::forward<_Up>(__u))))
|
||||
{}
|
||||
// NOLINTEND(bugprone-forwarding-reference-overload)
|
||||
|
||||
// NOLINTBEGIN(bugprone-forwarding-reference-overload)
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__can_construct_from_rvalue<_Up> _CCCL_AND(!is_convertible_v<_Up, _Tp&>))
|
||||
_CCCL_API explicit constexpr optional(_Up&& __u) noexcept(noexcept(static_cast<_Tp&>(::cuda::std::declval<_Up>())))
|
||||
: __value_(::cuda::std::addressof(static_cast<_Tp&>(::cuda::std::forward<_Up>(__u))))
|
||||
{}
|
||||
// NOLINTEND(bugprone-forwarding-reference-overload)
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__from_temporary<_Up>)
|
||||
_CCCL_API constexpr optional(_Up&&) = delete;
|
||||
|
||||
// [optional.ref.ctor]-8
|
||||
template <class _Up>
|
||||
static constexpr bool __can_convert_from_optional_reference =
|
||||
!is_same_v<remove_cvref_t<_Tp>, optional<_Up>> && !is_same_v<_Tp&, _Up> && is_constructible_v<_Tp&, _Up&>
|
||||
&& !__from_temporary<_Up&>;
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__can_convert_from_optional_reference<_Up> _CCCL_AND is_convertible_v<_Up&, _Tp&>)
|
||||
_CCCL_API constexpr optional(optional<_Up>& __u) noexcept(noexcept(static_cast<_Tp&>(::cuda::std::declval<_Up&>())))
|
||||
: __value_(__u.has_value() ? ::cuda::std::addressof(static_cast<_Tp&>(__u.value())) : nullptr)
|
||||
{}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__can_convert_from_optional_reference<_Up> _CCCL_AND(!is_convertible_v<_Up&, _Tp&>))
|
||||
_CCCL_API explicit constexpr optional(optional<_Up>& __u) noexcept(
|
||||
noexcept(static_cast<_Tp&>(::cuda::std::declval<_Up&>())))
|
||||
: __value_(__u.has_value() ? ::cuda::std::addressof(static_cast<_Tp&>(__u.value())) : nullptr)
|
||||
{}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__from_temporary<_Up&>)
|
||||
_CCCL_API constexpr optional(optional<_Up>&) = delete;
|
||||
|
||||
// [optional.ref.ctor]-11
|
||||
template <class _Up>
|
||||
static constexpr bool __can_convert_from_optional_const_reference =
|
||||
!is_same_v<remove_cvref_t<_Tp>, optional<_Up>> && !is_same_v<_Tp&, _Up> && is_constructible_v<_Tp&, const _Up&>
|
||||
&& !__from_temporary<const _Up&>;
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__can_convert_from_optional_const_reference<_Up> _CCCL_AND is_convertible_v<const _Up&, _Tp&>)
|
||||
_CCCL_API constexpr optional(const optional<_Up>& __u) noexcept(
|
||||
noexcept(static_cast<_Tp&>(::cuda::std::declval<const _Up&>())))
|
||||
: __value_(__u.has_value() ? ::cuda::std::addressof(static_cast<_Tp&>(__u.value())) : nullptr)
|
||||
{}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__can_convert_from_optional_const_reference<_Up> _CCCL_AND(!is_convertible_v<const _Up&, _Tp&>))
|
||||
_CCCL_API explicit constexpr optional(const optional<_Up>& __u) noexcept(
|
||||
noexcept(static_cast<_Tp&>(::cuda::std::declval<const _Up&>())))
|
||||
: __value_(__u.has_value() ? ::cuda::std::addressof(static_cast<_Tp&>(__u.value())) : nullptr)
|
||||
{}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__from_temporary<const _Up&>)
|
||||
_CCCL_API constexpr optional(const optional<_Up>&) = delete;
|
||||
|
||||
// [optional.ref.ctor]-14
|
||||
template <class _Up>
|
||||
static constexpr bool __can_convert_from_optional_rvalue_reference =
|
||||
!is_same_v<remove_cvref_t<_Tp>, optional<_Up>> && !is_same_v<_Tp&, _Up> && is_constructible_v<_Tp&, _Up>
|
||||
&& !__from_temporary<_Up>;
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__can_convert_from_optional_rvalue_reference<_Up> _CCCL_AND is_convertible_v<_Up, _Tp&>)
|
||||
_CCCL_API constexpr optional(optional<_Up>&& __u) noexcept(noexcept(static_cast<_Tp&>(::cuda::std::declval<_Up>())))
|
||||
: __value_(
|
||||
__u.has_value() ? ::cuda::std::addressof(static_cast<_Tp&>(::cuda::std::forward<_Up>(__u.value()))) : nullptr)
|
||||
{}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__can_convert_from_optional_rvalue_reference<_Up> _CCCL_AND(!is_convertible_v<_Up, _Tp&>))
|
||||
_CCCL_API explicit constexpr optional(optional<_Up>&& __u) noexcept(
|
||||
noexcept(static_cast<_Tp&>(::cuda::std::declval<_Up>())))
|
||||
: __value_(
|
||||
__u.has_value() ? ::cuda::std::addressof(static_cast<_Tp&>(::cuda::std::forward<_Up>(__u.value()))) : nullptr)
|
||||
{}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__from_temporary<_Up>)
|
||||
_CCCL_API constexpr optional(optional<_Up>&&) = delete;
|
||||
|
||||
// [optional.ref.ctor]-17
|
||||
template <class _Up>
|
||||
static constexpr bool __can_convert_from_optional_const_rvalue_reference =
|
||||
!is_same_v<remove_cvref_t<_Tp>, optional<_Up>> && !is_same_v<_Tp&, _Up> && is_constructible_v<_Tp&, const _Up>
|
||||
&& !__from_temporary<const _Up>;
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__can_convert_from_optional_const_rvalue_reference<_Up> _CCCL_AND is_convertible_v<const _Up, _Tp&>)
|
||||
_CCCL_API constexpr optional(const optional<_Up>&& __u) noexcept(
|
||||
noexcept(static_cast<_Tp&>(::cuda::std::declval<const _Up>())))
|
||||
: __value_(__u.has_value() ? ::cuda::std::addressof(static_cast<_Tp&>(__u.value())) : nullptr)
|
||||
{}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__can_convert_from_optional_const_rvalue_reference<_Up> _CCCL_AND(!is_convertible_v<const _Up, _Tp&>))
|
||||
_CCCL_API explicit constexpr optional(const optional<_Up>&& __u) noexcept(
|
||||
noexcept(static_cast<_Tp&>(::cuda::std::declval<const _Up>())))
|
||||
: __value_(__u.has_value() ? ::cuda::std::addressof(static_cast<_Tp&>(__u.value())) : nullptr)
|
||||
{}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up)
|
||||
_CCCL_REQUIRES(__from_temporary<const _Up>)
|
||||
_CCCL_API constexpr optional(const optional<_Up>&&) = delete;
|
||||
|
||||
_CCCL_HIDE_FROM_ABI constexpr optional& operator=(const optional&) noexcept = default;
|
||||
_CCCL_HIDE_FROM_ABI constexpr optional& operator=(optional&&) noexcept = default;
|
||||
|
||||
_CCCL_API constexpr optional& operator=(nullopt_t) noexcept
|
||||
{
|
||||
__value_ = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Up = _Tp)
|
||||
_CCCL_REQUIRES(is_constructible_v<_Tp&, _Up> _CCCL_AND(!__from_temporary<_Up>))
|
||||
_CCCL_API constexpr _Tp& emplace(_Up&& __u) noexcept(noexcept(static_cast<_Tp&>(::cuda::std::forward<_Up>(__u))))
|
||||
{
|
||||
__value_ = ::cuda::std::addressof(static_cast<_Tp&>(::cuda::std::forward<_Up>(__u)));
|
||||
return *__value_;
|
||||
}
|
||||
|
||||
_CCCL_API constexpr void swap(optional& __rhs) noexcept
|
||||
{
|
||||
return ::cuda::std::swap(__value_, __rhs.__value_);
|
||||
}
|
||||
|
||||
_CCCL_API constexpr _Tp* operator->() const noexcept
|
||||
{
|
||||
_CCCL_ASSERT(__value_ != nullptr, "optional operator-> called on a disengaged value");
|
||||
return __value_;
|
||||
}
|
||||
|
||||
_CCCL_API constexpr _Tp& operator*() const noexcept
|
||||
{
|
||||
_CCCL_ASSERT(__value_ != nullptr, "optional operator* called on a disengaged value");
|
||||
return *__value_;
|
||||
}
|
||||
|
||||
_CCCL_API constexpr explicit operator bool() const noexcept
|
||||
{
|
||||
return __value_ != nullptr;
|
||||
}
|
||||
|
||||
_CCCL_API constexpr bool has_value() const noexcept
|
||||
{
|
||||
return __value_ != nullptr;
|
||||
}
|
||||
|
||||
_CCCL_API constexpr _Tp& value() const
|
||||
{
|
||||
if (__value_ != nullptr)
|
||||
{
|
||||
return *__value_;
|
||||
}
|
||||
else
|
||||
{
|
||||
__throw_bad_optional_access();
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Up>
|
||||
_CCCL_API constexpr remove_cvref_t<_Tp> value_or(_Up&& __v) const
|
||||
{
|
||||
static_assert(is_copy_constructible_v<_Tp>, "optional<T&>::value_or: T must be copy constructible");
|
||||
static_assert(is_convertible_v<_Up, _Tp>, "optional<T&>::value_or: U must be convertible to T");
|
||||
return __value_ != nullptr ? *__value_ : static_cast<_Tp>(::cuda::std::forward<_Up>(__v));
|
||||
}
|
||||
|
||||
template <class _Func>
|
||||
_CCCL_API constexpr auto and_then(_Func&& __f) const
|
||||
{
|
||||
using _Up = invoke_result_t<_Func, _Tp&>;
|
||||
static_assert(__is_cuda_std_optional_v<remove_cvref_t<_Up>>,
|
||||
"optional<T&>::and_then: Result of f(value()) must be a specialization of std::optional");
|
||||
if (__value_ != nullptr)
|
||||
{
|
||||
return ::cuda::std::invoke(::cuda::std::forward<_Func>(__f), *__value_);
|
||||
}
|
||||
return remove_cvref_t<_Up>();
|
||||
}
|
||||
|
||||
template <class _Func>
|
||||
_CCCL_API constexpr auto transform(_Func&& __f) const
|
||||
{
|
||||
using _Up = invoke_result_t<_Func, _Tp&>;
|
||||
static_assert(!is_array_v<_Up>, "optional<T&>::transform: Result of f(value()) should not be an Array");
|
||||
static_assert(!is_same_v<_Up, in_place_t>,
|
||||
"optional<T&>::transform: Result of f(value()) should not be std::in_place_t");
|
||||
static_assert(!is_same_v<_Up, nullopt_t>,
|
||||
"optional<T&>::transform: Result of f(value()) should not be std::nullopt_t");
|
||||
if (__value_ != nullptr)
|
||||
{
|
||||
if constexpr (is_lvalue_reference_v<_Up>)
|
||||
{
|
||||
return optional<_Up>(::cuda::std::invoke(::cuda::std::forward<_Func>(__f), *__value_));
|
||||
}
|
||||
else
|
||||
{
|
||||
return optional<_Up>(__optional_construct_from_invoke_tag{}, ::cuda::std::forward<_Func>(__f), *__value_);
|
||||
}
|
||||
}
|
||||
return optional<_Up>();
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Func)
|
||||
_CCCL_REQUIRES(invocable<_Func>)
|
||||
_CCCL_API constexpr optional or_else(_Func&& __f) const
|
||||
{
|
||||
using _Up = invoke_result_t<_Func>;
|
||||
static_assert(is_same_v<remove_cvref_t<_Up>, optional>,
|
||||
"optional<T&>::or_else: Result of f() should be the same type as this optional");
|
||||
if (__value_ != nullptr)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
return ::cuda::std::forward<_Func>(__f)();
|
||||
}
|
||||
|
||||
_CCCL_API constexpr void reset() noexcept
|
||||
{
|
||||
__value_ = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___OPTIONAL_OPTIONAL_REF_H
|
||||
Reference in New Issue
Block a user