ATLAS Offline Software
AlignedDynArray.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /**
6  * @file AlignedDynArray.icc
7  * @date 26th November 2019
8  * @author Anthony Morley, Christos Anastopoulos
9  * @brief AlignedDynArray implementation
10  */
11 
12 #include <utility>
13 
14 namespace GSFUtils {
15 
16 template<typename T, size_t ALIGNMENT>
17 inline AlignedDynArray<T, ALIGNMENT>::AlignedDynArray(const size_type n)
18  : m_buffer(nullptr)
19  , m_size(n)
20 {
21 
22  const size_t bufferSize = n * sizeof(T);
23  m_buffer = static_cast<T*>(std::aligned_alloc(ALIGNMENT, bufferSize));
24  std::uninitialized_default_construct(m_buffer, m_buffer + m_size);
25 }
26 
27 template<typename T, size_t ALIGNMENT>
28 inline AlignedDynArray<T, ALIGNMENT>::AlignedDynArray(const size_type n,
29  const T& value)
30  : m_buffer(nullptr)
31  , m_size(n)
32 {
33  const size_t bufferSize = n * sizeof(T);
34  m_buffer = static_cast<T*>(std::aligned_alloc(ALIGNMENT, bufferSize));
35  std::uninitialized_fill(m_buffer, m_buffer + m_size, value);
36 }
37 
38 template<typename T, size_t ALIGNMENT>
39 inline AlignedDynArray<T, ALIGNMENT>::AlignedDynArray(
40  AlignedDynArray&& other) noexcept
41  : m_buffer(nullptr)
42  , m_size(0)
43 {
44  // copy over other
45  m_buffer = other.m_buffer;
46  m_size = other.m_size;
47  // set other to invalid
48  other.m_buffer = nullptr;
49  other.m_size = 0;
50 }
51 
52 template<typename T, size_t ALIGNMENT>
53 inline AlignedDynArray<T, ALIGNMENT>&
54 AlignedDynArray<T, ALIGNMENT>::operator=(AlignedDynArray&& other) noexcept
55 {
56  // cleanup this object
57  cleanup();
58  // copy over other
59  m_buffer = other.m_buffer;
60  m_size = other.m_size;
61  // set other to invalid
62  other.m_buffer = nullptr;
63  other.m_size = 0;
64 
65  return *this;
66 }
67 
68 template<typename T, size_t ALIGNMENT>
69 inline AlignedDynArray<T, ALIGNMENT>::~AlignedDynArray()
70 {
71  cleanup();
72 }
73 
74 template<typename T, size_t ALIGNMENT>
75 inline typename AlignedDynArray<T, ALIGNMENT>::pointer
76 AlignedDynArray<T, ALIGNMENT>::buffer() noexcept
77 {
78  return std::assume_aligned<ALIGNMENT>(m_buffer);
79 }
80 
81 template<typename T, size_t ALIGNMENT>
82 inline typename AlignedDynArray<T, ALIGNMENT>::const_pointer
83 AlignedDynArray<T, ALIGNMENT>::buffer() const noexcept
84 {
85  return std::assume_aligned<ALIGNMENT>(std::as_const(m_buffer));
86 }
87 
88 template<typename T, size_t ALIGNMENT>
89 inline typename AlignedDynArray<T, ALIGNMENT>::reference
90 AlignedDynArray<T, ALIGNMENT>::operator[](
91  const AlignedDynArray<T, ALIGNMENT>::size_type pos) noexcept
92 {
93  return m_buffer[pos];
94 }
95 
96 template<typename T, size_t ALIGNMENT>
97 inline typename AlignedDynArray<T, ALIGNMENT>::const_reference
98 AlignedDynArray<T, ALIGNMENT>::operator[](
99  const AlignedDynArray<T, ALIGNMENT>::size_type pos) const noexcept
100 {
101  return m_buffer[pos];
102 }
103 
104 template<typename T, size_t ALIGNMENT>
105 inline typename AlignedDynArray<T, ALIGNMENT>::iterator
106 AlignedDynArray<T, ALIGNMENT>::begin() noexcept
107 {
108  return std::assume_aligned<ALIGNMENT>(iterator(buffer()));
109 }
110 
111 template<typename T, size_t ALIGNMENT>
112 inline typename AlignedDynArray<T, ALIGNMENT>::const_iterator
113 AlignedDynArray<T, ALIGNMENT>::begin() const noexcept
114 {
115  return std::assume_aligned<ALIGNMENT>(const_iterator(buffer()));
116 }
117 
118 template<typename T, size_t ALIGNMENT>
119 inline typename AlignedDynArray<T, ALIGNMENT>::iterator
120 AlignedDynArray<T, ALIGNMENT>::end() noexcept
121 {
122  return iterator(buffer() + m_size);
123 }
124 
125 template<typename T, size_t ALIGNMENT>
126 inline typename AlignedDynArray<T, ALIGNMENT>::const_iterator
127 AlignedDynArray<T, ALIGNMENT>::end() const noexcept
128 {
129  return const_iterator(buffer() + m_size);
130 }
131 
132 template<typename T, size_t ALIGNMENT>
133 inline typename AlignedDynArray<T, ALIGNMENT>::size_type
134 AlignedDynArray<T, ALIGNMENT>::size() const noexcept
135 {
136  return m_size;
137 }
138 
139 template<typename T, size_t ALIGNMENT>
140 bool
141 AlignedDynArray<T, ALIGNMENT>::empty() const noexcept
142 {
143  return (size() == 0);
144 }
145 
146 // private cleanup helper
147 template<typename T, size_t ALIGNMENT>
148 inline void
149 AlignedDynArray<T, ALIGNMENT>::cleanup()
150 {
151  if (m_buffer) {
152  for (size_type pos = 0; pos < m_size; ++pos) {
153  m_buffer[pos].~T();
154  }
155  std::free(m_buffer);
156  }
157 }
158 
159 } // namespace GSFUtils