libvisiontransfer  10.6.0
alignedallocator.h
1 /*******************************************************************************
2  * Copyright (c) 2023 Allied Vision Technologies 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>
32 class AlignedAllocator {
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  if(p != nullptr) {
73  // Get address of unaligned pointer
74  unsigned char* alignedPtr = reinterpret_cast<unsigned char*>(p);
75  unsigned char* unalignedPtr = alignedPtr - alignedPtr[-1];
76 
77  // Delete it
78  ::operator delete[](unalignedPtr);
79  }
80  }
81 
82  // Size
83  size_type max_size() const {
84  return (std::numeric_limits<size_type>::max)() / sizeof(T);
85  }
86 
87  // Construction
88  void construct(pointer p, const T& t) {
89  new(p) T(t);
90  }
91 
92  // Destruction
93  void destroy(pointer p) {
94  p->~T();
95  }
96 };
97 
98 }} // namespace
99 
100 #endif
Allied Vision