Panda3D
 All Classes Functions Variables Enumerations
dcNumericRange.I
1 // Filename: dcNumericRange.I
2 // Created by: drose (21Jun04)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 
16 ////////////////////////////////////////////////////////////////////
17 // Function: DCNumericRange::Constructor
18 // Access: Public
19 // Description:
20 ////////////////////////////////////////////////////////////////////
21 template <class NUM>
24 }
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: DCNumericRange::Constructor
28 // Access: Public
29 // Description:
30 ////////////////////////////////////////////////////////////////////
31 template <class NUM>
33 DCNumericRange(Number min, Number max) {
34  add_range(min, max);
35 }
36 
37 ////////////////////////////////////////////////////////////////////
38 // Function: DCNumericRange::Copy Constructor
39 // Access: Public
40 // Description:
41 ////////////////////////////////////////////////////////////////////
42 template <class NUM>
45  _ranges(copy._ranges)
46 {
47 }
48 
49 ////////////////////////////////////////////////////////////////////
50 // Function: DCNumericRange::Copy Assignment Operator
51 // Access: Public
52 // Description:
53 ////////////////////////////////////////////////////////////////////
54 template <class NUM>
55 INLINE void DCNumericRange<NUM>::
56 operator = (const DCNumericRange<NUM> &copy) {
57  _ranges = copy._ranges;
58 }
59 
60 ////////////////////////////////////////////////////////////////////
61 // Function: DCNumericRange::is_in_range
62 // Access: Public
63 // Description: Returns true if the indicated number is within the
64 // specified range, false otherwise.
65 ////////////////////////////////////////////////////////////////////
66 template <class NUM>
68 is_in_range(Number num) const {
69  if (_ranges.empty()) {
70  return true;
71  }
72 
73  TYPENAME Ranges::const_iterator ri;
74  for (ri = _ranges.begin(); ri != _ranges.end(); ++ri) {
75  if (num >= (*ri)._min && num <= (*ri)._max) {
76  return true;
77  }
78  }
79 
80  return false;
81 }
82 
83 ////////////////////////////////////////////////////////////////////
84 // Function: DCNumericRange::validate
85 // Access: Public
86 // Description: Convenience function to validate the indicated
87 // number. If the number is within the specified range,
88 // does nothing; otherwise, if it is outside the range,
89 // sets range_error to true.
90 ////////////////////////////////////////////////////////////////////
91 template <class NUM>
92 INLINE void DCNumericRange<NUM>::
93 validate(Number num, bool &range_error) const {
94  if (!is_in_range(num)) {
95  range_error = true;
96  }
97 }
98 
99 ////////////////////////////////////////////////////////////////////
100 // Function: DCNumericRange::has_one_value
101 // Access: Public
102 // Description: Returns true if the numeric range specifies exactly
103 // one legal value, false if multiple values are legal.
104 ////////////////////////////////////////////////////////////////////
105 template <class NUM>
106 INLINE bool DCNumericRange<NUM>::
107 has_one_value() const {
108  return _ranges.size() == 1 && _ranges[0]._min == _ranges[0]._max;
109 }
110 
111 ////////////////////////////////////////////////////////////////////
112 // Function: DCNumericRange::get_one_value
113 // Access: Public
114 // Description: If has_one_value() returns true, this returns the one
115 // legal value accepted by the numeric range.
116 ////////////////////////////////////////////////////////////////////
117 template <class NUM>
118 INLINE TYPENAME DCNumericRange<NUM>::Number DCNumericRange<NUM>::
119 get_one_value() const {
120  nassertr(has_one_value(), 0);
121  return _ranges[0]._min;
122 }
123 
124 ////////////////////////////////////////////////////////////////////
125 // Function: DCNumericRange::generate_hash
126 // Access: Public
127 // Description:
128 ////////////////////////////////////////////////////////////////////
129 template <class NUM>
131 generate_hash(HashGenerator &hashgen) const {
132  if (!_ranges.empty()) {
133  hashgen.add_int(_ranges.size());
134  TYPENAME Ranges::const_iterator ri;
135  for (ri = _ranges.begin(); ri != _ranges.end(); ++ri) {
136  // We don't account for the fractional part of floating-point
137  // ranges here. Shouldn't be a real issue.
138  hashgen.add_int((int)(*ri)._min);
139  hashgen.add_int((int)(*ri)._max);
140  }
141  }
142 }
143 
144 ////////////////////////////////////////////////////////////////////
145 // Function: DCNumericRange::output
146 // Access: Public
147 // Description:
148 ////////////////////////////////////////////////////////////////////
149 template <class NUM>
151 output(ostream &out, Number divisor) const {
152  if (!_ranges.empty()) {
153  TYPENAME Ranges::const_iterator ri;
154  ri = _ranges.begin();
155  output_minmax(out, divisor, *ri);
156  ++ri;
157  while (ri != _ranges.end()) {
158  out << ", ";
159  output_minmax(out, divisor, *ri);
160  ++ri;
161  }
162  }
163 }
164 
165 ////////////////////////////////////////////////////////////////////
166 // Function: DCNumericRange::output_char
167 // Access: Public
168 // Description: Outputs the range, formatting the numeric values as
169 // quoted ASCII characters.
170 ////////////////////////////////////////////////////////////////////
171 template <class NUM>
173 output_char(ostream &out, Number divisor) const {
174  if (divisor != 1) {
175  output(out, divisor);
176 
177  } else {
178  if (!_ranges.empty()) {
179  TYPENAME Ranges::const_iterator ri;
180  ri = _ranges.begin();
181  output_minmax_char(out, *ri);
182  ++ri;
183  while (ri != _ranges.end()) {
184  out << ", ";
185  output_minmax_char(out, *ri);
186  ++ri;
187  }
188  }
189  }
190 }
191 
192 ////////////////////////////////////////////////////////////////////
193 // Function: DCNumericRange::clear
194 // Access: Public
195 // Description:
196 ////////////////////////////////////////////////////////////////////
197 template <class NUM>
198 INLINE void DCNumericRange<NUM>::
199 clear() {
200  _ranges.clear();
201 }
202 
203 ////////////////////////////////////////////////////////////////////
204 // Function: DCNumericRange::add_range
205 // Access: Public
206 // Description: Adds a new minmax to the list of ranges. This is
207 // normally called only during dc file parsing. Returns
208 // true if successful, or false if the new minmax
209 // overlaps an existing minmax.
210 ////////////////////////////////////////////////////////////////////
211 template <class NUM>
213 add_range(Number min, Number max) {
214  // Check for an overlap. This is probably indicative of a typo and
215  // should be reported.
216  if (max < min) {
217  return false;
218  }
219 
220  TYPENAME Ranges::const_iterator ri;
221  for (ri = _ranges.begin(); ri != _ranges.end(); ++ri) {
222  if ((min >= (*ri)._min && min <= (*ri)._max) ||
223  (max >= (*ri)._min && max <= (*ri)._max) ||
224  (min < (*ri)._min && max > (*ri)._max)) {
225  return false;
226  }
227  }
228 
229  MinMax minmax;
230  minmax._min = min;
231  minmax._max = max;
232  _ranges.push_back(minmax);
233 
234  return true;
235 }
236 
237 ////////////////////////////////////////////////////////////////////
238 // Function: DCNumericRange::is_empty
239 // Access: Private
240 // Description: Returns true if the range contains no elements (and
241 // thus allows all numbers), false if it contains at
242 // least one.
243 ////////////////////////////////////////////////////////////////////
244 template <class NUM>
245 INLINE bool DCNumericRange<NUM>::
246 is_empty() const {
247  return _ranges.empty();
248 }
249 
250 ////////////////////////////////////////////////////////////////////
251 // Function: DCNumericRange::get_num_ranges
252 // Access: Private
253 // Description: Returns the number of minmax components in the range
254 // description.
255 ////////////////////////////////////////////////////////////////////
256 template <class NUM>
257 INLINE int DCNumericRange<NUM>::
258 get_num_ranges() const {
259  return _ranges.size();
260 }
261 
262 ////////////////////////////////////////////////////////////////////
263 // Function: DCNumericRange::get_min
264 // Access: Private
265 // Description: Returns the minimum value defined by the nth component.
266 ////////////////////////////////////////////////////////////////////
267 template <class NUM>
268 INLINE TYPENAME DCNumericRange<NUM>::Number DCNumericRange<NUM>::
269 get_min(int n) const {
270  nassertr(n >= 0 && n < (int)_ranges.size(), 0);
271  return _ranges[n]._min;
272 }
273 
274 ////////////////////////////////////////////////////////////////////
275 // Function: DCNumericRange::get_max
276 // Access: Private
277 // Description: Returns the maximum value defined by the nth component.
278 ////////////////////////////////////////////////////////////////////
279 template <class NUM>
280 INLINE TYPENAME DCNumericRange<NUM>::Number DCNumericRange<NUM>::
281 get_max(int n) const {
282  nassertr(n >= 0 && n < (int)_ranges.size(), 0);
283  return _ranges[n]._max;
284 }
285 
286 ////////////////////////////////////////////////////////////////////
287 // Function: DCNumericRange::output_minmax
288 // Access: Private
289 // Description: Outputs a single element of the range description.
290 ////////////////////////////////////////////////////////////////////
291 template <class NUM>
292 INLINE void DCNumericRange<NUM>::
293 output_minmax(ostream &out, Number divisor, const MinMax &range) const {
294  if (divisor == 1) {
295  if (range._min == range._max) {
296  out << range._min;
297  } else {
298  out << range._min << "-" << range._max;
299  }
300  } else {
301  if (range._min == range._max) {
302  out << (double)range._min / (double)divisor;
303  } else {
304  out << (double)range._min / (double)divisor
305  << "-"
306  << (double)range._max / (double)divisor;
307  }
308  }
309 }
310 
311 ////////////////////////////////////////////////////////////////////
312 // Function: DCNumericRange::output_minmax_char
313 // Access: Private
314 // Description: Outputs a single element of the range description.
315 ////////////////////////////////////////////////////////////////////
316 template <class NUM>
317 INLINE void DCNumericRange<NUM>::
318 output_minmax_char(ostream &out, const MinMax &range) const {
319  if (range._min == range._max) {
320  DCPacker::enquote_string(out, '\'', string(1, range._min));
321  } else {
322  DCPacker::enquote_string(out, '\'', string(1, range._min));
323  out << "-";
324  DCPacker::enquote_string(out, '\'', string(1, range._max));
325  }
326 }
void output_char(ostream &out, Number divisor=1) const
Outputs the range, formatting the numeric values as quoted ASCII characters.
void add_int(int num)
Adds another integer to the hash so far.
bool add_range(Number min, Number max)
Adds a new minmax to the list of ranges.
bool is_empty() const
Returns true if the range contains no elements (and thus allows all numbers), false if it contains at...
Represents a range of legal integer or floating-point values.
Number get_min(int n) const
Returns the minimum value defined by the nth component.
This class generates an arbitrary hash number from a sequence of ints.
Definition: hashGenerator.h:26
static void enquote_string(ostream &out, char quote_mark, const string &str)
Outputs the indicated string within quotation marks.
Definition: dcPacker.cxx:1169
void validate(Number num, bool &range_error) const
Convenience function to validate the indicated number.
Number get_max(int n) const
Returns the maximum value defined by the nth component.
bool is_in_range(Number num) const
Returns true if the indicated number is within the specified range, false otherwise.
Number get_one_value() const
If has_one_value() returns true, this returns the one legal value accepted by the numeric range...
bool has_one_value() const
Returns true if the numeric range specifies exactly one legal value, false if multiple values are leg...
int get_num_ranges() const
Returns the number of minmax components in the range description.