ome-xml 5.2.3

ConstrainedNumeric.h
1 /*
2 * #%L
3 * OME-XML C++ library for working with OME-XML metadata structures.
4 * %%
5 * Copyright © 2006 - 2016 Open Microscopy Environment:
6 * - Massachusetts Institute of Technology
7 * - National Institutes of Health
8 * - University of Dundee
9 * - Board of Regents of the University of Wisconsin-Madison
10 * - Glencoe Software, Inc.
11 * %%
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * The views and conclusions contained in the software and documentation are
34 * those of the authors and should not be interpreted as representing official
35 * policies, either expressed or implied, of any organization.
36 * #L%
37 */
38
39 #ifndef OME_XML_MODEL_PRIMITIVES_CONSTRAINEDNUMERIC_H
40 #define OME_XML_MODEL_PRIMITIVES_CONSTRAINEDNUMERIC_H
41
42 #include <limits>
43 #include <string>
44 #include <sstream>
45
46 #include <boost/format.hpp>
47 #include <boost/operators.hpp>
48
49 #include <ome/compat/cstdint.h>
50
51 namespace ome
52 {
53 namespace xml
54 {
55 namespace model
56 {
60 namespace primitives
61 {
62
67 struct ConstrainedNumericError
68 {
76 template<typename T>
77 inline void
78 operator() (const T& value,
79 const std::string& typestr)
80 {
81 boost::format fmt("‘%1%’ not a supported value of %2%");
82 fmt % value % typestr;
83 throw std::invalid_argument(fmt.str());
84 }
85 };
86
116 template<typename N,
117 typename C,
118 typename E = ConstrainedNumericError>
119 class ConstrainedNumeric : private boost::partially_ordered<ConstrainedNumeric<N, C, E>, N,
120 boost::partially_ordered<ConstrainedNumeric<N, C, E>,
121 boost::equality_comparable2<ConstrainedNumeric<N, C, E>, N,
122 boost::equality_comparable<ConstrainedNumeric<N, C, E>,
123 boost::addable2<ConstrainedNumeric<N, C, E>, N,
124 boost::addable<ConstrainedNumeric<N, C, E>,
125 boost::subtractable2<ConstrainedNumeric<N, C, E>, N,
126 boost::subtractable<ConstrainedNumeric<N, C, E>,
127 boost::dividable2<ConstrainedNumeric<N, C, E>, N,
128 boost::dividable<ConstrainedNumeric<N, C, E>,
129 boost::multipliable2<ConstrainedNumeric<N, C, E>, N,
130 boost::multipliable<ConstrainedNumeric<N, C, E>,
131 boost::incrementable<ConstrainedNumeric<N, C, E>,
132 boost::decrementable<ConstrainedNumeric<N, C, E> > > > > > > > > > > > > > >
133 {
134 public:
136 typedef N value_type;
138 typedef C constraint_type;
140 typedef E error_policy_type;
141
143 static const value_type default_value;
144
154 ConstrainedNumeric():
155 value(default_value)
156 {
157 check();
158 }
159
167 ConstrainedNumeric(value_type value):
168 value(value)
169 {
170 check();
171 }
172
180 ConstrainedNumeric(const std::string& value)
181 {
182 std::istringstream is(value);
183 is.imbue(std::locale::classic());
184 value_type nval;
185 is >> nval;
186 if (!is)
187 {
188 error_policy_type error;
189 error(value, this->typestr);
190 }
191 this->value = nval;
192 check();
193 }
194
200 ConstrainedNumeric(const ConstrainedNumeric& value):
201 value(value)
202 {
203 check();
204 }
205
211 inline
212 operator value_type () const
213 {
214 return this->value;
215 }
216
226 inline ConstrainedNumeric&
227 operator= (const ConstrainedNumeric& value)
228 {
229 this->value = value.value;
230 check();
231 return *this;
232 }
233
242 inline ConstrainedNumeric&
243 operator= (const value_type& value)
244 {
245 this->value = value;
246 check();
247 return *this;
248 }
249
258 inline ConstrainedNumeric&
259 operator+= (const ConstrainedNumeric& value)
260 {
261 this->value += value.value;
262 check();
263 return *this;
264 }
265
274 inline ConstrainedNumeric&
275 operator-= (const ConstrainedNumeric& value)
276 {
277 this->value -= value.value;
278 check();
279 return *this;
280 }
281
290 inline ConstrainedNumeric&
291 operator*= (const ConstrainedNumeric& value)
292 {
293 this->value *= value.value;
294 check();
295 return *this;
296 }
297
306 inline ConstrainedNumeric&
307 operator/= (const ConstrainedNumeric& value)
308 {
309 this->value /= value.value;
310 check();
311 return *this;
312 }
313
322 inline ConstrainedNumeric&
323 operator%= (const ConstrainedNumeric& value)
324 {
325 this->value %= value.value;
326 check();
327 return *this;
328 }
329
338 inline ConstrainedNumeric&
339 operator+= (const value_type& value)
340 {
341 this->value += value;
342 check();
343 return *this;
344 }
345
354 inline ConstrainedNumeric&
355 operator-= (const value_type& value)
356 {
357 this->value -= value;
358 check();
359 return *this;
360 }
361
370 inline ConstrainedNumeric&
371 operator*= (const value_type& value)
372 {
373 this->value *= value;
374 check();
375 return *this;
376 }
377
386 inline ConstrainedNumeric&
387 operator/= (const value_type& value)
388 {
389 this->value /= value;
390 check();
391 return *this;
392 }
393
402 inline ConstrainedNumeric&
403 operator%= (const value_type& value)
404 {
405 this->value %= value;
406 check();
407 return *this;
408 }
409
416 inline ConstrainedNumeric&
417 operator++ ()
418 {
419 ++this->value;
420 check();
421 return *this;
422 }
423
430 inline ConstrainedNumeric&
431 operator-- ()
432 {
433 --this->value;
434 check();
435 return *this;
436 }
437
445 inline bool
446 operator< (const ConstrainedNumeric& value) const
447 {
448 return this->value < value.value;
449 }
450
458 inline bool
459 operator< (const value_type& value) const
460 {
461 return this->value < value;
462 }
463
464 // Note operator> (const ConstrainedNumeric& value) const is
465 // provided by Boost.Operators.
466
474 inline bool
475 operator> (const value_type& value) const
476 {
477 return this->value > value;
478 }
479
487 inline bool
488 operator== (const ConstrainedNumeric& value) const
489 {
490 return this->value == value.value;
491 }
492
500 inline bool
501 operator== (const value_type& value) const
502 {
503 return this->value == value;
504 }
505
506 private:
513 inline void
514 check ()
515 {
516 constraint_type constraint;
517 if (!constraint(this->value))
518 {
519 error_policy_type error;
520 error(this->value, this->typestr);
521 }
522 }
523
525 value_type value;
527 static const std::string typestr;
528
536 template<class _charT,
537 class _traits,
538 typename _N,
539 typename _C,
540 typename _E>
541 friend
542 std::basic_istream<_charT,_traits>&
543 operator>> (std::basic_istream<_charT,_traits>& is,
544 ConstrainedNumeric<_N, _C, _E>& value);
545 };
546
554 template<class charT,
555 class traits,
556 typename N,
557 typename C,
558 typename E>
559 inline std::basic_istream<charT,traits>&
560 operator>> (std::basic_istream<charT,traits>& is,
561 ConstrainedNumeric<N, C, E>& value)
562 {
563 typename ConstrainedNumeric<N, C, E>::value_type nval;
564 is >> nval;
565 if (!is)
566 {
567 boost::format fmt("Failed to parse invalid input for %1%");
568 fmt % ConstrainedNumeric<N, C, E>::typestr;
569 throw std::invalid_argument(fmt.str());
570 }
571
572 value = nval;
573
574 return is;
575 }
576
584 template<class charT,
585 class traits,
586 typename N,
587 typename C,
588 typename E>
589 inline std::basic_ostream<charT,traits>&
590 operator<< (std::basic_ostream<charT,traits>& os,
591 const ConstrainedNumeric<N, C, E>& value)
592 {
593 return os << static_cast<typename ConstrainedNumeric<N, C, E>::value_type>(value);
594 }
595
596 }
597 }
598 }
599 }
600
601 #endif // OME_XML_MODEL_PRIMITIVES_CONSTRAINEDNUMERIC_H
602
603 /*
604 * Local Variables:
605 * mode:C++
606 * End:
607 */
ome::xml::model::primitives::ConstrainedNumeric::constraint_type
C constraint_type
The constraint to impose.
Definition: ConstrainedNumeric.h:138
ome::xml::model::primitives::ConstrainedNumeric::value
value_type value
The value being constrained.
Definition: ConstrainedNumeric.h:525
ome::xml::model::primitives::ConstrainedNumeric::ConstrainedNumeric
ConstrainedNumeric(const ConstrainedNumeric &value)
Copy constructor.
Definition: ConstrainedNumeric.h:200
ome::xml::model::primitives::ConstrainedNumeric::default_value
static const value_type default_value
Default value for default construction.
Definition: ConstrainedNumeric.h:143
ome
Open Microscopy Environment C++ implementation.
ome::xml::model::primitives::ConstrainedNumeric::error_policy_type
E error_policy_type
The error policy to apply on constraint violation.
Definition: ConstrainedNumeric.h:140
ome::xml::model::primitives::operator==
bool operator==(const Color &lhs, const Color &rhs)
Compare two Color objects for equality.
Definition: Color.h:323
ome::xml::model::primitives::ConstrainedNumeric::ConstrainedNumeric
ConstrainedNumeric(value_type value)
Construct a ConstrainedNumeric from an unconstrained value.
Definition: ConstrainedNumeric.h:167
ome::xml::model::primitives::ConstrainedNumeric::check
void check()
Check that the set value meets the required constraints, and if it does not, handle this according to...
Definition: ConstrainedNumeric.h:514
ome::xml::model::primitives::ConstrainedNumeric::typestr
static const std::string typestr
The name of the type. Used for diagnostics only.
Definition: ConstrainedNumeric.h:527
ome::xml::model::primitives::ConstrainedNumericError
Default error handler for ConstrainedNumeric.
Definition: ConstrainedNumeric.h:67
cstdint.h
ome::xml::model::primitives::ConstrainedNumericError::operator()
void operator()(const T &value, const std::string &typestr)
Throw an exception.
Definition: ConstrainedNumeric.h:78
ome::xml::model::primitives::operator>>
std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &is, Color &color)
Set Color from input stream.
Definition: Color.h:479
ome::xml::model::primitives::ConstrainedNumeric::value_type
N value_type
The type to constrain.
Definition: ConstrainedNumeric.h:136
ome::xml::model::primitives::ConstrainedNumeric::ConstrainedNumeric
ConstrainedNumeric()
Construct a ConstrainedNumeric.
Definition: ConstrainedNumeric.h:154
ome::xml::model::primitives::ConstrainedNumeric::ConstrainedNumeric
ConstrainedNumeric(const std::string &value)
Construct a ConstrainedNumeric a string value.
Definition: ConstrainedNumeric.h:180
ome::xml::model::primitives::ConstrainedNumeric
A numeric type constrained to a subrange (or subranges) of its range limits.
Definition: ConstrainedNumeric.h:119