• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 #ifndef SUPPORT_VARIANT_TEST_HELPERS_HPP
11 #define SUPPORT_VARIANT_TEST_HELPERS_HPP
12 
13 #include <type_traits>
14 #include <utility>
15 #include <cassert>
16 
17 #include "test_macros.h"
18 
19 #if TEST_STD_VER <= 14
20 #error This file requires C++17
21 #endif
22 
23 // FIXME: Currently the variant<T&> tests are disabled using this macro.
24 #define TEST_VARIANT_HAS_NO_REFERENCES
25 
26 #ifndef TEST_HAS_NO_EXCEPTIONS
27 struct CopyThrows {
28   CopyThrows() = default;
CopyThrowsCopyThrows29   CopyThrows(CopyThrows const&) { throw 42; }
operator =CopyThrows30   CopyThrows& operator=(CopyThrows const&) { throw 42; }
31 };
32 
33 struct MoveThrows {
34   static int alive;
MoveThrowsMoveThrows35   MoveThrows() { ++alive; }
MoveThrowsMoveThrows36   MoveThrows(MoveThrows const&) {++alive;}
MoveThrowsMoveThrows37   MoveThrows(MoveThrows&&) {  throw 42; }
operator =MoveThrows38   MoveThrows& operator=(MoveThrows const&) { return *this; }
operator =MoveThrows39   MoveThrows& operator=(MoveThrows&&) { throw 42; }
~MoveThrowsMoveThrows40   ~MoveThrows() { --alive; }
41 };
42 
43 int MoveThrows::alive = 0;
44 
45 struct MakeEmptyT {
46   static int alive;
MakeEmptyTMakeEmptyT47   MakeEmptyT() { ++alive; }
MakeEmptyTMakeEmptyT48   MakeEmptyT(MakeEmptyT const&) {
49       ++alive;
50       // Don't throw from the copy constructor since variant's assignment
51       // operator performs a copy before committing to the assignment.
52   }
MakeEmptyTMakeEmptyT53   MakeEmptyT(MakeEmptyT &&) {
54       throw 42;
55   }
operator =MakeEmptyT56   MakeEmptyT& operator=(MakeEmptyT const&) {
57       throw 42;
58   }
operator =MakeEmptyT59   MakeEmptyT& operator=(MakeEmptyT&&) {
60       throw 42;
61   }
~MakeEmptyTMakeEmptyT62    ~MakeEmptyT() { --alive; }
63 };
64 static_assert(std::is_swappable_v<MakeEmptyT>, ""); // required for test
65 
66 int MakeEmptyT::alive = 0;
67 
68 template <class Variant>
makeEmpty(Variant & v)69 void makeEmpty(Variant& v) {
70     Variant v2(std::in_place_type<MakeEmptyT>);
71     try {
72         v = std::move(v2);
73         assert(false);
74     } catch (...) {
75         assert(v.valueless_by_exception());
76     }
77 }
78 #endif // TEST_HAS_NO_EXCEPTIONS
79 
80 
81 #endif // SUPPORT_VARIANT_TEST_HELPERS_HPP
82