45 T& operator*()
const {
46 return m_ptr[(m_tail + m_index) %
N];
48 T* operator->()
const {
49 return &m_ptr[(m_tail + m_index) %
N];
52 return m_ptr[(m_tail + m_index + offset) %
N];
82 return {m_index + offset};
85 return {m_index - offset};
88 GAIA_ASSERT(m_ptr == other.m_ptr);
91 GAIA_NODISCARD
bool operator==(
const iterator& other)
const {
92 GAIA_ASSERT(m_ptr == other.m_ptr);
93 return m_index == other.m_index;
95 GAIA_NODISCARD
bool operator!=(
const iterator& other)
const {
96 GAIA_ASSERT(m_ptr == other.m_ptr);
97 return m_index != other.m_index;
99 GAIA_NODISCARD
bool operator>(
const iterator& other)
const {
100 GAIA_ASSERT(m_ptr == other.m_ptr);
101 return m_index > other.m_index;
103 GAIA_NODISCARD
bool operator>=(
const iterator& other)
const {
104 GAIA_ASSERT(m_ptr == other.m_ptr);
105 return m_index >= other.m_index;
108 GAIA_ASSERT(m_ptr == other.m_ptr);
109 return m_index < other.m_index;
112 GAIA_ASSERT(m_ptr == other.m_ptr);
113 return m_index <= other.m_index;
124 static_assert(
N > 1);
126 using value_type = T;
127 using reference = T&;
128 using const_reference =
const T&;
130 using const_pointer =
const T*;
132 using size_type = sringbuffer_detail::size_type;
138 static constexpr size_type extent =
N;
146 template <
typename InputIt>
148 const auto count = (size_type)core::distance(first, last);
149 GAIA_ASSERT(count <= max_size());
156 if constexpr (std::is_pointer_v<InputIt>) {
157 for (size_type
i = 0;
i < count; ++
i)
158 m_data[
i] = first[
i];
159 }
else if constexpr (std::is_same_v<typename InputIt::iterator_category, core::random_access_iterator_tag>) {
160 for (size_type
i = 0;
i < count; ++
i)
161 m_data[
i] = *(first[
i]);
164 for (
auto it = first;
it != last; ++
it)
172 mem::copy_elements<T, false>(m_data, other.m_data, other.size(), 0, extent, other.extent);
176 mem::move_elements<T, false>(m_data, other.m_data, other.size(), 0, extent, other.extent);
178 other.m_tail = size_type(0);
179 other.m_size = size_type(0);
182 constexpr sringbuffer& operator=(std::initializer_list<T>
il)
noexcept {
188 GAIA_ASSERT(core::addressof(other) !=
this);
190 mem::copy_elements<T, false>(&m_data[0], other.m_data, other.size(), 0, extent, other.extent);
192 m_tail = other.m_tail;
193 m_size = other.m_size;
199 GAIA_ASSERT(core::addressof(other) !=
this);
201 mem::move_elements<T, false>(m_data, other.m_data, other.size(), 0, extent, other.extent);
203 m_tail = other.m_tail;
204 m_size = other.m_size;
206 other.m_tail = size_type(0);
207 other.m_size = size_type(0);
214 constexpr void push_back(
const T& arg) {
215 GAIA_ASSERT(m_size <
N);
216 const auto head = (m_tail + m_size) %
N;
221 constexpr void push_back(T&& arg) {
222 GAIA_ASSERT(m_size <
N);
223 const auto head = (m_tail + m_size) %
N;
224 m_data[
head] = GAIA_MOV(arg);
228 constexpr void pop_front(T&
out) {
229 GAIA_ASSERT(!empty());
230 out = m_data[m_tail];
231 m_tail = (m_tail + 1) %
N;
235 constexpr void pop_front(T&&
out) {
236 GAIA_ASSERT(!empty());
237 out = GAIA_MOV(m_data[m_tail]);
238 m_tail = (m_tail + 1) %
N;
242 constexpr void pop_back(T&
out) {
243 GAIA_ASSERT(m_size <
N);
244 const auto head = (m_tail + m_size - 1) %
N;
249 constexpr void pop_back(T&&
out) {
250 GAIA_ASSERT(m_size <
N);
251 const auto head = (m_tail + m_size - 1) %
N;
256 GAIA_NODISCARD
constexpr size_type size()
const noexcept {
260 GAIA_NODISCARD
constexpr bool empty()
const noexcept {
264 GAIA_NODISCARD
constexpr size_type capacity()
const noexcept {
268 GAIA_NODISCARD
constexpr size_type max_size()
const noexcept {
272 GAIA_NODISCARD
constexpr reference front()
noexcept {
273 GAIA_ASSERT(!empty());
274 return m_data[m_tail];
277 GAIA_NODISCARD
constexpr const_reference front()
const noexcept {
278 GAIA_ASSERT(!empty());
279 return m_data[m_tail];
282 GAIA_NODISCARD
constexpr reference back()
noexcept {
283 GAIA_ASSERT(!empty());
284 const auto head = (m_tail + m_size - 1) %
N;
288 GAIA_NODISCARD
constexpr const_reference back()
const noexcept {
289 GAIA_ASSERT(!empty());
290 const auto head = (m_tail + m_size - 1) %
N;
294 GAIA_NODISCARD
constexpr auto begin()
noexcept {
295 return iterator((T*)&m_data[0], m_tail, m_size, 0);
298 GAIA_NODISCARD
constexpr auto begin()
const noexcept {
302 GAIA_NODISCARD
constexpr auto cbegin()
const noexcept {
306 GAIA_NODISCARD
constexpr auto end()
noexcept {
307 return iterator((T*)&m_data[0], m_tail, m_size, m_size);
310 GAIA_NODISCARD
constexpr auto end()
const noexcept {
314 GAIA_NODISCARD
constexpr auto cend()
const noexcept {
318 GAIA_NODISCARD
constexpr bool operator==(
const sringbuffer& other)
const {
319 for (size_type
i = 0;
i <
N; ++
i) {
320 if (m_data[
i] == other.m_data[
i])