Skip to content
Merged
Next Next commit
Suppress execution checks for optional
  • Loading branch information
miscco committed Jan 29, 2025
commit 4e6fa9dce26026348924868d93e32fcd719ecabf
25 changes: 25 additions & 0 deletions libcudacxx/include/cuda/std/detail/libcxx/include/optional
Original file line number Diff line number Diff line change
Expand Up @@ -296,12 +296,14 @@ struct __optional_destruct_base<_Tp, false>
, __engaged_(false)
{}

_CCCL_EXEC_CHECK_DISABLE
template <class... _Args>
_LIBCUDACXX_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
: __val_(_CUDA_VSTD::forward<_Args>(__args)...)
, __engaged_(true)
{}

_CCCL_EXEC_CHECK_DISABLE
template <class _Fp, class... _Args>
_LIBCUDACXX_HIDE_FROM_ABI constexpr __optional_destruct_base(
__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
Expand Down Expand Up @@ -338,12 +340,14 @@ struct __optional_destruct_base<_Tp, true>
, __engaged_(false)
{}

_CCCL_EXEC_CHECK_DISABLE
template <class... _Args>
_LIBCUDACXX_HIDE_FROM_ABI constexpr explicit __optional_destruct_base(in_place_t, _Args&&... __args)
: __val_(_CUDA_VSTD::forward<_Args>(__args)...)
, __engaged_(true)
{}

_CCCL_EXEC_CHECK_DISABLE
template <class _Fp, class... _Args>
_LIBCUDACXX_HIDE_FROM_ABI constexpr __optional_destruct_base(
__optional_construct_from_invoke_tag, _Fp&& __f, _Args&&... __args)
Expand Down Expand Up @@ -389,6 +393,7 @@ struct __optional_storage_base : __optional_destruct_base<_Tp>
return _CUDA_VSTD::move(this->__val_);
}

_CCCL_EXEC_CHECK_DISABLE
template <class... _Args>
_LIBCUDACXX_HIDE_FROM_ABI _CCCL_CONSTEXPR_CXX20 void __construct(_Args&&... __args)
{
Expand All @@ -410,6 +415,7 @@ struct __optional_storage_base : __optional_destruct_base<_Tp>
}
}

_CCCL_EXEC_CHECK_DISABLE
template <class _That>
_LIBCUDACXX_HIDE_FROM_ABI constexpr void __assign_from(_That&& __opt)
{
Expand Down Expand Up @@ -811,6 +817,7 @@ public:
return this->__get();
}

_CCCL_EXEC_CHECK_DISABLE
_LIBCUDACXX_HIDE_FROM_ABI constexpr void swap(optional& __opt) noexcept(
_CCCL_TRAIT(is_nothrow_move_constructible, value_type) && _CCCL_TRAIT(is_nothrow_swappable, value_type))
{
Expand Down Expand Up @@ -1088,6 +1095,7 @@ _CCCL_HOST_DEVICE optional(_Tp) -> optional<_Tp>;
# endif // _CCCL_NO_DEDUCTION_GUIDES

// Comparisons between optionals
_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() == declval<const _Up&>()), bool),
Expand All @@ -1105,6 +1113,7 @@ operator==(const optional<_Tp>& __x, const optional<_Up>& __y)
return *__x == *__y;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() != declval<const _Up&>()), bool),
Expand All @@ -1122,6 +1131,7 @@ operator!=(const optional<_Tp>& __x, const optional<_Up>& __y)
return *__x != *__y;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() < declval<const _Up&>()), bool),
Expand All @@ -1139,6 +1149,7 @@ operator<(const optional<_Tp>& __x, const optional<_Up>& __y)
return *__x < *__y;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() > declval<const _Up&>()), bool),
Expand All @@ -1156,6 +1167,7 @@ operator>(const optional<_Tp>& __x, const optional<_Up>& __y)
return *__x > *__y;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() <= declval<const _Up&>()), bool),
Expand All @@ -1173,6 +1185,7 @@ operator<=(const optional<_Tp>& __x, const optional<_Up>& __y)
return *__x <= *__y;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() >= declval<const _Up&>()), bool),
Expand Down Expand Up @@ -1264,6 +1277,7 @@ _LIBCUDACXX_HIDE_FROM_ABI constexpr bool operator>=(nullopt_t, const optional<_T
}

