catch2/include/internal/benchmark/catch_constructor.hpp
Marc Mutz ca455815fd ObjectStorage: port away from std::aligned_storage
It's deprecated in C++23. Just use alignas on a char array, wrapped in
a struct to avoid decaying to char*, which is the canonical
implementation of aligned_storage:
https://en.cppreference.com/w/cpp/types/aligned_storage#Possible_implementation

Fixes #2419

Catch3 is not affected.
2022-05-10 00:06:45 +02:00

78 lines
2.4 KiB
C++

/*
* Created by Joachim on 16/04/2019.
* Adapted from donated nonius code.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
// Constructor and destructor helpers
#ifndef TWOBLUECUBES_CATCH_CONSTRUCTOR_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_CONSTRUCTOR_HPP_INCLUDED
#include <type_traits>
namespace Catch {
namespace Benchmark {
namespace Detail {
template <typename T, bool Destruct>
struct ObjectStorage
{
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<T>(); }
template <typename... Args>
void construct(Args&&... args)
{
new (&data) T(std::forward<Args>(args)...);
}
template <bool AllowManualDestruction = !Destruct>
typename std::enable_if<AllowManualDestruction>::type destruct()
{
stored_object().~T();
}
private:
// If this is a constructor benchmark, destruct the underlying object
template <typename U>
void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
// Otherwise, don't
template <typename U>
void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
T& stored_object() {
return *static_cast<T*>(static_cast<void*>(&data));
}
T const& stored_object() const {
return *static_cast<T*>(static_cast<void*>(&data));
}
struct { alignas(T) unsigned char data[sizeof(T)]; } data;
};
}
template <typename T>
using storage_for = Detail::ObjectStorage<T, true>;
template <typename T>
using destructable_object = Detail::ObjectStorage<T, false>;
}
}
#endif // TWOBLUECUBES_CATCH_CONSTRUCTOR_HPP_INCLUDED