triviality.pass.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. // UNSUPPORTED: c++98, c++03, c++11, c++14, c++17
  9. // <optional>
  10. // The following special member functions should propagate the triviality of
  11. // the element held in the optional (see P0602R4):
  12. //
  13. // constexpr optional(const optional& rhs);
  14. // constexpr optional(optional&& rhs) noexcept(see below);
  15. // constexpr optional<T>& operator=(const optional& rhs);
  16. // constexpr optional<T>& operator=(optional&& rhs) noexcept(see below);
  17. #include <optional>
  18. #include <type_traits>
  19. #include "archetypes.h"
  20. #include "test_macros.h"
  21. constexpr bool implies(bool p, bool q) {
  22. return !p || q;
  23. }
  24. template <class T>
  25. struct SpecialMemberTest {
  26. using O = std::optional<T>;
  27. static_assert(implies(std::is_trivially_copy_constructible_v<T>,
  28. std::is_trivially_copy_constructible_v<O>),
  29. "optional<T> is trivially copy constructible if T is trivially copy constructible.");
  30. static_assert(implies(std::is_trivially_move_constructible_v<T>,
  31. std::is_trivially_move_constructible_v<O>),
  32. "optional<T> is trivially move constructible if T is trivially move constructible");
  33. static_assert(implies(std::is_trivially_copy_constructible_v<T> &&
  34. std::is_trivially_copy_assignable_v<T> &&
  35. std::is_trivially_destructible_v<T>,
  36. std::is_trivially_copy_assignable_v<O>),
  37. "optional<T> is trivially copy assignable if T is "
  38. "trivially copy constructible, "
  39. "trivially copy assignable, and "
  40. "trivially destructible");
  41. static_assert(implies(std::is_trivially_move_constructible_v<T> &&
  42. std::is_trivially_move_assignable_v<T> &&
  43. std::is_trivially_destructible_v<T>,
  44. std::is_trivially_move_assignable_v<O>),
  45. "optional<T> is trivially move assignable if T is "
  46. "trivially move constructible, "
  47. "trivially move assignable, and"
  48. "trivially destructible.");
  49. };
  50. template <class ...Args> static void sink(Args&&...) {}
  51. template <class ...TestTypes>
  52. struct DoTestsMetafunction {
  53. DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
  54. };
  55. struct TrivialMoveNonTrivialCopy {
  56. TrivialMoveNonTrivialCopy() = default;
  57. TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {}
  58. TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default;
  59. TrivialMoveNonTrivialCopy& operator=(const TrivialMoveNonTrivialCopy&) { return *this; }
  60. TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) = default;
  61. };
  62. struct TrivialCopyNonTrivialMove {
  63. TrivialCopyNonTrivialMove() = default;
  64. TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) = default;
  65. TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {}
  66. TrivialCopyNonTrivialMove& operator=(const TrivialCopyNonTrivialMove&) = default;
  67. TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) { return *this; }
  68. };
  69. int main(int, char**) {
  70. sink(
  71. ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
  72. ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
  73. NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
  74. NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{},
  75. DoTestsMetafunction<TrivialMoveNonTrivialCopy, TrivialCopyNonTrivialMove>{}
  76. );
  77. return 0;
  78. }