catch_constructor.hpp 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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. // Constructor and destructor helpers
  9. #ifndef TWOBLUECUBES_CATCH_CONSTRUCTOR_HPP_INCLUDED
  10. #define TWOBLUECUBES_CATCH_CONSTRUCTOR_HPP_INCLUDED
  11. #include <type_traits>
  12. namespace Catch {
  13. namespace Benchmark {
  14. namespace Detail {
  15. template <typename T, bool Destruct>
  16. struct ObjectStorage
  17. {
  18. using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
  19. ObjectStorage() : data() {}
  20. ObjectStorage(const ObjectStorage& other)
  21. {
  22. new(&data) T(other.stored_object());
  23. }
  24. ObjectStorage(ObjectStorage&& other)
  25. {
  26. new(&data) T(std::move(other.stored_object()));
  27. }
  28. ~ObjectStorage() { destruct_on_exit<T>(); }
  29. template <typename... Args>
  30. void construct(Args&&... args)
  31. {
  32. new (&data) T(std::forward<Args>(args)...);
  33. }
  34. template <bool AllowManualDestruction = !Destruct>
  35. typename std::enable_if<AllowManualDestruction>::type destruct()
  36. {
  37. stored_object().~T();
  38. }
  39. private:
  40. // If this is a constructor benchmark, destruct the underlying object
  41. template <typename U>
  42. void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }
  43. // Otherwise, don't
  44. template <typename U>
  45. void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }
  46. T& stored_object() {
  47. return *static_cast<T*>(static_cast<void*>(&data));
  48. }
  49. T const& stored_object() const {
  50. return *static_cast<T*>(static_cast<void*>(&data));
  51. }
  52. TStorage data;
  53. };
  54. }
  55. template <typename T>
  56. using storage_for = Detail::ObjectStorage<T, true>;
  57. template <typename T>
  58. using destructable_object = Detail::ObjectStorage<T, false>;
  59. }
  60. }
  61. #endif // TWOBLUECUBES_CATCH_CONSTRUCTOR_HPP_INCLUDED