// Comparisons with T
_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() == declval<const _Up&>()), bool),
Expand All @@ -1273,6 +1287,7 @@ operator==(const optional<_Tp>& __x, const _Up& __v)
return static_cast<bool>(__x) ? *__x == __v : false;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() == declval<const _Up&>()), bool),
Expand All @@ -1282,6 +1297,7 @@ operator==(const _Tp& __v, const optional<_Up>& __x)
return static_cast<bool>(__x) ? __v == *__x : false;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() != declval<const _Up&>()), bool),
Expand All @@ -1291,6 +1307,7 @@ operator!=(const optional<_Tp>& __x, const _Up& __v)
return static_cast<bool>(__x) ? *__x != __v : true;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() != declval<const _Up&>()), bool),
Expand All @@ -1300,6 +1317,7 @@ operator!=(const _Tp& __v, const optional<_Up>& __x)
return static_cast<bool>(__x) ? __v != *__x : true;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() < declval<const _Up&>()), bool),
Expand All @@ -1309,6 +1327,7 @@ operator<(const optional<_Tp>& __x, const _Up& __v)
return static_cast<bool>(__x) ? *__x < __v : true;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() < declval<const _Up&>()), bool),
Expand All @@ -1318,6 +1337,7 @@ operator<(const _Tp& __v, const optional<_Up>& __x)
return static_cast<bool>(__x) ? __v < *__x : false;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() <= declval<const _Up&>()), bool),
Expand All @@ -1327,6 +1347,7 @@ operator<=(const optional<_Tp>& __x, const _Up& __v)
return static_cast<bool>(__x) ? *__x <= __v : true;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() <= declval<const _Up&>()), bool),
Expand All @@ -1336,6 +1357,7 @@ operator<=(const _Tp& __v, const optional<_Up>& __x)
return static_cast<bool>(__x) ? __v <= *__x : false;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() > declval<const _Up&>()), bool),
Expand All @@ -1345,6 +1367,7 @@ operator>(const optional<_Tp>& __x, const _Up& __v)
return static_cast<bool>(__x) ? *__x > __v : false;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() > declval<const _Up&>()), bool),
Expand All @@ -1354,6 +1377,7 @@ operator>(const _Tp& __v, const optional<_Up>& __x)
return static_cast<bool>(__x) ? __v > *__x : true;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() >= declval<const _Up&>()), bool),
Expand All @@ -1363,6 +1387,7 @@ operator>=(const optional<_Tp>& __x, const _Up& __v)
return static_cast<bool>(__x) ? *__x >= __v : false;
}

_CCCL_EXEC_CHECK_DISABLE
template <class _Tp, class _Up>
_LIBCUDACXX_HIDE_FROM_ABI constexpr enable_if_t<
_CCCL_TRAIT(is_convertible, decltype(declval<const _Tp&>() >= declval<const _Up&>()), bool),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
//===----------------------------------------------------------------------===//
//
// Part of the libcu++ 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.
//
//===----------------------------------------------------------------------===//

// We cannot suppress execution checks in cuda::std::construct_at
// XFAIL: c++20

#include <cuda/std/cassert>
#include <cuda/std/optional>

#include "test_macros.h"

