libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

triviality.pass.cpp (3702B)


      1 //===----------------------------------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
     11 
     12 // <optional>
     13 
     14 // The following special member functions should propagate the triviality of
     15 // the element held in the optional (see P0602R4):
     16 //
     17 // constexpr optional(const optional& rhs);
     18 // constexpr optional(optional&& rhs) noexcept(see below);
     19 // constexpr optional<T>& operator=(const optional& rhs);
     20 // constexpr optional<T>& operator=(optional&& rhs) noexcept(see below);
     21 
     22 
     23 #include <optional>
     24 #include <type_traits>
     25 
     26 #include "archetypes.hpp"
     27 
     28 
     29 constexpr bool implies(bool p, bool q) {
     30     return !p || q;
     31 }
     32 
     33 template <class T>
     34 struct SpecialMemberTest {
     35     using O = std::optional<T>;
     36 
     37     static_assert(implies(std::is_trivially_copy_constructible_v<T>,
     38                           std::is_trivially_copy_constructible_v<O>),
     39         "optional<T> is trivially copy constructible if T is trivially copy constructible.");
     40 
     41     static_assert(implies(std::is_trivially_move_constructible_v<T>,
     42                           std::is_trivially_move_constructible_v<O>),
     43         "optional<T> is trivially move constructible if T is trivially move constructible");
     44 
     45     static_assert(implies(std::is_trivially_copy_constructible_v<T> &&
     46                           std::is_trivially_copy_assignable_v<T> &&
     47                           std::is_trivially_destructible_v<T>,
     48 
     49                           std::is_trivially_copy_assignable_v<O>),
     50         "optional<T> is trivially copy assignable if T is "
     51         "trivially copy constructible, "
     52         "trivially copy assignable, and "
     53         "trivially destructible");
     54 
     55     static_assert(implies(std::is_trivially_move_constructible_v<T> &&
     56                           std::is_trivially_move_assignable_v<T> &&
     57                           std::is_trivially_destructible_v<T>,
     58 
     59                           std::is_trivially_move_assignable_v<O>),
     60         "optional<T> is trivially move assignable if T is "
     61         "trivially move constructible, "
     62         "trivially move assignable, and"
     63         "trivially destructible.");
     64 };
     65 
     66 template <class ...Args> static void sink(Args&&...) {}
     67 
     68 template <class ...TestTypes>
     69 struct DoTestsMetafunction {
     70     DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
     71 };
     72 
     73 struct TrivialMoveNonTrivialCopy {
     74     TrivialMoveNonTrivialCopy() = default;
     75     TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {}
     76     TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default;
     77     TrivialMoveNonTrivialCopy& operator=(const TrivialMoveNonTrivialCopy&) { return *this; }
     78     TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) = default;
     79 };
     80 
     81 struct TrivialCopyNonTrivialMove {
     82     TrivialCopyNonTrivialMove() = default;
     83     TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) = default;
     84     TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {}
     85     TrivialCopyNonTrivialMove& operator=(const TrivialCopyNonTrivialMove&) = default;
     86     TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) { return *this; }
     87 };
     88 
     89 int main() {
     90     sink(
     91         ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
     92         ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
     93         NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
     94         NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{},
     95         DoTestsMetafunction<TrivialMoveNonTrivialCopy, TrivialCopyNonTrivialMove>{}
     96     );
     97 }