variant_test_helpers.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // -*- C++ -*-
  2. //===----------------------------------------------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef SUPPORT_VARIANT_TEST_HELPERS_H
  10. #define SUPPORT_VARIANT_TEST_HELPERS_H
  11. #include <type_traits>
  12. #include <utility>
  13. #include <cassert>
  14. #include "test_macros.h"
  15. #if TEST_STD_VER <= 14
  16. #error This file requires C++17
  17. #endif
  18. // FIXME: Currently the variant<T&> tests are disabled using this macro.
  19. #define TEST_VARIANT_HAS_NO_REFERENCES
  20. #ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT
  21. # define TEST_VARIANT_ALLOWS_NARROWING_CONVERSIONS
  22. #endif
  23. #ifdef TEST_VARIANT_ALLOWS_NARROWING_CONVERSIONS
  24. constexpr bool VariantAllowsNarrowingConversions = true;
  25. #else
  26. constexpr bool VariantAllowsNarrowingConversions = false;
  27. #endif
  28. #ifndef TEST_HAS_NO_EXCEPTIONS
  29. struct CopyThrows {
  30. CopyThrows() = default;
  31. CopyThrows(CopyThrows const&) { throw 42; }
  32. CopyThrows& operator=(CopyThrows const&) { throw 42; }
  33. };
  34. struct MoveThrows {
  35. static int alive;
  36. MoveThrows() { ++alive; }
  37. MoveThrows(MoveThrows const&) {++alive;}
  38. MoveThrows(MoveThrows&&) { throw 42; }
  39. MoveThrows& operator=(MoveThrows const&) { return *this; }
  40. MoveThrows& operator=(MoveThrows&&) { throw 42; }
  41. ~MoveThrows() { --alive; }
  42. };
  43. int MoveThrows::alive = 0;
  44. struct MakeEmptyT {
  45. static int alive;
  46. MakeEmptyT() { ++alive; }
  47. MakeEmptyT(MakeEmptyT const&) {
  48. ++alive;
  49. // Don't throw from the copy constructor since variant's assignment
  50. // operator performs a copy before committing to the assignment.
  51. }
  52. MakeEmptyT(MakeEmptyT &&) {
  53. throw 42;
  54. }
  55. MakeEmptyT& operator=(MakeEmptyT const&) {
  56. throw 42;
  57. }
  58. MakeEmptyT& operator=(MakeEmptyT&&) {
  59. throw 42;
  60. }
  61. ~MakeEmptyT() { --alive; }
  62. };
  63. static_assert(std::is_swappable_v<MakeEmptyT>, ""); // required for test
  64. int MakeEmptyT::alive = 0;
  65. template <class Variant>
  66. void makeEmpty(Variant& v) {
  67. Variant v2(std::in_place_type<MakeEmptyT>);
  68. try {
  69. v = std::move(v2);
  70. assert(false);
  71. } catch (...) {
  72. assert(v.valueless_by_exception());
  73. }
  74. }
  75. #endif // TEST_HAS_NO_EXCEPTIONS
  76. #endif // SUPPORT_VARIANT_TEST_HELPERS_H