emlabcpp
modern opinionated embedded C++ library
static_storage.h
Go to the documentation of this file.
1 
24 #pragma once
25 
26 #include <cstddef>
27 #include <cstring>
28 #include <memory>
29 #include <utility>
30 
31 namespace emlabcpp
32 {
33 
35 {
36  template < typename F, typename T >
37  static F _copy_n( F first, std::size_t n, T* dest )
38  {
39  if constexpr ( std::is_trivially_copy_constructible_v< T > ) {
40  std::memcpy( dest, &*first, n * sizeof( T ) );
41  std::advance(
42  first,
43  static_cast< typename std::iterator_traits< F >::difference_type >(
44  n ) );
45  return first;
46  } else {
47  for ( std::size_t i = 0; i < n; ++i, ++first, ++dest )
48  ::new ( dest ) T( *first );
49  return first;
50  }
51  }
52 
53  template < typename F, typename T >
54  static F _move_n( F first, std::size_t n, T* dest )
55  {
56  if constexpr ( std::is_trivially_move_constructible_v< T > ) {
57  std::memcpy( dest, &*first, n * sizeof( T ) );
58  std::advance(
59  first,
60  static_cast< typename std::iterator_traits< F >::difference_type >(
61  n ) );
62  return first;
63  } else {
64  for ( std::size_t i = 0; i < n; ++i, ++first, ++dest )
65  ::new ( dest ) T( std::move( *first ) );
66  return first;
67  }
68  }
69 };
70 
73 template < typename T, std::size_t N >
75 {
76  static constexpr std::size_t capacity = N;
77 
78  using value_type = T;
79  using reference = T&;
80  using const_reference = T const&;
81  using pointer = T*;
82  using const_pointer = T const*;
83  using size_type = std::size_t;
84 
86  [[nodiscard]] constexpr pointer data() noexcept
87  {
88  return reinterpret_cast< pointer >( data_ );
89  }
90 
92  [[nodiscard]] constexpr const_pointer data() const noexcept
93  {
94  return reinterpret_cast< const_pointer >( data_ );
95  }
96 
98  template < typename... Args >
99  constexpr T& emplace_item( size_type const i, Args&&... args ) noexcept(
100  std::is_nothrow_constructible_v< T, Args... > )
101  {
102  return *std::construct_at( data() + i, std::forward< Args >( args )... );
103  }
104 
106  constexpr auto copy_n( size_type const i, size_type const n, auto iter ) noexcept(
107  std::is_nothrow_copy_constructible_v< T > )
108  {
109  return static_storage_base::_copy_n( iter, n, data() + i );
110  }
111 
113  constexpr auto move_n( size_type const i, size_type const n, auto iter ) noexcept(
114  std::is_nothrow_move_constructible_v< T > )
115  {
116  return static_storage_base::_move_n( iter, n, data() + i );
117  }
118 
120  constexpr void delete_n( size_type const i, size_type const n ) noexcept(
121  std::is_nothrow_destructible_v< T > )
122  {
123  for ( size_type j = 0; j < n; ++j )
124  std::destroy_at( data() + i + j );
125  }
126 
128  constexpr void
129  delete_item( size_type const i ) noexcept( std::is_nothrow_destructible_v< T > )
130  {
131  std::destroy_at( data() + i );
132  }
133 
135  [[nodiscard]] constexpr reference operator[]( size_type const i ) noexcept
136  {
137  return *( data() + i );
138  }
139 
141  [[nodiscard]] constexpr const_reference operator[]( size_type const i ) const noexcept
142  {
143  return *( data() + i );
144  }
145 
146 private:
147  alignas( T ) std::byte data_[N * sizeof( T )];
148 };
149 
150 template < typename T >
152  std::is_trivially_default_constructible_v< T > && std::is_trivially_destructible_v< T >;
153 
154 template < typename T, std::size_t N >
155 requires( trivial_for_static_storage< T > )
156 struct static_storage< T, N >
157 {
158  static constexpr std::size_t capacity = N;
159 
160  using value_type = T;
161  using reference = T&;
162  using const_reference = T const&;
163  using pointer = T*;
164  using const_pointer = T const*;
165  using size_type = std::size_t;
166 
168  [[nodiscard]] constexpr pointer data() noexcept
169  {
170  return data_;
171  }
172 
174  [[nodiscard]] constexpr const_pointer data() const noexcept
175  {
176  return data_;
177  }
178 
180  template < typename... Args >
181  constexpr T& emplace_item( size_type const i, Args&&... args ) noexcept(
182  std::is_nothrow_constructible_v< T, Args... > )
183  {
184  data_[i] = T{ std::forward< Args >( args )... };
185  return data_[i];
186  }
187 
189  constexpr auto copy_n( size_type const i, size_type const n, auto iter ) noexcept(
190  std::is_nothrow_copy_constructible_v< T > )
191  {
192  return static_storage_base::_copy_n( iter, n, data() + i );
193  }
194 
196  constexpr auto move_n( size_type const i, size_type const n, auto iter ) noexcept(
197  std::is_nothrow_move_constructible_v< T > )
198  {
199  return static_storage_base::_move_n( iter, n, data() + i );
200  }
201 
202  constexpr void delete_n( size_type const, size_type const ) noexcept
203  {
204  }
205 
207  constexpr void delete_item( size_type const ) noexcept
208  {
209  }
210 
212  [[nodiscard]] constexpr reference operator[]( size_type const i ) noexcept
213  {
214  return data_[i];
215  }
216 
218  [[nodiscard]] constexpr const_reference operator[]( size_type const i ) const noexcept
219  {
220  return data_[i];
221  }
222 
223 private:
224  T data_[N];
225 };
226 } // namespace emlabcpp
MIT License.
Definition: impl.h:31
constexpr void delete_item(size_type const) noexcept
Deconstructs an item at position i.
Definition: static_storage.h:207
std::size_t size_type
Definition: static_storage.h:165
constexpr pointer data() noexcept
Returns pointer to first item of the storage.
Definition: static_storage.h:168
T const * const_pointer
Definition: static_storage.h:164
T & reference
Definition: static_storage.h:161
constexpr reference operator[](size_type const i) noexcept
Provides a reference to item at position i.
Definition: static_storage.h:212
concept trivial_for_static_storage
Definition: static_storage.h:151
constexpr auto move_n(size_type const i, size_type const n, auto iter) noexcept(std::is_nothrow_move_constructible_v< T >)
Moves n items from iterator iter to storage starting at position i
Definition: static_storage.h:196
Args const & args
Definition: min_max.h:83
T * pointer
Definition: static_storage.h:163
T value_type
Definition: static_storage.h:160
constexpr T & emplace_item(size_type const i, Args &&... args) noexcept(std::is_nothrow_constructible_v< T, Args... >)
Constructs an item at position i with arguments args...
Definition: static_storage.h:181
requires(!range_container< Container >) const expr std
Returns index of an element in tuple 't', for which call to predicate f(x) holds true,...
Definition: algorithm.h:127
T const & const_reference
Definition: static_storage.h:162
constexpr void delete_n(size_type const, size_type const) noexcept
Definition: static_storage.h:202
N
Definition: static_storage.h:157
physical_quantity< 0, 0, 0, 0, 0, 0, 0, 0, 1 > byte
Definition: physical_quantity.h:118
constexpr auto copy_n(size_type const i, size_type const n, auto iter) noexcept(std::is_nothrow_copy_constructible_v< T >)
Copies n items from iterator iter to storage starting at position i
Definition: static_storage.h:189
Definition: static_storage.h:35
static F _copy_n(F first, std::size_t n, T *dest)
Definition: static_storage.h:37
static F _move_n(F first, std::size_t n, T *dest)
Definition: static_storage.h:54
Continuous data container that can contain N of uninitialized elements.
Definition: static_storage.h:75
T const & const_reference
Definition: static_storage.h:80
constexpr reference operator[](size_type const i) noexcept
Provides a reference to item at position i.
Definition: static_storage.h:135
static constexpr std::size_t capacity
Definition: static_storage.h:76
T * pointer
Definition: static_storage.h:81
T const * const_pointer
Definition: static_storage.h:82
constexpr auto move_n(size_type const i, size_type const n, auto iter) noexcept(std::is_nothrow_move_constructible_v< T >)
Moves n items from iterator iter to storage starting at position i
Definition: static_storage.h:113
std::size_t size_type
Definition: static_storage.h:83
constexpr T & emplace_item(size_type const i, Args &&... args) noexcept(std::is_nothrow_constructible_v< T, Args... >)
Constructs an item at position i with arguments args...
Definition: static_storage.h:99
constexpr const_pointer data() const noexcept
Returns pointer to first item of the storage.
Definition: static_storage.h:92
constexpr pointer data() noexcept
Returns pointer to first item of the storage.
Definition: static_storage.h:86
constexpr void delete_n(size_type const i, size_type const n) noexcept(std::is_nothrow_destructible_v< T >)
Deconstructs n items starting at position i.
Definition: static_storage.h:120
constexpr const_reference operator[](size_type const i) const noexcept
Provides a reference to item at position i.
Definition: static_storage.h:141
T & reference
Definition: static_storage.h:79
constexpr auto copy_n(size_type const i, size_type const n, auto iter) noexcept(std::is_nothrow_copy_constructible_v< T >)
Copies n items from iterator iter to storage starting at position i
Definition: static_storage.h:106
T value_type
Definition: static_storage.h:78
constexpr void delete_item(size_type const i) noexcept(std::is_nothrow_destructible_v< T >)
Deconstructs an item at position i.
Definition: static_storage.h:129