scalarRange.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 | Copyright (C) 2011 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "scalarRange.H"
27 #include "token.H"
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 int Foam::scalarRange::debug(::Foam::debug::debugSwitch("scalarRange", 0));
32 
33 
34 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35 
37 :
38  type_(EMPTY),
39  value_(0),
40  value2_(0)
41 {}
42 
43 
44 Foam::scalarRange::scalarRange(const scalar lower, const scalar upper)
45 :
46  type_(RANGE),
47  value_(lower),
48  value2_(upper)
49 {
50  // mark invalid range as empty
51  if (lower > upper)
52  {
53  type_ = EMPTY;
54  value_ = value2_ = 0;
55  }
56 }
57 
58 
60 :
61  type_(EXACT),
62  value_(0),
63  value2_(0)
64 {
65  is >> *this;
66 
68  {
69  Info<<"constructed scalarRange: " << *this << endl;
70  }
71 }
72 
73 
74 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
75 
77 {
78  return type_ == EMPTY;
79 }
80 
81 
83 {
84  return type_ != EMPTY;
85 }
86 
87 
89 {
90  return type_ == EXACT;
91 }
92 
93 
94 Foam::scalar Foam::scalarRange::value() const
95 {
96  return value_;
97 }
98 
99 
100 Foam::scalar Foam::scalarRange::lower() const
101 {
102  if (type_ == UPPER)
103  {
104  return -Foam::GREAT;
105  }
106  else
107  {
108  return value_;
109  }
110 }
111 
112 Foam::scalar Foam::scalarRange::upper() const
113 {
114  switch (type_)
115  {
116  case LOWER:
117  return Foam::GREAT;
118  break;
119 
120  case RANGE:
121  return value2_;
122  break;
123 
124  default:
125  return value_;
126  break;
127  }
128 }
129 
130 
131 bool Foam::scalarRange::selected(const scalar value) const
132 {
133  switch (type_)
134  {
135  case LOWER:
136  return value >= value_;
137 
138  case UPPER:
139  return value <= value_;
140 
141  case RANGE:
142  return value >= value_ && value <= value2_;
143 
144  case EXACT:
145  return value == value_;
146 
147  default:
148  return false;
149  }
150 }
151 
152 
153 
154 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
155 
157 {
158  return
159  (
160  type_ == range.type_
161  && value_ == range.value_
162  && value2_ == range.value2_
163  );
164 }
165 
166 
168 {
169  return !(operator==(range));
170 }
171 
172 
173 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
174 
176 {
177  range.type_ = scalarRange::EXACT;
178  range.value_ = 0;
179  range.value2_ = 0;
180 
181  List<token> toks(4);
182  label nTok = 0;
183 
184  // skip leading ','
185  do
186  {
187  is.read(toks[nTok]);
188  is.check("scalarRange token read");
189  }
190  while
191  (
192  toks[nTok].isPunctuation()
193  && toks[nTok].pToken() == token::COMMA
194  );
195 
196  ++nTok;
197 
198  // looks like ':VALUE'
199  if
200  (
201  toks[nTok-1].isPunctuation()
202  && toks[nTok-1].pToken() == token::COLON
203  )
204  {
205  range.type_ = scalarRange::UPPER;
206  is.read(toks[nTok++]);
207  is.check("scalarRange token read");
208  }
209 
210  // a number is now required
211  if (!toks[nTok-1].isNumber())
212  {
213  is.setBad();
214  range.type_ = scalarRange::EMPTY;
215  range.value_ = range.value2_ = 0;
216  Info<< "rejected ill-formed or empty range:";
217  for (label i=0; i<nTok; ++i)
218  {
219  Info<< " " << toks[i];
220  }
221  Info<< endl;
222  return is;
223  }
224 
225  range.value_ = toks[nTok-1].number();
226  is.read(toks[nTok++]);
227  is.check("scalarRange token read");
228 
229  if (scalarRange::debug)
230  {
231  Info<<"tokens:";
232  for (label i=0; i<nTok; ++i)
233  {
234  Info<< " " << toks[i];
235  }
236  Info<< endl;
237  }
238 
239  // could be 'VALUE:' or 'VALUE:VALUE'
240  if
241  (
242  toks[nTok-1].isPunctuation()
243  && toks[nTok-1].pToken() == token::COLON
244  )
245  {
246  if (range.type_ == scalarRange::UPPER)
247  {
248  is.setBad();
249  range.type_ = scalarRange::EMPTY;
250  range.value_ = range.value2_ = 0;
251  Info<< "rejected ill-formed range:";
252  for (label i=0; i<nTok; ++i)
253  {
254  Info<< " " << toks[i];
255  }
256  Info<< endl;
257  return is;
258  }
259 
260  is.read(toks[nTok++]);
261  is.check("scalarRange token read");
262 
263  if (scalarRange::debug)
264  {
265  Info<<"tokens:";
266  for (label i=0; i<nTok; ++i)
267  {
268  Info<< " " << toks[i];
269  }
270  Info<< endl;
271  }
272 
273 
274  // if there is a number, we have 'VALUE:VALUE' and not simply 'VALUE:'
275  if (toks[nTok-1].isNumber())
276  {
277  range.type_ = scalarRange::RANGE;
278  range.value2_ = toks[nTok-1].number();
279  is.read(toks[nTok++]);
280  is.check("scalarRange token read");
281  }
282  else
283  {
284  range.type_ = scalarRange::LOWER;
285  }
286  }
287 
288  if (scalarRange::debug)
289  {
290  Info<<"tokens:";
291  for (label i=0; i<nTok; ++i)
292  {
293  Info<< " " << toks[i];
294  }
295  Info<< endl;
296  }
297 
298 
299  // some remaining tokens, but they are not the next comma
300  // - this is a problem!
301  if
302  (
303  toks[nTok-1].good()
304  &&
305  (
306  !toks[nTok-1].isPunctuation()
307  || toks[nTok-1].pToken() != token::COMMA
308  )
309  )
310  {
311  is.setBad();
312  range.type_ = scalarRange::EMPTY;
313  range.value_ = range.value2_ = 0;
314 
315  Info<< "rejected ill-formed range:";
316  for (label i=0; i<nTok; ++i)
317  {
318  Info<< " " << toks[i];
319  }
320  Info<< endl;
321  }
322 
323  return is;
324 }
325 
326 
328 {
329  switch (range.type_)
330  {
331  case scalarRange::LOWER:
332  os << range.value_ << " <=> Inf";
333  break;
334 
335  case scalarRange::UPPER:
336  os << "-Inf <=> " << range.value_;
337  break;
338 
339  case scalarRange::RANGE:
340  os << range.value_ << " <=> " << range.value2_;
341  break;
342 
343  case scalarRange::EXACT:
344  os << range.value_;
345  break;
346 
347  default:
348  os << "empty";
349  break;
350  }
351 
352  return os;
353 }
354 
355 
356 // ************************************************************************* //
bool valid() const
Is the range non-empty?
Definition: scalarRange.C:82
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
bool operator!=(const scalarRange &) const
Definition: scalarRange.C:167
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:92
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
bool selected(const scalar) const
Return true if the value is within the range.
Definition: scalarRange.C:131
scalar range
bool empty() const
Is the range empty?
Definition: scalarRange.C:76
void setBad()
Set stream to be bad.
Definition: IOstream.H:487
virtual Istream & read(token &)=0
Return next token from stream.
bool operator==(const scalarRange &) const
Definition: scalarRange.C:156
Istream & operator>>(Istream &, directionInfo &)
int debugSwitch(const char *name, const int defaultValue=0)
Lookup debug switch or add default value.
Definition: debug.C:166
scalar upper() const
The upper limit.
Definition: scalarRange.C:112
bool isExact() const
Is the range &#39;EXACT&#39;?
Definition: scalarRange.C:88
scalar lower() const
The lower limit.
Definition: scalarRange.C:100
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
scalarRange()
Construct an empty range.
Definition: scalarRange.C:36
Ostream & operator<<(Ostream &, const ensightPart &)
static int debug
Definition: scalarRange.H:84
messageStream Info
scalar value() const
The value constituting an &#39;EXACT&#39; match.
Definition: scalarRange.C:94
A scalar range specifier.
Definition: scalarRange.H:62