SPH
AlignedStorage.h
Go to the documentation of this file.
1 #pragma once
2 
7 
8 #include "common/Assert.h"
9 #include "common/Traits.h"
10 #include <mm_malloc.h>
11 
13 
15 template <typename T, typename... TArgs>
16 INLINE T* alignedNew(TArgs&&... args) {
17  constexpr Size size = sizeof(T);
18  constexpr Size alignment = alignof(T);
19  void* ptr = _mm_malloc(size, alignment);
20  SPH_ASSERT(ptr);
21  return new (ptr) T(std::forward<TArgs>(args)...);
22 }
23 
25 template <typename T>
26 INLINE void alignedDelete(T* ptr) {
27  if (!ptr) {
28  return;
29  }
30 
31  ptr->~T();
32  _mm_free(ptr);
33  ptr = nullptr;
34 }
35 
36 template <typename T>
37 INLINE bool isAligned(const T& value) {
38  return reinterpret_cast<std::size_t>(std::addressof(value)) % alignof(T) == 0;
39 }
40 
42 
50 
51 // dereferencing type-punned pointer will break strict-aliasing rules
52 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
54 
55 template <typename Type>
57 private:
58  struct __attribute__((__may_alias__)) Holder {
59  alignas(Type) char storage[sizeof(Type)];
60  } holder;
61 
62 public:
63  AlignedStorage() = default;
64 
65  template <typename... TArgs>
66  INLINE void emplace(TArgs&&... rest) {
67  new (&holder) Type(std::forward<TArgs>(rest)...);
68  }
69 
70  INLINE void destroy() {
71  get().~Type();
72  }
73 
75  INLINE constexpr operator Type&() noexcept {
76  return get();
77  }
78 
80  INLINE constexpr operator const Type&() const noexcept {
81  return get();
82  }
83 
85  INLINE constexpr Type& get() noexcept {
86  return reinterpret_cast<Type&>(holder);
87  }
88 
90  INLINE constexpr const Type& get() const noexcept {
91  return reinterpret_cast<const Type&>(holder);
92  }
93 };
94 
97 template <typename Type>
98 class AlignedStorage<Type&> {
100 
101  StorageType storage;
102 
103 public:
104  AlignedStorage() = default;
105 
106  template <typename T>
107  INLINE void emplace(T& ref) {
108  storage = StorageType(ref);
109  }
110 
111  // no need do explicitly destroy reference wrapper
112  INLINE void destroy() {}
113 
114  INLINE constexpr operator Type&() noexcept {
115  return get();
116  }
117 
119  INLINE constexpr operator const Type&() const noexcept {
120  return get();
121  }
122 
124  INLINE constexpr Type& get() noexcept {
125  return storage;
126  }
127 
129  INLINE constexpr const Type& get() const noexcept {
130  return storage;
131  }
132 };
133 
134 
INLINE void alignedDelete(T *ptr)
Deletes an object previously allocated using alignedNew.
NAMESPACE_SPH_BEGIN INLINE T * alignedNew(TArgs &&... args)
Creates a new object of type T on heap, using aligned allocation.
INLINE bool isAligned(const T &value)
Custom assertions.
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define NAMESPACE_SPH_END
Definition: Object.h:12
Few non-standard type traits.
constexpr INLINE const Type & get() const noexcept
Returns the reference to the stored value, const version.
INLINE void emplace(T &ref)
constexpr INLINE Type & get() noexcept
Return the reference to the stored value.
Simple block of memory on stack with size and alignment given by template type.
INLINE void emplace(TArgs &&... rest)
constexpr INLINE const Type & get() const noexcept
Returns the reference to the stored value, const version.
constexpr INLINE Type & get() noexcept
Return the reference to the stored value.
INLINE void destroy()
AlignedStorage()=default