00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 template <class NUM>
00022 INLINE DCNumericRange<NUM>::
00023 DCNumericRange() {
00024 }
00025
00026
00027
00028
00029
00030
00031 template <class NUM>
00032 INLINE DCNumericRange<NUM>::
00033 DCNumericRange(Number min, Number max) {
00034 add_range(min, max);
00035 }
00036
00037
00038
00039
00040
00041
00042 template <class NUM>
00043 INLINE DCNumericRange<NUM>::
00044 DCNumericRange(const DCNumericRange<NUM> ©) :
00045 _ranges(copy._ranges)
00046 {
00047 }
00048
00049
00050
00051
00052
00053
00054 template <class NUM>
00055 INLINE void DCNumericRange<NUM>::
00056 operator = (const DCNumericRange<NUM> ©) {
00057 _ranges = copy._ranges;
00058 }
00059
00060
00061
00062
00063
00064
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
00085
00086
00087
00088
00089
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
00101
00102
00103
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
00113
00114
00115
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
00126
00127
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
00137
00138 hashgen.add_int((int)(*ri)._min);
00139 hashgen.add_int((int)(*ri)._max);
00140 }
00141 }
00142 }
00143
00144
00145
00146
00147
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
00167
00168
00169
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
00194
00195
00196
00197 template <class NUM>
00198 INLINE void DCNumericRange<NUM>::
00199 clear() {
00200 _ranges.clear();
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 template <class NUM>
00212 bool DCNumericRange<NUM>::
00213 add_range(Number min, Number max) {
00214
00215
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
00239
00240
00241
00242
00243
00244 template <class NUM>
00245 INLINE bool DCNumericRange<NUM>::
00246 is_empty() const {
00247 return _ranges.empty();
00248 }
00249
00250
00251
00252
00253
00254
00255
00256 template <class NUM>
00257 INLINE int DCNumericRange<NUM>::
00258 get_num_ranges() const {
00259 return _ranges.size();
00260 }
00261
00262
00263
00264
00265
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
00276
00277
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
00288
00289
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
00313
00314
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 }