Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:02:48

0001 
0002 //              Copyright Catch2 Authors
0003 // Distributed under the Boost Software License, Version 1.0.
0004 //   (See accompanying file LICENSE.txt or copy at
0005 //        https://www.boost.org/LICENSE_1_0.txt)
0006 
0007 // SPDX-License-Identifier: BSL-1.0
0008 // Adapted from donated nonius code.
0009 
0010 #ifndef CATCH_CONSTRUCTOR_HPP_INCLUDED
0011 #define CATCH_CONSTRUCTOR_HPP_INCLUDED
0012 
0013 #include <catch2/internal/catch_move_and_forward.hpp>
0014 
0015 #include <type_traits>
0016 
0017 namespace Catch {
0018     namespace Benchmark {
0019         namespace Detail {
0020             template <typename T, bool Destruct>
0021             struct ObjectStorage
0022             {
0023                 ObjectStorage() = default;
0024 
0025                 ObjectStorage(const ObjectStorage& other)
0026                 {
0027                     new(&data) T(other.stored_object());
0028                 }
0029 
0030                 ObjectStorage(ObjectStorage&& other)
0031                 {
0032                     new(data) T(CATCH_MOVE(other.stored_object()));
0033                 }
0034 
0035                 ~ObjectStorage() { destruct_on_exit<T>(); }
0036 
0037                 template <typename... Args>
0038                 void construct(Args&&... args)
0039                 {
0040                     new (data) T(CATCH_FORWARD(args)...);
0041                 }
0042 
0043                 template <bool AllowManualDestruction = !Destruct>
0044                 std::enable_if_t<AllowManualDestruction> destruct()
0045                 {
0046                     stored_object().~T();
0047                 }
0048 
0049             private:
0050                 // If this is a constructor benchmark, destruct the underlying object
0051                 template <typename U>
0052                 void destruct_on_exit(std::enable_if_t<Destruct, U>* = nullptr) { destruct<true>(); }
0053                 // Otherwise, don't
0054                 template <typename U>
0055                 void destruct_on_exit(std::enable_if_t<!Destruct, U>* = nullptr) { }
0056 
0057 #if defined( __GNUC__ ) && __GNUC__ <= 6
0058 #    pragma GCC diagnostic push
0059 #    pragma GCC diagnostic ignored "-Wstrict-aliasing"
0060 #endif
0061                 T& stored_object() { return *reinterpret_cast<T*>( data ); }
0062 
0063                 T const& stored_object() const {
0064                     return *reinterpret_cast<T const*>( data );
0065                 }
0066 #if defined( __GNUC__ ) && __GNUC__ <= 6
0067 #    pragma GCC diagnostic pop
0068 #endif
0069 
0070                 alignas( T ) unsigned char data[sizeof( T )]{};
0071             };
0072         } // namespace Detail
0073 
0074         template <typename T>
0075         using storage_for = Detail::ObjectStorage<T, true>;
0076 
0077         template <typename T>
0078         using destructable_object = Detail::ObjectStorage<T, false>;
0079     } // namespace Benchmark
0080 } // namespace Catch
0081 
0082 #endif // CATCH_CONSTRUCTOR_HPP_INCLUDED