Panda3D
 All Classes Functions Variables Enumerations
dcNumericRange.I
00001 // Filename: dcNumericRange.I
00002 // Created by:  drose (21Jun04)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 
00016 ////////////////////////////////////////////////////////////////////
00017 //     Function: DCNumericRange::Constructor
00018 //       Access: Public
00019 //  Description:
00020 ////////////////////////////////////////////////////////////////////
00021 template <class NUM>
00022 INLINE DCNumericRange<NUM>::
00023 DCNumericRange() {
00024 }
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //     Function: DCNumericRange::Constructor
00028 //       Access: Public
00029 //  Description:
00030 ////////////////////////////////////////////////////////////////////
00031 template <class NUM>
00032 INLINE DCNumericRange<NUM>::
00033 DCNumericRange(Number min, Number max) {
00034   add_range(min, max);
00035 }
00036 
00037 ////////////////////////////////////////////////////////////////////
00038 //     Function: DCNumericRange::Copy Constructor
00039 //       Access: Public
00040 //  Description:
00041 ////////////////////////////////////////////////////////////////////
00042 template <class NUM>
00043 INLINE DCNumericRange<NUM>::
00044 DCNumericRange(const DCNumericRange<NUM> &copy) :
00045   _ranges(copy._ranges)
00046 {
00047 }
00048 
00049 ////////////////////////////////////////////////////////////////////
00050 //     Function: DCNumericRange::Copy Assignment Operator
00051 //       Access: Public
00052 //  Description:
00053 ////////////////////////////////////////////////////////////////////
00054 template <class NUM>
00055 INLINE void DCNumericRange<NUM>::
00056 operator = (const DCNumericRange<NUM> &copy) {
00057   _ranges = copy._ranges;
00058 }
00059 
00060 ////////////////////////////////////////////////////////////////////
00061 //     Function: DCNumericRange::is_in_range
00062 //       Access: Public
00063 //  Description: Returns true if the indicated number is within the
00064 //               specified range, false otherwise.
00065 ////////////////////////////////////////////////////////////////////
00066 template <class NUM>
00067 bool DCNumericRange<NUM>::
00068 is_in_range(Number num) const {
00069   if (_ranges.empty()) {
00070     return true;
00071   }
00072 
00073   TYPENAME Ranges::const_iterator ri;
00074   for (ri = _ranges.begin(); ri != _ranges.end(); ++ri) {
00075     if (num >= (*ri)._min && num <= (*ri)._max) {
00076       return true;
00077     }
00078   }
00079 
00080   return false;
00081 }
00082 
00083 ////////////////////////////////////////////////////////////////////
00084 //     Function: DCNumericRange::validate
00085 //       Access: Public
00086 //  Description: Convenience function to validate the indicated
00087 //               number.  If the number is within the specified range,
00088 //               does nothing; otherwise, if it is outside the range,
00089 //               sets range_error to true.
00090 ////////////////////////////////////////////////////////////////////
00091 template <class NUM>
00092 INLINE void DCNumericRange<NUM>::
00093 validate(Number num, bool &range_error) const {
00094   if (!is_in_range(num)) {
00095     range_error = true;
00096   }
00097 }
00098 
00099 ////////////////////////////////////////////////////////////////////
00100 //     Function: DCNumericRange::has_one_value
00101 //       Access: Public
00102 //  Description: Returns true if the numeric range specifies exactly
00103 //               one legal value, false if multiple values are legal.
00104 ////////////////////////////////////////////////////////////////////
00105 template <class NUM>
00106 INLINE bool DCNumericRange<NUM>::
00107 has_one_value() const {
00108   return _ranges.size() == 1 && _ranges[0]._min == _ranges[0]._max;
00109 }
00110 
00111 ////////////////////////////////////////////////////////////////////
00112 //     Function: DCNumericRange::get_one_value
00113 //       Access: Public
00114 //  Description: If has_one_value() returns true, this returns the one
00115 //               legal value accepted by the numeric range.
00116 ////////////////////////////////////////////////////////////////////
00117 template <class NUM>
00118 INLINE TYPENAME DCNumericRange<NUM>::Number DCNumericRange<NUM>::
00119 get_one_value() const {
00120   nassertr(has_one_value(), 0);
00121   return _ranges[0]._min;
00122 }
00123 
00124 ////////////////////////////////////////////////////////////////////
00125 //     Function: DCNumericRange::generate_hash
00126 //       Access: Public
00127 //  Description: 
00128 ////////////////////////////////////////////////////////////////////
00129 template <class NUM>
00130 void DCNumericRange<NUM>::
00131 generate_hash(HashGenerator &hashgen) const {
00132   if (!_ranges.empty()) {
00133     hashgen.add_int(_ranges.size());
00134     TYPENAME Ranges::const_iterator ri;
00135     for (ri = _ranges.begin(); ri != _ranges.end(); ++ri) {
00136       // We don't account for the fractional part of floating-point
00137       // ranges here.  Shouldn't be a real issue.
00138       hashgen.add_int((int)(*ri)._min);
00139       hashgen.add_int((int)(*ri)._max);
00140     }
00141   }
00142 }
00143 
00144 ////////////////////////////////////////////////////////////////////
00145 //     Function: DCNumericRange::output
00146 //       Access: Public
00147 //  Description: 
00148 ////////////////////////////////////////////////////////////////////
00149 template <class NUM>
00150 void DCNumericRange<NUM>::
00151 output(ostream &out, Number divisor) const {
00152   if (!_ranges.empty()) {
00153     TYPENAME Ranges::const_iterator ri;
00154     ri = _ranges.begin();
00155     output_minmax(out, divisor, *ri);
00156     ++ri;
00157     while (ri != _ranges.end()) {
00158       out << ", ";
00159       output_minmax(out, divisor, *ri);
00160       ++ri;
00161     }
00162   }
00163 }
00164 
00165 ////////////////////////////////////////////////////////////////////
00166 //     Function: DCNumericRange::output_char
00167 //       Access: Public
00168 //  Description: Outputs the range, formatting the numeric values as
00169 //               quoted ASCII characters.
00170 ////////////////////////////////////////////////////////////////////
00171 template <class NUM>
00172 void DCNumericRange<NUM>::
00173 output_char(ostream &out, Number divisor) const {
00174   if (divisor != 1) {
00175     output(out, divisor);
00176 
00177   } else {
00178     if (!_ranges.empty()) {
00179       TYPENAME Ranges::const_iterator ri;
00180       ri = _ranges.begin();
00181       output_minmax_char(out, *ri);
00182       ++ri;
00183       while (ri != _ranges.end()) {
00184         out << ", ";
00185         output_minmax_char(out, *ri);
00186         ++ri;
00187       }
00188     }
00189   }
00190 }
00191 
00192 ////////////////////////////////////////////////////////////////////
00193 //     Function: DCNumericRange::clear
00194 //       Access: Public
00195 //  Description: 
00196 ////////////////////////////////////////////////////////////////////
00197 template <class NUM>
00198 INLINE void DCNumericRange<NUM>::
00199 clear() {
00200   _ranges.clear();
00201 }
00202 
00203 ////////////////////////////////////////////////////////////////////
00204 //     Function: DCNumericRange::add_range
00205 //       Access: Public
00206 //  Description: Adds a new minmax to the list of ranges.  This is
00207 //               normally called only during dc file parsing.  Returns
00208 //               true if successful, or false if the new minmax
00209 //               overlaps an existing minmax.
00210 ////////////////////////////////////////////////////////////////////
00211 template <class NUM>
00212 bool DCNumericRange<NUM>::
00213 add_range(Number min, Number max) {
00214   // Check for an overlap.  This is probably indicative of a typo and
00215   // should be reported.
00216   if (max < min) {
00217     return false;
00218   }
00219 
00220   TYPENAME Ranges::const_iterator ri;
00221   for (ri = _ranges.begin(); ri != _ranges.end(); ++ri) {
00222     if ((min >= (*ri)._min && min <= (*ri)._max) ||
00223         (max >= (*ri)._min && max <= (*ri)._max) ||
00224         (min < (*ri)._min && max > (*ri)._max)) {
00225       return false;
00226     }
00227   }
00228 
00229   MinMax minmax;
00230   minmax._min = min;
00231   minmax._max = max;
00232   _ranges.push_back(minmax);
00233 
00234   return true;
00235 }
00236 
00237 ////////////////////////////////////////////////////////////////////
00238 //     Function: DCNumericRange::is_empty
00239 //       Access: Private
00240 //  Description: Returns true if the range contains no elements (and
00241 //               thus allows all numbers), false if it contains at
00242 //               least one.
00243 ////////////////////////////////////////////////////////////////////
00244 template <class NUM>
00245 INLINE bool DCNumericRange<NUM>::
00246 is_empty() const {
00247   return _ranges.empty();
00248 }
00249 
00250 ////////////////////////////////////////////////////////////////////
00251 //     Function: DCNumericRange::get_num_ranges
00252 //       Access: Private
00253 //  Description: Returns the number of minmax components in the range
00254 //               description.
00255 ////////////////////////////////////////////////////////////////////
00256 template <class NUM>
00257 INLINE int DCNumericRange<NUM>::
00258 get_num_ranges() const {
00259   return _ranges.size();
00260 }
00261 
00262 ////////////////////////////////////////////////////////////////////
00263 //     Function: DCNumericRange::get_min
00264 //       Access: Private
00265 //  Description: Returns the minimum value defined by the nth component.
00266 ////////////////////////////////////////////////////////////////////
00267 template <class NUM>
00268 INLINE TYPENAME DCNumericRange<NUM>::Number DCNumericRange<NUM>::
00269 get_min(int n) const {
00270   nassertr(n >= 0 && n < (int)_ranges.size(), 0);
00271   return _ranges[n]._min;
00272 }
00273 
00274 ////////////////////////////////////////////////////////////////////
00275 //     Function: DCNumericRange::get_max
00276 //       Access: Private
00277 //  Description: Returns the maximum value defined by the nth component.
00278 ////////////////////////////////////////////////////////////////////
00279 template <class NUM>
00280 INLINE TYPENAME DCNumericRange<NUM>::Number DCNumericRange<NUM>::
00281 get_max(int n) const {
00282   nassertr(n >= 0 && n < (int)_ranges.size(), 0);
00283   return _ranges[n]._max;
00284 }
00285 
00286 ////////////////////////////////////////////////////////////////////
00287 //     Function: DCNumericRange::output_minmax
00288 //       Access: Private
00289 //  Description: Outputs a single element of the range description.
00290 ////////////////////////////////////////////////////////////////////
00291 template <class NUM>
00292 INLINE void DCNumericRange<NUM>::
00293 output_minmax(ostream &out, Number divisor, const MinMax &range) const {
00294   if (divisor == 1) {
00295     if (range._min == range._max) {
00296       out << range._min;
00297     } else {
00298       out << range._min << "-" << range._max;
00299     }
00300   } else {
00301     if (range._min == range._max) {
00302       out << (double)range._min / (double)divisor;
00303     } else {
00304       out << (double)range._min / (double)divisor
00305           << "-"
00306           << (double)range._max / (double)divisor;
00307     }
00308   }
00309 }
00310 
00311 ////////////////////////////////////////////////////////////////////
00312 //     Function: DCNumericRange::output_minmax_char
00313 //       Access: Private
00314 //  Description: Outputs a single element of the range description.
00315 ////////////////////////////////////////////////////////////////////
00316 template <class NUM>
00317 INLINE void DCNumericRange<NUM>::
00318 output_minmax_char(ostream &out, const MinMax &range) const {
00319   if (range._min == range._max) {
00320     DCPacker::enquote_string(out, '\'', string(1, range._min));
00321   } else {
00322     DCPacker::enquote_string(out, '\'', string(1, range._min));
00323     out << "-";
00324     DCPacker::enquote_string(out, '\'', string(1, range._max));
00325   }
00326 }
 All Classes Functions Variables Enumerations