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

source code of libcxx/test/std/containers/sequences/deque/deque.modifiers/push_front_exception_safety.pass.cpp