// 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 #include namespace Catch { namespace Benchmark { namespace Detail { template 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(); } template void construct(Args&&... args) { new (data) T(CATCH_FORWARD(args)...); } template std::enable_if_t destruct() { stored_object().~T(); } private: // If this is a constructor benchmark, destruct the underlying object template void destruct_on_exit(std::enable_if_t* = nullptr) { destruct(); } // Otherwise, don't template void destruct_on_exit(std::enable_if_t* = nullptr) { } #if defined( __GNUC__ ) && __GNUC__ <= 6 # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif T& stored_object() { return *reinterpret_cast( data ); } T const& stored_object() const { return *reinterpret_cast( data ); } #if defined( __GNUC__ ) && __GNUC__ <= 6 # pragma GCC diagnostic pop #endif alignas( T ) unsigned char data[sizeof( T )]{}; }; } // namespace Detail template using storage_for = Detail::ObjectStorage; template using destructable_object = Detail::ObjectStorage; } // namespace Benchmark } // namespace Catch #endif // CATCH_CONSTRUCTOR_HPP_INCLUDED