[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:
EngineX CI
2026-07-30 09:35:51 +00:00
parent b4d01f481e
commit 56fd68e7dd
8871 changed files with 1454674 additions and 0 deletions

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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