FE
0.13.1
Header-only C++ frontend library
Toggle main menu visibility
Loading...
Searching...
No Matches
ring.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <cstddef>
4
5
#include <algorithm>
6
#include <array>
7
#include <initializer_list>
8
9
#include <
fe/assert.h
>
10
11
namespace
fe
{
12
13
/// A ring buffer with @p N elements.
14
template
<
class
T,
size_t
N>
15
class
Ring
{
16
public
:
17
/// @name Construction
18
///@{
19
Ring
(std::initializer_list<T> list) {
20
assert(list.size() == N);
21
std::copy(list.begin(), list.end(), array_.begin());
22
}
23
Ring
() noexcept = default;
24
Ring
(const
Ring
&) = default;
25
Ring
(
Ring
&& other) noexcept
26
:
Ring
() {
27
swap
(*
this
, other);
28
}
29
Ring
&
operator=
(
Ring
other)
noexcept
{
return
swap
(*
this
, other), *
this
; }
30
///@}
31
32
/// @name Access
33
///@{
34
T&
front
() {
return
array_[first_]; }
35
const
T&
front
()
const
{
return
array_[first_]; }
36
T&
operator[]
(
size_t
i) {
37
assert(i < N);
38
return
array_[(first_ + i) % N];
39
}
40
const
T&
operator[]
(
size_t
i)
const
{
41
assert(i < N);
42
return
array_[(first_ + i) % N];
43
}
44
///@}
45
46
/// @name Modifiers
47
///@{
48
void
reset
() { first_ = 0; }
49
50
/// Puts @p item into buffer.
51
/// @returns item that falls out.
52
T
put
(T item) {
53
auto
res = array_[first_];
54
array_[first_] = item;
55
first_ = (first_ + 1) % N;
56
return
res;
57
}
58
///@}
59
60
friend
void
swap
(
Ring
& r1,
Ring
& r2)
noexcept
{
61
using
std::swap;
62
swap
(r1.array_, r2.array_);
63
swap
(r1.first_, r2.first_);
64
}
65
66
private
:
67
std::array<T, N> array_;
68
size_t
first_ = 0;
69
};
70
71
/// Specialization if `N == 1` - doesn't need a ring.
72
template
<
class
T>
73
class
Ring
<T, 1> {
74
public
:
75
/// @name Construction
76
///@{
77
Ring
(std::initializer_list<T> list)
78
: item_(*list.begin()) {}
79
Ring
() =
default
;
// no noexcept: we don't know whether T's default constructor throws
80
Ring
(
const
Ring
&) =
default
;
81
Ring
(
Ring
&& other)
82
:
Ring
() {
83
swap
(*
this
, other);
84
}
85
Ring
&
operator=
(
Ring
other)
noexcept
{
return
swap
(*
this
, other), *
this
; }
86
///@}
87
88
/// @name Access
89
///@{
90
T&
front
() {
return
item_; }
91
const
T&
front
()
const
{
return
item_; }
92
T&
operator[]
(
size_t
i) {
93
assert_unused
(i == 0);
94
return
item_;
95
}
96
const
T&
operator[]
(
size_t
i)
const
{
97
assert_unused
(i == 0);
98
return
item_;
99
}
100
///@}
101
102
/// @name Modifiers
103
///@{
104
void
reset
() {}
105
T
put
(T item) {
106
auto
res = item_;
107
item_ = item;
108
return
res;
109
}
110
///@}
111
112
friend
void
swap
(
Ring
& r1,
Ring
& r2)
noexcept
{
113
using
std::swap;
114
swap
(r1.item_, r2.item_);
115
}
116
117
private
:
118
T item_;
119
};
120
121
/// Specialization if `N == 2`; doesn't need a ring, we just copy.
122
template
<
class
T>
123
class
Ring
<T, 2> {
124
public
:
125
/// @name Construction
126
///@{
127
Ring
(std::initializer_list<T> list) {
128
assert(list.size() == 2);
129
std::copy(list.begin(), list.end(), array_.begin());
130
}
131
Ring
() noexcept = default;
132
Ring
(const
Ring
&) = default;
133
Ring
(
Ring
&& other) noexcept
134
:
Ring
() {
135
swap
(*
this
, other);
136
}
137
Ring
&
operator=
(
Ring
other)
noexcept
{
return
swap
(*
this
, other), *
this
; }
138
///@}
139
140
/// @name Access
141
///@{
142
T&
front
() {
return
array_[0]; }
143
const
T&
front
()
const
{
return
array_[0]; }
144
T&
operator[]
(
size_t
i) {
145
assert_unused
(i < 2);
146
return
array_[i];
147
}
148
const
T&
operator[]
(
size_t
i)
const
{
149
assert_unused
(i < 2);
150
return
array_[i];
151
}
152
///@}
153
154
/// @name Modifiers
155
///@{
156
void
reset
() {}
157
T
put
(T item) {
158
auto
res = array_[0];
159
array_[0] = array_[1];
160
array_[1] = item;
161
return
res;
162
}
163
///@}
164
165
friend
void
swap
(
Ring
& r1,
Ring
& r2)
noexcept
{
166
using
std::swap;
167
swap
(r1.array_, r2.array_);
168
}
169
170
private
:
171
std::array<T, 2> array_;
172
};
173
174
}
// namespace fe
assert.h
assert_unused
#define assert_unused(x)
Definition
assert.h:50
fe::Ring< T, 1 >::front
const T & front() const
Definition
ring.h:91
fe::Ring< T, 1 >::operator=
Ring & operator=(Ring other) noexcept
Definition
ring.h:85
fe::Ring< T, 1 >::Ring
Ring(const Ring &)=default
fe::Ring< T, 1 >::operator[]
const T & operator[](size_t i) const
Definition
ring.h:96
fe::Ring< T, 1 >::Ring
Ring(Ring &&other)
Definition
ring.h:81
fe::Ring< T, 1 >::operator[]
T & operator[](size_t i)
Definition
ring.h:92
fe::Ring< T, 1 >::put
T put(T item)
Definition
ring.h:105
fe::Ring< T, 1 >::front
T & front()
Definition
ring.h:90
fe::Ring< T, 1 >::swap
friend void swap(Ring &r1, Ring &r2) noexcept
Definition
ring.h:112
fe::Ring< T, 1 >::Ring
Ring()=default
fe::Ring< T, 1 >::Ring
Ring(std::initializer_list< T > list)
Definition
ring.h:77
fe::Ring< T, 1 >::reset
void reset()
Definition
ring.h:104
fe::Ring< T, 2 >::front
T & front()
Definition
ring.h:142
fe::Ring< T, 2 >::front
const T & front() const
Definition
ring.h:143
fe::Ring< T, 2 >::operator[]
const T & operator[](size_t i) const
Definition
ring.h:148
fe::Ring< T, 2 >::operator=
Ring & operator=(Ring other) noexcept
Definition
ring.h:137
fe::Ring< T, 2 >::Ring
Ring() noexcept=default
fe::Ring< T, 2 >::swap
friend void swap(Ring &r1, Ring &r2) noexcept
Definition
ring.h:165
fe::Ring< T, 2 >::reset
void reset()
Definition
ring.h:156
fe::Ring< T, 2 >::operator[]
T & operator[](size_t i)
Definition
ring.h:144
fe::Ring< T, 2 >::put
T put(T item)
Definition
ring.h:157
fe::Ring< T, 2 >::Ring
Ring(std::initializer_list< T > list)
Definition
ring.h:127
fe::Ring::reset
void reset()
Definition
ring.h:48
fe::Ring::operator=
Ring & operator=(Ring other) noexcept
Definition
ring.h:29
fe::Ring::operator[]
const T & operator[](size_t i) const
Definition
ring.h:40
fe::Ring::Ring
Ring() noexcept=default
fe::Ring::put
T put(T item)
Puts item into buffer.
Definition
ring.h:52
fe::Ring::swap
friend void swap(Ring &r1, Ring &r2) noexcept
Definition
ring.h:60
fe::Ring::Ring
Ring(std::initializer_list< T > list)
Definition
ring.h:19
fe::Ring::front
T & front()
Definition
ring.h:34
fe::Ring::front
const T & front() const
Definition
ring.h:35
fe::Ring::operator[]
T & operator[](size_t i)
Definition
ring.h:36
fe
Definition
algo.h:17
fe
ring.h
Generated by
1.18.0