FE 0.16.1
Fast, Effecient FrontEnds
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
11namespace fe {
12
13/// A ring buffer with @p N elements.
14template<class T, size_t N>
15class Ring {
16public:
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() = default; // no noexcept: we don't know whether T's operations throw
24 ///@}
25
26 /// @name Access
27 ///@{
28 T& front() { return array_[first_]; }
29 const T& front() const { return array_[first_]; }
30 T& operator[](size_t i) {
31 assert(i < N);
32 return array_[(first_ + i) % N];
33 }
34 const T& operator[](size_t i) const {
35 assert(i < N);
36 return array_[(first_ + i) % N];
37 }
38 ///@}
39
40 /// @name Modifiers
41 ///@{
42 void reset() { first_ = 0; }
43
44 /// Puts @p item into buffer.
45 /// @returns item that falls out.
46 T put(T item) {
47 auto res = array_[first_];
48 array_[first_] = item;
49 first_ = (first_ + 1) % N;
50 return res;
51 }
52 ///@}
53
54 friend void swap(Ring& r1, Ring& r2) {
55 using std::swap;
56 swap(r1.array_, r2.array_);
57 swap(r1.first_, r2.first_);
58 }
59
60private:
61 std::array<T, N> array_;
62 size_t first_ = 0;
63};
64
65/// Specialization if `N == 1` - doesn't need a ring.
66template<class T>
67class Ring<T, 1> {
68public:
69 /// @name Construction
70 ///@{
71 Ring(std::initializer_list<T> list)
72 : item_(*list.begin()) {}
73 Ring() = default;
74 ///@}
75
76 /// @name Access
77 ///@{
78 T& front() { return item_; }
79 const T& front() const { return item_; }
80 T& operator[](size_t i) {
81 assert_unused(i == 0);
82 return item_;
83 }
84 const T& operator[](size_t i) const {
85 assert_unused(i == 0);
86 return item_;
87 }
88 ///@}
89
90 /// @name Modifiers
91 ///@{
92 void reset() {}
93 T put(T item) {
94 auto res = item_;
95 item_ = item;
96 return res;
97 }
98 ///@}
99
100 friend void swap(Ring& r1, Ring& r2) {
101 using std::swap;
102 swap(r1.item_, r2.item_);
103 }
104
105private:
106 T item_;
107};
108
109/// Specialization if `N == 2`; doesn't need a ring, we just copy.
110template<class T>
111class Ring<T, 2> {
112public:
113 /// @name Construction
114 ///@{
115 Ring(std::initializer_list<T> list) {
116 assert(list.size() == 2);
117 std::copy(list.begin(), list.end(), array_.begin());
118 }
119 Ring() = default;
120 ///@}
121
122 /// @name Access
123 ///@{
124 T& front() { return array_[0]; }
125 const T& front() const { return array_[0]; }
126 T& operator[](size_t i) {
127 assert_unused(i < 2);
128 return array_[i];
129 }
130 const T& operator[](size_t i) const {
131 assert_unused(i < 2);
132 return array_[i];
133 }
134 ///@}
135
136 /// @name Modifiers
137 ///@{
138 void reset() {}
139 T put(T item) {
140 auto res = array_[0];
141 array_[0] = array_[1];
142 array_[1] = item;
143 return res;
144 }
145 ///@}
146
147 friend void swap(Ring& r1, Ring& r2) {
148 using std::swap;
149 swap(r1.array_, r2.array_);
150 }
151
152private:
153 std::array<T, 2> array_;
154};
155
156} // namespace fe
#define assert_unused(x)
Definition assert.h:27
const T & front() const
Definition ring.h:79
friend void swap(Ring &r1, Ring &r2)
Definition ring.h:100
const T & operator[](size_t i) const
Definition ring.h:84
T & operator[](size_t i)
Definition ring.h:80
T put(T item)
Definition ring.h:93
T & front()
Definition ring.h:78
Ring(std::initializer_list< T > list)
Definition ring.h:71
void reset()
Definition ring.h:92
T & front()
Definition ring.h:124
const T & front() const
Definition ring.h:125
const T & operator[](size_t i) const
Definition ring.h:130
friend void swap(Ring &r1, Ring &r2)
Definition ring.h:147
void reset()
Definition ring.h:138
T & operator[](size_t i)
Definition ring.h:126
T put(T item)
Definition ring.h:139
Ring(std::initializer_list< T > list)
Definition ring.h:115
void reset()
Definition ring.h:42
const T & operator[](size_t i) const
Definition ring.h:34
T put(T item)
Puts item into buffer.
Definition ring.h:46
friend void swap(Ring &r1, Ring &r2)
Definition ring.h:54
Ring(std::initializer_list< T > list)
Definition ring.h:19
T & front()
Definition ring.h:28
const T & front() const
Definition ring.h:29
Ring()=default
T & operator[](size_t i)
Definition ring.h:30
Definition algo.h:17