// Copyright Catch2 Authors // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.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 namespace Catch { namespace Benchmark { namespace Detail { template struct ObjectStorage { using TStorage = typename std::aligned_storage::value>::type; ObjectStorage() : data() {} ObjectStorage(const ObjectStorage& other) { new(&data) T(other.stored_object()); } ObjectStorage(ObjectStorage&& other) { new(&data) T(std::move(other.stored_object())); } ~ObjectStorage() { destruct_on_exit(); } template void construct(Args&&... args) { new (&data) T(std::forward(args)...); } template typename std::enable_if::type destruct() { stored_object().~T(); } private: // If this is a constructor benchmark, destruct the underlying object template void destruct_on_exit(typename std::enable_if::type* = 0) { destruct(); } // Otherwise, don't template void destruct_on_exit(typename std::enable_if::type* = 0) { } T& stored_object() { return *static_cast(static_cast(&data)); } T const& stored_object() const { return *static_cast(static_cast(&data)); } TStorage data; }; } // namespace Detail template using storage_for = Detail::ObjectStorage; template using destructable_object = Detail::ObjectStorage; } // namespace Benchmark } // namespace Catch #endif // CATCH_CONSTRUCTOR_HPP_INCLUDED