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 // <deque> 11 12 // void push_back(const value_type& x); 13 14 #include <deque> 15 #include "test_allocator.h" 16 #include <cassert> 17 18 // Flag that makes the copy constructor for CMyClass throw an exception 19 static bool gCopyConstructorShouldThow = false; 20 21 class CMyClass { 22 public: CMyClass(int tag); 23 public: CMyClass(const CMyClass& iOther); 24 public: ~CMyClass(); 25 26 bool equal(const CMyClass &rhs) const 27 { return fTag == rhs.fTag && fMagicValue == rhs.fMagicValue; } 28 29 private: 30 int fMagicValue; 31 int fTag; 32 33 private: static int kStartedConstructionMagicValue; 34 private: static int kFinishedConstructionMagicValue; 35 }; 36 37 // Value for fMagicValue when the constructor has started running, but not yet finished 38 int CMyClass::kStartedConstructionMagicValue = 0; 39 // Value for fMagicValue when the constructor has finished running 40 int CMyClass::kFinishedConstructionMagicValue = 12345; 41 42 CMyClass::CMyClass(int tag) : 43 fMagicValue(kStartedConstructionMagicValue), fTag(tag) 44 { 45 // Signal that the constructor has finished running 46 fMagicValue = kFinishedConstructionMagicValue; 47 } 48 49 CMyClass::CMyClass(const CMyClass& iOther) : 50 fMagicValue(kStartedConstructionMagicValue), fTag(iOther.fTag) 51 { 52 // If requested, throw an exception _before_ setting fMagicValue to kFinishedConstructionMagicValue 53 if (gCopyConstructorShouldThow) { 54 throw std::exception(); 55 } 56 // Signal that the constructor has finished running 57 fMagicValue = kFinishedConstructionMagicValue; 58 } 59 60 CMyClass::~CMyClass() { 61 // Only instances for which the constructor has finished running should be destructed 62 assert(fMagicValue == kFinishedConstructionMagicValue); 63 } 64 65 bool operator==(const CMyClass &lhs, const CMyClass &rhs) { return lhs.equal(rhs); } 66 67 int main() 68 { 69 CMyClass instance(42); 70 { 71 std::deque<CMyClass> vec; 72 73 vec.push_back(instance); 74 std::deque<CMyClass> vec2(vec); 75 76 gCopyConstructorShouldThow = true; 77 try { 78 vec.push_back(instance); 79 assert(false); 80 } 81 catch (...) { 82 gCopyConstructorShouldThow = false; 83 assert(vec==vec2); 84 } 85 } 86 87 { 88 typedef std::deque<CMyClass, test_allocator<CMyClass> > C; 89 C vec; 90 C vec2(vec); 91 92 C::allocator_type::throw_after = 1; 93 try { 94 vec.push_back(instance); 95 assert(false); 96 } 97 catch (...) { 98 assert(vec==vec2); 99 } 100 } 101 } 102