Guest User

Untitled

a guest
Feb 24th, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.58 KB | None | 0 0
  1. namespace detail {
  2. /// Helper template that is forwarded to the mixins used
  3. /// for the extension of wrapper<•> in order to enable
  4. /// access to the actual type `Derived`
  5. template <typename Derived>
  6. struct Cast {
  7. using type = Derived;
  8.  
  9. template <typename T>
  10. static constexpr Derived& self(T* self) { return *static_cast<Derived*>(self); }
  11.  
  12. template <typename T>
  13. static constexpr Derived const& self(T const* self) { return *static_cast<Derived const*>(self); }
  14. };
  15.  
  16. /// This helper template is used to derive from all the Mixins
  17. /// one after another, making sure the constructor is mixed in as well:
  18. template <typename Cast, typename T,template <typename...> class...Mixins>
  19. struct wrapper_impl;
  20.  
  21. template <typename Cast, typename T,template <typename...> class First, template <typename...> class...Rest>
  22. struct wrapper_impl<Cast, T, First, Rest...>
  23. : First<Cast, T>
  24. , wrapper_impl<Cast, T, Rest...>
  25. {
  26. using First<Cast, T>::First;
  27. using wrapper_impl<Cast, T, Rest...>::wrapper_impl;
  28. };
  29.  
  30. template <typename Cast, typename T, template <typename...> class First>
  31. struct wrapper_impl<Cast, T, First>
  32. : First<Cast, T>
  33. , wrapper_impl<Cast, T>
  34. {
  35. using First<Cast, T>::First;
  36. using wrapper_impl<Cast, T>::wrapper_impl;
  37. };
  38.  
  39. template <typename Cast, typename T>
  40. struct wrapper_impl<Cast, T> {
  41. };
  42. }
  43.  
  44.  
  45. template <typename T, typename Tag, template <typename...> class...Mixins>
  46. class wrapper : public detail::wrapper_impl<detail::Cast<wrapper<T,Tag,Mixins...>>, T, Mixins...> {
  47. public:
  48. using value_type = T;
  49. using detail::wrapper_impl<detail::Cast<wrapper<T,Tag,Mixins...>>, T, Mixins...>::wrapper_impl;
  50.  
  51. T& get() { return *reinterpret_cast<T*>(&m_buffer); }
  52. T const& get() const { return *reinterpret_cast<T const*>(&m_buffer); }
  53.  
  54. template <typename...Args>
  55. void construct(Args&&...args) {
  56. new (&m_buffer) T(std::forward<Args>(args)...);
  57. }
  58.  
  59. void destruct() {
  60. get().~T();
  61. }
  62.  
  63. ~wrapper() {
  64. destruct();
  65. }
  66.  
  67. private:
  68. std::aligned_storage_t<sizeof(T), alignof(T)> m_buffer;;
  69. };
  70.  
  71. template <typename T>
  72. struct constructor_from {
  73. template <typename Cast, typename U>
  74. struct mixin {
  75. explicit mixin(T const& value) {
  76. Cast::self(this).construct(U{value});
  77. }
  78. };
  79. };
  80.  
  81. using my_int = wrapper<int, struct Tag, constructor_from<int>::mixin>;
  82. my_int instance{42};
  83.  
  84. using my_int = wrapper<int, struct Tag, constructor_from<int>::mixin>;
  85. my_int instance{4.2};
Add Comment
Please, Sign In to add comment