aboutsummaryrefslogtreecommitdiffstats
path: root/src/catch2/benchmark/catch_constructor.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/catch2/benchmark/catch_constructor.hpp')
-rw-r--r--src/catch2/benchmark/catch_constructor.hpp82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/catch2/benchmark/catch_constructor.hpp b/src/catch2/benchmark/catch_constructor.hpp
new file mode 100644
index 0000000..853bd6c
--- /dev/null
+++ b/src/catch2/benchmark/catch_constructor.hpp
@@ -0,0 +1,82 @@
+
+// Copyright Catch2 Authors
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+// SPDX-License-Identifier: BSL-1.0
+// Adapted from donated nonius code.
+
+#ifndef CATCH_CONSTRUCTOR_HPP_INCLUDED
+#define CATCH_CONSTRUCTOR_HPP_INCLUDED
+
+#include <catch2/internal/catch_move_and_forward.hpp>
+
+#include <type_traits>
+
+namespace Catch {
+ namespace Benchmark {
+ namespace Detail {
+ template <typename T, bool Destruct>
+ struct ObjectStorage
+ {
+ ObjectStorage() = default;
+
+ ObjectStorage(const ObjectStorage& other)
+ {
+ new(&data) T(other.stored_object());
+ }
+
+ ObjectStorage(ObjectStorage&& other)
+ {
+ new(data) T(CATCH_MOVE(other.stored_object()));
+ }
+
+ ~ObjectStorage() { destruct_on_exit<T>(); }
+
+ template <typename... Args>
+ void construct(Args&&... args)
+ {
+ new (data) T(CATCH_FORWARD(args)...);
+ }
+
+ template <bool AllowManualDestruction = !Destruct>
+ std::enable_if_t<AllowManualDestruction> destruct()
+ {
+ stored_object().~T();
+ }
+
+ private:
+ // If this is a constructor benchmark, destruct the underlying object
+ template <typename U>
+ void destruct_on_exit(std::enable_if_t<Destruct, U>* = nullptr) { destruct<true>(); }
+ // Otherwise, don't
+ template <typename U>
+ void destruct_on_exit(std::enable_if_t<!Destruct, U>* = nullptr) { }
+
+#if defined( __GNUC__ ) && __GNUC__ <= 6
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#endif
+ T& stored_object() { return *reinterpret_cast<T*>( data ); }
+
+ T const& stored_object() const {
+ return *reinterpret_cast<T const*>( data );
+ }
+#if defined( __GNUC__ ) && __GNUC__ <= 6
+# pragma GCC diagnostic pop
+#endif
+
+ alignas( T ) unsigned char data[sizeof( T )]{};
+ };
+ } // namespace Detail
+
+ template <typename T>
+ using storage_for = Detail::ObjectStorage<T, true>;
+
+ template <typename T>
+ using destructable_object = Detail::ObjectStorage<T, false>;
+ } // namespace Benchmark
+} // namespace Catch
+
+#endif // CATCH_CONSTRUCTOR_HPP_INCLUDED