Loading...
Searching...
No Matches
CircularBuffer.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2022 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
29
30template<class T>
31void Foam::CircularBuffer<T>::doReserve
32(
33 const bool nocopy,
34 const label len
35)
36{
37 if (storage_.size() < len)
38 {
39 // Increase capacity (doubling)
40 const label newCapacity =
41 Foam::max(min_size(), Foam::max(len+1, label(2*storage_.size())));
42
43 // OR
44 // Foam::ListPolicy::reserve_size<min_size(), 2>
45 // (
46 // len+1,
47 // storage_.size()
48 // );
49
50 if (nocopy || empty())
51 {
52 // Simple - no content to preserve
53
54 clear(); // Reset begin/end
55 storage_.resize_nocopy(newCapacity);
56 }
57 else
58 {
59 // Preserve content
60 const labelRange range1 = range_one();
61 const labelRange range2 = range_two();
62
63 List<T> old(newCapacity);
64 storage_.swap(old);
65 begin_ = 0;
66 end_ = 0;
67
68 for (const label i : range1)
69 {
70 storage_[end_++] = std::move(old[i]);
71 }
72 for (const label i : range2)
73 {
74 storage_[end_++] = std::move(old[i]);
75 }
76 }
77 }
78}
79
80
81// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
82
83template<class T>
86 const label len = size_one();
87 return (len ? storage_.slice(begin_, len) : SubList<T>());
88}
89
90
91template<class T>
94 const label len = size_two();
95 return (len ? storage_.slice(0, len) : SubList<T>());
96}
97
98
99template<class T>
102 const label len = size_one();
103 return (len ? storage_.slice(begin_, len) : SubList<T>());
104}
105
106
107template<class T>
110 const label len = size_two();
111 return (len ? storage_.slice(0, len) : SubList<T>());
112}
113
114
115template<class T>
116Foam::label Foam::CircularBuffer<T>::find(const T& val, label pos) const
117{
118 if (pos < 0) return -1; // no-op
119
120 label i = -1;
121
122 const auto list1 = this->array_one();
123
124 if (pos < list1.size())
125 {
126 // Can start search in first array
127 i = list1.find(val, pos);
128
129 // Position for continued search in second array
130 pos = 0;
131 }
132 else
133 {
134 // Position for continued search in second array
135 pos -= list1.size();
136 }
137
138 const auto list2 = this->array_two();
139
140 if (i < 0 && list2.size())
141 {
142 // Not yet found, continue search in second array
143 i = list2.find(val, pos);
144
145 if (i >= 0)
146 {
147 // As flat index into the entire buffer
148 i += list1.size();
149 }
151
152 return i;
153}
154
155
156template<class T>
158{
159 const label n = this->size();
160 const label nBy2 = n/2;
161
162 for (label i = 0; i < nBy2; ++i)
164 Foam::Swap(operator[](i), operator[](n-1-i));
165 }
166}
167
168
169template<class T>
171{
172 const auto list1 = array_one();
173 const auto list2 = array_two();
174
175 List<T> result(list1.size() + list2.size());
176
177 if (list1.size())
178 {
179 result.slice(0, list1.size()) = list1;
180 }
181 if (list2.size())
182 {
183 result.slice(list1.size(), list1.size() + list2.size()) = list2;
184 }
185
186 return result;
187}
188
189
190// ************************************************************************* //
label n
void reverse()
Reverse the buffer order, swapping elements.
label find(const T &val, label pos=0) const
Find index of the first occurrence of the value.
label size() const noexcept
The current number of buffer items.
SubList< T > array_two()
The contents of the second internal array.
List< T > list() const
Return a copy of the buffer flattened into a single List. Use sparingly!
SubList< T > array_one()
The contents of the first internal array.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
A non-owning sub-view of a List (allocated or unallocated storage).
Definition SubList.H:61
SubList< T > slice(const label pos, label len=-1)
Return SubList slice (non-const access) - no range checking.
Definition SubList.H:258
surface1 clear()
dimensionedScalar pos(const dimensionedScalar &ds)
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:40
void Swap(DynamicList< T, SizeMinA > &a, DynamicList< T, SizeMinB > &b)
Exchange contents of lists - see DynamicList::swap().
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)