• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Created by Joachim on 16/04/2019.
3  *  Adapted from donated nonius code.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 
9 // Constructor and destructor helpers
10 
11 #ifndef TWOBLUECUBES_CATCH_CONSTRUCTOR_HPP_INCLUDED
12 #define TWOBLUECUBES_CATCH_CONSTRUCTOR_HPP_INCLUDED
13 
14 #include <type_traits>
15 
16 namespace Catch {
17     namespace Benchmark {
18         namespace Detail {
19             template <typename T, bool Destruct>
20             struct ObjectStorage
21             {
22                 using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
23 
ObjectStorageCatch::Benchmark::Detail::ObjectStorage24                 ObjectStorage() : data() {}
25 
ObjectStorageCatch::Benchmark::Detail::ObjectStorage26                 ObjectStorage(const ObjectStorage& other)
27                 {
28                     new(&data) T(other.stored_object());
29                 }
30 
ObjectStorageCatch::Benchmark::Detail::ObjectStorage31                 ObjectStorage(ObjectStorage&& other)
32                 {
33                     new(&data) T(std::move(other.stored_object()));
34                 }
35 
~ObjectStorageCatch::Benchmark::Detail::ObjectStorage36                 ~ObjectStorage() { destruct_on_exit<T>(); }
37 
38                 template <typename... Args>
constructCatch::Benchmark::Detail::ObjectStorage39                 void construct(Args&&... args)
40                 {
41                     new (&data) T(std::forward<Args>(args)...);
42                 }
43 
44                 template <bool AllowManualDestruction = !Destruct>
destructCatch::Benchmark::Detail::ObjectStorage45                 typename std::enable_if<AllowManualDestruction>::type destruct()
46                 {
47                     stored_object().~T();
48                 }
49 
50             private:
51                 // If this is a constructor benchmark, destruct the underlying object
52                 template <typename U>
destruct_on_exitCatch::Benchmark::Detail::ObjectStorage53                 void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
54                 // Otherwise, don't
55                 template <typename U>
destruct_on_exitCatch::Benchmark::Detail::ObjectStorage56                 void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
57 
stored_objectCatch::Benchmark::Detail::ObjectStorage58                 T& stored_object() {
59                     return *static_cast<T*>(static_cast<void*>(&data));
60                 }
61 
stored_objectCatch::Benchmark::Detail::ObjectStorage62                 T const& stored_object() const {
63                     return *static_cast<T*>(static_cast<void*>(&data));
64                 }
65 
66 
67                 TStorage data;
68             };
69         }
70 
71         template <typename T>
72         using storage_for = Detail::ObjectStorage<T, true>;
73 
74         template <typename T>
75         using destructable_object = Detail::ObjectStorage<T, false>;
76     }
77 }
78 
79 #endif // TWOBLUECUBES_CATCH_CONSTRUCTOR_HPP_INCLUDED
80