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  max(min_size(), max(len+1, label(2*storage_.size())));
42 
43  if (nocopy || empty())
44  {
45  // Simple - no content to preserve
46 
47  clear(); // Reset begin/end
48  storage_.resize_nocopy(newCapacity);
49  }
50  else
51  {
52  // Preserve content
53  const labelRange range1 = range_one();
54  const labelRange range2 = range_two();
55 
56  List<T> old(newCapacity);
57  storage_.swap(old);
58  begin_ = 0;
59  end_ = 0;
60 
61  for (const label i : range1)
62  {
63  storage_[end_++] = std::move(old[i]);
64  }
65  for (const label i : range2)
66  {
67  storage_[end_++] = std::move(old[i]);
68  }
69  }
70  }
71 }
72 
73 
74 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
75 
76 template<class T>
78 {
79  const label len = size_one();
80  return (len ? storage_.slice(begin_, len) : SubList<T>());
81 }
82 
83 
84 template<class T>
86 {
87  const label len = size_two();
88  return (len ? storage_.slice(0, len) : SubList<T>());
89 }
90 
91 
92 template<class T>
94 {
95  const label len = size_one();
96  return (len ? storage_.slice(begin_, len) : SubList<T>());
97 }
98 
99 
100 template<class T>
102 {
103  const label len = size_two();
104  return (len ? storage_.slice(0, len) : SubList<T>());
105 }
106 
107 
108 template<class T>
109 Foam::label Foam::CircularBuffer<T>::find(const T& val, label pos) const
110 {
111  if (pos < 0) return -1; // no-op
112 
113  label i = -1;
114 
115  const auto list1 = this->array_one();
116 
117  if (pos < list1.size())
118  {
119  // Can start search in first array
120  i = list1.find(val, pos);
121 
122  // Position for continued search in second array
123  pos = 0;
124  }
125  else
126  {
127  // Position for continued search in second array
128  pos -= list1.size();
129  }
130 
131  const auto list2 = this->array_two();
132 
133  if (i < 0 && list2.size())
134  {
135  // Not yet found, continue search in second array
136  i = list2.find(val, pos);
137 
138  if (i >= 0)
139  {
140  // As flat index into the entire buffer
141  i += list1.size();
142  }
143  }
144 
145  return i;
146 }
147 
148 
149 template<class T>
151 {
152  const label n = this->size();
153  const label nBy2 = n/2;
154 
155  for (label i = 0; i < nBy2; ++i)
156  {
157  Foam::Swap(operator[](i), operator[](n-1-i));
158  }
159 }
160 
161 
162 template<class T>
164 {
165  const auto list1 = array_one();
166  const auto list2 = array_two();
167 
168  List<T> result(list1.size() + list2.size());
169 
170  if (list1.size())
171  {
172  result.slice(0, list1.size()) = list1;
173  }
174  if (list2.size())
175  {
176  result.slice(list1.size(), list1.size() + list2.size()) = list2;
177  }
178 
179  return result;
180 }
181 
182 
183 // ************************************************************************* //
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 List obtained as a section of another List.
Definition: SubList.H:50
A simple list of objects of type <T> that is intended to be used as a circular buffer (eg...
patchWriters clear()
const volScalarField & T
SubList< T > array_one()
The contents of the first internal array.
void Swap(DynamicList< T, SizeMinA > &a, DynamicList< T, SizeMinB > &b)
Exchange contents of lists - see DynamicList::swap().
Definition: DynamicList.H:692
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.