Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2020-09-01 20:35:14 +0300
committerHans Goudey <h.goudey@me.com>2020-09-01 20:38:05 +0300
commitbaca8611e5fe4b3dcd6f5065fb125bc0a9d65934 (patch)
treebb1230387cd53b15f9621f10c4d0e5e2050b5580 /source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh
parent31705201dddebf7e3be5c4533b89f380aad1ede1 (diff)
parent2930d4fcea405985f2212c5f28c061af7c4849f8 (diff)
Merge branch 'master' into active-fcurve-keyframeactive-fcurve-keyframe
Diffstat (limited to 'source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh')
-rw-r--r--source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh102
1 files changed, 102 insertions, 0 deletions
diff --git a/source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh b/source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh
new file mode 100644
index 00000000000..91270767a25
--- /dev/null
+++ b/source/blender/blenlib/tests/BLI_exception_safety_test_utils.hh
@@ -0,0 +1,102 @@
+#include "BLI_hash.hh"
+#include "BLI_utildefines.h"
+#include "MEM_guardedalloc.h"
+#include "testing/testing.h"
+
+namespace blender::tests {
+
+class ExceptionThrower {
+ private:
+ /* Use some random values that are unlikely to exist at the memory location already. */
+ static constexpr uint32_t is_alive_state = 0x21254634;
+ static constexpr uint32_t is_destructed_state = 0xFA4BC327;
+
+ uint32_t state_;
+
+ /* Make use of leak detector to check if this value has been destructed. */
+ void *my_memory_;
+
+ public:
+ mutable bool throw_during_copy;
+ mutable bool throw_during_move;
+ /* Used for hashing and comparing. */
+ int value;
+
+ ExceptionThrower(int value = 0)
+ : state_(is_alive_state),
+ my_memory_(MEM_mallocN(1, AT)),
+ throw_during_copy(false),
+ throw_during_move(false),
+ value(value)
+ {
+ }
+
+ ExceptionThrower(const ExceptionThrower &other) : ExceptionThrower(other.value)
+ {
+ EXPECT_EQ(other.state_, is_alive_state);
+ if (other.throw_during_copy) {
+ throw std::runtime_error("throwing during copy, as requested");
+ }
+ }
+
+ ExceptionThrower(ExceptionThrower &&other) : ExceptionThrower(other.value)
+ {
+ EXPECT_EQ(other.state_, is_alive_state);
+ if (other.throw_during_move) {
+ throw std::runtime_error("throwing during move, as requested");
+ }
+ }
+
+ ExceptionThrower &operator=(const ExceptionThrower &other)
+ {
+ EXPECT_EQ(other.state_, is_alive_state);
+ if (throw_during_copy || other.throw_during_copy) {
+ throw std::runtime_error("throwing during copy, as requested");
+ }
+ value = other.value;
+ return *this;
+ }
+
+ ExceptionThrower &operator=(ExceptionThrower &&other)
+ {
+ EXPECT_EQ(other.state_, is_alive_state);
+ if (throw_during_move || other.throw_during_move) {
+ throw std::runtime_error("throwing during move, as requested");
+ }
+ value = other.value;
+ return *this;
+ }
+
+ ~ExceptionThrower()
+ {
+ const char *message = "";
+ if (state_ != is_alive_state) {
+ if (state_ == is_destructed_state) {
+ message = "Trying to destruct an already destructed instance.";
+ }
+ else {
+ message = "Trying to destruct an uninitialized instance.";
+ }
+ }
+ EXPECT_EQ(state_, is_alive_state) << message;
+ state_ = is_destructed_state;
+ MEM_freeN(my_memory_);
+ }
+
+ uint64_t hash() const
+ {
+ return static_cast<uint64_t>(value);
+ }
+
+ friend bool operator==(const ExceptionThrower &a, const ExceptionThrower &b)
+ {
+ return a.value == b.value;
+ }
+
+ friend bool operator!=(const ExceptionThrower &a, const ExceptionThrower &b)
+ {
+ return !(a == b);
+ }
+};
+
+} // namespace blender::tests