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 -------------------------------------------------------------------------------
10 License
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 
30 template<class T>
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 
83 template<class T>
85 {
86  const label len = size_one();
87  return (len ? storage_.slice(begin_, len) : SubList<T>());
88 }
89 
90 
91 template<class T>
93 {
94  const label len = size_two();
95  return (len ? storage_.slice(0, len) : SubList<T>());
96 }
97 
98 
99 template<class T>
101 {
102  const label len = size_one();
103  return (len ? storage_.slice(begin_, len) : SubList<T>());
104 }
105 
106 
107 template<class T>
109 {
110  const label len = size_two();
111  return (len ? storage_.slice(0, len) : SubList<T>());
112 }
113 
114 
115 template<class T>
116 Foam::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  }
150  }
151 
152  return i;
153 }
154 
155 
156 template<class T>
158 {
159  const label n = this->size();
160  const label nBy2 = n/2;
161 
162  for (label i = 0; i < nBy2; ++i)
163  {
164  Foam::Swap(operator[](i), operator[](n-1-i));
165  }
166 }
167 
168 
169 template<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 // ************************************************************************* //
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
dimensionedScalar pos(const dimensionedScalar &ds)
List< T > list() const
Return a copy of the buffer flattened into a single List. Use sparingly!
A non-owning sub-view of a List (allocated or unallocated storage).
Definition: SubList.H:44
A simple list of objects of type <T> that is intended to be used as a circular buffer (eg...
const volScalarField & T
SubList< T > array_one()
The contents of the first internal array.
surface1 clear()
void Swap(DynamicList< T, SizeMinA > &a, DynamicList< T, SizeMinB > &b)
Exchange contents of lists - see DynamicList::swap().
Definition: DynamicList.H:694
label n
SubList< T > array_two()
The contents of the second internal array.
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.