[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,79 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_AS_CONST_H
|
||||
#define _CUDA_STD___UTILITY_AS_CONST_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/__type_traits/add_const.h>
|
||||
|
||||
#if _CCCL_COMPILER(CLANG, >=, 15) || _CCCL_COMPILER(GCC, >=, 12)
|
||||
# define _CCCL_HAS_BUILTIN_STD_AS_CONST() 1
|
||||
#else // ^^^ has builtin std::as_const ^^^ / vvv no builtin std::as_const vvv
|
||||
# define _CCCL_HAS_BUILTIN_STD_AS_CONST() 0
|
||||
#endif // ^^^ no builtin std::as_const ^^^
|
||||
|
||||
// nvcc warns about host only std::as_const being used in device code
|
||||
#if _CCCL_CUDA_COMPILER(NVCC) && _CCCL_DEVICE_COMPILATION()
|
||||
# undef _CCCL_HAS_BUILTIN_STD_AS_CONST
|
||||
# define _CCCL_HAS_BUILTIN_STD_AS_CONST() 0
|
||||
#endif // _CCCL_CUDA_COMPILER(NVCC) && _CCCL_DEVICE_COMPILATION()
|
||||
|
||||
// We cannot use host features if we are building in freestanding
|
||||
#if _CCCL_FREESTANDING()
|
||||
# undef _CCCL_HAS_BUILTIN_STD_AS_CONST
|
||||
# define _CCCL_HAS_BUILTIN_STD_AS_CONST() 0
|
||||
#endif // _CCCL_FREESTANDING()
|
||||
|
||||
// include minimal std:: headers
|
||||
#if _CCCL_HAS_BUILTIN_STD_AS_CONST()
|
||||
# if _CCCL_HOST_STD_LIB(LIBCXX) && __has_include(<__utility/as_const.h>)
|
||||
# include <__utility/as_const.h>
|
||||
# elif _CCCL_HOSTED()
|
||||
# include <utility>
|
||||
# endif // _CCCL_HOSTED()
|
||||
#endif // _CCCL_HAS_BUILTIN_STD_AS_CONST()
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
#if _CCCL_HAS_BUILTIN_STD_AS_CONST()
|
||||
|
||||
// The compiler treats ::std::as_const as a builtin function so it does not need to be
|
||||
// instantiated and will be compiled away even at -O0.
|
||||
using ::std::as_const;
|
||||
|
||||
#else // ^^^ _CCCL_HAS_BUILTIN_STD_AS_CONST() ^^^ / vvv !_CCCL_HAS_BUILTIN_STD_AS_CONST() vvv
|
||||
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _CCCL_INTRINSIC _CCCL_API constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept
|
||||
{
|
||||
return __t;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
void as_const(const _Tp&&) = delete;
|
||||
|
||||
#endif // ^^^ !_CCCL_HAS_BUILTIN_STD_AS_CONST() ^^^
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_AS_CONST_H
|
||||
@@ -0,0 +1,34 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_AUTO_CAST_H
|
||||
#define _CUDA_STD___UTILITY_AUTO_CAST_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/__type_traits/decay.h>
|
||||
|
||||
#if _CCCL_STD_VER >= 2023 && __cpp_auto_cast >= 202110L && !_CCCL_CUDA_COMPILER(NVCC)
|
||||
# define _LIBCUDACXX_AUTO_CAST(expr) auto(expr)
|
||||
#elif _CCCL_STD_VER < 2020 && _CCCL_COMPILER(MSVC)
|
||||
# define _LIBCUDACXX_AUTO_CAST(expr) (::cuda::std::decay_t<decltype((expr))>) (expr)
|
||||
#else
|
||||
# define _LIBCUDACXX_AUTO_CAST(expr) static_cast<::cuda::std::decay_t<decltype((expr))>>(expr)
|
||||
#endif
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_AUTO_CAST_H
|
||||
114
cccl_upstream/libcudacxx/include/cuda/std/__utility/cmp.h
Normal file
114
cccl_upstream/libcudacxx/include/cuda/std/__utility/cmp.h
Normal file
@@ -0,0 +1,114 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_CMP_H
|
||||
#define _CUDA_STD___UTILITY_CMP_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/__type_traits/disjunction.h>
|
||||
#include <cuda/std/__type_traits/enable_if.h>
|
||||
#include <cuda/std/__type_traits/is_integer.h>
|
||||
#include <cuda/std/__type_traits/is_same.h>
|
||||
#include <cuda/std/__type_traits/is_signed.h>
|
||||
#include <cuda/std/__type_traits/make_unsigned.h>
|
||||
#include <cuda/std/__utility/forward.h>
|
||||
#include <cuda/std/__utility/move.h>
|
||||
#include <cuda/std/limits>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
_CCCL_TEMPLATE(class _Tp, class _Up)
|
||||
_CCCL_REQUIRES(__cccl_is_integer_v<_Tp> _CCCL_AND __cccl_is_integer_v<_Up>)
|
||||
_CCCL_API constexpr bool cmp_equal(_Tp __t, _Up __u) noexcept
|
||||
{
|
||||
if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
|
||||
{
|
||||
return __t == __u;
|
||||
}
|
||||
else if constexpr (is_signed_v<_Tp>)
|
||||
{
|
||||
return __t < 0 ? false : make_unsigned_t<_Tp>(__t) == __u;
|
||||
}
|
||||
else
|
||||
{
|
||||
return __u < 0 ? false : __t == make_unsigned_t<_Up>(__u);
|
||||
}
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Tp, class _Up)
|
||||
_CCCL_REQUIRES(__cccl_is_integer_v<_Tp> _CCCL_AND __cccl_is_integer_v<_Up>)
|
||||
_CCCL_API constexpr bool cmp_not_equal(_Tp __t, _Up __u) noexcept
|
||||
{
|
||||
return !::cuda::std::cmp_equal(__t, __u);
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Tp, class _Up)
|
||||
_CCCL_REQUIRES(__cccl_is_integer_v<_Tp> _CCCL_AND __cccl_is_integer_v<_Up>)
|
||||
_CCCL_API constexpr bool cmp_less(_Tp __t, _Up __u) noexcept
|
||||
{
|
||||
if constexpr (is_signed_v<_Tp> == is_signed_v<_Up>)
|
||||
{
|
||||
return __t < __u;
|
||||
}
|
||||
else if constexpr (is_signed_v<_Tp>)
|
||||
{
|
||||
return __t < 0 ? true : make_unsigned_t<_Tp>(__t) < __u;
|
||||
}
|
||||
else
|
||||
{
|
||||
return __u < 0 ? false : __t < make_unsigned_t<_Up>(__u);
|
||||
}
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Tp, class _Up)
|
||||
_CCCL_REQUIRES(__cccl_is_integer_v<_Tp> _CCCL_AND __cccl_is_integer_v<_Up>)
|
||||
_CCCL_API constexpr bool cmp_greater(_Tp __t, _Up __u) noexcept
|
||||
{
|
||||
return ::cuda::std::cmp_less(__u, __t);
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Tp, class _Up)
|
||||
_CCCL_REQUIRES(__cccl_is_integer_v<_Tp> _CCCL_AND __cccl_is_integer_v<_Up>)
|
||||
_CCCL_API constexpr bool cmp_less_equal(_Tp __t, _Up __u) noexcept
|
||||
{
|
||||
return !::cuda::std::cmp_greater(__t, __u);
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Tp, class _Up)
|
||||
_CCCL_REQUIRES(__cccl_is_integer_v<_Tp> _CCCL_AND __cccl_is_integer_v<_Up>)
|
||||
_CCCL_API constexpr bool cmp_greater_equal(_Tp __t, _Up __u) noexcept
|
||||
{
|
||||
return !::cuda::std::cmp_less(__t, __u);
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Tp, class _Up)
|
||||
_CCCL_REQUIRES(__cccl_is_integer_v<_Tp> _CCCL_AND __cccl_is_integer_v<_Up>)
|
||||
_CCCL_API constexpr bool in_range(_Up __u) noexcept
|
||||
{
|
||||
return ::cuda::std::cmp_less_equal(__u, numeric_limits<_Tp>::max())
|
||||
&& ::cuda::std::cmp_greater_equal(__u, numeric_limits<_Tp>::min());
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_CMP_H
|
||||
@@ -0,0 +1,558 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_CONSTANT_WRAPPER_H
|
||||
#define _CUDA_STD___UTILITY_CONSTANT_WRAPPER_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_STD_VER >= 2020 && !_CCCL_COMPILER(NVRTC)
|
||||
|
||||
# include <cuda/std/__concepts/concept_macros.h>
|
||||
# include <cuda/std/__cstddef/types.h>
|
||||
# include <cuda/std/__functional/invoke.h>
|
||||
# include <cuda/std/__type_traits/fold.h>
|
||||
# include <cuda/std/__type_traits/is_constructible.h>
|
||||
# include <cuda/std/__type_traits/remove_cvref.h>
|
||||
# include <cuda/std/__type_traits/void_t.h>
|
||||
# include <cuda/std/__utility/declval.h>
|
||||
# include <cuda/std/__utility/forward.h>
|
||||
# include <cuda/std/__utility/integer_sequence.h>
|
||||
|
||||
# include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
// operator may not be a static member function
|
||||
// a host member cannot be directly read in a __device__/__global__ function
|
||||
_CCCL_BEGIN_NV_DIAG_SUPPRESS(342, 20094)
|
||||
|
||||
_CCCL_DIAG_PUSH
|
||||
_CCCL_DIAG_SUPPRESS_NVHPC(static_member_operator_not_allowed)
|
||||
|
||||
template <class _Tp>
|
||||
struct __cw_fixed_value
|
||||
{
|
||||
using type _CCCL_NODEBUG_ALIAS = _Tp;
|
||||
_CCCL_HOST_DEVICE_API consteval __cw_fixed_value(_Tp __v) noexcept
|
||||
: __data(__v)
|
||||
{}
|
||||
_Tp __data;
|
||||
};
|
||||
|
||||
template <class _Tp, size_t _Extent>
|
||||
struct __cw_fixed_value<_Tp[_Extent]>
|
||||
{
|
||||
using type _CCCL_NODEBUG_ALIAS = _Tp[_Extent];
|
||||
_Tp __data[_Extent];
|
||||
|
||||
_CCCL_HOST_DEVICE_API consteval __cw_fixed_value(_Tp (&__arr)[_Extent]) noexcept
|
||||
: __cw_fixed_value(__arr, make_index_sequence<_Extent>{})
|
||||
{}
|
||||
|
||||
private:
|
||||
template <size_t... _Idxs>
|
||||
_CCCL_HOST_DEVICE_API consteval __cw_fixed_value(_Tp (&__arr)[_Extent], index_sequence<_Idxs...>) noexcept
|
||||
: __data{__arr[_Idxs]...}
|
||||
{}
|
||||
};
|
||||
|
||||
template <class _Tp, size_t _Extent>
|
||||
_CCCL_DEDUCTION_GUIDE_ATTRIBUTES __cw_fixed_value(_Tp (&)[_Extent]) -> __cw_fixed_value<_Tp[_Extent]>;
|
||||
|
||||
template <__cw_fixed_value _Xp, class = typename decltype(__cw_fixed_value(_Xp))::type>
|
||||
struct __constant_wrapper;
|
||||
|
||||
template <class _Tp, class = void>
|
||||
inline constexpr bool __is_constexpr_param_v = false;
|
||||
template <class _Tp>
|
||||
inline constexpr bool __is_constexpr_param_v<_Tp, void_t<__constant_wrapper<__cw_fixed_value(_Tp::value)>>> = true;
|
||||
|
||||
template <__cw_fixed_value _Xp>
|
||||
inline constexpr __constant_wrapper<_Xp> __cw;
|
||||
|
||||
struct __cw_operators
|
||||
{
|
||||
// unary operators
|
||||
_CCCL_TEMPLATE(class _Tp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Tp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(+_Tp::value)>{})
|
||||
operator+(_Tp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Tp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Tp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(-_Tp::value)>{})
|
||||
operator-(_Tp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Tp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Tp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(~_Tp::value)>{})
|
||||
operator~(_Tp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Tp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Tp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(!_Tp::value)>{})
|
||||
operator!(_Tp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
// todo(dabayer): nvcc 13.1-13.3 needs this to be concept, otherwise cudafe++ produces invalid input file for the host
|
||||
// compiler for code like `constant_wrapper<&v>`. Try to find a workaround that could work even in C++17.
|
||||
_CCCL_TEMPLATE(class _Tp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Tp> _CCCL_AND requires { typename __constant_wrapper<(&_Tp::value)>; })
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API friend consteval auto operator&(_Tp) noexcept
|
||||
{
|
||||
return __constant_wrapper<(&_Tp::value)>{};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Tp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Tp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(*_Tp::value)>{})
|
||||
operator*(_Tp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// binary operators
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value + _Rp::value)>{})
|
||||
operator+(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value - _Rp::value)>{})
|
||||
operator-(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value* _Rp::value)>{})
|
||||
operator*(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value / _Rp::value)>{})
|
||||
operator/(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value % _Rp::value)>{})
|
||||
operator%(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value << _Rp::value)>{})
|
||||
operator<<(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value >> _Rp::value)>{})
|
||||
operator>>(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value& _Rp::value)>{})
|
||||
operator&(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value | _Rp::value)>{})
|
||||
operator|(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value ^ _Rp::value)>{})
|
||||
operator^(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp> _CCCL_AND(
|
||||
!is_constructible_v<bool, decltype(_Lp::value)> || !is_constructible_v<bool, decltype(_Rp::value)>))
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value&& _Rp::value)>{})
|
||||
operator&&(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp> _CCCL_AND(
|
||||
!is_constructible_v<bool, decltype(_Lp::value)> || !is_constructible_v<bool, decltype(_Rp::value)>))
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value || _Rp::value)>{})
|
||||
operator||(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
// comparisons
|
||||
# if _LIBCUDACXX_HAS_SPACESHIP_OPERATOR()
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<
|
||||
__cw_fixed_value(_Lp::value <=> _Rp::value)>{})
|
||||
operator<=>(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
# endif // _LIBCUDACXX_HAS_SPACESHIP_OPERATOR()
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value < _Rp::value)>{})
|
||||
operator<(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value <= _Rp::value)>{})
|
||||
operator<=(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value == _Rp::value)>{})
|
||||
operator==(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value != _Rp::value)>{})
|
||||
operator!=(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value > _Rp::value)>{})
|
||||
operator>(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value >= _Rp::value)>{})
|
||||
operator>=(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
friend auto operator,(_Lp, _Rp) = delete;
|
||||
|
||||
_CCCL_TEMPLATE(class _Lp, class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Lp> _CCCL_AND __is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API friend consteval decltype(__constant_wrapper<__cw_fixed_value(_Lp::value->*_Rp::value)>{})
|
||||
operator->*(_Lp, _Rp) noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Fn, class _Void, class... _Args>
|
||||
inline constexpr bool __cw_is_constexpr_callable_v = false;
|
||||
template <class _Fn, class... _Args>
|
||||
inline constexpr bool __cw_is_constexpr_callable_v<
|
||||
_Fn,
|
||||
void_t<__constant_wrapper<__cw_fixed_value(::cuda::std::invoke(_Fn::value, _Args::value...))>>,
|
||||
_Args...> = true;
|
||||
|
||||
template <class _Vp, class _Void, class... _Args>
|
||||
inline constexpr bool __cw_is_constexpr_indexable_v = false;
|
||||
# if _CCCL_HAS_MULTIARG_OPERATOR_BRACKETS()
|
||||
template <class _Vp, class... _Args>
|
||||
inline constexpr bool
|
||||
__cw_is_constexpr_indexable_v<_Vp, void_t<__constant_wrapper<__cw_fixed_value(_Vp::value[_Args::value...])>>, _Args...> =
|
||||
true;
|
||||
# else // ^^^ _CCCL_HAS_MULTIARG_OPERATOR_BRACKETS() ^^^ / vvv !_CCCL_HAS_MULTIARG_OPERATOR_BRACKETS() vvv
|
||||
template <class _Vp, class _Arg>
|
||||
inline constexpr bool
|
||||
__cw_is_constexpr_indexable_v<_Vp, void_t<__constant_wrapper<__cw_fixed_value(_Vp::value[_Arg::value])>>, _Arg> =
|
||||
true;
|
||||
# endif // ^^^ !_CCCL_HAS_MULTIARG_OPERATOR_BRACKETS() ^^^
|
||||
|
||||
template <class _Vp, class _Void, class... _Args>
|
||||
inline constexpr bool __cw_is_indexable_v = false;
|
||||
# if _CCCL_HAS_MULTIARG_OPERATOR_BRACKETS()
|
||||
template <class _Vp, class... _Args>
|
||||
inline constexpr bool
|
||||
__cw_is_indexable_v<_Vp, void_t<decltype(_Vp::value[::cuda::std::declval<_Args>()...])>, _Args...> = true;
|
||||
# else // ^^^ _CCCL_HAS_MULTIARG_OPERATOR_BRACKETS() ^^^ / vvv !_CCCL_HAS_MULTIARG_OPERATOR_BRACKETS() vvv
|
||||
template <class _Vp, class _Arg>
|
||||
inline constexpr bool __cw_is_indexable_v<_Vp, void_t<decltype(_Vp::value[::cuda::std::declval<_Arg>()])>, _Arg> = true;
|
||||
# endif // ^^^ !_CCCL_HAS_MULTIARG_OPERATOR_BRACKETS() ^^^
|
||||
|
||||
template <__cw_fixed_value _Xp, class _Tp>
|
||||
struct __constant_wrapper : __cw_operators
|
||||
{
|
||||
static constexpr const auto& value = _Xp.__data;
|
||||
using __cw_fixed_value_type = remove_cvref_t<decltype(_Xp)>;
|
||||
using type = __constant_wrapper;
|
||||
using value_type = _Tp;
|
||||
|
||||
_CCCL_TEMPLATE(class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval decltype(__constant_wrapper<__cw_fixed_value(value = _Rp::value)>{})
|
||||
operator=(_Rp) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
_CCCL_HOST_DEVICE_API constexpr operator const _Tp&() const noexcept
|
||||
{
|
||||
return _Xp.__data;
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class... _Args)
|
||||
_CCCL_REQUIRES(__fold_and_v<__is_constexpr_param_v<remove_cvref_t<_Args>>...> _CCCL_AND
|
||||
__cw_is_constexpr_callable_v<__constant_wrapper, void, remove_cvref_t<_Args>...>)
|
||||
# if _CCCL_HAS_STATIC_CALL_OPERATOR()
|
||||
_CCCL_HOST_DEVICE_API static constexpr auto operator()(_Args&&...) noexcept
|
||||
# else // ^^^ _CCCL_HAS_STATIC_CALL_OPERATOR() ^^^ / vvv !_CCCL_HAS_STATIC_CALL_OPERATOR() vvv
|
||||
_CCCL_HOST_DEVICE_API constexpr auto operator()(_Args&&...) const noexcept
|
||||
# endif // ^^^ !_CCCL_HAS_STATIC_CALL_OPERATOR() ^^^
|
||||
{
|
||||
return __constant_wrapper<__cw_fixed_value(::cuda::std::invoke(value, remove_cvref_t<_Args>::value...))>{};
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class... _Args)
|
||||
_CCCL_REQUIRES((!(__fold_and_v<__is_constexpr_param_v<remove_cvref_t<_Args>>...>
|
||||
&& __cw_is_constexpr_callable_v<__constant_wrapper, void, remove_cvref_t<_Args>...>) )
|
||||
_CCCL_AND is_invocable_v<const _Tp&, _Args&&...>)
|
||||
# if _CCCL_HAS_STATIC_CALL_OPERATOR()
|
||||
_CCCL_HOST_DEVICE_API static constexpr decltype(auto) operator()(_Args&&... __args)
|
||||
# else // ^^^ _CCCL_HAS_STATIC_CALL_OPERATOR() ^^^ / vvv !_CCCL_HAS_STATIC_CALL_OPERATOR() vvv
|
||||
_CCCL_HOST_DEVICE_API constexpr decltype(auto) operator()(_Args&&... __args) const
|
||||
# endif // ^^^ !_CCCL_HAS_STATIC_CALL_OPERATOR() ^^^
|
||||
noexcept(::cuda::std::is_nothrow_invocable_v<const _Tp&, _Args...>)
|
||||
{
|
||||
return ::cuda::std::invoke(value, ::cuda::std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
# if _CCCL_HAS_MULTIARG_OPERATOR_BRACKETS()
|
||||
_CCCL_TEMPLATE(class... _Args)
|
||||
_CCCL_REQUIRES(__fold_and_v<__is_constexpr_param_v<remove_cvref_t<_Args>>...> _CCCL_AND
|
||||
__cw_is_constexpr_indexable_v<__constant_wrapper, void, remove_cvref_t<_Args>...>)
|
||||
# if _CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR()
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API consteval static __constant_wrapper<__cw_fixed_value(value[remove_cvref_t<_Args>::value...])>
|
||||
operator[](_Args&&...) noexcept
|
||||
# else // ^^^ _CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR() ^^^ / vvv !_CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR() vvv
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval __constant_wrapper<
|
||||
__cw_fixed_value(value[remove_cvref_t<_Args>::value...])>
|
||||
operator[](_Args&&...) const noexcept
|
||||
# endif // ^^^ _CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR() ^^^
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class... _Args)
|
||||
_CCCL_REQUIRES((!(__fold_and_v<__is_constexpr_param_v<remove_cvref_t<_Args>>...>
|
||||
&& __cw_is_constexpr_indexable_v<__constant_wrapper, void, remove_cvref_t<_Args>...>) )
|
||||
_CCCL_AND __cw_is_indexable_v<__constant_wrapper, void, _Args...>)
|
||||
# if _CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR()
|
||||
_CCCL_HOST_DEVICE_API static constexpr decltype(auto) operator[](_Args&&... __args)
|
||||
# else // ^^^ _CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR() ^^^ / vvv !_CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR() vvv
|
||||
_CCCL_HOST_DEVICE_API constexpr decltype(auto) operator[](_Args&&... __args) const
|
||||
# endif // ^^^ _CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR() ^^^
|
||||
noexcept(noexcept(value[::cuda::std::forward<_Args>(__args)...]))
|
||||
{
|
||||
return value[::cuda::std::forward<_Args>(__args)...];
|
||||
}
|
||||
# else // ^^^ _CCCL_HAS_MULTIARG_OPERATOR_BRACKETS() ^^^ / vvv !_CCCL_HAS_MULTIARG_OPERATOR_BRACKETS() vvv
|
||||
_CCCL_TEMPLATE(class _Arg)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<remove_cvref_t<_Arg>> _CCCL_AND
|
||||
__cw_is_constexpr_indexable_v<__constant_wrapper, void, remove_cvref_t<_Arg>>)
|
||||
# if _CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR()
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_DEVICE_API consteval static __constant_wrapper<__cw_fixed_value(value[remove_cvref_t<_Arg>::value])>
|
||||
operator[](_Arg&&) noexcept
|
||||
# else // ^^^ _CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR() ^^^ / vvv !_CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR() vvv
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval __constant_wrapper<__cw_fixed_value(value[remove_cvref_t<_Arg>::value])>
|
||||
operator[](_Arg&&) const noexcept
|
||||
# endif // ^^^ _CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR() ^^^
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Arg)
|
||||
_CCCL_REQUIRES((!(__is_constexpr_param_v<remove_cvref_t<_Arg>>
|
||||
&& __cw_is_constexpr_indexable_v<__constant_wrapper, void, remove_cvref_t<_Arg>>) )
|
||||
_CCCL_AND __cw_is_indexable_v<__constant_wrapper, void, _Arg>)
|
||||
# if _CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR()
|
||||
_CCCL_HOST_DEVICE_API static constexpr decltype(auto) operator[](_Arg&& __arg)
|
||||
# else // ^^^ _CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR() ^^^ / vvv !_CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR() vvv
|
||||
_CCCL_HOST_DEVICE_API constexpr decltype(auto) operator[](_Arg&& __arg) const
|
||||
# endif // ^^^ _CCCL_HAS_STATIC_SUBSCRIPT_OPERATOR() ^^^
|
||||
noexcept(noexcept(value[::cuda::std::forward<_Arg>(__arg)]))
|
||||
{
|
||||
return value[::cuda::std::forward<_Arg>(__arg)];
|
||||
}
|
||||
# endif // ^^^ !_CCCL_HAS_MULTIARG_OPERATOR_BRACKETS() ^^^
|
||||
|
||||
// pseudo-mutators
|
||||
template <class _This = __constant_wrapper>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval __constant_wrapper<__cw_fixed_value(++_This::value)>
|
||||
operator++() const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
template <class _This = __constant_wrapper>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval __constant_wrapper<__cw_fixed_value(_This::value++)>
|
||||
operator++(int) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
template <class _This = __constant_wrapper>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval __constant_wrapper<__cw_fixed_value(--_This::value)>
|
||||
operator--() const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
template <class _This = __constant_wrapper>
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval __constant_wrapper<__cw_fixed_value(_This::value--)>
|
||||
operator--(int) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval decltype(__constant_wrapper<__cw_fixed_value(value += _Rp::value)>{})
|
||||
operator+=(_Rp) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval decltype(__constant_wrapper<__cw_fixed_value(value -= _Rp::value)>{})
|
||||
operator-=(_Rp) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval decltype(__constant_wrapper<__cw_fixed_value(value *= _Rp::value)>{})
|
||||
operator*=(_Rp) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval decltype(__constant_wrapper<__cw_fixed_value(value /= _Rp::value)>{})
|
||||
operator/=(_Rp) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval decltype(__constant_wrapper<__cw_fixed_value(value %= _Rp::value)>{})
|
||||
operator%=(_Rp) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval decltype(__constant_wrapper<__cw_fixed_value(value &= _Rp::value)>{})
|
||||
operator&=(_Rp) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval decltype(__constant_wrapper<__cw_fixed_value(value |= _Rp::value)>{})
|
||||
operator|=(_Rp) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval decltype(__constant_wrapper<__cw_fixed_value(value ^= _Rp::value)>{})
|
||||
operator^=(_Rp) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval decltype(__constant_wrapper<__cw_fixed_value(value <<= _Rp::value)>{})
|
||||
operator<<=(_Rp) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
_CCCL_TEMPLATE(class _Rp)
|
||||
_CCCL_REQUIRES(__is_constexpr_param_v<_Rp>)
|
||||
[[nodiscard]] _CCCL_HOST_DEVICE_API consteval decltype(__constant_wrapper<__cw_fixed_value(value >>= _Rp::value)>{})
|
||||
operator>>=(_Rp) const noexcept
|
||||
{
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
_CCCL_DIAG_POP
|
||||
|
||||
_CCCL_END_NV_DIAG_SUPPRESS()
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
# include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CCCL_STD_VER >= 2020 && !_CCCL_COMPILER(NVRTC)
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_CONSTANT_WRAPPER_H
|
||||
@@ -0,0 +1,101 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_CONVERT_TO_INTEGRAL_H
|
||||
#define _CUDA_STD___UTILITY_CONVERT_TO_INTEGRAL_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/__type_traits/enable_if.h>
|
||||
#include <cuda/std/__type_traits/is_enum.h>
|
||||
#include <cuda/std/__type_traits/is_floating_point.h>
|
||||
#include <cuda/std/__type_traits/underlying_type.h>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
_CCCL_API constexpr int __convert_to_integral(int __val)
|
||||
{
|
||||
return __val;
|
||||
}
|
||||
|
||||
_CCCL_API constexpr unsigned __convert_to_integral(unsigned __val)
|
||||
{
|
||||
return __val;
|
||||
}
|
||||
|
||||
_CCCL_API constexpr long __convert_to_integral(long __val)
|
||||
{
|
||||
return __val;
|
||||
}
|
||||
|
||||
_CCCL_API constexpr unsigned long __convert_to_integral(unsigned long __val)
|
||||
{
|
||||
return __val;
|
||||
}
|
||||
|
||||
_CCCL_API constexpr long long __convert_to_integral(long long __val)
|
||||
{
|
||||
return __val;
|
||||
}
|
||||
|
||||
_CCCL_API constexpr unsigned long long __convert_to_integral(unsigned long long __val)
|
||||
{
|
||||
return __val;
|
||||
}
|
||||
|
||||
template <typename _Fp>
|
||||
_CCCL_API constexpr enable_if_t<is_floating_point_v<_Fp>, long long> __convert_to_integral(_Fp __val)
|
||||
{
|
||||
return __val;
|
||||
}
|
||||
|
||||
#if _CCCL_HAS_INT128()
|
||||
_CCCL_API constexpr __int128_t __convert_to_integral(__int128_t __val)
|
||||
{
|
||||
return __val;
|
||||
}
|
||||
|
||||
_CCCL_API constexpr __uint128_t __convert_to_integral(__uint128_t __val)
|
||||
{
|
||||
return __val;
|
||||
}
|
||||
#endif // _CCCL_HAS_INT128()
|
||||
|
||||
template <class _Tp, bool = is_enum_v<_Tp>>
|
||||
struct __sfinae_underlying_type
|
||||
{
|
||||
using type = typename underlying_type<_Tp>::type;
|
||||
using __promoted_type = decltype(((type) 1) + 0);
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct __sfinae_underlying_type<_Tp, false>
|
||||
{};
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr typename __sfinae_underlying_type<_Tp>::__promoted_type __convert_to_integral(_Tp __val)
|
||||
{
|
||||
return __val;
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_CONVERT_TO_INTEGRAL_H
|
||||
@@ -0,0 +1,27 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_CTAD_SUPPORT_H
|
||||
#define _CUDA_STD___UTILITY_CTAD_SUPPORT_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
|
||||
|
||||
#define _CCCL_CTAD_SUPPORTED_FOR_TYPE(_ClassName) \
|
||||
template <class... _Tag> \
|
||||
_ClassName(typename _Tag::__allow_ctad...)->_ClassName<_Tag...>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_CTAD_SUPPORT_H
|
||||
@@ -0,0 +1,77 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_DECLVAL_H
|
||||
#define _CUDA_STD___UTILITY_DECLVAL_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/__type_traits/void_t.h>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
#ifndef _CCCL_DOXYGEN_INVOKED
|
||||
// Handy in concept definitions for turning:
|
||||
// requires (T&& t) { ... std::forward<T>(t) ...; }
|
||||
// into:
|
||||
// requires (__declfn_t<T> t) { ... t() ...; }
|
||||
//
|
||||
// NOTE: Unlike std::declval, the return type of __declfn_t is not
|
||||
// rvalue-reference-qualified. In most cases this does not matter, except when _Tp is an
|
||||
// incomplete class type. In places where that matters, use __declfn_t<_Tp&&> instead of
|
||||
// __declfn_t<_Tp>.
|
||||
template <class _Tp, bool _Noexcept = true>
|
||||
using __declfn_t _CCCL_NODEBUG_ALIAS = _Tp (*)() noexcept(_Noexcept);
|
||||
#endif // _CCCL_DOXYGEN_INVOKED
|
||||
|
||||
// When variable templates and noexcept function types are available, a faster
|
||||
// implementation of declval is available. It compiles approximately 2x faster
|
||||
// than the fallback. NOTE: this implementation causes nvcc < 12.4 to ICE and
|
||||
// MSVC < 19.39 to miscompile so we use the fallback instead. The use of the
|
||||
// `__declfn_t` alias is help MSVC parse the declaration correctly.
|
||||
#if !_CCCL_CUDA_COMPILER(NVCC, <, 12, 4) && !_CCCL_COMPILER(MSVC, <, 19, 39) && !_CCCL_TILE_COMPILATION()
|
||||
|
||||
template <class _Tp, class = void>
|
||||
extern __declfn_t<void> declval;
|
||||
|
||||
template <class _Tp>
|
||||
extern __declfn_t<_Tp&&> declval<_Tp, void_t<_Tp&&>>;
|
||||
|
||||
#else // ^^^ fast declval ^^^ / vvv default impl vvv
|
||||
|
||||
// Suppress deprecation notice for volatile-qualified return type resulting
|
||||
// from volatile-qualified types _Tp.
|
||||
_CCCL_SUPPRESS_DEPRECATED_PUSH
|
||||
_CCCL_SUPPRESS_DEPRECATED_NVRTC_DIAG
|
||||
template <class _Tp>
|
||||
_CCCL_API inline _Tp&& __declval(int);
|
||||
template <class _Tp>
|
||||
_CCCL_API inline _Tp __declval(long);
|
||||
_CCCL_SUPPRESS_DEPRECATED_POP
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_API inline decltype(::cuda::std::__declval<_Tp>(0)) declval() noexcept;
|
||||
|
||||
#endif // default impl
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_DECLVAL_H
|
||||
@@ -0,0 +1,51 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_DELEGATE_CONSTRUCTORS_H
|
||||
#define _CUDA_STD___UTILITY_DELEGATE_CONSTRUCTORS_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/__type_traits/is_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_default_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_nothrow_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_nothrow_default_constructible.h>
|
||||
#include <cuda/std/__utility/forward.h>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
// NVRTC has a bug that prevented the use of delegated constructors, as it did not accept execution space annotations.
|
||||
// This creates a whole lot of boilerplate that we can avoid through a macro (see nvbug3961621)
|
||||
#if _CCCL_COMPILER(NVRTC, <, 12, 6)
|
||||
# define _CCCL_DELEGATE_CONSTRUCTORS(__class, __baseclass, ...) \
|
||||
using __base = __baseclass<__VA_ARGS__>; \
|
||||
_CCCL_TEMPLATE(class... _Args) \
|
||||
_CCCL_REQUIRES(::cuda::std::is_constructible_v<__base, _Args...>) \
|
||||
_CCCL_API constexpr __class(_Args&&... __args) noexcept(::cuda::std::is_nothrow_constructible_v<__base, _Args...>) \
|
||||
: __base(::cuda::std::forward<_Args>(__args)...) \
|
||||
{} \
|
||||
_CCCL_HIDE_FROM_ABI constexpr __class() noexcept(::cuda::std::is_nothrow_default_constructible_v<__base>) = default;
|
||||
#else // ^^^ workaround ^^^ / vvv no workaround vvv
|
||||
# define _CCCL_DELEGATE_CONSTRUCTORS(__class, __baseclass, ...) \
|
||||
using __base = __baseclass<__VA_ARGS__>; \
|
||||
using __base::__base; \
|
||||
_CCCL_HIDE_FROM_ABI constexpr __class() noexcept(::cuda::std::is_nothrow_default_constructible_v<__base>) = default;
|
||||
#endif // ^^^ no workaround ^^^
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_DELEGATE_CONSTRUCTORS_H
|
||||
@@ -0,0 +1,162 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_EXCEPTION_GUARD_H
|
||||
#define _CUDA_STD___UTILITY_EXCEPTION_GUARD_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/__type_traits/is_nothrow_move_constructible.h>
|
||||
#include <cuda/std/__utility/ctad_support.h>
|
||||
#include <cuda/std/__utility/exchange.h>
|
||||
#include <cuda/std/__utility/move.h>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
// __exception_guard is a helper class for writing code with the strong exception guarantee.
|
||||
//
|
||||
// When writing code that can throw an exception, one can store rollback instructions in an
|
||||
// exception guard so that if an exception is thrown at any point during the lifetime of the
|
||||
// exception guard, it will be rolled back automatically. When the exception guard is done, one
|
||||
// must mark it as being complete so it isn't rolled back when the exception guard is destroyed.
|
||||
//
|
||||
// Exception guards are not default constructible, they can't be copied or assigned to, but
|
||||
// they can be moved around for convenience.
|
||||
//
|
||||
// __exception_guard is a no-op in -fno-exceptions mode to produce better code-gen. This means
|
||||
// that we don't provide the strong exception guarantees. However, Clang doesn't generate cleanup
|
||||
// code with exceptions disabled, so even if we wanted to provide the strong exception guarantees
|
||||
// we couldn't. This is also only relevant for constructs with a stack of
|
||||
// -fexceptions > -fno-exceptions > -fexceptions code, since the exception can't be caught where
|
||||
// exceptions are disabled. While -fexceptions > -fno-exceptions is quite common
|
||||
// (e.g. libc++.dylib > -fno-exceptions), having another layer with exceptions enabled seems a lot
|
||||
// less common, especially one that tries to catch an exception through -fno-exceptions code.
|
||||
//
|
||||
// __exception_guard can help greatly simplify code that would normally be cluttered by
|
||||
// `#if !_CCCL_HAS_EXCEPTIONS()`. For example:
|
||||
//
|
||||
// template <class Iterator, class Size, class OutputIterator>
|
||||
// Iterator uninitialized_copy_n(Iterator iter, Size n, OutputIterator out) {
|
||||
// using value_type = typename iterator_traits<Iterator>::value_type;
|
||||
// __exception_guard guard([start=out, &out] {
|
||||
// ::cuda::std::destroy(start, out);
|
||||
// });
|
||||
//
|
||||
// for (; n > 0; ++iter, ++out, --n) {
|
||||
// ::new ((void*)::cuda::std::addressof(*out)) value_type(*iter);
|
||||
// }
|
||||
// guard.__complete();
|
||||
// return out;
|
||||
// }
|
||||
//
|
||||
|
||||
template <class _Rollback>
|
||||
struct __exception_guard_exceptions
|
||||
{
|
||||
__exception_guard_exceptions() = delete;
|
||||
|
||||
_CCCL_API inline _CCCL_CONSTEXPR_CXX20 explicit __exception_guard_exceptions(_Rollback __rollback)
|
||||
: __rollback_(::cuda::std::move(__rollback))
|
||||
, __completed_(false)
|
||||
{}
|
||||
|
||||
_CCCL_API inline _CCCL_CONSTEXPR_CXX20 __exception_guard_exceptions(__exception_guard_exceptions&& __other) noexcept(
|
||||
is_nothrow_move_constructible_v<_Rollback>)
|
||||
: __rollback_(::cuda::std::move(__other.__rollback_))
|
||||
, __completed_(__other.__completed_)
|
||||
{
|
||||
__other.__completed_ = true;
|
||||
}
|
||||
|
||||
__exception_guard_exceptions(__exception_guard_exceptions const&) = delete;
|
||||
__exception_guard_exceptions& operator=(__exception_guard_exceptions const&) = delete;
|
||||
__exception_guard_exceptions& operator=(__exception_guard_exceptions&&) = delete;
|
||||
|
||||
_CCCL_API inline _CCCL_CONSTEXPR_CXX20 void __complete() noexcept
|
||||
{
|
||||
__completed_ = true;
|
||||
}
|
||||
|
||||
_CCCL_API inline _CCCL_CONSTEXPR_CXX20 ~__exception_guard_exceptions()
|
||||
{
|
||||
if (!__completed_)
|
||||
{
|
||||
__rollback_();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
_Rollback __rollback_;
|
||||
bool __completed_;
|
||||
};
|
||||
|
||||
_CCCL_CTAD_SUPPORTED_FOR_TYPE(__exception_guard_exceptions);
|
||||
|
||||
template <class _Rollback>
|
||||
struct __exception_guard_noexceptions
|
||||
{
|
||||
__exception_guard_noexceptions() = delete;
|
||||
_CCCL_API inline _CCCL_CONSTEXPR_CXX20 _CCCL_NODEBUG_ALIAS explicit __exception_guard_noexceptions(_Rollback) {}
|
||||
|
||||
_CCCL_API inline _CCCL_CONSTEXPR_CXX20 _CCCL_NODEBUG_ALIAS __exception_guard_noexceptions(
|
||||
__exception_guard_noexceptions&& __other) noexcept(is_nothrow_move_constructible_v<_Rollback>)
|
||||
: __completed_(__other.__completed_)
|
||||
{
|
||||
__other.__completed_ = true;
|
||||
}
|
||||
|
||||
__exception_guard_noexceptions(__exception_guard_noexceptions const&) = delete;
|
||||
__exception_guard_noexceptions& operator=(__exception_guard_noexceptions const&) = delete;
|
||||
__exception_guard_noexceptions& operator=(__exception_guard_noexceptions&&) = delete;
|
||||
|
||||
_CCCL_API inline _CCCL_CONSTEXPR_CXX20 _CCCL_NODEBUG_ALIAS void __complete() noexcept
|
||||
{
|
||||
__completed_ = true;
|
||||
}
|
||||
|
||||
_CCCL_API inline _CCCL_CONSTEXPR_CXX20 _CCCL_NODEBUG_ALIAS ~__exception_guard_noexceptions()
|
||||
{
|
||||
_CCCL_ASSERT(__completed_, "__exception_guard not completed with exceptions disabled");
|
||||
}
|
||||
|
||||
private:
|
||||
bool __completed_ = false;
|
||||
};
|
||||
|
||||
_CCCL_CTAD_SUPPORTED_FOR_TYPE(__exception_guard_noexceptions);
|
||||
|
||||
#if !_CCCL_HAS_EXCEPTIONS()
|
||||
template <class _Rollback>
|
||||
using __exception_guard = __exception_guard_noexceptions<_Rollback>;
|
||||
#else // ^^^ !_CCCL_HAS_EXCEPTIONS() ^^^ / vvv _CCCL_HAS_EXCEPTIONS() vvv
|
||||
template <class _Rollback>
|
||||
using __exception_guard = __exception_guard_exceptions<_Rollback>;
|
||||
#endif // _CCCL_HAS_EXCEPTIONS()
|
||||
|
||||
template <class _Rollback>
|
||||
_CCCL_API constexpr __exception_guard<_Rollback> __make_exception_guard(_Rollback __rollback)
|
||||
{
|
||||
return __exception_guard<_Rollback>(::cuda::std::move(__rollback));
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_EXCEPTION_GUARD_H
|
||||
@@ -0,0 +1,46 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_EXCHANGE_H
|
||||
#define _CUDA_STD___UTILITY_EXCHANGE_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/__type_traits/is_nothrow_assignable.h>
|
||||
#include <cuda/std/__type_traits/is_nothrow_move_constructible.h>
|
||||
#include <cuda/std/__utility/forward.h>
|
||||
#include <cuda/std/__utility/move.h>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _T1, class _T2 = _T1>
|
||||
_CCCL_API constexpr _T1 exchange(_T1& __obj, _T2&& __new_value) noexcept(
|
||||
is_nothrow_move_constructible_v<_T1> && is_nothrow_assignable_v<_T1&, _T2>)
|
||||
{
|
||||
_T1 __old_value = ::cuda::std::move(__obj);
|
||||
__obj = ::cuda::std::forward<_T2>(__new_value);
|
||||
return __old_value;
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_EXCHANGE_H
|
||||
@@ -0,0 +1,90 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_FORWARD_H
|
||||
#define _CUDA_STD___UTILITY_FORWARD_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/__type_traits/is_reference.h>
|
||||
#include <cuda/std/__type_traits/remove_reference.h>
|
||||
#include <cuda/std/cstddef>
|
||||
|
||||
#if _CCCL_COMPILER(CLANG, >=, 15) || _CCCL_COMPILER(GCC, >=, 12) \
|
||||
|| (_CCCL_COMPILER(NVRTC) && defined(__NV_BUILTIN_MOVE_FORWARD))
|
||||
# define _CCCL_HAS_BUILTIN_STD_FORWARD() 1
|
||||
#else // ^^^ has builtin std::forward ^^^ / vvv no builtin std::forward vvv
|
||||
# define _CCCL_HAS_BUILTIN_STD_FORWARD() 0
|
||||
#endif // ^^^ no builtin std::forward ^^^
|
||||
|
||||
// nvcc always supports std::forward in device code.
|
||||
#if _CCCL_CUDA_COMPILER(NVCC) && _CCCL_DEVICE_COMPILATION()
|
||||
# undef _CCCL_HAS_BUILTIN_STD_FORWARD
|
||||
# define _CCCL_HAS_BUILTIN_STD_FORWARD() 1
|
||||
#endif // _CCCL_CUDA_COMPILER(NVCC) && _CCCL_DEVICE_COMPILATION()
|
||||
|
||||
// We cannot use host features if we are building in freestanding
|
||||
// However, NVRTC handles it specially
|
||||
#if _CCCL_FREESTANDING() && !_CCCL_COMPILER(NVRTC)
|
||||
# undef _CCCL_HAS_BUILTIN_STD_FORWARD
|
||||
# define _CCCL_HAS_BUILTIN_STD_FORWARD() 0
|
||||
#endif // _CCCL_ENABLE_FREESTANDING
|
||||
|
||||
// include minimal std:: headers, nvcc in device mode doesn't need the std:: header
|
||||
#if _CCCL_HAS_BUILTIN_STD_FORWARD() && !(_CCCL_CUDA_COMPILER(NVCC) && _CCCL_DEVICE_COMPILATION())
|
||||
# if _CCCL_HOST_STD_LIB(LIBSTDCXX) && __has_include(<bits/move.h>)
|
||||
# include <bits/move.h>
|
||||
# elif _CCCL_HOST_STD_LIB(LIBCXX) && __has_include(<__utility/forward.h>)
|
||||
# include <__utility/forward.h>
|
||||
# elif _CCCL_HOSTED()
|
||||
# include <utility>
|
||||
# endif // _CCCL_HOSTED()
|
||||
#endif // _CCCL_HAS_BUILTIN_STD_FORWARD() && !(_CCCL_CUDA_COMPILER(NVCC) && _CCCL_DEVICE_COMPILATION())
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
#if _CCCL_HAS_BUILTIN_STD_FORWARD()
|
||||
|
||||
// The compiler treats ::std::forward as a builtin function so it does not need to be instantiated and will be compiled
|
||||
// away even at -O0.
|
||||
using ::std::forward;
|
||||
|
||||
#else // ^^^ _CCCL_HAS_BUILTIN_STD_FORWARD() ^^^ / vvv !_CCCL_HAS_BUILTIN_STD_FORWARD() vvv
|
||||
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _CCCL_INTRINSIC _CCCL_API constexpr _Tp&& forward(remove_reference_t<_Tp>& __t) noexcept
|
||||
{
|
||||
return static_cast<_Tp&&>(__t);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _CCCL_INTRINSIC _CCCL_API constexpr _Tp&& forward(remove_reference_t<_Tp>&& __t) noexcept
|
||||
{
|
||||
static_assert(!is_lvalue_reference_v<_Tp>, "cannot forward an rvalue as an lvalue");
|
||||
return static_cast<_Tp&&>(__t);
|
||||
}
|
||||
|
||||
#endif // ^^^ !_CCCL_HAS_BUILTIN_STD_FORWARD() ^^^
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_FORWARD_H
|
||||
@@ -0,0 +1,84 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_FORWARD_LIKE_H
|
||||
#define _CUDA_STD___UTILITY_FORWARD_LIKE_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/__type_traits/conditional.h>
|
||||
#include <cuda/std/__type_traits/copy_cvref.h>
|
||||
#include <cuda/std/__type_traits/remove_reference.h>
|
||||
|
||||
#if (_CCCL_COMPILER(CLANG, >=, 17) || _CCCL_COMPILER(GCC, >=, 15)) && __cpp_lib_forward_like >= 202217L
|
||||
# define _CCCL_HAS_BUILTIN_STD_FORWARD_LIKE() 1
|
||||
#else // ^^^ has builtin std::forward_like ^^^ / vvv no builtin std::forward_like vvv
|
||||
# define _CCCL_HAS_BUILTIN_STD_FORWARD_LIKE() 0
|
||||
#endif // ^^^ no builtin std::forward_like ^^^
|
||||
|
||||
// nvcc warns about host only std::forward_like being used in device code
|
||||
#if _CCCL_CUDA_COMPILER(NVCC) && _CCCL_DEVICE_COMPILATION()
|
||||
# undef _CCCL_HAS_BUILTIN_STD_FORWARD_LIKE
|
||||
# define _CCCL_HAS_BUILTIN_STD_FORWARD_LIKE() 0
|
||||
#endif // _CCCL_CUDA_COMPILER(NVCC) && _CCCL_DEVICE_COMPILATION()
|
||||
|
||||
// We cannot use host features if we are building in freestanding
|
||||
#if _CCCL_FREESTANDING()
|
||||
# undef _CCCL_HAS_BUILTIN_STD_FORWARD_LIKE
|
||||
# define _CCCL_HAS_BUILTIN_STD_FORWARD_LIKE() 0
|
||||
#endif // _CCCL_FREESTANDING()
|
||||
|
||||
// include minimal std:: headers
|
||||
#if _CCCL_HAS_BUILTIN_STD_FORWARD_LIKE()
|
||||
# if _CCCL_HOST_STD_LIB(LIBSTDCXX) && __has_include(<bits/move.h>)
|
||||
# include <bits/move.h>
|
||||
# elif _CCCL_HOST_STD_LIB(LIBCXX) && __has_include(<__utility/forward_like.h>)
|
||||
# include <__utility/forward_like.h>
|
||||
# elif _CCCL_HOSTED()
|
||||
# include <utility>
|
||||
# endif // _CCCL_HOSTED()
|
||||
#endif // _CCCL_HAS_BUILTIN_STD_FORWARD_LIKE()
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
#if _CCCL_HAS_BUILTIN_STD_FORWARD_LIKE()
|
||||
|
||||
// The compiler treats ::std::forward_like as a builtin function so it does not need to be
|
||||
// instantiated and will be compiled away even at -O0.
|
||||
using ::std::forward_like;
|
||||
|
||||
#else // ^^^ _CCCL_HAS_BUILTIN_STD_FORWARD_LIKE() ^^^ / vvv !_CCCL_HAS_BUILTIN_STD_FORWARD_LIKE() vvv
|
||||
|
||||
template <class _Ap, class _Bp>
|
||||
using _ForwardLike = __copy_cvref_t<_Ap&&, remove_reference_t<_Bp>>;
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
[[nodiscard]] _CCCL_INTRINSIC _CCCL_API constexpr auto forward_like(_Up&& __ux) noexcept -> _ForwardLike<_Tp, _Up>
|
||||
{
|
||||
return static_cast<_ForwardLike<_Tp, _Up>>(__ux);
|
||||
}
|
||||
|
||||
#endif // ^^^ !_CCCL_HAS_BUILTIN_STD_FORWARD_LIKE() ^^^
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_FORWARD_LIKE_H
|
||||
@@ -0,0 +1,86 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_IN_PLACE_H
|
||||
#define _CUDA_STD___UTILITY_IN_PLACE_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/__type_traits/is_reference.h>
|
||||
#include <cuda/std/__type_traits/remove_cvref.h>
|
||||
#include <cuda/std/__type_traits/remove_reference.h>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT in_place_t
|
||||
{
|
||||
_CCCL_HIDE_FROM_ABI explicit in_place_t() = default;
|
||||
};
|
||||
_CCCL_GLOBAL_CONSTANT in_place_t in_place{};
|
||||
|
||||
template <class _Tp>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT in_place_type_t
|
||||
{
|
||||
_CCCL_HIDE_FROM_ABI explicit in_place_type_t() = default;
|
||||
};
|
||||
template <class _Tp>
|
||||
inline constexpr in_place_type_t<_Tp> in_place_type{};
|
||||
|
||||
template <size_t _Idx>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT in_place_index_t
|
||||
{
|
||||
_CCCL_HIDE_FROM_ABI explicit in_place_index_t() = default;
|
||||
};
|
||||
template <size_t _Idx>
|
||||
inline constexpr in_place_index_t<_Idx> in_place_index{};
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr bool __is_cuda_std_inplace_type_v = false;
|
||||
template <class _Tp>
|
||||
inline constexpr bool __is_cuda_std_inplace_type_v<in_place_type_t<_Tp>> = true;
|
||||
|
||||
template <class _Tp>
|
||||
inline constexpr bool __is_cuda_std_inplace_index_v = false;
|
||||
template <size_t _Idx>
|
||||
inline constexpr bool __is_cuda_std_inplace_index_v<in_place_index_t<_Idx>> = true;
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
// CCCL extensions below
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA
|
||||
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT in_place_from_t
|
||||
{
|
||||
_CCCL_HIDE_FROM_ABI explicit in_place_from_t() = default;
|
||||
};
|
||||
_CCCL_GLOBAL_CONSTANT in_place_from_t in_place_from{};
|
||||
|
||||
template <class _Tp>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT in_place_from_type_t
|
||||
{
|
||||
_CCCL_HIDE_FROM_ABI explicit in_place_from_type_t() = default;
|
||||
};
|
||||
template <class _Tp>
|
||||
inline constexpr in_place_from_type_t<_Tp> in_place_from_type{};
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_IN_PLACE_H
|
||||
@@ -0,0 +1,308 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_INTEGER_SEQUENCE_H
|
||||
#define _CUDA_STD___UTILITY_INTEGER_SEQUENCE_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/__cstddef/types.h>
|
||||
#include <cuda/std/__tuple_dir/tuple_element.h>
|
||||
#include <cuda/std/__tuple_dir/tuple_size.h>
|
||||
#include <cuda/std/__type_traits/integral_constant.h>
|
||||
#include <cuda/std/__type_traits/is_integral.h>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
template <size_t...>
|
||||
struct __tuple_indices
|
||||
{};
|
||||
|
||||
template <class _IdxType, _IdxType... _Values>
|
||||
struct __integer_sequence
|
||||
{
|
||||
template <template <class _OIdxType, _OIdxType...> class _ToIndexSeq, class _ToIndexType>
|
||||
using __convert _CCCL_NODEBUG_ALIAS = _ToIndexSeq<_ToIndexType, _Values...>;
|
||||
|
||||
template <size_t _Sp>
|
||||
using __to_tuple_indices _CCCL_NODEBUG_ALIAS = __tuple_indices<(_Values + _Sp)...>;
|
||||
};
|
||||
|
||||
#if defined(_CCCL_BUILTIN_MAKE_INTEGER_SEQ)
|
||||
|
||||
template <size_t _Ep, size_t _Sp>
|
||||
using __make_indices_imp _CCCL_NODEBUG_ALIAS =
|
||||
typename _CCCL_BUILTIN_MAKE_INTEGER_SEQ(__integer_sequence, size_t, _Ep - _Sp)::template __to_tuple_indices<_Sp>;
|
||||
|
||||
#elif defined(_CCCL_BUILTIN_INTEGER_PACK)
|
||||
|
||||
template <size_t _Ep, size_t _Sp>
|
||||
using __make_indices_imp _CCCL_NODEBUG_ALIAS =
|
||||
typename __integer_sequence<size_t, _CCCL_BUILTIN_INTEGER_PACK(_Ep - _Sp)...>::template __to_tuple_indices<_Sp>;
|
||||
|
||||
#else // ^^^ _CCCL_BUILTIN_INTEGER_PACK ^^^ / vvv !_CCCL_BUILTIN_INTEGER_PACK vvv
|
||||
|
||||
namespace __detail
|
||||
{
|
||||
template <typename _Tp, size_t... _Extra>
|
||||
struct __repeat;
|
||||
template <typename _Tp, _Tp... _Np, size_t... _Extra>
|
||||
struct __repeat<__integer_sequence<_Tp, _Np...>, _Extra...>
|
||||
{
|
||||
using type _CCCL_NODEBUG_ALIAS = __integer_sequence<
|
||||
_Tp,
|
||||
_Np...,
|
||||
sizeof...(_Np) + _Np...,
|
||||
2 * sizeof...(_Np) + _Np...,
|
||||
3 * sizeof...(_Np) + _Np...,
|
||||
4 * sizeof...(_Np) + _Np...,
|
||||
5 * sizeof...(_Np) + _Np...,
|
||||
6 * sizeof...(_Np) + _Np...,
|
||||
7 * sizeof...(_Np) + _Np...,
|
||||
_Extra...>;
|
||||
};
|
||||
|
||||
template <size_t _Np>
|
||||
struct __parity;
|
||||
|
||||
template <size_t _Np>
|
||||
struct __make : __parity<_Np % 8>::template __pmake<_Np>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct __make<0>
|
||||
{
|
||||
using type = __integer_sequence<size_t>;
|
||||
};
|
||||
template <>
|
||||
struct __make<1>
|
||||
{
|
||||
using type = __integer_sequence<size_t, 0>;
|
||||
};
|
||||
template <>
|
||||
struct __make<2>
|
||||
{
|
||||
using type = __integer_sequence<size_t, 0, 1>;
|
||||
};
|
||||
template <>
|
||||
struct __make<3>
|
||||
{
|
||||
using type = __integer_sequence<size_t, 0, 1, 2>;
|
||||
};
|
||||
template <>
|
||||
struct __make<4>
|
||||
{
|
||||
using type = __integer_sequence<size_t, 0, 1, 2, 3>;
|
||||
};
|
||||
template <>
|
||||
struct __make<5>
|
||||
{
|
||||
using type = __integer_sequence<size_t, 0, 1, 2, 3, 4>;
|
||||
};
|
||||
template <>
|
||||
struct __make<6>
|
||||
{
|
||||
using type = __integer_sequence<size_t, 0, 1, 2, 3, 4, 5>;
|
||||
};
|
||||
template <>
|
||||
struct __make<7>
|
||||
{
|
||||
using type = __integer_sequence<size_t, 0, 1, 2, 3, 4, 5, 6>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct __parity<0>
|
||||
{
|
||||
template <size_t _Np>
|
||||
struct __pmake : __repeat<typename __make<_Np / 8>::type>
|
||||
{};
|
||||
};
|
||||
template <>
|
||||
struct __parity<1>
|
||||
{
|
||||
template <size_t _Np>
|
||||
struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 1>
|
||||
{};
|
||||
};
|
||||
template <>
|
||||
struct __parity<2>
|
||||
{
|
||||
template <size_t _Np>
|
||||
struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 2, _Np - 1>
|
||||
{};
|
||||
};
|
||||
template <>
|
||||
struct __parity<3>
|
||||
{
|
||||
template <size_t _Np>
|
||||
struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 3, _Np - 2, _Np - 1>
|
||||
{};
|
||||
};
|
||||
template <>
|
||||
struct __parity<4>
|
||||
{
|
||||
template <size_t _Np>
|
||||
struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 4, _Np - 3, _Np - 2, _Np - 1>
|
||||
{};
|
||||
};
|
||||
template <>
|
||||
struct __parity<5>
|
||||
{
|
||||
template <size_t _Np>
|
||||
struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1>
|
||||
{};
|
||||
};
|
||||
template <>
|
||||
struct __parity<6>
|
||||
{
|
||||
template <size_t _Np>
|
||||
struct __pmake : __repeat<typename __make<_Np / 8>::type, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1>
|
||||
{};
|
||||
};
|
||||
template <>
|
||||
struct __parity<7>
|
||||
{
|
||||
template <size_t _Np>
|
||||
struct __pmake
|
||||
: __repeat<typename __make<_Np / 8>::type, _Np - 7, _Np - 6, _Np - 5, _Np - 4, _Np - 3, _Np - 2, _Np - 1>
|
||||
{};
|
||||
};
|
||||
} // namespace __detail
|
||||
|
||||
template <size_t _Ep, size_t _Sp>
|
||||
using __make_indices_imp _CCCL_NODEBUG_ALIAS =
|
||||
typename __detail::__make<_Ep - _Sp>::type::template __to_tuple_indices<_Sp>;
|
||||
|
||||
#endif // !_CCCL_BUILTIN_INTEGER_PACK
|
||||
|
||||
template <class _Tp, _Tp... _Ip>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT integer_sequence
|
||||
{
|
||||
using value_type = _Tp;
|
||||
static_assert(is_integral_v<_Tp>, "std::integer_sequence can only be instantiated with an integral type");
|
||||
static _CCCL_API constexpr size_t size() noexcept
|
||||
{
|
||||
return sizeof...(_Ip);
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t... _Ip>
|
||||
using index_sequence = integer_sequence<size_t, _Ip...>;
|
||||
|
||||
#if defined(_CCCL_BUILTIN_MAKE_INTEGER_SEQ)
|
||||
|
||||
template <class _Tp, _Tp _Ep>
|
||||
using __make_integer_sequence _CCCL_NODEBUG_ALIAS = _CCCL_BUILTIN_MAKE_INTEGER_SEQ(integer_sequence, _Tp, _Ep);
|
||||
|
||||
#elif defined(_CCCL_BUILTIN_INTEGER_PACK)
|
||||
|
||||
template <class _Tp, _Tp _Ep>
|
||||
using __make_integer_sequence _CCCL_NODEBUG_ALIAS = integer_sequence<_Tp, __integer_pack(_Ep)...>;
|
||||
|
||||
#else // ^^^ _CCCL_BUILTIN_INTEGER_PACK ^^^ / vvv !_CCCL_BUILTIN_INTEGER_PACK vvv
|
||||
|
||||
template <typename _Tp, _Tp _Np>
|
||||
using __make_integer_sequence_unchecked _CCCL_NODEBUG_ALIAS =
|
||||
typename __detail::__make<_Np>::type::template __convert<integer_sequence, _Tp>;
|
||||
|
||||
template <class _Tp, _Tp _Ep>
|
||||
struct __make_integer_sequence_checked
|
||||
{
|
||||
static_assert(is_integral_v<_Tp>, "std::make_integer_sequence can only be instantiated with an integral type");
|
||||
static_assert(0 <= _Ep, "std::make_integer_sequence must have a non-negative sequence length");
|
||||
// Workaround GCC bug by preventing bad installations when 0 <= _Ep
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68929
|
||||
using type _CCCL_NODEBUG_ALIAS = __make_integer_sequence_unchecked<_Tp, 0 <= _Ep ? _Ep : 0>;
|
||||
};
|
||||
|
||||
template <class _Tp, _Tp _Ep>
|
||||
using __make_integer_sequence _CCCL_NODEBUG_ALIAS = typename __make_integer_sequence_checked<_Tp, _Ep>::type;
|
||||
|
||||
#endif // !_CCCL_BUILTIN_INTEGER_PACK
|
||||
|
||||
template <class _Tp, _Tp _Np>
|
||||
using make_integer_sequence = __make_integer_sequence<_Tp, _Np>;
|
||||
|
||||
template <size_t _Np>
|
||||
using make_index_sequence = make_integer_sequence<size_t, _Np>;
|
||||
|
||||
template <class... _Tp>
|
||||
using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
|
||||
|
||||
// specialize cuda::std::tuple_size and cuda::std::tuple_element for cuda::std::integer_sequence
|
||||
|
||||
template <class _Tp, _Tp... _Indices>
|
||||
struct tuple_size<integer_sequence<_Tp, _Indices...>> : integral_constant<size_t, sizeof...(_Indices)>
|
||||
{};
|
||||
|
||||
template <size_t _Ip, class _Tp, _Tp... _Indices>
|
||||
struct tuple_element<_Ip, integer_sequence<_Tp, _Indices...>>
|
||||
{
|
||||
static_assert(_Ip < sizeof...(_Indices),
|
||||
"Index out of bounds in cuda::std::tuple_element<> (cuda::std::integer_sequence)");
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
template <size_t _Ip, class _Tp, _Tp... _Indices>
|
||||
struct tuple_element<_Ip, const integer_sequence<_Tp, _Indices...>>
|
||||
{
|
||||
static_assert(_Ip < sizeof...(_Indices),
|
||||
"Index out of bounds in cuda::std::tuple_element<> (const cuda::std::integer_sequence)");
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
template <size_t _Ip, class _Tp, _Tp... _Indices>
|
||||
[[nodiscard]] _CCCL_API constexpr _Tp get(integer_sequence<_Tp, _Indices...>) noexcept
|
||||
{
|
||||
static_assert(_Ip < sizeof...(_Indices), "Index out of bounds in cuda::std::get<> (cuda::std::integer_sequence)");
|
||||
constexpr _Tp __indices[]{_Indices...};
|
||||
return __indices[_Ip];
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
// tuple protocol for cuda::std::integer_sequence
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Tp, _Tp... _Indices>
|
||||
struct tuple_size<::cuda::std::integer_sequence<_Tp, _Indices...>>
|
||||
: ::cuda::std::integral_constant<::cuda::std::size_t, sizeof...(_Indices)>
|
||||
{};
|
||||
|
||||
template <::cuda::std::size_t _Ip, class _Tp, _Tp... _Indices>
|
||||
struct tuple_element<_Ip, ::cuda::std::integer_sequence<_Tp, _Indices...>>
|
||||
{
|
||||
static_assert(_Ip < sizeof...(_Indices), "Index out of bounds in std::tuple_element<> (cuda::std::integer_sequence)");
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
template <::cuda::std::size_t _Ip, class _Tp, _Tp... _Indices>
|
||||
struct tuple_element<_Ip, const ::cuda::std::integer_sequence<_Tp, _Indices...>>
|
||||
{
|
||||
static_assert(_Ip < sizeof...(_Indices),
|
||||
"Index out of bounds in std::tuple_element<> (const cuda::std::integer_sequence)");
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
_CCCL_END_NAMESPACE_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_INTEGER_SEQUENCE_H
|
||||
@@ -0,0 +1,99 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_MONOSTATE_H
|
||||
#define _CUDA_STD___UTILITY_MONOSTATE_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 _LIBCUDACXX_HAS_SPACESHIP_OPERATOR()
|
||||
# include <cuda/std/__compare/ordering.h>
|
||||
#endif // _LIBCUDACXX_HAS_SPACESHIP_OPERATOR()
|
||||
#include <cuda/std/__functional/hash.h>
|
||||
#include <cuda/std/cstddef>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT monostate
|
||||
{};
|
||||
|
||||
_CCCL_API constexpr bool operator==(monostate, monostate) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#if _CCCL_STD_VER < 2020
|
||||
|
||||
_CCCL_API constexpr bool operator!=(monostate, monostate) noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // _CCCL_STD_VER < 2020
|
||||
|
||||
#if _LIBCUDACXX_HAS_SPACESHIP_OPERATOR()
|
||||
|
||||
_CCCL_API constexpr strong_ordering operator<=>(monostate, monostate) noexcept
|
||||
{
|
||||
return strong_ordering::equal;
|
||||
}
|
||||
|
||||
#else // ^^^ _LIBCUDACXX_HAS_SPACESHIP_OPERATOR() ^^^ / vvv !_LIBCUDACXX_HAS_SPACESHIP_OPERATOR()
|
||||
|
||||
_CCCL_API constexpr bool operator<(monostate, monostate) noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_CCCL_API constexpr bool operator>(monostate, monostate) noexcept
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_CCCL_API constexpr bool operator<=(monostate, monostate) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
_CCCL_API constexpr bool operator>=(monostate, monostate) noexcept
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // !_LIBCUDACXX_HAS_SPACESHIP_OPERATOR()
|
||||
|
||||
#ifndef __cuda_std__
|
||||
template <>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT hash<monostate>
|
||||
{
|
||||
using argument_type = monostate;
|
||||
using result_type = size_t;
|
||||
|
||||
_CCCL_API inline result_type operator()(const argument_type&) const noexcept
|
||||
{
|
||||
return 66740831; // return a fundamentally attractive random value.
|
||||
}
|
||||
};
|
||||
#endif // __cuda_std__
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_MONOSTATE_H
|
||||
140
cccl_upstream/libcudacxx/include/cuda/std/__utility/move.h
Normal file
140
cccl_upstream/libcudacxx/include/cuda/std/__utility/move.h
Normal file
@@ -0,0 +1,140 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_MOVE_H
|
||||
#define _CUDA_STD___UTILITY_MOVE_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/__type_traits/conditional.h>
|
||||
#include <cuda/std/__type_traits/is_copy_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_nothrow_move_constructible.h>
|
||||
#include <cuda/std/__type_traits/remove_reference.h>
|
||||
|
||||
#if _CCCL_COMPILER(CLANG, >=, 15) || _CCCL_COMPILER(GCC, >=, 12) \
|
||||
|| (_CCCL_COMPILER(NVRTC) && defined(__NV_BUILTIN_MOVE_FORWARD))
|
||||
# define _CCCL_HAS_BUILTIN_STD_MOVE() 1
|
||||
#else // ^^^ has builtin std::move ^^^ / vvv no builtin std::move vvv
|
||||
# define _CCCL_HAS_BUILTIN_STD_MOVE() 0
|
||||
#endif // ^^^ no builtin std::move ^^^
|
||||
|
||||
// nvcc always supports std::move in device code.
|
||||
#if _CCCL_CUDA_COMPILER(NVCC) && _CCCL_DEVICE_COMPILATION()
|
||||
# undef _CCCL_HAS_BUILTIN_STD_MOVE
|
||||
# define _CCCL_HAS_BUILTIN_STD_MOVE() 1
|
||||
#endif // _CCCL_CUDA_COMPILER(NVCC) && _CCCL_DEVICE_COMPILATION()
|
||||
|
||||
// We cannot use host features if we are building in freestanding
|
||||
// However, NVRTC handles it specially
|
||||
#if _CCCL_FREESTANDING() && !_CCCL_COMPILER(NVRTC)
|
||||
# undef _CCCL_HAS_BUILTIN_STD_MOVE
|
||||
# define _CCCL_HAS_BUILTIN_STD_MOVE() 0
|
||||
#endif // _CCCL_ENABLE_FREESTANDING
|
||||
|
||||
#if _CCCL_COMPILER(CLANG, >=, 15)
|
||||
# define _CCCL_HAS_BUILTIN_STD_MOVE_IF_NOEXCEPT() 1
|
||||
#else // ^^^ has builtin std::move_if_noexcept ^^^ / vvv no builtin std::move_if_noexcept vvv
|
||||
# define _CCCL_HAS_BUILTIN_STD_MOVE_IF_NOEXCEPT() 0
|
||||
#endif // ^^^ no builtin std::move_if_noexcept ^^^
|
||||
|
||||
// nvcc warns about host only std::move_if_noexcept being used in device code
|
||||
#if _CCCL_CUDA_COMPILER(NVCC) && _CCCL_DEVICE_COMPILATION()
|
||||
# undef _CCCL_HAS_BUILTIN_STD_MOVE_IF_NOEXCEPT
|
||||
# define _CCCL_HAS_BUILTIN_STD_MOVE_IF_NOEXCEPT() 0
|
||||
#endif // _CCCL_CUDA_COMPILER(NVCC) && _CCCL_DEVICE_COMPILATION()
|
||||
|
||||
// We cannot use host features if we are building in freestanding
|
||||
#if _CCCL_FREESTANDING()
|
||||
# undef _CCCL_HAS_BUILTIN_STD_MOVE_IF_NOEXCEPT
|
||||
# define _CCCL_HAS_BUILTIN_STD_MOVE_IF_NOEXCEPT() 0
|
||||
#endif // _CCCL_FREESTANDING()
|
||||
|
||||
// include minimal std:: headers, nvcc in device mode doesn't need the std:: header
|
||||
#if _CCCL_HAS_BUILTIN_STD_MOVE() || _CCCL_HAS_BUILTIN_STD_MOVE_IF_NOEXCEPT()
|
||||
# if _CCCL_HOST_STD_LIB(LIBSTDCXX) && __has_include(<bits/move.h>)
|
||||
# include <bits/move.h>
|
||||
# elif _CCCL_HOST_STD_LIB(LIBCXX) && __has_include(<__utility/move.h>)
|
||||
# include <__utility/move.h> // includes std::move_if_noexcept, too
|
||||
# elif _CCCL_HOSTED()
|
||||
# include <utility>
|
||||
# endif // _CCCL_HOSTED()
|
||||
#endif // _CCCL_HAS_BUILTIN_STD_MOVE() || _CCCL_HAS_BUILTIN_STD_MOVE_IF_NOEXCEPT()
|
||||
|
||||
// _CCCL_MOVE macro always expands to std::move builtin, if available, and fallbacks to cuda::std::move otherwise.
|
||||
#if _CCCL_HAS_BUILTIN_STD_MOVE()
|
||||
# define _CCCL_MOVE(...) ::std::move(__VA_ARGS__)
|
||||
#else // ^^^ _CCCL_HAS_BUILTIN_STD_MOVE() ^^^ / vvv !_CCCL_HAS_BUILTIN_STD_MOVE() vvv
|
||||
# define _CCCL_MOVE(...) ::cuda::std::move(__VA_ARGS__)
|
||||
#endif // ^^^ !_CCCL_HAS_BUILTIN_STD_MOVE() ^^^
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
// We cannot simply use ::std::move here because it would drag in the move algorithm. This can work only if either/
|
||||
// compiling with nvrtc or decorating the move algorithm with `requires true` which overrides the imported move
|
||||
// algorithm. But this solution requires concepts.
|
||||
#if _CCCL_HAS_BUILTIN_STD_MOVE() && (_CCCL_HAS_CONCEPTS() || _CCCL_COMPILER(NVRTC))
|
||||
|
||||
// Forward declare move algorithm decorated with `requires true` to override the imported move algorithm.
|
||||
# if _CCCL_HAS_CONCEPTS()
|
||||
template <class _InputIterator, class _OutputIterator>
|
||||
requires true
|
||||
_CCCL_API constexpr _OutputIterator move(_InputIterator __first, _InputIterator __last, _OutputIterator __result);
|
||||
# endif // _CCCL_HAS_CONCEPTS()
|
||||
|
||||
// The compiler treats ::std::move as a builtin function so it does not need to be instantiated and will be compiled
|
||||
// away even at -O0.
|
||||
using ::std::move;
|
||||
|
||||
#else // ^^^ _CCCL_HAS_BUILTIN_STD_MOVE() && (_CCCL_HAS_CONCEPTS() || _CCCL_COMPILER(NVRTC)) ^^^ /
|
||||
// vvv !_CCCL_HAS_BUILTIN_STD_MOVE() || !(_CCCL_HAS_CONCEPTS() || _CCCL_COMPILER(NVRTC)) vvv
|
||||
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _CCCL_INTRINSIC _CCCL_API constexpr remove_reference_t<_Tp>&& move(_Tp&& __t) noexcept
|
||||
{
|
||||
return static_cast<remove_reference_t<_Tp>&&>(__t);
|
||||
}
|
||||
|
||||
#endif // ^^^ !_CCCL_HAS_BUILTIN_STD_MOVE() || !(_CCCL_HAS_CONCEPTS() || _CCCL_COMPILER(NVRTC)) ^^^
|
||||
|
||||
#if _CCCL_HAS_BUILTIN_STD_MOVE_IF_NOEXCEPT()
|
||||
|
||||
// The compiler treats ::std::move_if_noexcept as a builtin function so it does not need to be
|
||||
// instantiated and will be compiled away even at -O0.
|
||||
using ::std::move_if_noexcept;
|
||||
|
||||
#else // ^^^ _CCCL_HAS_BUILTIN_STD_MOVE_IF_NOEXCEPT() ^^^ / vvv !_CCCL_HAS_BUILTIN_STD_MOVE_IF_NOEXCEPT() vvv
|
||||
|
||||
template <class _Tp>
|
||||
using __move_if_noexcept_result_t =
|
||||
conditional_t<!is_nothrow_move_constructible_v<_Tp> && is_copy_constructible_v<_Tp>, const _Tp&, _Tp&&>;
|
||||
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _CCCL_INTRINSIC _CCCL_API constexpr __move_if_noexcept_result_t<_Tp> move_if_noexcept(_Tp& __x) noexcept
|
||||
{
|
||||
return ::cuda::std::move(__x);
|
||||
}
|
||||
|
||||
#endif // ^^^ !_CCCL_HAS_BUILTIN_STD_MOVE_IF_NOEXCEPT() ^^^
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_MOVE_H
|
||||
943
cccl_upstream/libcudacxx/include/cuda/std/__utility/pair.h
Normal file
943
cccl_upstream/libcudacxx/include/cuda/std/__utility/pair.h
Normal file
@@ -0,0 +1,943 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_PAIR_H
|
||||
#define _CUDA_STD___UTILITY_PAIR_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 _LIBCUDACXX_HAS_SPACESHIP_OPERATOR()
|
||||
# include <cuda/std/__compare/common_comparison_category.h>
|
||||
# include <cuda/std/__compare/synth_three_way.h>
|
||||
#endif // _LIBCUDACXX_HAS_SPACESHIP_OPERATOR()
|
||||
|
||||
#include <cuda/std/__cstddef/types.h>
|
||||
#include <cuda/std/__functional/unwrap_ref.h>
|
||||
#include <cuda/std/__fwd/get.h>
|
||||
#include <cuda/std/__fwd/pair.h>
|
||||
#include <cuda/std/__fwd/subrange.h>
|
||||
#include <cuda/std/__fwd/tuple.h>
|
||||
#include <cuda/std/__tuple_dir/sfinae_helpers.h>
|
||||
#include <cuda/std/__tuple_dir/tuple_constraints.h>
|
||||
#include <cuda/std/__tuple_dir/tuple_element.h>
|
||||
#include <cuda/std/__tuple_dir/tuple_indices.h>
|
||||
#include <cuda/std/__tuple_dir/tuple_like.h>
|
||||
#include <cuda/std/__tuple_dir/tuple_size.h>
|
||||
#include <cuda/std/__type_traits/common_reference.h>
|
||||
#include <cuda/std/__type_traits/conditional.h>
|
||||
#include <cuda/std/__type_traits/decay.h>
|
||||
#include <cuda/std/__type_traits/enable_if.h>
|
||||
#include <cuda/std/__type_traits/integral_constant.h>
|
||||
#include <cuda/std/__type_traits/is_assignable.h>
|
||||
#include <cuda/std/__type_traits/is_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_convertible.h>
|
||||
#include <cuda/std/__type_traits/is_copy_assignable.h>
|
||||
#include <cuda/std/__type_traits/is_default_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_implicitly_default_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_move_assignable.h>
|
||||
#include <cuda/std/__type_traits/is_nothrow_assignable.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_same.h>
|
||||
#include <cuda/std/__type_traits/is_swappable.h>
|
||||
#include <cuda/std/__type_traits/make_const_lvalue_ref.h>
|
||||
#include <cuda/std/__type_traits/reference_constructs_from_temporary.h>
|
||||
#include <cuda/std/__type_traits/sfinae_traits.h>
|
||||
#include <cuda/std/__utility/forward.h>
|
||||
#include <cuda/std/__utility/move.h>
|
||||
#include <cuda/std/__utility/piecewise_construct.h>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
// On Windows we are getting a warning when compiling the const assignment operators with a reference type
|
||||
_CCCL_BEGIN_NV_DIAG_SUPPRESS(1770) // type qualifiers are ignored (underlying type is a reference)
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _UPair, class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API _CCCL_CONSTEVAL __select_constructor __pair_select_pair_like_constructible() noexcept
|
||||
{
|
||||
using ::cuda::std::get;
|
||||
// NOLINTBEGIN(bugprone-branch-clone)
|
||||
if constexpr (__is_cuda_std_ranges_subrange_v<remove_cvref_t<_UPair>>)
|
||||
{ // [pairs#pair]-15.1: remove_cvref_t<UTuple> is not a specialization of ranges::subrange,
|
||||
return __select_constructor::__invalid;
|
||||
}
|
||||
else if constexpr (!__pair_like<_UPair>)
|
||||
{
|
||||
return __select_constructor::__invalid;
|
||||
}
|
||||
else if constexpr (!is_constructible_v<_T1, decltype(get<0>(::cuda::std::declval<_UPair>()))>)
|
||||
{ // [pairs#pair]-15.2: is_constructible<T1, decltype(get<0>(std::forward<UTuple>(u)))>... is true
|
||||
return __select_constructor::__invalid;
|
||||
}
|
||||
else if constexpr (!is_constructible_v<_T2, decltype(get<1>(::cuda::std::declval<_UPair>()))>)
|
||||
{ // [pairs#pair]-15.3: is_constructible<T2, decltype(get<1>(std::forward<UTuple>(u)))>... is true
|
||||
return __select_constructor::__invalid;
|
||||
}
|
||||
#if defined(_CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY)
|
||||
else if constexpr (reference_constructs_from_temporary_v<_T1, decltype(get<0>(::cuda::std::declval<_UPair>()))>
|
||||
|| reference_constructs_from_temporary_v<_T2, decltype(get<1>(::cuda::std::declval<_UPair>()))>)
|
||||
{ // [pairs#pair]-17: This constructor is defined as deleted if
|
||||
// reference_constructs_from_temporary_v<T1, decltype(get<0>(FWD(u)))> or
|
||||
// reference_constructs_from_temporary_v<T2, decltype(get<1>(FWD(u)))> is true
|
||||
return __select_constructor::__deleted;
|
||||
}
|
||||
#endif // _CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY
|
||||
else if constexpr (is_convertible_v<decltype(get<0>(::cuda::std::declval<_UPair>())), _T1>
|
||||
&& is_convertible_v<decltype(get<1>(::cuda::std::declval<_UPair>())), _T2>)
|
||||
{ // [pairs#pair]-17 !is_convertible_v<decltype(get<0>(FWD(u))), T1> &&
|
||||
// !is_convertible_v<decltype(get<1>(FWD(u))), T2>
|
||||
return __select_constructor::__implicit;
|
||||
}
|
||||
else
|
||||
{
|
||||
return __select_constructor::__explicit;
|
||||
}
|
||||
// NOLINTEND(bugprone-branch-clone)
|
||||
}
|
||||
|
||||
template <class _UPair, class _T1, class _T2>
|
||||
inline constexpr __select_constructor __pair_select_pair_like_constructible_v =
|
||||
::cuda::std::__pair_select_pair_like_constructible<_UPair, _T1, _T2>();
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <bool _IsConst, class _UPair, class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API _CCCL_CONSTEVAL __select_assignment __pair_select_pair_like_assignable() noexcept
|
||||
{
|
||||
using ::cuda::std::get;
|
||||
// NOLINTBEGIN(bugprone-branch-clone)
|
||||
if constexpr (is_same_v<remove_cvref_t<_UPair>, pair<_T1, _T2>>)
|
||||
{ // [pairs.pair]-42.1: different-from<UPair, pair>
|
||||
// [pairs.pair]-45.1: different-from<UPair, pair>
|
||||
return __select_assignment::__invalid;
|
||||
}
|
||||
else if constexpr (__is_cuda_std_ranges_subrange_v<remove_cvref_t<_UPair>>)
|
||||
{ // [pairs.pair]-42.2: remove_cvref_t<UTuple> is not a specialization of ranges::subrange,
|
||||
// [pairs.pair]-45.2: remove_cvref_t<UTuple> is not a specialization of ranges::subrange,
|
||||
return __select_assignment::__invalid;
|
||||
}
|
||||
else if constexpr (!__pair_like<_UPair>)
|
||||
{ // [pairs.pair]-42: pair-like P
|
||||
// [pairs.pair]-45: pair-like P
|
||||
return __select_assignment::__invalid;
|
||||
}
|
||||
else if constexpr (_IsConst)
|
||||
{
|
||||
if constexpr (!is_assignable_v<const _T1&, decltype(get<0>(::cuda::std::declval<_UPair>()))>)
|
||||
{ // [pairs.pair]-45.3: is_assignable_v<const T1&, decltype(get<0>(std::forward<P>(p)))> is true
|
||||
return __select_assignment::__invalid;
|
||||
}
|
||||
else if constexpr (!is_assignable_v<const _T2&, decltype(get<1>(::cuda::std::declval<_UPair>()))>)
|
||||
{ // [pairs.pair]-45.4: is_assignable_v<const T2&, decltype(get<1>(std::forward<P>(p)))> is true
|
||||
return __select_assignment::__invalid;
|
||||
}
|
||||
else if constexpr (is_nothrow_assignable_v<const _T1&, decltype(get<0>(::cuda::std::declval<_UPair>()))>
|
||||
&& is_nothrow_assignable_v<const _T2&, decltype(get<1>(::cuda::std::declval<_UPair>()))>)
|
||||
{
|
||||
return __select_assignment::__is_nothrow;
|
||||
}
|
||||
else
|
||||
{
|
||||
return __select_assignment::__may_throw;
|
||||
}
|
||||
}
|
||||
else if constexpr (!is_assignable_v<_T1&, decltype(get<0>(::cuda::std::declval<_UPair>()))>)
|
||||
{ // [pairs.pair]-42.3: is_assignable_v<const T1&, decltype(get<0>(std::forward<P>(p)))> is true
|
||||
return __select_assignment::__invalid;
|
||||
}
|
||||
else if constexpr (!is_assignable_v<_T2&, decltype(get<1>(::cuda::std::declval<_UPair>()))>)
|
||||
{ // [pairs.pair]-42.4: is_assignable_v<const T2&, decltype(get<1>(std::forward<P>(p)))> is true
|
||||
return __select_assignment::__invalid;
|
||||
}
|
||||
else if constexpr (is_nothrow_assignable_v<_T1&, decltype(get<0>(::cuda::std::declval<_UPair>()))>
|
||||
&& is_nothrow_assignable_v<_T2&, decltype(get<1>(::cuda::std::declval<_UPair>()))>)
|
||||
{
|
||||
return __select_assignment::__is_nothrow;
|
||||
}
|
||||
else
|
||||
{
|
||||
return __select_assignment::__may_throw;
|
||||
}
|
||||
// NOLINTEND(bugprone-branch-clone)
|
||||
}
|
||||
|
||||
template <bool _IsConst, class _UPair, class _T1, class _T2>
|
||||
inline constexpr __select_assignment __pair_select_pair_like_assignable_v =
|
||||
::cuda::std::__pair_select_pair_like_assignable<_IsConst, _UPair, _T1, _T2>();
|
||||
|
||||
// base class to ensure `is_trivially_copyable` when possible
|
||||
template <class _T1, class _T2, bool = __must_synthesize_assignment_v<_T1> || __must_synthesize_assignment_v<_T2>>
|
||||
struct __pair_base
|
||||
{
|
||||
_T1 first;
|
||||
_T2 second;
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <__select_constructor _Trait = ::cuda::std::__tuple_select_default_constructible(__tuple_types<_T1, _T2>{}),
|
||||
enable_if_t<__can_construct_implicitly<_Trait>, int> = 0>
|
||||
_CCCL_API constexpr __pair_base() noexcept(is_nothrow_default_constructible_v<_T1>
|
||||
&& is_nothrow_default_constructible_v<_T2>)
|
||||
: first()
|
||||
, second()
|
||||
{}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <__select_constructor _Trait = ::cuda::std::__tuple_select_default_constructible(__tuple_types<_T1, _T2>{}),
|
||||
enable_if_t<__can_construct_explicitly<_Trait>, int> = 0>
|
||||
_CCCL_API explicit constexpr __pair_base() noexcept(
|
||||
is_nothrow_default_constructible_v<_T1> && is_nothrow_default_constructible_v<_T2>)
|
||||
: first()
|
||||
, second()
|
||||
{}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _U1, class _U2>
|
||||
_CCCL_API constexpr __pair_base(_U1&& __t1, _U2&& __t2) noexcept(
|
||||
is_nothrow_constructible_v<_T1, _U1> && is_nothrow_constructible_v<_T2, _U2>)
|
||||
: first(::cuda::std::forward<_U1>(__t1))
|
||||
, second(::cuda::std::forward<_U2>(__t2))
|
||||
{}
|
||||
|
||||
protected:
|
||||
template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
|
||||
_CCCL_API constexpr __pair_base(
|
||||
piecewise_construct_t,
|
||||
tuple<_Args1...>& __first_args,
|
||||
tuple<_Args2...>& __second_args,
|
||||
__tuple_indices<_I1...>,
|
||||
__tuple_indices<_I2...>);
|
||||
};
|
||||
|
||||
template <class _T1, class _T2>
|
||||
struct __pair_base<_T1, _T2, true>
|
||||
{
|
||||
_T1 first;
|
||||
_T2 second;
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <__select_constructor _Trait = ::cuda::std::__tuple_select_default_constructible(__tuple_types<_T1, _T2>{}),
|
||||
enable_if_t<__can_construct_implicitly<_Trait>, int> = 0>
|
||||
_CCCL_API constexpr __pair_base() noexcept(is_nothrow_default_constructible_v<_T1>
|
||||
&& is_nothrow_default_constructible_v<_T2>)
|
||||
: first()
|
||||
, second()
|
||||
{}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <__select_constructor _Trait = ::cuda::std::__tuple_select_default_constructible(__tuple_types<_T1, _T2>{}),
|
||||
enable_if_t<__can_construct_explicitly<_Trait>, int> = 0>
|
||||
_CCCL_API explicit constexpr __pair_base() noexcept(
|
||||
is_nothrow_default_constructible_v<_T1> && is_nothrow_default_constructible_v<_T2>)
|
||||
: first()
|
||||
, second()
|
||||
{}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
_CCCL_HIDE_FROM_ABI constexpr __pair_base(const __pair_base&) = default;
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
_CCCL_HIDE_FROM_ABI constexpr __pair_base(__pair_base&&) = default;
|
||||
|
||||
// We need to ensure that a reference type, which would inhibit the implicit copy assignment still works
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
_CCCL_API constexpr __pair_base&
|
||||
operator=(const conditional_t<is_copy_assignable_v<_T1> && is_copy_assignable_v<_T2>, __pair_base, __nat>&
|
||||
__p) noexcept(is_nothrow_copy_assignable_v<_T1> && is_nothrow_copy_assignable_v<_T2>)
|
||||
{
|
||||
first = __p.first;
|
||||
second = __p.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// We need to ensure that a reference type, which would inhibit the implicit move assignment still works
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
_CCCL_API constexpr __pair_base&
|
||||
operator=(conditional_t<is_move_assignable_v<_T1> && is_move_assignable_v<_T2>, __pair_base, __nat>&& __p) noexcept(
|
||||
is_nothrow_move_assignable_v<_T1> && is_nothrow_move_assignable_v<_T2>)
|
||||
{
|
||||
first = ::cuda::std::move(__p.first);
|
||||
second = ::cuda::std::move(__p.second);
|
||||
return *this;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _U1, class _U2>
|
||||
_CCCL_API constexpr __pair_base(_U1&& __t1, _U2&& __t2) noexcept(
|
||||
is_nothrow_constructible_v<_T1, _U1> && is_nothrow_constructible_v<_T2, _U2>)
|
||||
: first(::cuda::std::forward<_U1>(__t1))
|
||||
, second(::cuda::std::forward<_U2>(__t2))
|
||||
{}
|
||||
|
||||
protected:
|
||||
template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2>
|
||||
_CCCL_API constexpr __pair_base(
|
||||
piecewise_construct_t,
|
||||
tuple<_Args1...>& __first_args,
|
||||
tuple<_Args2...>& __second_args,
|
||||
__tuple_indices<_I1...>,
|
||||
__tuple_indices<_I2...>);
|
||||
};
|
||||
|
||||
template <class _T1, class _T2>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT pair : public __pair_base<_T1, _T2>
|
||||
{
|
||||
using __base = __pair_base<_T1, _T2>;
|
||||
|
||||
using first_type = _T1;
|
||||
using second_type = _T2;
|
||||
|
||||
template <__select_constructor _Trait = ::cuda::std::__tuple_select_default_constructible(__tuple_types<_T1, _T2>{}),
|
||||
enable_if_t<__can_construct_implicitly<_Trait>, int> = 0>
|
||||
_CCCL_API constexpr pair() noexcept(is_nothrow_default_constructible_v<_T1> && is_nothrow_default_constructible_v<_T2>)
|
||||
: __base()
|
||||
{}
|
||||
|
||||
template <__select_constructor _Trait = ::cuda::std::__tuple_select_default_constructible(__tuple_types<_T1, _T2>{}),
|
||||
enable_if_t<__can_construct_explicitly<_Trait>, int> = 0>
|
||||
_CCCL_API explicit constexpr pair() noexcept(is_nothrow_default_constructible_v<_T1>
|
||||
&& is_nothrow_default_constructible_v<_T2>)
|
||||
: __base()
|
||||
{}
|
||||
|
||||
// copy and move constructors
|
||||
_CCCL_HIDE_FROM_ABI pair(const pair&) = default;
|
||||
_CCCL_HIDE_FROM_ABI pair(pair&&) = default;
|
||||
|
||||
// element wise constructors
|
||||
template <__select_constructor _Trait = __tuple_select_variadic_copy_constructible_v<__tuple_types<_T1, _T2>>,
|
||||
enable_if_t<__can_construct_implicitly<_Trait>, int> = 0>
|
||||
_CCCL_API constexpr pair(const _T1& __t1, const _T2& __t2) noexcept(
|
||||
is_nothrow_copy_constructible_v<_T1> && is_nothrow_copy_constructible_v<_T2>)
|
||||
: __base(__t1, __t2)
|
||||
{}
|
||||
template <__select_constructor _Trait = __tuple_select_variadic_copy_constructible_v<__tuple_types<_T1, _T2>>,
|
||||
enable_if_t<__can_construct_explicitly<_Trait>, int> = 0>
|
||||
_CCCL_API explicit constexpr pair(const _T1& __t1, const _T2& __t2) noexcept(
|
||||
is_nothrow_copy_constructible_v<_T1> && is_nothrow_copy_constructible_v<_T2>)
|
||||
: __base(__t1, __t2)
|
||||
{}
|
||||
|
||||
template <class _U1 = _T1,
|
||||
class _U2 = _T2,
|
||||
__select_constructor _Trait =
|
||||
__tuple_select_variadic_constructible_v<__tuple_types<_T1, _T2>, __tuple_types<_U1, _U2>>,
|
||||
enable_if_t<__can_construct_implicitly<_Trait>, int> = 0>
|
||||
_CCCL_API constexpr pair(_U1&& __u1, _U2&& __u2) noexcept(
|
||||
is_nothrow_constructible_v<_T1, _U1> && is_nothrow_constructible_v<_T2, _U2>)
|
||||
: __base(::cuda::std::forward<_U1>(__u1), ::cuda::std::forward<_U2>(__u2))
|
||||
{}
|
||||
|
||||
template <class _U1 = _T1,
|
||||
class _U2 = _T2,
|
||||
__select_constructor _Trait =
|
||||
__tuple_select_variadic_constructible_v<__tuple_types<_T1, _T2>, __tuple_types<_U1, _U2>>,
|
||||
enable_if_t<__can_construct_explicitly<_Trait>, int> = 0>
|
||||
_CCCL_API explicit constexpr pair(_U1&& __u1, _U2&& __u2) noexcept(
|
||||
is_nothrow_constructible_v<_T1, _U1> && is_nothrow_constructible_v<_T2, _U2>)
|
||||
: __base(::cuda::std::forward<_U1>(__u1), ::cuda::std::forward<_U2>(__u2))
|
||||
{}
|
||||
|
||||
#if defined(_CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY)
|
||||
template <class _U1 = _T1,
|
||||
class _U2 = _T2,
|
||||
__select_constructor _Trait =
|
||||
__tuple_select_variadic_constructible_v<__tuple_types<_T1, _T2>, __tuple_types<_U1, _U2>>,
|
||||
enable_if_t<__is_deleted<_Trait>, int> = 0>
|
||||
constexpr pair(_U1&&, _U2&&) = delete;
|
||||
#endif // _CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY
|
||||
|
||||
// converting constructors
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<pair<_U1, _U2>&, _T1, _T2>,
|
||||
enable_if_t<__can_construct_implicitly<_Trait>, int> = 0>
|
||||
_CCCL_API constexpr pair(pair<_U1, _U2>& __p) noexcept(
|
||||
is_nothrow_constructible_v<_T1, _U1&> && is_nothrow_constructible_v<_T2, _U2&>)
|
||||
: __base(__p.first, __p.second)
|
||||
{}
|
||||
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<pair<_U1, _U2>&, _T1, _T2>,
|
||||
enable_if_t<__can_construct_explicitly<_Trait>, int> = 0>
|
||||
_CCCL_API explicit constexpr pair(pair<_U1, _U2>& __p) noexcept(
|
||||
is_nothrow_constructible_v<_T1, _U1&> && is_nothrow_constructible_v<_T2, _U2&>)
|
||||
: __base(__p.first, __p.second)
|
||||
{}
|
||||
|
||||
#if defined(_CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY)
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<pair<_U1, _U2>&, _T1, _T2>,
|
||||
enable_if_t<__is_deleted<_Trait>, int> = 0>
|
||||
constexpr pair(pair<_U1, _U2>&) = delete;
|
||||
#endif // _CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY
|
||||
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<const pair<_U1, _U2>&, _T1, _T2>,
|
||||
enable_if_t<__can_construct_implicitly<_Trait>, int> = 0>
|
||||
_CCCL_API constexpr pair(const pair<_U1, _U2>& __p) noexcept(
|
||||
is_nothrow_constructible_v<_T1, const _U1&> && is_nothrow_constructible_v<_T2, const _U2&>)
|
||||
: __base(__p.first, __p.second)
|
||||
{}
|
||||
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<const pair<_U1, _U2>&, _T1, _T2>,
|
||||
enable_if_t<__can_construct_explicitly<_Trait>, int> = 0>
|
||||
_CCCL_API explicit constexpr pair(const pair<_U1, _U2>& __p) noexcept(
|
||||
is_nothrow_constructible_v<_T1, const _U1&> && is_nothrow_constructible_v<_T2, const _U2&>)
|
||||
: __base(__p.first, __p.second)
|
||||
{}
|
||||
|
||||
#if defined(_CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY)
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<const pair<_U1, _U2>&, _T1, _T2>,
|
||||
enable_if_t<__is_deleted<_Trait>, int> = 0>
|
||||
constexpr pair(const pair<_U1, _U2>&) = delete;
|
||||
#endif // _CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY
|
||||
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<pair<_U1, _U2>&&, _T1, _T2>,
|
||||
enable_if_t<__can_construct_implicitly<_Trait>, int> = 0>
|
||||
_CCCL_API constexpr pair(pair<_U1, _U2>&& __p) noexcept(
|
||||
is_nothrow_constructible_v<_T1, _U1> && is_nothrow_constructible_v<_T2, _U2>)
|
||||
: __base(::cuda::std::move(__p.first), ::cuda::std::move(__p.second))
|
||||
{}
|
||||
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<pair<_U1, _U2>&&, _T1, _T2>,
|
||||
enable_if_t<__can_construct_explicitly<_Trait>, int> = 0>
|
||||
_CCCL_API explicit constexpr pair(pair<_U1, _U2>&& __p) noexcept(
|
||||
is_nothrow_constructible_v<_T1, _U1> && is_nothrow_constructible_v<_T2, _U2>)
|
||||
: __base(::cuda::std::move(__p.first), ::cuda::std::move(__p.second))
|
||||
{}
|
||||
|
||||
#if defined(_CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY)
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<pair<_U1, _U2>&&, _T1, _T2>,
|
||||
enable_if_t<__is_deleted<_Trait>, int> = 0>
|
||||
constexpr pair(pair<_U1, _U2>&&) = delete;
|
||||
#endif // _CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY
|
||||
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<const pair<_U1, _U2>&&, _T1, _T2>,
|
||||
enable_if_t<__can_construct_implicitly<_Trait>, int> = 0>
|
||||
_CCCL_API constexpr pair(const pair<_U1, _U2>&& __p) noexcept(
|
||||
is_nothrow_constructible_v<_T1, const _U1> && is_nothrow_constructible_v<_T2, const _U2>)
|
||||
: __base(::cuda::std::move(__p.first), ::cuda::std::move(__p.second))
|
||||
{}
|
||||
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<const pair<_U1, _U2>&&, _T1, _T2>,
|
||||
enable_if_t<__can_construct_explicitly<_Trait>, int> = 0>
|
||||
_CCCL_API explicit constexpr pair(const pair<_U1, _U2>&& __p) noexcept(
|
||||
is_nothrow_constructible_v<_T1, const _U1> && is_nothrow_constructible_v<_T2, const _U2>)
|
||||
: __base(::cuda::std::move(__p.first), ::cuda::std::move(__p.second))
|
||||
{}
|
||||
|
||||
#if defined(_CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY)
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<const pair<_U1, _U2>&&, _T1, _T2>,
|
||||
enable_if_t<__is_deleted<_Trait>, int> = 0>
|
||||
constexpr pair(const pair<_U1, _U2>&&) = delete;
|
||||
#endif // _CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY
|
||||
|
||||
// NOLINTBEGIN(bugprone-forwarding-reference-overload)
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _UPair,
|
||||
enable_if_t<!is_same_v<remove_cvref_t<_UPair>, pair>, int> = 0,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<_UPair, _T1, _T2>,
|
||||
enable_if_t<__can_construct_implicitly<_Trait>, int> = 0>
|
||||
_CCCL_API constexpr pair(_UPair&& __p) noexcept(
|
||||
is_nothrow_constructible_v<_T1, decltype(::cuda::std::__adl_get<0>(::cuda::std::forward<_UPair>(__p)))>
|
||||
&& is_nothrow_constructible_v<_T2, decltype(::cuda::std::__adl_get<1>(::cuda::std::forward<_UPair>(__p)))>)
|
||||
: __base(
|
||||
// __adl_get() specifically will only move the sub-object, it's therefore OK to
|
||||
// "move" the outer pair twice
|
||||
// NOLINTBEGIN(bugprone-use-after-move)
|
||||
::cuda::std::__adl_get<0>(::cuda::std::forward<_UPair>(__p)),
|
||||
::cuda::std::__adl_get<1>(::cuda::std::forward<_UPair>(__p))
|
||||
// NOLINTEND(bugprone-use-after-move)
|
||||
)
|
||||
{}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _UPair,
|
||||
enable_if_t<!is_same_v<remove_cvref_t<_UPair>, pair>, int> = 0,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<_UPair, _T1, _T2>,
|
||||
enable_if_t<__can_construct_explicitly<_Trait>, int> = 0>
|
||||
_CCCL_API explicit constexpr pair(_UPair&& __p) noexcept(
|
||||
is_nothrow_constructible_v<_T1, decltype(::cuda::std::__adl_get<0>(::cuda::std::forward<_UPair>(__p)))>
|
||||
&& is_nothrow_constructible_v<_T2, decltype(::cuda::std::__adl_get<1>(::cuda::std::forward<_UPair>(__p)))>)
|
||||
: __base(::cuda::std::__adl_get<0>(::cuda::std::forward<_UPair>(__p)),
|
||||
::cuda::std::__adl_get<1>(::cuda::std::forward<_UPair>(__p)))
|
||||
{}
|
||||
|
||||
#if defined(_CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY)
|
||||
template <class _UPair,
|
||||
enable_if_t<!is_same_v<remove_cvref_t<_UPair>, pair>, int> = 0,
|
||||
__select_constructor _Trait = __pair_select_pair_like_constructible_v<_UPair, _T1, _T2>,
|
||||
enable_if_t<__is_deleted<_Trait>, int> = 0>
|
||||
_CCCL_API constexpr pair(_UPair&&) = delete;
|
||||
#endif // _CCCL_BUILTIN_REFERENCE_CONSTRUCTS_FROM_TEMPORARY
|
||||
// NOLINTEND(bugprone-forwarding-reference-overload)
|
||||
|
||||
template <class... _Args1, class... _Args2>
|
||||
_CCCL_API constexpr pair(piecewise_construct_t __pc,
|
||||
tuple<_Args1...> __first_args,
|
||||
tuple<_Args2...> __second_args) noexcept((is_nothrow_constructible_v<_T1, _Args1...>
|
||||
&& is_nothrow_constructible_v<_T2, _Args2...>) )
|
||||
: __base(__pc,
|
||||
__first_args,
|
||||
__second_args,
|
||||
__make_tuple_indices_t<sizeof...(_Args1)>(),
|
||||
__make_tuple_indices_t<sizeof...(_Args2)>())
|
||||
{}
|
||||
|
||||
// assignments
|
||||
_CCCL_HIDE_FROM_ABI pair& operator=(const pair&) = default;
|
||||
_CCCL_HIDE_FROM_ABI pair& operator=(pair&&) = default;
|
||||
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
enable_if_t<is_assignable_v<_T1&, const _U1&>, int> = 0,
|
||||
enable_if_t<is_assignable_v<_T2&, const _U2&>, int> = 0>
|
||||
_CCCL_API constexpr pair& operator=(const pair<_U1, _U2>& __p) noexcept(
|
||||
is_nothrow_assignable_v<_T1&, const _U1&> && is_nothrow_assignable_v<_T2&, const _U2&>)
|
||||
{
|
||||
this->first = __p.first;
|
||||
this->second = __p.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
enable_if_t<is_assignable_v<const _T1&, const _U1&>, int> = 0,
|
||||
enable_if_t<is_assignable_v<const _T2&, const _U2&>, int> = 0>
|
||||
_CCCL_API constexpr const pair& operator=(const pair<_U1, _U2>& __p) const
|
||||
noexcept(is_nothrow_assignable_v<const _T1&, const _U1&> && is_nothrow_assignable_v<const _T2&, const _U2&>)
|
||||
{
|
||||
this->first = __p.first;
|
||||
this->second = __p.second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
enable_if_t<is_assignable_v<_T1&, _U1>, int> = 0,
|
||||
enable_if_t<is_assignable_v<_T2&, _U2>, int> = 0>
|
||||
_CCCL_API constexpr pair&
|
||||
operator=(pair<_U1, _U2>&& __p) noexcept(is_nothrow_assignable_v<_T1&, _U1> && is_nothrow_assignable_v<_T2&, _U2>)
|
||||
{
|
||||
this->first = ::cuda::std::forward<_U1>(__p.first);
|
||||
this->second = ::cuda::std::forward<_U2>(__p.second);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class _U1,
|
||||
class _U2,
|
||||
enable_if_t<is_assignable_v<const _T1&, _U1>, int> = 0,
|
||||
enable_if_t<is_assignable_v<const _T2&, _U2>, int> = 0>
|
||||
_CCCL_API constexpr const pair& operator=(pair<_U1, _U2>&& __p) const
|
||||
noexcept(is_nothrow_assignable_v<const _T1&, _U1> && is_nothrow_assignable_v<const _T2&, _U2>)
|
||||
{
|
||||
this->first = ::cuda::std::forward<_U1>(__p.first);
|
||||
this->second = ::cuda::std::forward<_U2>(__p.second);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ``get`` will specifically only move the sub-object, it's therefore OK to
|
||||
// "move" the outer pair twice
|
||||
// NOLINTBEGIN(bugprone-use-after-move)
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _UPair,
|
||||
__select_assignment _Trait = __pair_select_pair_like_assignable_v</*__is_const=*/false, _UPair, _T1, _T2>,
|
||||
enable_if_t<__can_assign<_Trait>, int> = 0>
|
||||
_CCCL_API constexpr pair& operator=(_UPair&& __p) noexcept(__can_nothrow_assign<_Trait>)
|
||||
{
|
||||
using ::cuda::std::get;
|
||||
this->first = get<0>(::cuda::std::forward<_UPair>(__p));
|
||||
this->second = get<1>(::cuda::std::forward<_UPair>(__p));
|
||||
return *this;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _UPair,
|
||||
__select_assignment _Trait = __pair_select_pair_like_assignable_v</*__is_const=*/true, _UPair, _T1, _T2>,
|
||||
enable_if_t<__can_assign<_Trait>, int> = 0>
|
||||
_CCCL_API constexpr const pair& operator=(_UPair&& __p) const noexcept(__can_nothrow_assign<_Trait>)
|
||||
{
|
||||
using ::cuda::std::get;
|
||||
this->first = get<0>(::cuda::std::forward<_UPair>(__p));
|
||||
this->second = get<1>(::cuda::std::forward<_UPair>(__p));
|
||||
return *this;
|
||||
}
|
||||
// NOLINTEND(bugprone-use-after-move)
|
||||
|
||||
_CCCL_API constexpr void swap(pair& __p) noexcept(is_nothrow_swappable_v<_T1> && is_nothrow_swappable_v<_T2>)
|
||||
{
|
||||
using ::cuda::std::swap;
|
||||
swap(this->first, __p.first);
|
||||
swap(this->second, __p.second);
|
||||
}
|
||||
|
||||
#if _CCCL_STD_VER >= 2023
|
||||
_CCCL_API constexpr void swap(const pair& __p) const
|
||||
noexcept(is_nothrow_swappable_v<const _T1> && is_nothrow_swappable_v<const _T2>)
|
||||
{
|
||||
using ::cuda::std::swap;
|
||||
swap(this->first, __p.first);
|
||||
swap(this->second, __p.second);
|
||||
}
|
||||
#endif // _CCCL_STD_VER >= 2023
|
||||
|
||||
#if _CCCL_HOSTED()
|
||||
_CCCL_HOST_API constexpr operator ::std::pair<_T1, _T2>() const
|
||||
{
|
||||
return {this->first, this->second};
|
||||
}
|
||||
#endif // _CCCL_HOSTED()
|
||||
};
|
||||
|
||||
template <class _T1, class _T2>
|
||||
_CCCL_DEDUCTION_GUIDE_ATTRIBUTES pair(_T1, _T2) -> pair<_T1, _T2>;
|
||||
|
||||
// [pairs.spec], specialized algorithms
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _T1, class _T2>
|
||||
_CCCL_API constexpr bool operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
|
||||
{
|
||||
return __x.first == __y.first && __x.second == __y.second;
|
||||
}
|
||||
|
||||
#if _LIBCUDACXX_HAS_SPACESHIP_OPERATOR()
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _T1, class _T2>
|
||||
_CCCL_API constexpr common_comparison_category_t<__synth_three_way_result<_T1>, __synth_three_way_result<_T2>>
|
||||
operator<=>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
|
||||
{
|
||||
if (auto __c = ::cuda::std::__synth_three_way(__x.first, __y.first); __c != 0)
|
||||
{
|
||||
return __c;
|
||||
}
|
||||
return ::cuda::std::__synth_three_way(__x.second, __y.second);
|
||||
}
|
||||
|
||||
#else // ^^^ _LIBCUDACXX_HAS_SPACESHIP_OPERATOR() ^^^ / vvv !_LIBCUDACXX_HAS_SPACESHIP_OPERATOR() vvv
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _T1, class _T2>
|
||||
_CCCL_API constexpr bool operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
|
||||
{
|
||||
return !(__x == __y);
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _T1, class _T2>
|
||||
_CCCL_API constexpr bool operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
|
||||
{
|
||||
return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _T1, class _T2>
|
||||
_CCCL_API constexpr bool operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
|
||||
{
|
||||
return __y < __x;
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _T1, class _T2>
|
||||
_CCCL_API constexpr bool operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
|
||||
{
|
||||
return !(__x < __y);
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _T1, class _T2>
|
||||
_CCCL_API constexpr bool operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
|
||||
{
|
||||
return !(__y < __x);
|
||||
}
|
||||
|
||||
#endif // !_LIBCUDACXX_HAS_SPACESHIP_OPERATOR()
|
||||
|
||||
#if _CCCL_STD_VER >= 2023
|
||||
template <class _T1, class _T2, class _U1, class _U2, template <class> class _TQual, template <class> class _UQual>
|
||||
requires requires {
|
||||
typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
|
||||
}
|
||||
struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual>
|
||||
{
|
||||
using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>, common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
|
||||
};
|
||||
|
||||
template <class _T1, class _T2, class _U1, class _U2>
|
||||
requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; }
|
||||
struct common_type<pair<_T1, _T2>, pair<_U1, _U2>>
|
||||
{
|
||||
using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>;
|
||||
};
|
||||
#endif // _CCCL_STD_VER >= 2023
|
||||
|
||||
_CCCL_TEMPLATE(class _T1, class _T2)
|
||||
_CCCL_REQUIRES(is_swappable_v<_T1> _CCCL_AND is_swappable_v<_T2>)
|
||||
_CCCL_API constexpr void
|
||||
swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) noexcept((is_nothrow_swappable_v<_T1> && is_nothrow_swappable_v<_T2>) )
|
||||
{
|
||||
__x.swap(__y);
|
||||
}
|
||||
|
||||
_CCCL_TEMPLATE(class _T1, class _T2)
|
||||
_CCCL_REQUIRES(is_swappable_v<const _T1> _CCCL_AND is_swappable_v<const _T2>)
|
||||
_CCCL_API constexpr void swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y) noexcept(
|
||||
(is_nothrow_swappable_v<const _T1> && is_nothrow_swappable_v<const _T2>) )
|
||||
{
|
||||
__x.swap(__y);
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
_CCCL_API constexpr pair<unwrap_ref_decay_t<_T1>, unwrap_ref_decay_t<_T2>> make_pair(_T1&& __t1, _T2&& __t2)
|
||||
{
|
||||
return pair<unwrap_ref_decay_t<_T1>, unwrap_ref_decay_t<_T2>>(
|
||||
::cuda::std::forward<_T1>(__t1), ::cuda::std::forward<_T2>(__t2));
|
||||
}
|
||||
|
||||
template <size_t _Ip>
|
||||
struct __get_pair;
|
||||
|
||||
template <>
|
||||
struct __get_pair<0>
|
||||
{
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API static constexpr _T1& get(pair<_T1, _T2>& __p) noexcept
|
||||
{
|
||||
return __p.first;
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API static constexpr const _T1& get(const pair<_T1, _T2>& __p) noexcept
|
||||
{
|
||||
return __p.first;
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API static constexpr _T1&& get(pair<_T1, _T2>&& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::forward<_T1>(__p.first);
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API static constexpr const _T1&& get(const pair<_T1, _T2>&& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::forward<const _T1>(__p.first);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct __get_pair<1>
|
||||
{
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API static constexpr _T2& get(pair<_T1, _T2>& __p) noexcept
|
||||
{
|
||||
return __p.second;
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API static constexpr const _T2& get(const pair<_T1, _T2>& __p) noexcept
|
||||
{
|
||||
return __p.second;
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API static constexpr _T2&& get(pair<_T1, _T2>&& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::forward<_T2>(__p.second);
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API static constexpr const _T2&& get(const pair<_T1, _T2>&& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::forward<const _T2>(__p.second);
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t _Ip, class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API constexpr tuple_element_t<_Ip, pair<_T1, _T2>>& get(pair<_T1, _T2>& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::__get_pair<_Ip>::get(__p);
|
||||
}
|
||||
|
||||
template <size_t _Ip, class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API constexpr const tuple_element_t<_Ip, pair<_T1, _T2>>& get(const pair<_T1, _T2>& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::__get_pair<_Ip>::get(__p);
|
||||
}
|
||||
|
||||
template <size_t _Ip, class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API constexpr tuple_element_t<_Ip, pair<_T1, _T2>>&& get(pair<_T1, _T2>&& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::__get_pair<_Ip>::get(::cuda::std::move(__p));
|
||||
}
|
||||
|
||||
template <size_t _Ip, class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API constexpr const tuple_element_t<_Ip, pair<_T1, _T2>>&& get(const pair<_T1, _T2>&& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::__get_pair<_Ip>::get(::cuda::std::move(__p));
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API constexpr _T1& get(pair<_T1, _T2>& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::__get_pair<0>::get(__p);
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API constexpr const _T1& get(const pair<_T1, _T2>& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::__get_pair<0>::get(__p);
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API constexpr _T1&& get(pair<_T1, _T2>&& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::__get_pair<0>::get(::cuda::std::move(__p));
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API constexpr const _T1&& get(const pair<_T1, _T2>&& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::__get_pair<0>::get(::cuda::std::move(__p));
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API constexpr _T1& get(pair<_T2, _T1>& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::__get_pair<1>::get(__p);
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API constexpr const _T1& get(const pair<_T2, _T1>& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::__get_pair<1>::get(__p);
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API constexpr _T1&& get(pair<_T2, _T1>&& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::__get_pair<1>::get(::cuda::std::move(__p));
|
||||
}
|
||||
|
||||
template <class _T1, class _T2>
|
||||
[[nodiscard]] _CCCL_API constexpr const _T1&& get(const pair<_T2, _T1>&& __p) noexcept
|
||||
{
|
||||
return ::cuda::std::__get_pair<1>::get(::cuda::std::move(__p));
|
||||
}
|
||||
|
||||
// specialize cuda::std::tuple_size and cuda::std::tuple_element for std::pair and cuda::std::pair
|
||||
|
||||
#if _CCCL_HAS_HOST_STD_LIB()
|
||||
template <class _Tp, class _Up>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT tuple_size<::std::pair<_Tp, _Up>> : integral_constant<size_t, 2>
|
||||
{};
|
||||
|
||||
template <size_t _Ip, class _Tp, class _Up>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT tuple_element<_Ip, ::std::pair<_Tp, _Up>>
|
||||
{
|
||||
static_assert(_Ip < 2, "Index out of bounds in cuda::std::tuple_element<std::pair<_Tp, _Up>>");
|
||||
};
|
||||
template <class _Tp, class _Up>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT tuple_element<0, ::std::pair<_Tp, _Up>>
|
||||
{
|
||||
using type _CCCL_NODEBUG_ALIAS = _Tp;
|
||||
};
|
||||
template <class _Tp, class _Up>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT tuple_element<1, ::std::pair<_Tp, _Up>>
|
||||
{
|
||||
using type _CCCL_NODEBUG_ALIAS = _Up;
|
||||
};
|
||||
#endif // _CCCL_HAS_HOST_STD_LIB()
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT tuple_size<pair<_Tp, _Up>> : integral_constant<size_t, 2>
|
||||
{};
|
||||
|
||||
template <size_t _Ip, class _Tp, class _Up>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT tuple_element<_Ip, pair<_Tp, _Up>>
|
||||
{
|
||||
static_assert(_Ip < 2, "Index out of bounds in cuda::std::tuple_element<cuda::std::pair<_Tp, _Up>>");
|
||||
};
|
||||
template <class _Tp, class _Up>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT tuple_element<0, pair<_Tp, _Up>>
|
||||
{
|
||||
using type _CCCL_NODEBUG_ALIAS = _Tp;
|
||||
};
|
||||
template <class _Tp, class _Up>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT tuple_element<1, pair<_Tp, _Up>>
|
||||
{
|
||||
using type _CCCL_NODEBUG_ALIAS = _Up;
|
||||
};
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
// tuple protocol for cuda::std::pair
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_STD
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
struct tuple_size<::cuda::std::pair<_Tp, _Up>> : ::cuda::std::integral_constant<::cuda::std::size_t, 2>
|
||||
{};
|
||||
|
||||
template <::cuda::std::size_t _Ip, class _Tp, class _Up>
|
||||
struct tuple_element<_Ip, ::cuda::std::pair<_Tp, _Up>>
|
||||
{
|
||||
static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<cuda::std::pair<_Tp, _Up>>");
|
||||
};
|
||||
template <class _Tp, class _Up>
|
||||
struct tuple_element<0, ::cuda::std::pair<_Tp, _Up>>
|
||||
{
|
||||
using type _CCCL_NODEBUG_ALIAS = _Tp;
|
||||
};
|
||||
template <class _Tp, class _Up>
|
||||
struct tuple_element<1, ::cuda::std::pair<_Tp, _Up>>
|
||||
{
|
||||
using type _CCCL_NODEBUG_ALIAS = _Up;
|
||||
};
|
||||
|
||||
_CCCL_END_NAMESPACE_STD
|
||||
|
||||
_CCCL_END_NV_DIAG_SUPPRESS()
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_PAIR_H
|
||||
@@ -0,0 +1,37 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_PIECEWISE_CONSTRUCT_H
|
||||
#define _CUDA_STD___UTILITY_PIECEWISE_CONSTRUCT_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 _CCCL_TYPE_VISIBILITY_DEFAULT piecewise_construct_t
|
||||
{
|
||||
_CCCL_HIDE_FROM_ABI explicit piecewise_construct_t() = default;
|
||||
};
|
||||
_CCCL_GLOBAL_CONSTANT piecewise_construct_t piecewise_construct = piecewise_construct_t();
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_PIECEWISE_CONSTRUCT_H
|
||||
425
cccl_upstream/libcudacxx/include/cuda/std/__utility/pod_tuple.h
Normal file
425
cccl_upstream/libcudacxx/include/cuda/std/__utility/pod_tuple.h
Normal file
@@ -0,0 +1,425 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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___UTILITY_POD_TUPLE_H
|
||||
#define __CUDA_STD___UTILITY_POD_TUPLE_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/__type_traits/decay.h>
|
||||
#include <cuda/std/__type_traits/is_callable.h>
|
||||
#include <cuda/std/__type_traits/remove_reference.h>
|
||||
#include <cuda/std/__utility/declval.h>
|
||||
#include <cuda/std/__utility/integer_sequence.h>
|
||||
#include <cuda/std/__utility/undefined.h>
|
||||
|
||||
/**
|
||||
* @file pod_tuple.h
|
||||
* @brief Provides a lightweight implementation of a tuple-like structure that can be
|
||||
* aggregate-initialized. It can be used to return a tuple of immovable types from a function.
|
||||
* It is guaranteed to be a structural type up to 8 elements.
|
||||
*
|
||||
* This header defines the `__tuple` template and related utilities for creating and
|
||||
* manipulating tuples with compile-time optimizations.
|
||||
*
|
||||
* @details
|
||||
* The `__tuple` structure is designed to minimize template instantiations and improve
|
||||
* compile-time performance by unrolling tuples of sizes 1-8. It also provides utilities
|
||||
* for accessing tuple elements and applying callable objects to tuple contents.
|
||||
*
|
||||
* Key features:
|
||||
* - Lightweight tuple implementation that can be aggregate initialized.
|
||||
* - Tuple elements can be direct-initialized.
|
||||
* - Compile-time optimizations for small tuples (sizes 1-8).
|
||||
* - Support for callable application via `__apply`.
|
||||
* - Utilities for accessing tuple elements using `__get`.
|
||||
*/
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
#if _CCCL_COMPILER(GCC) || _CCCL_COMPILER(NVHPC)
|
||||
// GCC (as of v14) does not implement the resolution of CWG1835
|
||||
// https://cplusplus.github.io/CWG/issues/1835.html
|
||||
// See: https://godbolt.org/z/TzxrhK6ea
|
||||
# define _CCCL_NO_CWG1835
|
||||
#endif
|
||||
|
||||
#ifdef _CCCL_NO_CWG1835
|
||||
# define _CCCL_CWG1835_TEMPLATE
|
||||
#else
|
||||
# define _CCCL_CWG1835_TEMPLATE template
|
||||
#endif
|
||||
|
||||
template <class... _Ts>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT _CCCL_DECLSPEC_EMPTY_BASES __tuple;
|
||||
|
||||
namespace __detail
|
||||
{
|
||||
template <class _Fn, class _Tuple, class... _Us>
|
||||
extern __undefined<_Fn, _Tuple, _Us...> __applicable_v;
|
||||
|
||||
template <class _Fn, class... _Ts, class... _Us>
|
||||
inline constexpr bool __applicable_v<_Fn, __tuple<_Ts...>, _Us...> = __is_callable_v<_Fn, _Us..., _Ts...>;
|
||||
|
||||
template <class _Fn, class... _Ts, class... _Us>
|
||||
inline constexpr bool __applicable_v<_Fn, __tuple<_Ts...>&, _Us...> = __is_callable_v<_Fn, _Us..., _Ts&...>;
|
||||
|
||||
template <class _Fn, class... _Ts, class... _Us>
|
||||
inline constexpr bool __applicable_v<_Fn, const __tuple<_Ts...>&, _Us...> = __is_callable_v<_Fn, _Us..., const _Ts&...>;
|
||||
|
||||
template <class _Fn, class _Tuple, class... _Us>
|
||||
extern __undefined<_Fn, _Tuple, _Us...> __nothrow_applicable_v;
|
||||
|
||||
template <class _Fn, class... _Ts, class... _Us>
|
||||
inline constexpr bool __nothrow_applicable_v<_Fn, __tuple<_Ts...>, _Us...> =
|
||||
__is_nothrow_callable_v<_Fn, _Us..., _Ts...>;
|
||||
|
||||
template <class _Fn, class... _Ts, class... _Us>
|
||||
inline constexpr bool __nothrow_applicable_v<_Fn, __tuple<_Ts...>&, _Us...> =
|
||||
__is_nothrow_callable_v<_Fn, _Us..., _Ts&...>;
|
||||
|
||||
template <class _Fn, class... _Ts, class... _Us>
|
||||
inline constexpr bool __nothrow_applicable_v<_Fn, const __tuple<_Ts...>&, _Us...> =
|
||||
__is_nothrow_callable_v<_Fn, _Us..., const _Ts&...>;
|
||||
|
||||
template <size_t _Index, class _Ty>
|
||||
struct __box
|
||||
{
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Ty __value;
|
||||
};
|
||||
|
||||
template <class _Index, class... _Ts>
|
||||
struct __tupl_base;
|
||||
|
||||
template <size_t... _Index, class... _Ts>
|
||||
struct _CCCL_DECLSPEC_EMPTY_BASES __tupl_base<index_sequence<_Index...>, _Ts...> : __box<_Index, _Ts>...
|
||||
{
|
||||
static constexpr size_t __size = sizeof...(_Ts);
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Fn, class _Self, class... _Us>
|
||||
_CCCL_TRIVIAL_API static constexpr auto
|
||||
__apply(_Fn&& __fn, _Self&& __self, _Us&&... __us) noexcept(__nothrow_applicable_v<_Fn, _Self, _Us...>)
|
||||
-> decltype(auto)
|
||||
{
|
||||
return static_cast<_Fn&&>(__fn)(
|
||||
static_cast<_Us&&>(__us)..., static_cast<_Self&&>(__self)._CCCL_CWG1835_TEMPLATE __box<_Index, _Ts>::__value...);
|
||||
}
|
||||
};
|
||||
} // namespace __detail
|
||||
|
||||
template <class... _Ts>
|
||||
struct __tuple : __detail::__tupl_base<index_sequence_for<_Ts...>, _Ts...>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT __tuple<>
|
||||
{
|
||||
static constexpr size_t __size = 0;
|
||||
};
|
||||
|
||||
template <class _Tp0>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT __tuple<_Tp0>
|
||||
{
|
||||
static constexpr size_t __size = 1;
|
||||
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp0 __val0;
|
||||
};
|
||||
|
||||
template <class _Tp0, class _Tp1>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT __tuple<_Tp0, _Tp1>
|
||||
{
|
||||
static constexpr size_t __size = 2;
|
||||
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp0 __val0;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp1 __val1;
|
||||
};
|
||||
|
||||
template <class _Tp0, class _Tp1, class _Tp2>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT __tuple<_Tp0, _Tp1, _Tp2>
|
||||
{
|
||||
static constexpr size_t __size = 3;
|
||||
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp0 __val0;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp1 __val1;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp2 __val2;
|
||||
};
|
||||
|
||||
template <class _Tp0, class _Tp1, class _Tp2, class _Tp3>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT __tuple<_Tp0, _Tp1, _Tp2, _Tp3>
|
||||
{
|
||||
static constexpr size_t __size = 4;
|
||||
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp0 __val0;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp1 __val1;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp2 __val2;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp3 __val3;
|
||||
};
|
||||
|
||||
template <class _Tp0, class _Tp1, class _Tp2, class _Tp3, class _Tp4>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT __tuple<_Tp0, _Tp1, _Tp2, _Tp3, _Tp4>
|
||||
{
|
||||
static constexpr size_t __size = 5;
|
||||
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp0 __val0;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp1 __val1;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp2 __val2;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp3 __val3;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp4 __val4;
|
||||
};
|
||||
|
||||
template <class _Tp0, class _Tp1, class _Tp2, class _Tp3, class _Tp4, class _Tp5>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT __tuple<_Tp0, _Tp1, _Tp2, _Tp3, _Tp4, _Tp5>
|
||||
{
|
||||
static constexpr size_t __size = 6;
|
||||
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp0 __val0;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp1 __val1;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp2 __val2;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp3 __val3;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp4 __val4;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp5 __val5;
|
||||
};
|
||||
|
||||
template <class _Tp0, class _Tp1, class _Tp2, class _Tp3, class _Tp4, class _Tp5, class _Tp6>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT __tuple<_Tp0, _Tp1, _Tp2, _Tp3, _Tp4, _Tp5, _Tp6>
|
||||
{
|
||||
static constexpr size_t __size = 7;
|
||||
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp0 __val0;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp1 __val1;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp2 __val2;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp3 __val3;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp4 __val4;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp5 __val5;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp6 __val6;
|
||||
};
|
||||
|
||||
template <class _Tp0, class _Tp1, class _Tp2, class _Tp3, class _Tp4, class _Tp5, class _Tp6, class _Tp7>
|
||||
struct _CCCL_TYPE_VISIBILITY_DEFAULT __tuple<_Tp0, _Tp1, _Tp2, _Tp3, _Tp4, _Tp5, _Tp6, _Tp7>
|
||||
{
|
||||
static constexpr size_t __size = 8;
|
||||
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp0 __val0;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp1 __val1;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp2 __val2;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp3 __val3;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp4 __val4;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp5 __val5;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp6 __val6;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Tp7 __val7;
|
||||
};
|
||||
|
||||
template <class... _Ts>
|
||||
_CCCL_DEDUCTION_GUIDE_ATTRIBUTES __tuple(_Ts...) -> __tuple<_Ts...>;
|
||||
|
||||
//
|
||||
// __apply(fn, tuple, extra...)
|
||||
//
|
||||
#define _CCCL_TUPLE_GET(_Idx) , static_cast<_Tuple&&>(__tupl).__val##_Idx
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
_CCCL_TEMPLATE(class _Fn, class _Tuple, class... _Us)
|
||||
_CCCL_REQUIRES(__detail::__applicable_v<_Fn, _Tuple, _Us...>)
|
||||
_CCCL_TRIVIAL_API constexpr auto
|
||||
__apply(_Fn&& __fn, _Tuple&& __tupl, _Us&&... __us) noexcept(__detail::__nothrow_applicable_v<_Fn, _Tuple, _Us...>)
|
||||
-> decltype(auto)
|
||||
{
|
||||
constexpr size_t __size = remove_reference_t<_Tuple>::__size;
|
||||
|
||||
if constexpr (__size == 0)
|
||||
{
|
||||
return static_cast<_Fn&&>(__fn)(static_cast<_Us&&>(__us)...);
|
||||
}
|
||||
else if constexpr (__size == 1)
|
||||
{
|
||||
return static_cast<_Fn&&>(__fn)(static_cast<_Us&&>(__us)... _CCCL_PP_REPEAT(1, _CCCL_TUPLE_GET));
|
||||
}
|
||||
else if constexpr (__size == 2)
|
||||
{
|
||||
return static_cast<_Fn&&>(__fn)(static_cast<_Us&&>(__us)... _CCCL_PP_REPEAT(2, _CCCL_TUPLE_GET));
|
||||
}
|
||||
else if constexpr (__size == 3)
|
||||
{
|
||||
return static_cast<_Fn&&>(__fn)(static_cast<_Us&&>(__us)... _CCCL_PP_REPEAT(3, _CCCL_TUPLE_GET));
|
||||
}
|
||||
else if constexpr (__size == 4)
|
||||
{
|
||||
return static_cast<_Fn&&>(__fn)(static_cast<_Us&&>(__us)... _CCCL_PP_REPEAT(4, _CCCL_TUPLE_GET));
|
||||
}
|
||||
else if constexpr (__size == 5)
|
||||
{
|
||||
return static_cast<_Fn&&>(__fn)(static_cast<_Us&&>(__us)... _CCCL_PP_REPEAT(5, _CCCL_TUPLE_GET));
|
||||
}
|
||||
else if constexpr (__size == 6)
|
||||
{
|
||||
return static_cast<_Fn&&>(__fn)(static_cast<_Us&&>(__us)... _CCCL_PP_REPEAT(6, _CCCL_TUPLE_GET));
|
||||
}
|
||||
else if constexpr (__size == 7)
|
||||
{
|
||||
return static_cast<_Fn&&>(__fn)(static_cast<_Us&&>(__us)... _CCCL_PP_REPEAT(7, _CCCL_TUPLE_GET));
|
||||
}
|
||||
else if constexpr (__size == 8)
|
||||
{
|
||||
return static_cast<_Fn&&>(__fn)(static_cast<_Us&&>(__us)... _CCCL_PP_REPEAT(8, _CCCL_TUPLE_GET));
|
||||
}
|
||||
else
|
||||
{
|
||||
return __tupl.__apply(static_cast<_Fn&&>(__fn), static_cast<_Tuple&&>(__tupl), static_cast<_Us&&>(__us)...);
|
||||
}
|
||||
}
|
||||
|
||||
#undef _CCCL_TUPLE_GET
|
||||
|
||||
template <class _Fn, class _Tuple, class... _Us>
|
||||
using __apply_result_t _CCCL_NODEBUG_ALIAS =
|
||||
decltype(::cuda::std::__apply(declval<_Fn>(), declval<_Tuple>(), declval<_Us>()...));
|
||||
|
||||
template <class _Fn, class _Tuple, class... _Us>
|
||||
_CCCL_CONCEPT __applicable = __detail::__applicable_v<_Fn, _Tuple, _Us...>;
|
||||
|
||||
template <class _Fn, class _Tuple, class... _Us>
|
||||
_CCCL_CONCEPT __nothrow_applicable = __detail::__nothrow_applicable_v<_Fn, _Tuple, _Us...>;
|
||||
|
||||
//
|
||||
// __get<I>(tupl)
|
||||
//
|
||||
namespace __detail
|
||||
{
|
||||
template <size_t _Index, class _Value>
|
||||
_CCCL_TRIVIAL_API constexpr auto __get(__box<_Index, _Value>&& __b) noexcept -> _Value&&
|
||||
{
|
||||
return static_cast<_Value&&>(__b.__value);
|
||||
}
|
||||
|
||||
template <size_t _Index, class _Value>
|
||||
_CCCL_TRIVIAL_API constexpr auto __get(__box<_Index, _Value>& __b) noexcept -> _Value&
|
||||
{
|
||||
return __b.__value;
|
||||
}
|
||||
|
||||
template <size_t _Index, class _Value>
|
||||
_CCCL_TRIVIAL_API constexpr auto __get(const __box<_Index, _Value>& __b) noexcept -> const _Value&
|
||||
{
|
||||
return __b.__value;
|
||||
}
|
||||
} // namespace __detail
|
||||
|
||||
template <size_t _Index, class _Tuple>
|
||||
_CCCL_TRIVIAL_API constexpr auto __get(_Tuple&& __tupl) noexcept -> auto&&
|
||||
{
|
||||
constexpr auto __size = remove_reference_t<_Tuple>::__size;
|
||||
static_assert(_Index < __size, "Index out of bounds in __get");
|
||||
|
||||
if constexpr (_Index == 0)
|
||||
{
|
||||
return static_cast<_Tuple&&>(__tupl).__val0;
|
||||
}
|
||||
else if constexpr (_Index == 1)
|
||||
{
|
||||
return static_cast<_Tuple&&>(__tupl).__val1;
|
||||
}
|
||||
else if constexpr (_Index == 2)
|
||||
{
|
||||
return static_cast<_Tuple&&>(__tupl).__val2;
|
||||
}
|
||||
else if constexpr (_Index == 3)
|
||||
{
|
||||
return static_cast<_Tuple&&>(__tupl).__val3;
|
||||
}
|
||||
else if constexpr (_Index == 4)
|
||||
{
|
||||
return static_cast<_Tuple&&>(__tupl).__val4;
|
||||
}
|
||||
else if constexpr (_Index == 5)
|
||||
{
|
||||
return static_cast<_Tuple&&>(__tupl).__val5;
|
||||
}
|
||||
else if constexpr (_Index == 6)
|
||||
{
|
||||
return static_cast<_Tuple&&>(__tupl).__val6;
|
||||
}
|
||||
else if constexpr (_Index == 7)
|
||||
{
|
||||
return static_cast<_Tuple&&>(__tupl).__val7;
|
||||
}
|
||||
else if constexpr (_Index == 8)
|
||||
{
|
||||
return static_cast<_Tuple&&>(__tupl).__val8;
|
||||
}
|
||||
else
|
||||
{
|
||||
return __detail::__get<_Index>(static_cast<_Tuple&&>(__tupl));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// __decayed_tuple<Ts...>
|
||||
//
|
||||
template <class... _Ts>
|
||||
using __decayed_tuple _CCCL_NODEBUG_ALIAS = __tuple<decay_t<_Ts>...>;
|
||||
|
||||
//
|
||||
// __pair
|
||||
//
|
||||
template <class _First, class _Second>
|
||||
struct __pair
|
||||
{
|
||||
_CCCL_NO_UNIQUE_ADDRESS _First first;
|
||||
_CCCL_NO_UNIQUE_ADDRESS _Second second;
|
||||
};
|
||||
|
||||
template <class _First, class _Second>
|
||||
_CCCL_DEDUCTION_GUIDE_ATTRIBUTES __pair(_First, _Second) -> __pair<_First, _Second>;
|
||||
|
||||
//
|
||||
// __tuple_size_v
|
||||
//
|
||||
template <class _Tuple>
|
||||
extern __undefined<_Tuple> __tuple_size_v;
|
||||
|
||||
template <class... _Ts>
|
||||
inline constexpr size_t __tuple_size_v<__tuple<_Ts...>> = sizeof...(_Ts);
|
||||
|
||||
template <class... _Ts>
|
||||
inline constexpr size_t __tuple_size_v<const __tuple<_Ts...>> = sizeof...(_Ts);
|
||||
|
||||
template <class... _Ts>
|
||||
inline constexpr size_t __tuple_size_v<__tuple<_Ts...>&> = sizeof...(_Ts);
|
||||
|
||||
template <class... _Ts>
|
||||
inline constexpr size_t __tuple_size_v<const __tuple<_Ts...>&> = sizeof...(_Ts);
|
||||
|
||||
//
|
||||
// __tuple_element_t
|
||||
//
|
||||
template <class _Tp>
|
||||
_CCCL_API auto __remove_rvalue_ref(_Tp&&) noexcept -> _Tp;
|
||||
|
||||
template <size_t _Index, class _Tuple>
|
||||
using __tuple_element_t _CCCL_NODEBUG_ALIAS =
|
||||
decltype(::cuda::std::__remove_rvalue_ref(::cuda::std::__get<_Index>(declval<_Tuple>())));
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // __CUDA_STD___UTILITY_POD_TUPLE_H
|
||||
@@ -0,0 +1,40 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_PRIORITY_TAG_H
|
||||
#define _CUDA_STD___UTILITY_PRIORITY_TAG_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/cstddef>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
template <size_t _Ip>
|
||||
struct __priority_tag : __priority_tag<_Ip - 1>
|
||||
{};
|
||||
template <>
|
||||
struct __priority_tag<0>
|
||||
{};
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_PRIORITY_TAG_H
|
||||
@@ -0,0 +1,61 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_REL_OPS_H
|
||||
#define _CUDA_STD___UTILITY_REL_OPS_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/__utility/forward.h>
|
||||
#include <cuda/std/__utility/move.h>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
namespace rel_ops
|
||||
{
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _CCCL_DEPRECATED_IN_CXX20 _CCCL_API inline bool operator!=(const _Tp& __x, const _Tp& __y)
|
||||
{
|
||||
return !(__x == __y);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _CCCL_DEPRECATED_IN_CXX20 _CCCL_API inline bool operator>(const _Tp& __x, const _Tp& __y)
|
||||
{
|
||||
return __y < __x;
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _CCCL_DEPRECATED_IN_CXX20 _CCCL_API inline bool operator<=(const _Tp& __x, const _Tp& __y)
|
||||
{
|
||||
return !(__y < __x);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _CCCL_DEPRECATED_IN_CXX20 _CCCL_API inline bool operator>=(const _Tp& __x, const _Tp& __y)
|
||||
{
|
||||
return !(__x < __y);
|
||||
}
|
||||
} // namespace rel_ops
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_REL_OPS_H
|
||||
64
cccl_upstream/libcudacxx/include/cuda/std/__utility/swap.h
Normal file
64
cccl_upstream/libcudacxx/include/cuda/std/__utility/swap.h
Normal file
@@ -0,0 +1,64 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_SWAP_H
|
||||
#define _CUDA_STD___UTILITY_SWAP_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/__type_traits/enable_if.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_move_assignable.h>
|
||||
#include <cuda/std/__type_traits/is_nothrow_move_constructible.h>
|
||||
#include <cuda/std/__type_traits/is_swappable.h>
|
||||
#include <cuda/std/__utility/move.h>
|
||||
#include <cuda/std/cstddef>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
// we use type_identity_t<_Tp> as second parameter, to avoid ambiguity with std::swap, which will thus be preferred by
|
||||
// overload resolution (which is ok since std::swap is only considered when explicitly called, or found by ADL for types
|
||||
// from std::)
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp>
|
||||
_CCCL_API constexpr __swap_result_t<_Tp> swap(_Tp& __x, type_identity_t<_Tp>& __y) noexcept(
|
||||
is_nothrow_move_constructible_v<_Tp> && is_nothrow_move_assignable_v<_Tp>)
|
||||
{
|
||||
_Tp __t(::cuda::std::move(__x));
|
||||
__x = ::cuda::std::move(__y);
|
||||
__y = ::cuda::std::move(__t);
|
||||
}
|
||||
|
||||
_CCCL_EXEC_CHECK_DISABLE
|
||||
template <class _Tp, size_t _Np>
|
||||
_CCCL_API constexpr enable_if_t<__detect_adl_swap::__has_no_adl_swap_array<_Tp, _Np>::value && __is_swappable<_Tp>::value>
|
||||
swap(_Tp (&__a)[_Np], _Tp (&__b)[_Np]) noexcept(__is_nothrow_swappable<_Tp>::value)
|
||||
{
|
||||
for (size_t __i = 0; __i != _Np; ++__i)
|
||||
{
|
||||
swap(__a[__i], __b[__i]);
|
||||
}
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_SWAP_H
|
||||
@@ -0,0 +1,40 @@
|
||||
// -*- C++ -*-
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_TO_UNDERLYING_H
|
||||
#define _CUDA_STD___UTILITY_TO_UNDERLYING_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/__type_traits/underlying_type.h>
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _CCCL_API constexpr underlying_type_t<_Tp> to_underlying(_Tp __val) noexcept
|
||||
{
|
||||
return static_cast<underlying_type_t<_Tp>>(__val);
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_TO_UNDERLYING_H
|
||||
502
cccl_upstream/libcudacxx/include/cuda/std/__utility/typeid.h
Normal file
502
cccl_upstream/libcudacxx/include/cuda/std/__utility/typeid.h
Normal file
@@ -0,0 +1,502 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_TYPEID_H
|
||||
#define _CUDA_STD___UTILITY_TYPEID_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
|
||||
|
||||
// This file provides a minimal implementation of `std::type_info` for platforms
|
||||
// that do not support RTTI. It defines the following:
|
||||
//
|
||||
// `cuda::std::type_info` - An alias for `std::type_info` if RTTI is available, or
|
||||
// an alias for `cuda::std::__type_info` if RTTI is not
|
||||
// available.
|
||||
// `cuda::std::__type_info` - A class type that provides the `std::type_info` interface
|
||||
// where the member functions are `constexpr`.
|
||||
// `cuda::std::__type_info_ptr`
|
||||
// - The result of taking the address of a
|
||||
// `cuda::std::__type_info` object.
|
||||
// `_CCCL_TYPEID(<type>)` - A macro that returns a reference to the `const`
|
||||
// `cuda::std::type_info` object for the specified type.
|
||||
// `_CCCL_CONSTEXPR_TYPEID(<type>)`
|
||||
// - A macro that returns a reference to the `const`
|
||||
// `cuda::std::__type_info` object for the specified type.
|
||||
|
||||
#if _LIBCUDACXX_HAS_SPACESHIP_OPERATOR()
|
||||
# include <cuda/std/compare>
|
||||
#endif // _LIBCUDACXX_HAS_SPACESHIP_OPERATOR()
|
||||
#include <cuda/std/__cccl/preprocessor.h>
|
||||
#include <cuda/std/__string/string_view.h>
|
||||
#include <cuda/std/__type_traits/enable_if.h>
|
||||
#include <cuda/std/__type_traits/integral_constant.h>
|
||||
#include <cuda/std/__type_traits/is_function.h>
|
||||
#include <cuda/std/__type_traits/is_member_function_pointer.h>
|
||||
#include <cuda/std/__type_traits/remove_cv.h>
|
||||
#include <cuda/std/__type_traits/remove_pointer.h>
|
||||
#include <cuda/std/__utility/integer_sequence.h>
|
||||
#include <cuda/std/cstddef>
|
||||
|
||||
#if !defined(_CCCL_NO_TYPEID)
|
||||
# include <typeinfo>
|
||||
#endif
|
||||
|
||||
// _CCCL_MSVC_BROKEN_FUNCSIG:
|
||||
//
|
||||
// When using MSVC as the host compiler, there is a bug in the EDG front-end of
|
||||
// cudafe++ that causes the __FUNCSIG__ predefined macro to be expanded too
|
||||
// early in the compilation process. The result is that within a function
|
||||
// template the __FUNCSIG__ string does not mention the template arguments. This
|
||||
// makes it impossible to extract the pretty name of a type from __FUNCSIG__,
|
||||
// which in turn makes it impossible to implement a constexpr replacement for
|
||||
// typeid. On MSVC v19.35 and higher, the __builtin_FUNCSIG() intrinsic is
|
||||
// available and can be used in place of __FUNCSIG__, resolving the issue. For
|
||||
// older versions of MSVC, we fall back to using the built-in typeid feature,
|
||||
// which is always available on MSVC, even when RTTI is disabled.
|
||||
|
||||
#include <cuda/std/__cccl/prologue.h>
|
||||
|
||||
_CCCL_BEGIN_NAMESPACE_CUDA_STD
|
||||
|
||||
#define _CCCL_STD_TYPEID(...) typeid(::cuda::std::_CCCL_TYPEID_ONLY_SUPPORTS_TYPES<__VA_ARGS__>)
|
||||
|
||||
#if !defined(_CCCL_NO_TYPEID) && !defined(_CCCL_USE_TYPEID_FALLBACK)
|
||||
|
||||
# define _CCCL_TYPEID _CCCL_STD_TYPEID
|
||||
using type_info = ::std::type_info;
|
||||
using __type_info_ptr = type_info const*;
|
||||
using __type_info_ref = type_info const&;
|
||||
using __type_info_ref_ = type_info const&;
|
||||
|
||||
#else // ^^^ !_CCCL_NO_TYPEID ^^^ / vvv _CCCL_NO_TYPEID vvv
|
||||
|
||||
# define _CCCL_TYPEID _CCCL_TYPEID_FALLBACK
|
||||
|
||||
#endif // _CCCL_NO_TYPEID
|
||||
|
||||
// We find a type _Tp's name as follows:
|
||||
// 1. Use __PRETTY_FUNCTION__ in a function template parameterized by
|
||||
// __pretty_name_begin<_Tp>::__pretty_name_end.
|
||||
// 2. Find the substrings "__pretty_name_begin<" and ">::__pretty_name_end".
|
||||
// Everything between them is the name of type _Tp.
|
||||
|
||||
template <class _Tp>
|
||||
using _CCCL_TYPEID_ONLY_SUPPORTS_TYPES = _Tp;
|
||||
|
||||
// Earlier versions of gcc (before gcc-9) do not treat __PRETTY_FUNCTION__ as a
|
||||
// constexpr value after a reference to it has been returned from a function.
|
||||
// Instead, arrange things so that the pretty name gets stored in a class static
|
||||
// data member, where it can be referenced from other constexpr contexts.
|
||||
|
||||
#if _CCCL_COMPILER(GCC, <, 9)
|
||||
|
||||
template <size_t _Np>
|
||||
struct __sstring
|
||||
{
|
||||
char __str_[_Np];
|
||||
size_t __len_;
|
||||
};
|
||||
|
||||
template <class _Tp, size_t _Np>
|
||||
struct __static_nameof;
|
||||
|
||||
template <size_t _Np, size_t _Mp, size_t... _Is>
|
||||
_CCCL_API constexpr __sstring<_Np> __make_pretty_name_impl(char const (&__s)[_Mp], index_sequence<_Is...>) noexcept
|
||||
{
|
||||
static_assert(_Mp <= _Np, "Type name too long for __pretty_nameof");
|
||||
return __sstring<_Np>{{(_Is < _Mp ? __s[_Is] : '\0')...}, _Mp - 1};
|
||||
}
|
||||
|
||||
template <class _Tp, size_t _Np>
|
||||
_CCCL_API constexpr auto __make_pretty_name(integral_constant<size_t, _Np>) noexcept //
|
||||
-> enable_if_t<_Np == size_t(-1), __string_view>
|
||||
{
|
||||
using _TpName = __static_nameof<_Tp, sizeof(_CCCL_BUILTIN_PRETTY_FUNCTION())>;
|
||||
return __string_view(_TpName::value.__str_, _TpName::value.__len_);
|
||||
}
|
||||
|
||||
template <class _Tp, size_t _Np>
|
||||
_CCCL_API constexpr auto __make_pretty_name(integral_constant<size_t, _Np>) noexcept //
|
||||
-> enable_if_t<_Np != size_t(-1), __sstring<_Np>>
|
||||
{
|
||||
return ::cuda::std::__make_pretty_name_impl<_Np>(_CCCL_BUILTIN_PRETTY_FUNCTION(), make_index_sequence<_Np>{});
|
||||
}
|
||||
|
||||
// TODO: class statics cannot be accessed from device code, so we need to use
|
||||
// a variable template when that is available.
|
||||
template <class _Tp, size_t _Np>
|
||||
struct __static_nameof
|
||||
{
|
||||
static constexpr __sstring<_Np> value = ::cuda::std::__make_pretty_name<_Tp>(integral_constant<size_t, _Np>());
|
||||
};
|
||||
|
||||
template <class _Tp, size_t _Np>
|
||||
constexpr __sstring<_Np> __static_nameof<_Tp, _Np>::value;
|
||||
|
||||
#endif // _CCCL_COMPILER(GCC, <, 9)
|
||||
|
||||
template <class _Tp>
|
||||
struct __pretty_name_begin
|
||||
{
|
||||
struct __pretty_name_end;
|
||||
};
|
||||
|
||||
// If a position is -1, it is an invalid position. Return it unchanged.
|
||||
[[nodiscard]] _CCCL_API constexpr ptrdiff_t __add_string_view_position(ptrdiff_t __pos, ptrdiff_t __diff) noexcept
|
||||
{
|
||||
return __pos == -1 ? -1 : __pos + __diff;
|
||||
}
|
||||
|
||||
// Get the type name from the pretty name by trimming the front and back.
|
||||
//
|
||||
// __sv.substr() technically may throw an exception if the indices are out of range, but this
|
||||
// is not possible because they are generated by calls to find()
|
||||
[[nodiscard]] _CCCL_API constexpr __string_view
|
||||
__find_pretty_name(__string_view __sv) noexcept // NOLINT(bugprone-exception-escape)
|
||||
{
|
||||
return __sv.substr(::cuda::std::__add_string_view_position(
|
||||
__sv.find("__pretty_name_begin<"), static_cast<ptrdiff_t>(sizeof("__pretty_name_begin<")) - 1),
|
||||
__sv.find_end(">::__pretty_name_end"));
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _CCCL_API constexpr __string_view __pretty_nameof_helper() noexcept
|
||||
{
|
||||
#if _CCCL_COMPILER(GCC, <, 9) && !defined(__CUDA_ARCH__)
|
||||
return ::cuda::std::__find_pretty_name(::cuda::std::__make_pretty_name<_Tp>(integral_constant<size_t, size_t(-1)>{}));
|
||||
#else // ^^^ gcc < 9 ^^^^/ vvv other compiler vvv
|
||||
return ::cuda::std::__find_pretty_name(::cuda::std::__string_view(_CCCL_BUILTIN_PRETTY_FUNCTION()));
|
||||
#endif // not gcc < 9
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _CCCL_API constexpr __string_view __pretty_nameof() noexcept
|
||||
{
|
||||
return ::cuda::std::__pretty_nameof_helper<typename __pretty_name_begin<_Tp>::__pretty_name_end>();
|
||||
}
|
||||
|
||||
// In device code with old versions of gcc, we cannot have nice things.
|
||||
#if _CCCL_COMPILER(GCC, <, 9) && defined(__CUDA_ARCH__)
|
||||
# define _CCCL_NO_CONSTEXPR_PRETTY_NAMEOF
|
||||
#endif
|
||||
|
||||
#if !defined(_CCCL_NO_CONSTEXPR_PRETTY_NAMEOF) && !defined(_CCCL_BROKEN_MSVC_FUNCSIG) \
|
||||
&& defined(_CCCL_ENABLE_DEBUG_MODE)
|
||||
// A quick smoke test to ensure that the pretty name extraction is working.
|
||||
static_assert(::cuda::std::__pretty_nameof<int>() == __string_view("int"));
|
||||
static_assert(::cuda::std::__pretty_nameof<float>() < ::cuda::std::__pretty_nameof<int>());
|
||||
#endif // !_CCCL_NO_CONSTEXPR_PRETTY_NAMEOF && !_CCCL_BROKEN_MSVC_FUNCSIG && _CCCL_ENABLE_DEBUG_MODE
|
||||
|
||||
// We find the spelling of a non-type template parameter value _Vp as follows:
|
||||
// 1. Wrap the value in the class template __stringof_wrapper and obtain
|
||||
// the pretty name of that type via __pretty_nameof. This reuses all of the
|
||||
// compiler-specific machinery (and quirk handling) that __pretty_nameof
|
||||
// already implements.
|
||||
// 2. The resulting string looks like "...__stringof_wrapper<42>...".
|
||||
// Trim the surrounding wrapper to recover the value's spelling.
|
||||
//
|
||||
// The exact spelling is whatever the compiler emits for the value and is not
|
||||
// guaranteed to be identical across compilers (e.g. a char might be spelled
|
||||
// 'A', an enumerator might be spelled by name or by a cast). Integral values
|
||||
// such as `42` are spelled identically everywhere.
|
||||
|
||||
template <auto _Vp>
|
||||
struct __stringof_wrapper
|
||||
{};
|
||||
|
||||
// Extract the value's spelling from the pretty name of __stringof_wrapper<_Vp>.
|
||||
//
|
||||
// __sv.substr() technically may throw an exception if the indices are out of range, but this
|
||||
// is not possible because they are generated by calls to find()
|
||||
[[nodiscard]] _CCCL_API constexpr __string_view
|
||||
__find_stringof(__string_view __sv) noexcept // NOLINT(bugprone-exception-escape)
|
||||
{
|
||||
// Trim the surrounding "__stringof_wrapper<" ... ">".
|
||||
return __sv.substr(::cuda::std::__add_string_view_position(
|
||||
__sv.find("__stringof_wrapper<"), static_cast<ptrdiff_t>(sizeof("__stringof_wrapper<")) - 1),
|
||||
__sv.find_end(">"));
|
||||
}
|
||||
|
||||
//! @brief Returns the compiler's spelling of a value passed as a non-type
|
||||
//! template parameter, e.g. `__stringof<42>()` yields `"42"` and
|
||||
//! `__stringof<cudaStreamSynchronize>()` yields `"cudaStreamSynchronize"`.
|
||||
//!
|
||||
//! @tparam _Vp The value whose compiler spelling is returned.
|
||||
//! @return A string view containing the compiler's spelling of `_Vp`.
|
||||
//!
|
||||
//! This is the value counterpart of `__pretty_nameof` (which spells types). It
|
||||
//! supports the same set of compilers and the same compiler quirks, because it
|
||||
//! is implemented on top of `__pretty_nameof`.
|
||||
//!
|
||||
//! When the value is a function (or function pointer), the leading '&' that
|
||||
//! clang and cudafe prepend to a function template argument is dropped, so the
|
||||
//! result is just the function's (possibly qualified) name. The exact spelling
|
||||
//! of other values is whatever the compiler emits and is not guaranteed to be
|
||||
//! identical across compilers.
|
||||
template <auto _Vp>
|
||||
[[nodiscard]] _CCCL_API constexpr __string_view __stringof() noexcept // NOLINT(bugprone-exception-escape)
|
||||
{
|
||||
__string_view __sv =
|
||||
::cuda::std::__find_stringof(::cuda::std::__pretty_nameof<::cuda::std::__stringof_wrapper<_Vp>>());
|
||||
// For a function argument, clang and cudafe prepend a '&' (e.g. "&fn"); drop
|
||||
// it so the result is just the function's name.
|
||||
if constexpr (is_function_v<remove_pointer_t<decltype(_Vp)>> || is_member_function_pointer_v<decltype(_Vp)>)
|
||||
{
|
||||
if (__sv.size() != 0 && __sv[0] == '&')
|
||||
{
|
||||
// substr() technically may throw an exception, but clang-tidy does not realize this is safe
|
||||
__sv = __sv.substr(1, static_cast<ptrdiff_t>(__sv.size()));
|
||||
}
|
||||
}
|
||||
return __sv;
|
||||
}
|
||||
|
||||
#if !defined(_CCCL_NO_CONSTEXPR_PRETTY_NAMEOF) && !defined(_CCCL_BROKEN_MSVC_FUNCSIG) \
|
||||
&& defined(_CCCL_ENABLE_DEBUG_MODE)
|
||||
// A quick smoke test to ensure that the value spelling extraction is working.
|
||||
// An integer literal is spelled identically on every supported compiler.
|
||||
static_assert(::cuda::std::__stringof<42>() == __string_view("42"));
|
||||
static_assert(::cuda::std::__stringof<42>() != ::cuda::std::__stringof<43>());
|
||||
// And that function arguments work (including the leading-'&' trim). We use a
|
||||
// host/device function defined above so this works in both compilation passes
|
||||
// without depending on any external symbols. The function lives in an inline
|
||||
// namespace, whose spelling varies between compilers, so we only check that the
|
||||
// unqualified name is present rather than matching it exactly.
|
||||
static_assert(::cuda::std::__stringof<&::cuda::std::__add_string_view_position>().find("__add_string_view_position")
|
||||
!= -1);
|
||||
#endif // !_CCCL_NO_CONSTEXPR_PRETTY_NAMEOF && !_CCCL_BROKEN_MSVC_FUNCSIG && _CCCL_ENABLE_DEBUG_MODE
|
||||
|
||||
// There are many complications with defining a unique constexpr global object
|
||||
// for each type in device code, particularly on Windows. So rather than try,
|
||||
// we use an alternate formulation of typeid that does not require such objects.
|
||||
#if defined(__CUDA_ARCH__)
|
||||
|
||||
struct __type_info;
|
||||
struct __type_info_ptr_;
|
||||
struct __type_info_ref_;
|
||||
|
||||
struct __type_info_impl
|
||||
{
|
||||
__string_view __name_;
|
||||
};
|
||||
|
||||
struct __type_info_ptr_
|
||||
{
|
||||
_CCCL_HIDE_FROM_ABI constexpr __type_info_ptr_() noexcept = default;
|
||||
|
||||
_CCCL_API constexpr __type_info_ptr_(__type_info_impl (*__pfn_)() noexcept) noexcept
|
||||
: __pfn_(__pfn_)
|
||||
{}
|
||||
|
||||
[[nodiscard]] _CCCL_API constexpr __type_info_ref_ operator*() const noexcept;
|
||||
|
||||
[[nodiscard]] _CCCL_API friend constexpr bool operator==(__type_info_ptr_ __a, __type_info_ptr_ __b) noexcept
|
||||
{
|
||||
return __a.__pfn_ == __b.__pfn_;
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_API friend constexpr bool operator!=(__type_info_ptr_ __a, __type_info_ptr_ __b) noexcept
|
||||
{
|
||||
return !(__a == __b);
|
||||
}
|
||||
|
||||
__type_info_impl (*__pfn_)() noexcept = nullptr;
|
||||
};
|
||||
|
||||
/// @brief A minimal implementation of `std::type_info` for device code that does
|
||||
/// not depend on RTTI or variable templates.
|
||||
struct __type_info
|
||||
{
|
||||
__type_info() = delete;
|
||||
|
||||
_CCCL_API explicit constexpr __type_info(__type_info_impl (*__pfn)() noexcept) noexcept
|
||||
: __pfn_(__pfn)
|
||||
{}
|
||||
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _CCCL_API static constexpr __type_info_impl __get_ti_for() noexcept
|
||||
{
|
||||
return __type_info_impl{::cuda::std::__pretty_nameof<_Tp>()};
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_API constexpr char const* name() const noexcept
|
||||
{
|
||||
return __pfn_().__name_.begin();
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_API constexpr __string_view __name_view() const noexcept
|
||||
{
|
||||
return __pfn_().__name_;
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_API constexpr bool before(__type_info const& __other) const noexcept
|
||||
{
|
||||
return __pfn_().__name_ < __other.__pfn_().__name_;
|
||||
}
|
||||
|
||||
// Not yet implemented:
|
||||
// [[nodiscard]] _CCCL_API constexpr size_t hash_code() const noexcept
|
||||
// {
|
||||
// return ;
|
||||
// }
|
||||
|
||||
[[nodiscard]] _CCCL_API constexpr __type_info_ptr_ operator&() const noexcept
|
||||
{
|
||||
return __type_info_ptr_{__pfn_};
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_API friend constexpr bool operator==(__type_info const& __a, __type_info const& __b) noexcept
|
||||
{
|
||||
return __a.__pfn_ == __b.__pfn_ || __a.__pfn_().__name_ == __b.__pfn_().__name_;
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_API friend constexpr bool operator!=(__type_info const& __a, __type_info const& __b) noexcept
|
||||
{
|
||||
return !(__a == __b);
|
||||
}
|
||||
|
||||
__type_info& operator=(__type_info const&) = delete;
|
||||
|
||||
private:
|
||||
friend struct __type_info_ptr_;
|
||||
friend struct __type_info_ref_;
|
||||
|
||||
__type_info(__type_info const&) = default; // needed by __type_info_ptr_::operator*() before C++17
|
||||
__type_info_impl (*__pfn_)() noexcept;
|
||||
};
|
||||
|
||||
struct __type_info_ref_ : __type_info
|
||||
{
|
||||
_CCCL_API constexpr __type_info_ref_(__type_info_impl (*__pfn)() noexcept) noexcept
|
||||
: __type_info(__pfn)
|
||||
{}
|
||||
|
||||
_CCCL_API constexpr __type_info_ref_(__type_info const& __other) noexcept
|
||||
: __type_info(__other)
|
||||
{}
|
||||
|
||||
_CCCL_HIDE_FROM_ABI constexpr __type_info_ref_(__type_info_ref_ const& __other) noexcept = default;
|
||||
};
|
||||
|
||||
[[nodiscard]] _CCCL_API constexpr __type_info_ref_ __type_info_ptr_::operator*() const noexcept
|
||||
{
|
||||
return __type_info_ref_(__pfn_);
|
||||
}
|
||||
|
||||
# if defined(_CCCL_NO_TYPEID) || defined(_CCCL_USE_TYPEID_FALLBACK)
|
||||
using type_info = __type_info;
|
||||
using __type_info_ptr = __type_info_ptr_;
|
||||
using __type_info_ref = __type_info_ref_;
|
||||
# endif // defined(_CCCL_NO_TYPEID) || defined(_CCCL_USE_TYPEID_FALLBACK)
|
||||
|
||||
# define _CCCL_TYPEID_FALLBACK(...) \
|
||||
::cuda::std::__type_info_ref(&::cuda::std::__type_info::__get_ti_for<::cuda::std::remove_cv_t<__VA_ARGS__>>)
|
||||
|
||||
#elif defined(_CCCL_BROKEN_MSVC_FUNCSIG) // ^^^ defined(__CUDA_ARCH__) ^^^
|
||||
|
||||
// See comment above about _CCCL_BROKEN_MSVC_FUNCSIG
|
||||
# define _CCCL_TYPEID_FALLBACK _CCCL_STD_TYPEID
|
||||
# if defined(_CCCL_NO_TYPEID) || defined(_CCCL_USE_TYPEID_FALLBACK)
|
||||
using type_info = ::std::type_info;
|
||||
using __type_info_ptr = ::std::type_info const*;
|
||||
using __type_info_ref = ::std::type_info const&;
|
||||
# endif // defined(_CCCL_NO_TYPEID) || defined(_CCCL_USE_TYPEID_FALLBACK)
|
||||
|
||||
#else // ^^^ _CCCL_BROKEN_MSVC_FUNCSIG ^^^ / vvv !__CUDA_ARCH__ && !_CCCL_BROKEN_MSVC_FUNCSIG vvv
|
||||
|
||||
/// @brief A minimal implementation of `std::type_info` for platforms that do
|
||||
/// not support RTTI.
|
||||
struct __type_info
|
||||
{
|
||||
__type_info() = delete;
|
||||
__type_info(__type_info const&) = delete;
|
||||
__type_info& operator=(__type_info const&) = delete;
|
||||
|
||||
_CCCL_HOST_API constexpr __type_info(__string_view __name) noexcept
|
||||
: __name_(__name)
|
||||
{}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API constexpr char const* name() const noexcept
|
||||
{
|
||||
return __name_.begin();
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API constexpr __string_view __name_view() const noexcept
|
||||
{
|
||||
return __name_;
|
||||
}
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API constexpr bool before(const __type_info& __other) const noexcept
|
||||
{
|
||||
return __name_ < __other.__name_;
|
||||
}
|
||||
|
||||
// Not yet implemented:
|
||||
// [[nodiscard]] _CCCL_HOST_API constexpr size_t hash_code() const noexcept
|
||||
// {
|
||||
// return ;
|
||||
// }
|
||||
|
||||
[[nodiscard]] _CCCL_HOST_API friend constexpr bool
|
||||
operator==(const __type_info& __lhs, const __type_info& __rhs) noexcept
|
||||
{
|
||||
return &__lhs == &__rhs || __lhs.__name_ == __rhs.__name_;
|
||||
}
|
||||
|
||||
# if _CCCL_STD_VER <= 2017
|
||||
[[nodiscard]]
|
||||
_CCCL_HOST_API friend constexpr bool operator!=(const __type_info& __lhs, const __type_info& __rhs) noexcept
|
||||
{
|
||||
return !(__lhs == __rhs);
|
||||
}
|
||||
# endif // _CCCL_STD_VER <= 2017
|
||||
|
||||
private:
|
||||
__string_view __name_;
|
||||
};
|
||||
|
||||
# if defined(_CCCL_NO_TYPEID) || defined(_CCCL_USE_TYPEID_FALLBACK)
|
||||
using type_info = __type_info;
|
||||
using __type_info_ptr = __type_info const*;
|
||||
using __type_info_ref = __type_info const&;
|
||||
# endif // defined(_CCCL_NO_TYPEID) || defined(_CCCL_USE_TYPEID_FALLBACK)
|
||||
|
||||
template <class _Tp>
|
||||
_CCCL_GLOBAL_CONSTANT __type_info __typeid_v{::cuda::std::__pretty_nameof<_Tp>()};
|
||||
|
||||
// When inline variables are available, this indirection through an inline function
|
||||
// is not necessary, but it doesn't hurt either.
|
||||
template <class _Tp>
|
||||
[[nodiscard]] _CCCL_HOST_API constexpr __type_info const& __typeid() noexcept
|
||||
{
|
||||
return __typeid_v<_Tp>;
|
||||
}
|
||||
|
||||
# define _CCCL_TYPEID_FALLBACK(...) ::cuda::std::__typeid<::cuda::std::remove_cv_t<__VA_ARGS__>>()
|
||||
|
||||
#endif // !defined(__CUDA_ARCH__) && !_CCCL_BROKEN_MSVC_FUNCSIG
|
||||
|
||||
// if `__pretty_nameof` is constexpr _CCCL_TYPEID_FALLBACK is also constexpr.
|
||||
#if !defined(_CCCL_NO_CONSTEXPR_PRETTY_NAMEOF) && (!defined(_CCCL_BROKEN_MSVC_FUNCSIG) || defined(__CUDA_ARCH__))
|
||||
# define _CCCL_TYPEOF_CONSTEXPR _CCCL_TYPEOF_FALLBACK
|
||||
#endif
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_TYPEID_H
|
||||
@@ -0,0 +1,34 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_UNDEFINED_H
|
||||
#define _CUDA_STD___UTILITY_UNDEFINED_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
|
||||
|
||||
template <class...>
|
||||
struct __undefined; // leave this undefined
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_UNDEFINED_H
|
||||
@@ -0,0 +1,37 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _CUDA_STD___UTILITY_UNREACHABLE_H
|
||||
#define _CUDA_STD___UTILITY_UNREACHABLE_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
|
||||
|
||||
[[noreturn]] _CCCL_API inline void unreachable()
|
||||
{
|
||||
_CCCL_ASSERT(false, "unreachable");
|
||||
_CCCL_UNREACHABLE();
|
||||
}
|
||||
|
||||
_CCCL_END_NAMESPACE_CUDA_STD
|
||||
|
||||
#include <cuda/std/__cccl/epilogue.h>
|
||||
|
||||
#endif // _CUDA_STD___UTILITY_UNREACHABLE_H
|
||||
Reference in New Issue
Block a user