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)69void 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