Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
stlallocator.h
Go to the documentation of this file.
1 
18 #ifndef ION_BASE_STLALLOC_STLALLOCATOR_H_
19 #define ION_BASE_STLALLOC_STLALLOCATOR_H_
20 
21 #include <memory>
22 #include <type_traits>
23 
24 #include "ion/base/allocatable.h"
25 #include "ion/base/allocator.h"
26 #include "ion/base/type_structs.h"
27 #include "ion/port/align.h"
28 
29 namespace ion {
30 namespace base {
31 
35 template <typename T> class StlAllocator : public std::allocator<T> {
36  public:
38  typedef typename std::allocator<T>::const_pointer ConstPointer;
39  typedef typename std::allocator<T>::size_type SizeType;
40 
45  typedef std::true_type propagate_on_container_swap;
46 
47  explicit StlAllocator(const AllocatorPtr& allocator)
48  : allocator_(allocator) {}
51  template <typename U> StlAllocator(const StlAllocator<U>& a)
52  : allocator_(a.allocator_) {}
54  const AllocatorPtr& GetAllocator() const { return allocator_; }
55 
57  DCHECK(allocator_.Get());
58  void* p = allocator_->AllocateMemory(n * sizeof(T));
59  return reinterpret_cast<Pointer>(p);
60  }
62  allocator_->DeallocateMemory(p);
63  }
64 
73  void construct(Pointer p, const T& val) {
79  T>::type VoidOrT;
80  const VoidOrT* select_overload = NULL;
81  construct_impl(select_overload, p, val);
82  }
83  template <typename... Args>
84  void construct(Pointer p, Args&&... args) { // NOLINT
90  T>::type VoidOrT;
91  const VoidOrT* select_overload = NULL;
92  construct_impl(select_overload, p, std::forward<Args>(args)...); // NOLINT
93  }
94  template <class U, class... Args>
95  void construct(U* p, Args&&... args) { // NOLINT
102  U>::type VoidOrU;
103  const VoidOrU* select_overload = NULL;
104  construct_impl(select_overload, p, std::forward<Args>(args)...); // NOLINT
105  }
106 
107  template <typename U>
108  struct rebind {
110  };
111 
112  private:
113  StlAllocator(); // Not default constructible.
114 
116  void construct_impl(const void* dummy, Pointer p, const T& val) {
117  std::allocator<T>::construct(p, val);
118  }
119  template <typename... Args>
120  void construct_impl(const void* dummy, Pointer p,
121  Args&&... args) { // NOLINT
122  std::allocator<T>::construct(p, std::forward<Args>(args)...); // NOLINT
123  }
124  template <class U, class... Args>
125  void construct_impl(const void* dummy, U* p, Args&&... args) { // NOLINT
126  std::allocator<T>::construct(p, std::forward<Args>(args)...); // NOLINT
127  }
128 
131  void construct_impl(const T* dummy, Pointer p, const T& val) {
132  Allocatable::SetPlacementAllocator(allocator_.Get());
133  std::allocator<T>::construct(p, val);
134  Allocatable::SetPlacementAllocator(NULL);
135  }
136  template <typename... Args>
137  void construct_impl(const T* dummy, Pointer p, Args&&... args) { // NOLINT
138  Allocatable::SetPlacementAllocator(allocator_.Get());
139  std::allocator<T>::construct(p, std::forward<Args>(args)...); // NOLINT
140  Allocatable::SetPlacementAllocator(NULL);
141  }
142  template <class U, class... Args>
143  void construct_impl(const U* dummy, U* p, Args&&... args) { // NOLINT
144  Allocatable::SetPlacementAllocator(allocator_.Get());
145  std::allocator<T>::construct(p, std::forward<Args>(args)...); // NOLINT
146  Allocatable::SetPlacementAllocator(NULL);
147  }
148 
149  AllocatorPtr allocator_;
150  template <typename U> friend class StlAllocator;
151 };
152 
156 template <typename T, int N>
158  public:
162  explicit StlInlinedAllocator(const AllocatorPtr& allocator)
163  : StlAllocator<T>(allocator), current_(NULL), inlined_(true) {}
167  : StlAllocator<T>(a.GetAllocator()),
168  current_(NULL),
169  inlined_(a.inlined_) {}
172  template <typename U>
174  : StlAllocator<T>(a.GetAllocator()),
175  current_(NULL),
176  inlined_(a.inlined_) {}
180  if (n <= N && inlined_) {
181  if (current_ == reinterpret_cast<T*>(&storage_[0]))
182  current_ = reinterpret_cast<T*>(&storage_[sizeof(T) * N]);
183  else
184  current_ = reinterpret_cast<T*>(&storage_[0]);
185  return reinterpret_cast<Pointer>(current_);
186  } else {
187  inlined_ = false;
188  return this->StlAllocator<T>::allocate(n, hint);
189  }
190  }
194  if (p != reinterpret_cast<Pointer>(&storage_) &&
195  p != reinterpret_cast<Pointer>(&storage_[sizeof(T) * N])) {
196  inlined_ = true;
197  this->StlAllocator<T>::deallocate(p, n);
198  }
199  }
200 
204  template <typename U, typename V>
205  struct RebindHelper {
207  };
210  template <typename U>
211  struct RebindHelper<U, U> {
213  };
214  template <typename U> struct rebind {
216  };
217 
218  private:
227  ION_ALIGN(16) char storage_[sizeof(T) * N * 2];
228  T* current_;
229  bool inlined_;
230  template <typename U, int M> friend class StlInlinedAllocator;
231 };
232 
236 template <class T1, class T2>
237 bool operator==(const StlAllocator<T1>& lhs, const StlAllocator<T2>& rhs) {
238  return false;
239 }
240 
241 template <class T1, class T2>
242 bool operator!=(const StlAllocator<T1>& lhs, const StlAllocator<T2>& rhs) {
243  return true;
244 }
245 
246 template <class T>
247 bool operator==(const StlAllocator<T>& lhs, const StlAllocator<T>& rhs) {
248  return lhs.GetAllocator() == rhs.GetAllocator();
249 }
250 
251 template <class T>
252 bool operator!=(const StlAllocator<T>& lhs, const StlAllocator<T>& rhs) {
253  return lhs.GetAllocator() != rhs.GetAllocator();
254 }
255 
257 template <class T1, class T2, int N1, int N2>
259  const StlInlinedAllocator<T2, N2>& rhs) {
260  return &lhs == &rhs;
261 }
262 
263 template <class T1, class T2, int N1, int N2>
265  const StlInlinedAllocator<T2, N2>& rhs) {
266  return &lhs != &rhs;
267 }
268 
269 } // namespace base
270 } // namespace ion
271 
272 #endif // ION_BASE_STLALLOC_STLALLOCATOR_H_
StlAllocator< T >::ConstPointer ConstPointer
Definition: stlallocator.h:160
StlAllocator is derived std::allocator class that allows an Ion Allocator to be used for STL containe...
Definition: stlallocator.h:35
std::string type
Definition: printer.cc:353
std::allocator< T >::size_type SizeType
Definition: stlallocator.h:39
StlAllocator< V >::template rebind< U >::other other
Definition: stlallocator.h:206
#define DCHECK(expr)
Definition: logging.h:331
double value
void construct(Pointer p, const T &val)
Replace the construct() functions so that we can pass an Allocator to Allocatable types...
Definition: stlallocator.h:73
std::allocator< T >::pointer Pointer
Definition: stlallocator.h:37
void construct(U *p, Args &&...args)
Definition: stlallocator.h:95
const AllocatorPtr & GetAllocator() const
Returns the Allocator used by this.
Definition: stlallocator.h:54
StlInlinedAllocator(const StlInlinedAllocator< T, N > &a)
Copy constructor.
Definition: stlallocator.h:166
void deallocate(Pointer p, SizeType n)
Definition: stlallocator.h:61
SharedPtr< Allocator > AllocatorPtr
Definition: allocator.h:51
T * Get() const
Returns a raw pointer to the instance, which may be NULL.
Definition: sharedptr.h:89
StlAllocator< T >::Pointer Pointer
Definition: stlallocator.h:159
StlInlinedAllocator is a derived StlAllocator class that uses inlined storage for its first N element...
Definition: stlallocator.h:157
const void * pointer
Definition: printer.cc:111
Pointer allocate(SizeType n, ConstPointer hint=0)
Definition: stlallocator.h:56
Pointer allocate(SizeType n, ConstPointer hint=0)
Definition: stlallocator.h:177
StlInlinedAllocator(const StlInlinedAllocator< U, N > &a)
This copy constructor cannot be explicit because older versions of STL seem to implicitly cast betwee...
Definition: stlallocator.h:173
Windows uses transient proxy allocators.
Definition: stlallocator.h:205
std::allocator< T >::const_pointer ConstPointer
Definition: stlallocator.h:38
StlAllocator< T >::SizeType SizeType
Definition: stlallocator.h:161
void DeallocateMemory(void *p)
Deallocates a previously-allocated memory block.
Definition: allocator.cc:39
RebindHelper< U, T >::other other
Definition: stlallocator.h:215
void * AllocateMemory(size_t size)
Allocates memory of the given size.
Definition: allocator.cc:32
std::true_type propagate_on_container_move_assignment
These allocator traits affect the behavior of containers such as AllocVector.
Definition: stlallocator.h:44
bool operator==(const StlAllocator< T1 > &lhs, const StlAllocator< T2 > &rhs)
Each StlAllocator holds an Allocator.
Definition: stlallocator.h:237
StlAllocator(const StlAllocator< U > &a)
This copy constructor cannot be explicit because older versions of STL seem to implicitly cast betwee...
Definition: stlallocator.h:51
StlAllocator(const AllocatorPtr &allocator)
Definition: stlallocator.h:47
bool operator!=(const StlAllocator< T1 > &lhs, const StlAllocator< T2 > &rhs)
Definition: stlallocator.h:242
void deallocate(Pointer p, SizeType n)
Definition: stlallocator.h:191
void construct(Pointer p, Args &&...args)
Definition: stlallocator.h:84
StlInlinedAllocator(const AllocatorPtr &allocator)
Definition: stlallocator.h:162
std::true_type propagate_on_container_swap
Definition: stlallocator.h:45