| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| |
|
| | #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 |
| | { |
| | using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::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<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: |
| | |
| | template <typename U> |
| | void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); } |
| | |
| | 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)); |
| | } |
| |
|
| |
|
| | TStorage data; |
| | }; |
| | } |
| |
|
| | template <typename T> |
| | using storage_for = Detail::ObjectStorage<T, true>; |
| |
|
| | template <typename T> |
| | using destructable_object = Detail::ObjectStorage<T, false>; |
| | } |
| | } |
| |
|
| | #endif |
| |
|