//===----------------------------------------------------------------------===// // // 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. // //===----------------------------------------------------------------------===// // // The following special member functions should propagate the triviality of // the element held in the optional (see P0602R4): // // constexpr optional(const optional& rhs); // constexpr optional(optional&& rhs) noexcept(see below); // constexpr optional& operator=(const optional& rhs); // constexpr optional& operator=(optional&& rhs) noexcept(see below); #include #include #if !defined(_CCCL_BUILTIN_ADDRESSOF) # define TEST_WORKAROUND_NO_ADDRESSOF #endif #include "archetypes.h" #include "test_macros.h" __host__ __device__ constexpr bool implies(bool p, bool q) { return !p || q; } template struct SpecialMemberTest { using O = cuda::std::optional; static_assert(implies(cuda::std::is_trivially_copy_constructible_v, cuda::std::is_trivially_copy_constructible_v), "optional is trivially copy constructible if T is trivially copy constructible."); static_assert(implies(cuda::std::is_trivially_move_constructible_v, cuda::std::is_trivially_move_constructible_v), "optional is trivially move constructible if T is trivially move constructible"); static_assert(implies(cuda::std::is_trivially_copy_constructible_v && cuda::std::is_trivially_copy_assignable_v && cuda::std::is_trivially_destructible_v, cuda::std::is_trivially_copy_assignable_v), "optional is trivially copy assignable if T is " "trivially copy constructible, " "trivially copy assignable, and " "trivially destructible"); static_assert(implies(cuda::std::is_trivially_move_constructible_v && cuda::std::is_trivially_move_assignable_v && cuda::std::is_trivially_destructible_v, cuda::std::is_trivially_move_assignable_v), "optional is trivially move assignable if T is " "trivially move constructible, " "trivially move assignable, and" "trivially destructible."); using ORef = cuda::std::optional; static_assert(cuda::std::is_trivially_copy_constructible_v, "optional is trivially copy constructible."); static_assert(cuda::std::is_trivially_move_constructible_v, "optional is trivially move constructible."); static_assert(cuda::std::is_trivially_copy_assignable_v, "optional is trivially copy assignable."); static_assert(cuda::std::is_trivially_move_assignable_v, "optional is trivially move assignable."); }; template __host__ __device__ static void sink(Args&&...) {} template struct DoTestsMetafunction { __host__ __device__ DoTestsMetafunction() { sink(SpecialMemberTest{}...); } }; struct TrivialMoveNonTrivialCopy { TrivialMoveNonTrivialCopy() = default; __host__ __device__ TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {} TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default; __host__ __device__ TrivialMoveNonTrivialCopy& operator=(const TrivialMoveNonTrivialCopy&) { return *this; } TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) = default; }; struct TrivialCopyNonTrivialMove { TrivialCopyNonTrivialMove() = default; TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) = default; __host__ __device__ TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {} TrivialCopyNonTrivialMove& operator=(const TrivialCopyNonTrivialMove&) = default; __host__ __device__ TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) { return *this; } }; int main(int, char**) { sink(ImplicitTypes::ApplyTypes{}, ExplicitTypes::ApplyTypes{}, NonLiteralTypes::ApplyTypes{}, NonTrivialTypes::ApplyTypes{}, DoTestsMetafunction{}); return 0; }