casa  5.7.0-16
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Allocator.h
Go to the documentation of this file.
1 //# Allocator.h:
2 //# Copyright (C) 2015
3 //# National Astronomical Observatory of Japan
4 //# 2-21-1, Osawa, Mitaka, Tokyo, 181-8588, Japan.
5 //#
6 //# This library is free software; you can redistribute it and/or modify it
7 //# under the terms of the GNU Library General Public License as published by
8 //# the Free Software Foundation; either version 2 of the License, or (at your
9 //# option) any later version.
10 //#
11 //# This library is distributed in the hope that it will be useful, but WITHOUT
12 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14 //# License for more details.
15 //#
16 //# You should have received a copy of the GNU Library General Public License
17 //# along with this library; if not, write to the Free Software Foundation,
18 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
19 //#
20 //# Correspondence concerning AIPS++ should be addressed as follows:
21 //# Internet email: aips2-request@nrao.edu.
22 //# Postal address: AIPS++ Project Office
23 //# National Radio Astronomy Observatory
24 //# 520 Edgemont Road
25 //# Charlottesville, VA 22903-2475 USA
26 //#
27 //# $Id$
28 
29 #ifndef CASA_CONTAINERS_ALLOCATOR_H_
30 #define CASA_CONTAINERS_ALLOCATOR_H_
31 
32 #include <casacore/casa/config.h>
33 #include <casacore/casa/aips.h>
35 
36 #include <cstdlib>
37 #include <memory>
38 #include <new>
39 #include <typeinfo>
40 #include <type_traits>
41 
42 namespace casacore { //# NAMESPACE CASACORE - BEGIN
43 
44 #ifndef CASA_DEFAULT_ALIGNMENT
45 # define CASA_DEFAULT_ALIGNMENT (32UL) // AVX/AVX2 alignment
46 #endif
47 
48 // <summary>
49 // A global enum used by some Array/Block constructors.
50 // </summary>
51 // <synopsis>
52 // ArrayInitPolicy is used in functions where an array is allocated/resized.
53 // </synopsis>
55 public:
57  return init == other.init;
58  }
60  return init != other.init;
61  }
62 private:
64  explicit constexpr ArrayInitPolicy(bool v): init(v) {}
65  friend struct ArrayInitPolicies;
66 };
67 
69  // Don't initialize elements in the array. (The array will be explicitly filled with values other than the default value.)
70  static constexpr ArrayInitPolicy NO_INIT = ArrayInitPolicy(false);
71  // Initialize all elements in the array with the default value.
72  static constexpr ArrayInitPolicy INIT = ArrayInitPolicy(true);
73 };
74 
75 template<typename T>
76 using std11_allocator = std::allocator<T>;
77 
78 
79 template<typename T, size_t ALIGNMENT = CASA_DEFAULT_ALIGNMENT>
82  typedef typename Super::size_type size_type;
83  typedef typename Super::difference_type difference_type;
84  typedef typename Super::pointer pointer;
85  typedef typename Super::const_pointer const_pointer;
86  typedef typename Super::reference reference;
87  typedef typename Super::const_reference const_reference;
88  typedef typename Super::value_type value_type;
89 
90  static constexpr size_t alignment = ALIGNMENT;
91 
92  template<typename TOther>
93  struct rebind {
95  };
96  casacore_allocator() throw () {
97  }
98 
99  casacore_allocator(const casacore_allocator&other) noexcept
100  :Super(other) {
101  }
102 
103  template<typename TOther>
105  }
106 
107  ~casacore_allocator() noexcept {
108  }
109 
110  pointer allocate(size_type elements, const void* = 0) {
111  if (elements > this->max_size()) {
112  throw std::bad_alloc();
113  }
114  void *memptr = 0;
115  int result = posix_memalign(&memptr, ALIGNMENT, sizeof(T) * elements);
116  if (result != 0) {
117  throw std::bad_alloc();
118  }
119  return static_cast<pointer>(memptr);
120  }
121 
123  free(ptr);
124  }
125 };
126 
127 template<typename T, size_t ALIGNMENT>
130  return true;
131 }
132 
133 template<typename T, size_t ALIGNMENT>
136  return false;
137 }
138 
139 template<typename T>
142  typedef typename Super::size_type size_type;
143  typedef typename Super::difference_type difference_type;
144  typedef typename Super::pointer pointer;
145  typedef typename Super::const_pointer const_pointer;
146  typedef typename Super::reference reference;
147  typedef typename Super::const_reference const_reference;
148  typedef typename Super::value_type value_type;
149 
150  template<typename TOther>
151  struct rebind {
153  };
154  new_del_allocator() noexcept {
155  }
156 
157  new_del_allocator(const new_del_allocator&other) noexcept
158  :Super(other) {
159  }
160 
161  template<typename TOther>
163  }
164 
165  ~new_del_allocator() noexcept {
166  }
167 
168  pointer allocate(size_type elements, const void* = 0) {
169  if (elements > this->max_size()) {
170  throw std::bad_alloc();
171  }
172  return new T[elements];
173  }
174 
176  delete[] ptr;
177  }
178  template<typename U, typename... Args>
179  void construct(U *, Args&&... ) {} // do nothing because new T[] does
180  template<typename U>
181  void construct(U *ptr, U &&value) {
182  *ptr = value; // because *ptr was already contructed by new[].
183  }
184  template<typename U>
185  void construct(U *ptr, U &value) {
186  *ptr = value; // because *ptr was already contructed by new[].
187  }
188  template<typename U>
189  void construct(U *ptr, U const &value) {
190  *ptr = value; // because *ptr was already contructed by new[].
191  }
192 
193  template<typename U>
194  void destroy(U *) {} // do nothing because delete[] will do.
195 };
196 
197 template<typename T>
198 inline bool operator==(const new_del_allocator<T>&,
199  const new_del_allocator<T>&) {
200  return true;
201 }
202 
203 template<typename T>
204 inline bool operator!=(const new_del_allocator<T>&,
205  const new_del_allocator<T>&) {
206  return false;
207 }
208 
209 template<typename T> class Array;
210 template<typename T> class Block;
211 
213  template<typename T> friend class AbstractAllocator;
214  template<typename T, typename Sub> friend class BaseAllocator;
215  template<typename T> friend class Array;
216  template<typename T> friend class Block;
217 
218  template<typename T2>
219  struct BulkAllocator {
220  typedef typename std::allocator<T2>::size_type size_type;
221  typedef typename std::allocator<T2>::pointer pointer;
222  typedef typename std::allocator<T2>::const_pointer const_pointer;
223  typedef typename std::allocator<T2>::value_type value_type;
224 
225  virtual pointer allocate(size_type elements, const void*ptr = 0) = 0;
226  virtual void deallocate(pointer ptr, size_type size) = 0;
227 
228  virtual void construct(pointer ptr, size_type n, const_pointer src) = 0;
229  virtual void construct(pointer ptr, size_type n, value_type const &initial_value) = 0;
230  virtual void construct(pointer ptr, size_type n) = 0;
231  virtual void destroy(pointer ptr, size_type n) = 0;
232  virtual std::type_info const &allocator_typeid() const = 0;
233  virtual ~BulkAllocator() {}
234  };
235 
236  template<typename Allocator>
237  struct BulkAllocatorImpl: public BulkAllocator<typename Allocator::value_type> {
238  typedef typename Allocator::size_type size_type;
239  typedef typename Allocator::pointer pointer;
240  typedef typename Allocator::const_pointer const_pointer;
241  typedef typename Allocator::value_type value_type;
242  virtual pointer allocate(size_type elements, const void *ptr = 0) override {
243  return allocator.allocate(elements, ptr);
244  }
245  virtual void deallocate(pointer ptr, size_type size) override {
246  allocator.deallocate(ptr, size);
247  }
248 
249  virtual void construct(pointer ptr, size_type n, const_pointer src) override {
250  size_type i = 0;
251  try {
252  for (i = 0; i < n; ++i) {
253  allocator.construct(&ptr[i], src[i]);
254  }
255  } catch (...) {
256  destroy(ptr, i); // rollback constructions
257  throw;
258  }
259  }
260  virtual void construct(pointer ptr, size_type n,
261  value_type const &initial_value) override {
262  size_type i = 0;
263  try {
264  for (i = 0; i < n; ++i) {
265  allocator.construct(&ptr[i], initial_value);
266  }
267  } catch (...) {
268  destroy(ptr, i); // rollback constructions
269  throw;
270  }
271  }
272  virtual void construct(pointer ptr, size_type n) override {
273  size_type i = 0;
274  try {
275  for (i = 0; i < n; ++i) {
276  allocator.construct(&ptr[i]);
277  }
278  } catch (...) {
279  destroy(ptr, i); // rollback constructions
280  throw;
281  }
282  }
283  virtual void destroy(pointer ptr, size_type n) override {
284  for (size_type i = n; i > 0;) {
285  --i;
286  try {
287  allocator.destroy(&ptr[i]);
288  } catch (...) {
289  // Destructor should not raise any exception.
290  }
291  }
292  }
293  virtual std::type_info const &allocator_typeid() const override {
294  return typeid(Allocator);
295  }
296  virtual ~BulkAllocatorImpl() override {}
297 
298  private:
299  static Allocator allocator;
300  };
301 
302  template<typename Allocator>
304  return get_allocator_raw<Allocator>();
305  }
306 
307  template<typename Allocator>
309  // Because this function gets called from destructors of statically allocated objects that get destructed
310  // after the program finishes, the allocator is constructed in a static storage space and is never
311  // destructed.
312  static typename std::aligned_storage<sizeof(BulkAllocatorImpl<Allocator>), alignof(BulkAllocatorImpl<Allocator>)>::type storage;
313  static BulkAllocatorImpl<Allocator>* ptr =
314  new (reinterpret_cast<BulkAllocatorImpl<Allocator>*>(&storage)) BulkAllocatorImpl<Allocator>();
315  return ptr;
316  }
317 
318  // <summary>Allocator specifier</summary>
319  // <synopsis>
320  // This class is just used to avoid ambiguity between overloaded functions.
321  // </synopsis>
322  template<typename T>
323  struct AllocSpec {
325  explicit AllocSpec(BulkAllocator<T> *alloc) : allocator(alloc) {}
326  };
327 };
328 
329 template<typename Allocator>
330 Allocator Allocator_private::BulkAllocatorImpl<Allocator>::allocator;
331 
332 template<typename T>
334 public:
335  typedef T value_type;
336  virtual ~AbstractAllocator(){}
337 protected:
339  friend class Array<T>;
340  friend class Block<T>;
341 
343 };
344 
345 template<typename T, typename Sub>
347 public:
348  typedef T value_type;
349  typedef Sub facade_type;
350  virtual ~BaseAllocator() {}
351 protected:
353 
354  virtual typename Allocator_private::BulkAllocator<T> *getAllocator() const override {
355  return Allocator_private::get_allocator<typename facade_type::type>();
356  }
357 };
358 
359 // An allocator behaves like operator new[]/delete[].
360 // Because it is impossible to decouple construction/destruction from allocation/deallocation with this allocator,
361 // it is discouraged to use this allocator.
362 // Use <src>DefaultAllocator<T></src> or <src>AlignedAllocator<T, ALIGNMENT></src> as possible.
363 // This allocator is provided only for compatibility for calling
364 // <src>Array::takeStorage(), Block::replaceStorage(), Block(size_t, T *&, Bool)</src> etc.
365 // with a storage allocated by operator new[].
366 template<typename T>
367 class NewDelAllocator: public BaseAllocator<T, NewDelAllocator<T> > {
368 public:
370  // an instance of this allocator.
372 protected:
374 };
375 template<typename T>
376 NewDelAllocator<T> NewDelAllocator<T>::value;
377 
378 // An allocator which allocates aligned memory.
379 template<typename T, size_t ALIGNMENT = CASA_DEFAULT_ALIGNMENT>
380 class AlignedAllocator: public BaseAllocator<T, AlignedAllocator<T, ALIGNMENT> > {
381 public:
383  // an instance of this allocator.
385 protected:
387 };
388 template<typename T, size_t ALIGNMENT>
389 AlignedAllocator<T, ALIGNMENT> AlignedAllocator<T, ALIGNMENT>::value;
390 
391 // An aligned allocator with the default alignment.
392 template<typename T>
394 public:
395  typedef typename AlignedAllocator<T>::type type;
396  // an instance of this allocator.
398 protected:
400 };
401 template<typename T>
402 DefaultAllocator<T> DefaultAllocator<T>::value;
403 
404 // <summary>Allocator specifier</summary>
405 // <synopsis>
406 // This class is just used to avoid ambiguity between overloaded functions.
407 // </synopsis>
408 template<typename T>
409 struct AllocSpec {
410  typedef T type;
411  static AllocSpec<T> const value;
412 };
413 template<typename T>
415 
416 
417 } //# NAMESPACE CASACORE - END
418 
419 #endif /* CASA_CONTAINERS_ALLOCATOR_H_ */
virtual Allocator_private::BulkAllocator< T > * getAllocator() const =0
std::allocator< T2 >::pointer pointer
Definition: Allocator.h:221
AlignedAllocator< T >::type type
Definition: Allocator.h:395
std::allocator< T2 >::const_pointer const_pointer
Definition: Allocator.h:222
void construct(U *ptr, U const &value)
Definition: Allocator.h:189
Super::const_reference const_reference
Definition: Allocator.h:147
static constexpr ArrayInitPolicy NO_INIT
Don&#39;t initialize elements in the array.
Definition: Allocator.h:70
An allocator which allocates aligned memory.
Definition: Allocator.h:380
static constexpr size_t alignment
Definition: Allocator.h:90
Super::const_pointer const_pointer
Definition: Allocator.h:145
static NewDelAllocator< T > value
an instance of this allocator.
Definition: Allocator.h:371
std::allocator< T > std11_allocator
Definition: Allocator.h:76
std::allocator< T2 >::size_type size_type
Definition: Allocator.h:220
An aligned allocator with the default alignment.
Definition: Allocator.h:393
each selection effectively specify the desired channel data in a specified spectral window If the user uses the FrequencySelectionChannel class then the selection simply selects a range of channels The other derived class is FrequencySelectionReferential which specifies a range of frequencies in a specified frame of reference(e.g., LSRK).Unlike the other first method
void deallocate(pointer ptr, size_type)
Definition: Allocator.h:175
LatticeExprNode operator!=(const LatticeExprNode &left, const LatticeExprNode &right)
virtual void construct(pointer ptr, size_type n, const_pointer src)=0
virtual void destroy(pointer ptr, size_type n)=0
virtual casacore::String type() const
Implements RegionShape::type.
Definition: RegionShapes.h:548
static AllocSpec< T > const value
Definition: Allocator.h:411
Super::difference_type difference_type
Definition: Allocator.h:83
new_del_allocator< TOther > other
Definition: Allocator.h:152
size_t size() const
pointer allocate(size_type elements, const void *=0)
Definition: Allocator.h:110
A global enum used by some Array/Block constructors.
Definition: Allocator.h:54
static AlignedAllocator< T, ALIGNMENT > value
an instance of this allocator.
Definition: Allocator.h:384
Super::size_type size_type
Definition: Allocator.h:82
static DefaultAllocator< T > value
an instance of this allocator.
Definition: Allocator.h:397
new_del_allocator< T > type
Definition: Allocator.h:369
virtual void deallocate(pointer ptr, size_type size) override
Definition: Allocator.h:245
casacore_allocator< TOther > other
Definition: Allocator.h:94
Super::pointer pointer
Definition: Allocator.h:144
virtual pointer allocate(size_type elements, const void *ptr=0) override
Definition: Allocator.h:242
Super::pointer pointer
Definition: Allocator.h:84
new_del_allocator(const new_del_allocator &other) noexcept
Definition: Allocator.h:157
Super::value_type value_type
Definition: Allocator.h:88
virtual std::type_info const & allocator_typeid() const =0
casacore_allocator< T, ALIGNMENT > type
Definition: Allocator.h:382
new_del_allocator(const new_del_allocator< TOther > &) noexcept
Definition: Allocator.h:162
Super::const_pointer const_pointer
Definition: Allocator.h:85
virtual pointer allocate(size_type elements, const void *ptr=0)=0
virtual std::type_info const & allocator_typeid() const override
Definition: Allocator.h:293
Super::const_reference const_reference
Definition: Allocator.h:87
virtual void destroy(pointer ptr, size_type n) override
Definition: Allocator.h:283
void deallocate(pointer ptr, size_type)
Definition: Allocator.h:122
void construct(U *ptr, U &&value)
Definition: Allocator.h:181
virtual void deallocate(pointer ptr, size_type size)=0
constexpr ArrayInitPolicy(bool v)
Definition: Allocator.h:64
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
virtual void construct(pointer ptr, size_type n, const_pointer src) override
Definition: Allocator.h:249
static BulkAllocatorImpl< Allocator > * get_allocator_raw()
Definition: Allocator.h:308
static constexpr ArrayInitPolicy INIT
Initialize all elements in the array with the default value.
Definition: Allocator.h:72
virtual void construct(pointer ptr, size_type n, value_type const &initial_value) override
Definition: Allocator.h:260
template &lt;class T, class U&gt; class vector;
Definition: MSFlagger.h:37
std::allocator< T2 >::value_type value_type
Definition: Allocator.h:223
Bool operator!=(ArrayInitPolicy const &other)
Definition: Allocator.h:59
pointer allocate(size_type elements, const void *=0)
Definition: Allocator.h:168
virtual void construct(pointer ptr, size_type n) override
Definition: Allocator.h:272
simple 1-D array
void construct(U *, Args &&...)
Definition: Allocator.h:179
void construct(U *ptr, U &value)
Definition: Allocator.h:185
virtual Allocator_private::BulkAllocator< T > * getAllocator() const override
Definition: Allocator.h:354
free(pool)
Bool operator==(ArrayInitPolicy const &other)
Definition: Allocator.h:56
AllocSpec(BulkAllocator< T > *alloc)
Definition: Allocator.h:325
Super::value_type value_type
Definition: Allocator.h:148
Allocator specifier.
Definition: Allocator.h:409
casacore_allocator(const casacore_allocator &other) noexcept
Definition: Allocator.h:99
Super::reference reference
Definition: Allocator.h:146
static BulkAllocator< typename Allocator::value_type > * get_allocator()
Definition: Allocator.h:303
An allocator behaves like operator new[]/delete[].
Definition: Allocator.h:367
Super::reference reference
Definition: Allocator.h:86
casacore_allocator(const casacore_allocator< TOther > &) noexcept
Definition: Allocator.h:104
Bool operator==(const MVTime &lh, const MVTime &rh)
is equal operator, uses operator Double which returns days
Definition: MVTime.h:465
std11_allocator< T > Super
Definition: Allocator.h:81
Super::size_type size_type
Definition: Allocator.h:142
Super::difference_type difference_type
Definition: Allocator.h:143
std11_allocator< T > Super
Definition: Allocator.h:141
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.
virtual ~BaseAllocator()
Definition: Allocator.h:350
#define casacore
&lt;X11/Intrinsic.h&gt; #defines true, false, casacore::Bool, and String.
Definition: X11Intrinsic.h:42