66 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410 11// <optional>12 13// Make sure we properly generate special member functions for optional<T>14// based on the properties of T itself.15 16#include <optional>17#include <type_traits>18 19#include "archetypes.h"20 21#include "test_macros.h"22 23 24template <class T>25struct SpecialMemberTest {26 using O = std::optional<T>;27 28 static_assert(std::is_default_constructible_v<O>,29 "optional is always default constructible.");30 31 static_assert(std::is_copy_constructible_v<O> == std::is_copy_constructible_v<T>,32 "optional<T> is copy constructible if and only if T is copy constructible.");33 34 static_assert(std::is_move_constructible_v<O> ==35 (std::is_copy_constructible_v<T> || std::is_move_constructible_v<T>),36 "optional<T> is move constructible if and only if T is copy or move constructible.");37 38 static_assert(std::is_copy_assignable_v<O> ==39 (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>),40 "optional<T> is copy assignable if and only if T is both copy "41 "constructible and copy assignable.");42 43 static_assert(std::is_move_assignable_v<O> ==44 ((std::is_move_constructible_v<T> && std::is_move_assignable_v<T>) ||45 (std::is_copy_constructible_v<T> && std::is_copy_assignable_v<T>)),46 "optional<T> is move assignable if and only if T is both move constructible and "47 "move assignable, or both copy constructible and copy assignable.");48};49 50template <class ...Args> static void sink(Args&&...) {}51 52template <class ...TestTypes>53struct DoTestsMetafunction {54 DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }55};56 57int main(int, char**) {58 sink(59 ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},60 ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},61 NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},62 NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{}63 );64 return 0;65}66