struct device_only_type
{
int val_;

__device__ device_only_type(const int val = 0) noexcept
: val_(val)
{}

__device__ device_only_type(const device_only_type& other) noexcept
: val_(other.val_)
{}
__device__ device_only_type(device_only_type&& other) noexcept
: val_(cuda::std::exchange(other.val_, -1))
{}

__device__ device_only_type& operator=(const device_only_type& other) noexcept
{
val_ = other.val_;
return *this;
}

__device__ device_only_type& operator=(device_only_type&& other) noexcept

{
val_ = cuda::std::exchange(other.val_, -1);
return *this;
}

__device__ ~device_only_type() noexcept {}

__device__ friend bool operator==(const device_only_type& lhs, const device_only_type& rhs) noexcept
{
return lhs.val_ == rhs.val_;
}
__device__ friend bool operator!=(const device_only_type& lhs, const device_only_type& rhs) noexcept
{
return lhs.val_ != rhs.val_;
}
__device__ friend bool operator<(const device_only_type& lhs, const device_only_type& rhs) noexcept
{
return lhs.val_ < rhs.val_;
}
__device__ friend bool operator<=(const device_only_type& lhs, const device_only_type& rhs) noexcept
{
return lhs.val_ <= rhs.val_;
}
__device__ friend bool operator>(const device_only_type& lhs, const device_only_type& rhs) noexcept
{
return lhs.val_ > rhs.val_;
}
__device__ friend bool operator>=(const device_only_type& lhs, const device_only_type& rhs) noexcept
{
return lhs.val_ >= rhs.val_;
}

__device__ void swap(device_only_type& other) noexcept
{
cuda::std::swap(val_, other.val_);
}
};

__device__ void test()
{
using optional = cuda::std::optional<device_only_type>;
{ // default construction
optional default_constructed{};
assert(!default_constructed.has_value());
}

{ // in_place zero initialization
optional in_place_zero_initialization{cuda::std::in_place};
assert(in_place_zero_initialization.has_value());
assert(*in_place_zero_initialization == 0);
}

{ // in_place initialization
optional in_place_initialization{cuda::std::in_place, 42};
assert(in_place_initialization.has_value());
assert(*in_place_initialization == 42);
}

{ // value initialization
optional value_initialization{42};
assert(value_initialization.has_value());
assert(*value_initialization == 42);
}

{ // copy construction
optional input{42};
optional dest{input};
assert(dest.has_value());
assert(*dest == 42);
}

{ // move construction
optional input{42};
optional dest{cuda::std::move(input)};
assert(dest.has_value());
assert(*dest == 42);
}

{ // assignment, value to value
optional input{42};
optional dest{1337};
dest = input;
assert(dest.has_value());
assert(*dest == 42);
}

{ // assignment, value to empty
optional input{42};
optional dest{};
dest = input;
assert(dest.has_value());
assert(*dest == 42);
}

{ // assignment, empty to value
optional input{};
optional dest{1337};
dest = input;
assert(!dest.has_value());
}

{ // assignment, empty to empty
optional input{};
optional dest{};
dest = input;
assert(!dest.has_value());
}

{ // comparison with optional
optional lhs{42};
optional rhs{1337};
assert(!(lhs == rhs));
assert(lhs != rhs);
assert(lhs < rhs);
assert(lhs <= rhs);
assert(!(lhs > rhs));
assert(!(lhs >= rhs));
}

{ // comparison with type
optional opt{42};
assert(opt == device_only_type{42});
assert(device_only_type{42} == opt);
assert(opt != device_only_type{1337});
assert(device_only_type{1337} != opt);

assert(opt < device_only_type{1337});
assert(device_only_type{7} < opt);
assert(opt <= device_only_type{1337});
assert(device_only_type{7} <= opt);

assert(opt > device_only_type{7});
assert(device_only_type{1337} > opt);
assert(opt >= device_only_type{7});
assert(device_only_type{1337} >= opt);
}

{ // swap
optional lhs{42};
optional rhs{1337};
lhs.swap(rhs);
assert(*lhs == 1337);
assert(*rhs == 42);

swap(lhs, rhs);
assert(*lhs == 42);
assert(*rhs == 1337);
}
}

int main(int arg, char** argv)
{
NV_IF_TARGET(NV_IS_DEVICE, (test();))
return 0;
}
Loading