libvisiontransfer  6.4.0
alignedallocator.h
1 /*******************************************************************************
2  * Copyright (c) 2019 Nerian Vision GmbH
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *******************************************************************************/
14 
15 #ifndef ALIGNEDALLOCATOR_H
16 #define ALIGNEDALLOCATOR_H
17 
18 #include <cstdlib>
19 #include <memory>
20 #include <limits>
21 
22 namespace visiontransfer {
23 namespace internal {
24 
31 template<typename T, int alignment = 32>
33 public :
34  // Typedefs
35  typedef T value_type;
36  typedef value_type* pointer;
37  typedef const value_type* const_pointer;
38  typedef value_type& reference;
39  typedef const value_type& const_reference;
40  typedef std::size_t size_type;
41  typedef std::ptrdiff_t difference_type;
42 
43  // convert an allocator<T> to allocator<U>
44  template<typename U>
45  struct rebind {
46  typedef AlignedAllocator<U> other;
47  };
48 
49  explicit AlignedAllocator() {}
50  ~AlignedAllocator() {}
51  explicit AlignedAllocator(AlignedAllocator const&) {}
52  template<typename U>
53  explicit AlignedAllocator(AlignedAllocator<U> const&) {}
54 
55  // Address
56  inline pointer address(reference r) { return &r; }
57  inline const_pointer address(const_reference r) { return &r; }
58 
59  // Memory allocation
60  pointer allocate(size_type cnt, typename std::allocator<void>::const_pointer = 0) {
61  // Allocate memory and align it
62  unsigned char* ptr = new unsigned char[sizeof(T) * cnt + (alignment-1) + 1];
63  unsigned char* alignedPtr = reinterpret_cast<unsigned char*>((size_t(ptr + 1) + alignment-1) & -alignment);
64 
65  // Store offset in allocated memory area
66  alignedPtr[-1] = static_cast<unsigned char>(alignedPtr - ptr);
67 
68  return reinterpret_cast<pointer>(alignedPtr);
69  }
70 
71  void deallocate(pointer p, size_type) {
72  // Get address of unaligned pointer
73  unsigned char* alignedPtr = reinterpret_cast<unsigned char*>(p);
74  unsigned char* unalignedPtr = alignedPtr - alignedPtr[-1];
75 
76  // Delete it
77  ::operator delete[](unalignedPtr);
78  }
79 
80  // Size
81  size_type max_size() const {
82  return std::numeric_limits<size_type>::max() / sizeof(T);
83  }
84 
85  // Construction
86  void construct(pointer p, const T& t) {
87  new(p) T(t);
88  }
89 
90  // Destruction
91  void destroy(pointer p) {
92  p->~T();
93  }
94 };
95 
96 }} // namespace
97 
98 #endif
STL-compatible allocator for memory-aligned allocations.
Nerian Vision Technologies