1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#include "BLI_memory_utils.hh"
#include "BLI_strict_flags.h"
#include "testing/testing.h"
namespace blender {
struct MyValue {
static inline int alive = 0;
MyValue()
{
if (alive == 15) {
throw std::exception();
}
alive++;
}
MyValue(const MyValue &other)
{
if (alive == 15) {
throw std::exception();
}
alive++;
}
~MyValue()
{
alive--;
}
};
TEST(memory_utils, DefaultConstructN_ActuallyCallsConstructor)
{
constexpr int amount = 10;
TypedBuffer<MyValue, amount> buffer;
EXPECT_EQ(MyValue::alive, 0);
default_construct_n(buffer.ptr(), amount);
EXPECT_EQ(MyValue::alive, amount);
destruct_n(buffer.ptr(), amount);
EXPECT_EQ(MyValue::alive, 0);
}
TEST(memory_utils, DefaultConstructN_StrongExceptionSafety)
{
constexpr int amount = 20;
TypedBuffer<MyValue, amount> buffer;
EXPECT_EQ(MyValue::alive, 0);
EXPECT_THROW(default_construct_n(buffer.ptr(), amount), std::exception);
EXPECT_EQ(MyValue::alive, 0);
}
TEST(memory_utils, UninitializedCopyN_ActuallyCopies)
{
constexpr int amount = 5;
TypedBuffer<MyValue, amount> buffer1;
TypedBuffer<MyValue, amount> buffer2;
EXPECT_EQ(MyValue::alive, 0);
default_construct_n(buffer1.ptr(), amount);
EXPECT_EQ(MyValue::alive, amount);
uninitialized_copy_n(buffer1.ptr(), amount, buffer2.ptr());
EXPECT_EQ(MyValue::alive, 2 * amount);
destruct_n(buffer1.ptr(), amount);
EXPECT_EQ(MyValue::alive, amount);
destruct_n(buffer2.ptr(), amount);
EXPECT_EQ(MyValue::alive, 0);
}
TEST(memory_utils, UninitializedCopyN_StrongExceptionSafety)
{
constexpr int amount = 10;
TypedBuffer<MyValue, amount> buffer1;
TypedBuffer<MyValue, amount> buffer2;
EXPECT_EQ(MyValue::alive, 0);
default_construct_n(buffer1.ptr(), amount);
EXPECT_EQ(MyValue::alive, amount);
EXPECT_THROW(uninitialized_copy_n(buffer1.ptr(), amount, buffer2.ptr()), std::exception);
EXPECT_EQ(MyValue::alive, amount);
destruct_n(buffer1.ptr(), amount);
EXPECT_EQ(MyValue::alive, 0);
}
TEST(memory_utils, UninitializedFillN_ActuallyCopies)
{
constexpr int amount = 10;
TypedBuffer<MyValue, amount> buffer;
EXPECT_EQ(MyValue::alive, 0);
{
MyValue value;
EXPECT_EQ(MyValue::alive, 1);
uninitialized_fill_n(buffer.ptr(), amount, value);
EXPECT_EQ(MyValue::alive, 1 + amount);
destruct_n(buffer.ptr(), amount);
EXPECT_EQ(MyValue::alive, 1);
}
EXPECT_EQ(MyValue::alive, 0);
}
TEST(memory_utils, UninitializedFillN_StrongExceptionSafety)
{
constexpr int amount = 20;
TypedBuffer<MyValue, amount> buffer;
EXPECT_EQ(MyValue::alive, 0);
{
MyValue value;
EXPECT_EQ(MyValue::alive, 1);
EXPECT_THROW(uninitialized_fill_n(buffer.ptr(), amount, value), std::exception);
EXPECT_EQ(MyValue::alive, 1);
}
EXPECT_EQ(MyValue::alive, 0);
}
} // namespace blender
|