ome-xml  5.5.0
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 <cstdint>
43 #include <limits>
44 #include <string>
45 #include <sstream>
46 
47 #include <boost/format.hpp>
48 #include <boost/operators.hpp>
49 
50 namespace ome
51 {
52  namespace xml
53  {
54  namespace model
55  {
59  namespace primitives
60  {
61 
67  {
75  template<typename T>
76  inline void
77  operator() (const T& value,
78  const std::string& typestr)
79  {
80  boost::format fmt("‘%1%’ not a supported value of %2%");
81  fmt % value % typestr;
82  throw std::invalid_argument(fmt.str());
83  }
84  };
85 
115  template<typename N,
116  typename C,
117  typename E = ConstrainedNumericError>
118  class ConstrainedNumeric : private boost::partially_ordered<ConstrainedNumeric<N, C, E>, N,
119  boost::partially_ordered<ConstrainedNumeric<N, C, E>,
120  boost::equality_comparable2<ConstrainedNumeric<N, C, E>, N,
121  boost::equality_comparable<ConstrainedNumeric<N, C, E>,
122  boost::addable2<ConstrainedNumeric<N, C, E>, N,
123  boost::addable<ConstrainedNumeric<N, C, E>,
124  boost::subtractable2<ConstrainedNumeric<N, C, E>, N,
125  boost::subtractable<ConstrainedNumeric<N, C, E>,
126  boost::dividable2<ConstrainedNumeric<N, C, E>, N,
127  boost::dividable<ConstrainedNumeric<N, C, E>,
128  boost::multipliable2<ConstrainedNumeric<N, C, E>, N,
129  boost::multipliable<ConstrainedNumeric<N, C, E>,
130  boost::incrementable<ConstrainedNumeric<N, C, E>,
131  boost::decrementable<ConstrainedNumeric<N, C, E>>>>>>>>>>>>>>>
132  {
133  public:
135  typedef N value_type;
137  typedef C constraint_type;
139  typedef E error_policy_type;
140 
142  static const value_type default_value;
143 
154  value(default_value)
155  {
156  check();
157  }
158 
166  ConstrainedNumeric(value_type value):
167  value(value)
168  {
169  check();
170  }
171 
179  ConstrainedNumeric(const std::string& value)
180  {
181  std::istringstream is(value);
182  is.imbue(std::locale::classic());
183  value_type nval;
184  is >> nval;
185  if (!is)
186  {
187  error_policy_type error;
188  error(value, this->typestr);
189  }
190  this->value = nval;
191  check();
192  }
193 
200  value(value)
201  {
202  check();
203  }
204 
210  inline
211  operator value_type () const
212  {
213  return this->value;
214  }
215 
225  inline ConstrainedNumeric&
226  operator= (const ConstrainedNumeric& value)
227  {
228  this->value = value.value;
229  check();
230  return *this;
231  }
232 
241  inline ConstrainedNumeric&
242  operator= (const value_type& value)
243  {
244  this->value = value;
245  check();
246  return *this;
247  }
248 
257  inline ConstrainedNumeric&
258  operator+= (const ConstrainedNumeric& value)
259  {
260  this->value += value.value;
261  check();
262  return *this;
263  }
264 
273  inline ConstrainedNumeric&
274  operator-= (const ConstrainedNumeric& value)
275  {
276  this->value -= value.value;
277  check();
278  return *this;
279  }
280 
289  inline ConstrainedNumeric&
290  operator*= (const ConstrainedNumeric& value)
291  {
292  this->value *= value.value;
293  check();
294  return *this;
295  }
296 
305  inline ConstrainedNumeric&
306  operator/= (const ConstrainedNumeric& value)
307  {
308  this->value /= value.value;
309  check();
310  return *this;
311  }
312 
321  inline ConstrainedNumeric&
322  operator%= (const ConstrainedNumeric& value)
323  {
324  this->value %= value.value;
325  check();
326  return *this;
327  }
328 
337  inline ConstrainedNumeric&
338  operator+= (const value_type& value)
339  {
340  this->value += value;
341  check();
342  return *this;
343  }
344 
353  inline ConstrainedNumeric&
354  operator-= (const value_type& value)
355  {
356  this->value -= value;
357  check();
358  return *this;
359  }
360 
369  inline ConstrainedNumeric&
370  operator*= (const value_type& value)
371  {
372  this->value *= value;
373  check();
374  return *this;
375  }
376 
385  inline ConstrainedNumeric&
386  operator/= (const value_type& value)
387  {
388  this->value /= value;
389  check();
390  return *this;
391  }
392 
401  inline ConstrainedNumeric&
402  operator%= (const value_type& value)
403  {
404  this->value %= value;
405  check();
406  return *this;
407  }
408 
415  inline ConstrainedNumeric&
416  operator++ ()
417  {
418  ++this->value;
419  check();
420  return *this;
421  }
422 
429  inline ConstrainedNumeric&
430  operator-- ()
431  {
432  --this->value;
433  check();
434  return *this;
435  }
436 
444  inline bool
445  operator< (const ConstrainedNumeric& value) const
446  {
447  return this->value < value.value;
448  }
449 
457  inline bool
458  operator< (const value_type& value) const
459  {
460  return this->value < value;
461  }
462 
463  // Note operator> (const ConstrainedNumeric& value) const is
464  // provided by Boost.Operators.
465 
473  inline bool
474  operator> (const value_type& value) const
475  {
476  return this->value > value;
477  }
478 
486  inline bool
487  operator== (const ConstrainedNumeric& value) const
488  {
489  return this->value == value.value;
490  }
491 
499  inline bool
500  operator== (const value_type& value) const
501  {
502  return this->value == value;
503  }
504 
505  private:
512  inline void
513  check ()
514  {
515  constraint_type constraint;
516  if (!constraint(this->value))
517  {
518  error_policy_type error;
519  error(this->value, this->typestr);
520  }
521  }
522 
524  value_type value;
526  static const std::string typestr;
527 
535  template<class _charT,
536  class _traits,
537  typename _N,
538  typename _C,
539  typename _E>
540  friend
541  std::basic_istream<_charT,_traits>&
542  operator>> (std::basic_istream<_charT,_traits>& is,
544  };
545 
553  template<class charT,
554  class traits,
555  typename N,
556  typename C,
557  typename E>
558  inline std::basic_istream<charT,traits>&
559  operator>> (std::basic_istream<charT,traits>& is,
561  {
563  is >> nval;
564  if (!is)
565  {
566  boost::format fmt("Failed to parse invalid input for %1%");
568  throw std::invalid_argument(fmt.str());
569  }
570 
571  value = nval;
572 
573  return is;
574  }
575 
583  template<class charT,
584  class traits,
585  typename N,
586  typename C,
587  typename E>
588  inline std::basic_ostream<charT,traits>&
589  operator<< (std::basic_ostream<charT,traits>& os,
590  const ConstrainedNumeric<N, C, E>& value)
591  {
592  return os << static_cast<typename ConstrainedNumeric<N, C, E>::value_type>(value);
593  }
594 
595  }
596  }
597  }
598 }
599 
600 #endif // OME_XML_MODEL_PRIMITIVES_CONSTRAINEDNUMERIC_H
601 
602 /*
603  * Local Variables:
604  * mode:C++
605  * End:
606  */
C constraint_type
The constraint to impose.
Definition: ConstrainedNumeric.h:137
value_type value
The value being constrained.
Definition: ConstrainedNumeric.h:524
ConstrainedNumeric(const ConstrainedNumeric &value)
Copy constructor.
Definition: ConstrainedNumeric.h:199
static const value_type default_value
Default value for default construction.
Definition: ConstrainedNumeric.h:142
Open Microscopy Environment C++ implementation.
E error_policy_type
The error policy to apply on constraint violation.
Definition: ConstrainedNumeric.h:139
bool operator==(const Color &lhs, const Color &rhs)
Compare two Color objects for equality.
Definition: Color.h:322
ConstrainedNumeric(value_type value)
Construct a ConstrainedNumeric from an unconstrained value.
Definition: ConstrainedNumeric.h:166
void check()
Check that the set value meets the required constraints, and if it does not, handle this according to...
Definition: ConstrainedNumeric.h:513
static const std::string typestr
The name of the type. Used for diagnostics only.
Definition: ConstrainedNumeric.h:526
Default error handler for ConstrainedNumeric.
Definition: ConstrainedNumeric.h:66
void operator()(const T &value, const std::string &typestr)
Throw an exception.
Definition: ConstrainedNumeric.h:77
std::basic_istream< charT, traits > & operator>>(std::basic_istream< charT, traits > &is, Color &color)
Set Color from input stream.
Definition: Color.h:478
N value_type
The type to constrain.
Definition: ConstrainedNumeric.h:135
ConstrainedNumeric()
Construct a ConstrainedNumeric.
Definition: ConstrainedNumeric.h:153
ConstrainedNumeric(const std::string &value)
Construct a ConstrainedNumeric a string value.
Definition: ConstrainedNumeric.h:179
A numeric type constrained to a subrange (or subranges) of its range limits.
Definition: ConstrainedNumeric.h:118