iLab Neuromorphic Robotics Toolkit  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Range.H
Go to the documentation of this file.
1 /*! @file
2  @author Laurent Itti
3  @copyright GNU Public License (GPL v3)
4  @section License
5  @verbatim
6  // ////////////////////////////////////////////////////////////////////////
7  // The iLab Neuromorphic Robotics Toolkit (NRT) //
8  // Copyright 2010-2012 by the University of Southern California (USC) //
9  // and the iLab at USC. //
10  // //
11  // iLab - University of Southern California //
12  // Hedco Neurociences Building, Room HNB-10 //
13  // Los Angeles, Ca 90089-2520 - USA //
14  // //
15  // See http://ilab.usc.edu for information about this project. //
16  // ////////////////////////////////////////////////////////////////////////
17  // This file is part of The iLab Neuromorphic Robotics Toolkit. //
18  // //
19  // The iLab Neuromorphic Robotics Toolkit is free software: you can //
20  // redistribute it and/or modify it under the terms of the GNU General //
21  // Public License as published by the Free Software Foundation, either //
22  // version 3 of the License, or (at your option) any later version. //
23  // //
24  // The iLab Neuromorphic Robotics Toolkit is distributed in the hope //
25  // that it will be useful, but WITHOUT ANY WARRANTY; without even the //
26  // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
27  // PURPOSE. See the GNU General Public License for more details. //
28  // //
29  // You should have received a copy of the GNU General Public License //
30  // along with The iLab Neuromorphic Robotics Toolkit. If not, see //
31  // <http://www.gnu.org/licenses/>. //
32  // ////////////////////////////////////////////////////////////////////////
33  @endverbatim */
34 
35 
36 #ifndef INCLUDE_NRT_CORE_TYPING_RANGE_H
37 #define INCLUDE_NRT_CORE_TYPING_RANGE_H
38 
39 #include <nrt/External/cereal/access.hpp>
40 #include <iostream>
41 
42 namespace nrt
43 {
44  //! A generic range class
45  /*! The Range class is used to represent a range from [min .. max]
46 
47  \note The operators of Range do not use type promotions (see \ref promotions). This is to minimize template burden
48  and also possible programmer confusion. For example, while in principle one could define Range<int> + float and
49  return a Range<float>, here we do not define such an operator. The same result can be achieved by first converting
50  the range and then adding the constant:
51  @code
52  nrt::Range<int> r1(0, 100);
53  // NOT ALLOWED: nrt::Range<float> r2 = r1 + 1.23F;
54  nrt::Range<float> r2 = nrt::Range<float>(r1) + 1.23F; // OK, no hidden conversions, easy to read, explicit, nice
55  @endcode
56 
57  \note Operators on Range use range checking and clamping internally. Thus, be careful if using Range<byte>. For
58  example:
59  @code
60  nrt::Range<nrt::byte> r(nrt::byte(0), nrt::byte(250));
61  r += nrt::byte(100); // new range is 100-255
62  @endcode
63 
64  \ingroup typingmisc */
65  template <class T>
66  class Range
67  {
68  public:
69  //! Default constructor, range is [0 .. 0]
70  explicit Range();
71 
72  //! Constructor
73  explicit Range(T const mini, T const maxi);
74 
75  //! Copy constructor
76  Range(Range<T> const & other) = default;
77 
78  //! Move constructor
79  Range(Range<T> && other) = default;
80 
81  //! Copy-conversion constructor, uses nrt::clamped_convert<T,U> internally
82  /*! Note that this constructor is \e explicit, i.e., you need to explicitly mention it. This is to avoid
83  conversions to happen without a programmer being aware of it. For example:
84  @code
85  void myFunc(nrt::Range<float> const & rng) { ... }
86  nrt::Range<int> r1(0, 100);
87  nrt::Range<float> r2(r1); // ok, explicit constructor call
88  myFunc(r2); // ok, no conversion necessary
89  //myFunc(r1) // NO: passing Range<int> to function that takes a Range<float> arg fails to compile
90  myFunc(nrt::Range<float>(r1)); // ok, nice and explicit; and you can thing about whether r1 should
91  // have been a Range<float> in the first place so you don't waste CPU
92  // doing this conversion (as opposed to just not being aware of the wasting)
93  @endcode */
94  template <class U>
95  explicit Range(Range<U> const & other);
96 
97  //! Assignment
98  Range<T> & operator=(Range<T> const & other) = default;
99 
100  //! Move assignment
101  Range<T> & operator=(Range<T> && other) = default;
102 
103  //! Return the minimum value
104  T const & min() const;
105 
106  //! Return the maximum value
107  T const & max() const;
108 
109  //! Return whether min() == max()
110  bool const empty() const;
111 
112  //! Extend the range, if needed, so that it includes val
113  void extend(T const val);
114 
115  private:
116  T itsMin; //!< the min
117  T itsMax; //!< the max
118 
119  friend class cereal::access;
120  template <class Archive> void serialize(Archive & ar)
121  { ar( itsMin, itsMax ); }
122  };
123 
124  // ######################################################################
125  // Free functions for Range<T>
126  // ######################################################################
127 
128  //! Merge two ranges
129  /*! \relates nrt::Range */
130  template <class T>
131  Range<T> merge(Range<T> const & r1, Range<T> const & r2);
132 
133  //! Stream out as "min-max"
134  /*! \relates nrt::Range */
135  template <class T>
136  std::ostream & operator<<(std::ostream & out, Range<T> const & r);
137 
138  //! Stream in as "min-max"
139  /*! \relates nrt::Range */
140  template <class T>
141  std::istream & operator>>(std::istream & in, Range<T> & r);
142 
143  //! Machine-readable output to a string, for use in nrt::Parameter: outputs \c min-max (e.g., 0-100)
144  /*! This is an overload for Range<T> of the function template in nrt/Core/Model/ParameterStringConversion.H.
145  \relates nrt::Range */
146  template <class T>
147  void paramValToString(Range<T> const & val, std::string & result);
148 
149  //! Machine-readable input from a string, for use in nrt::Parameter: reads \c min-max (e.g., 0-100)
150  /*! @throws nrt::exception::Exception if input is malformed.
151  This is an overload for Range<T> of the function template in nrt/Core/Model/ParameterStringConversion.H.
152  \relates nrt::Range */
153  template <class T>
154  void paramStringToVal(std::string const & valstring, Range<T> & result);
155 
156  //! Equality test: Range<T> == Range<T>
157  /*! \relates nrt::Range */
158  template <class T>
159  bool operator==(Range<T> const & range1, Range<T> const & range2);
160 
161  //! Inequality test: Range<T> != Range<T>
162  /*! \relates nrt::Range */
163  template <class T>
164  bool operator!=(Range<T> const & range1, Range<T> const & range2);
165 
166  //! Add constant to both ends of a range: Range<T> + T
167  /*! \relates nrt::Range */
168  template <class T>
169  Range<T> operator+(Range<T> const & range, T const & scalar);
170 
171  //! Add constant to both ends of a range: T + Range<T>
172  /*! \relates nrt::Range */
173  template <class T>
174  Range<T> operator+(T const & scalar, Range<T> const & range);
175 
176  //! Subtract constant from both ends of a range: Range<T> - T
177  /*! \relates nrt::Range */
178  template <class T>
179  Range<T> operator-(Range<T> const & range, T const & scalar);
180 
181  //! Subtract constant from both ends of a range: T - Range<T>
182  /*! \relates nrt::Range */
183  template <class T>
184  Range<T> operator-(T const & scalar, Range<T> const & range);
185 
186  //! Divide both ends of a range by a factor: Range<T> / T
187  /*! \relates nrt::Range */
188  template <class T>
189  Range<T> operator/(Range<T> const & range, T const & scalar);
190 
191  //! Divide a factor by both ends of a range: T / Range<T>
192  /*! \relates nrt::Range */
193  template <class T>
194  Range<T> operator/(T const & scalar, Range<T> const & range);
195 
196  //! Multiply both ends of a range by a factor: Range<T> * T
197  /*! \relates nrt::Range */
198  template <class T>
199  Range<T> operator*(Range<T> const & range, T const & scalar);
200 
201  //! Multiply a factor by both ends of a range: T * Range<T>
202  /*! \relates nrt::Range */
203  template <class T>
204  Range<T> operator*(T const & scalar, Range<T> const & range);
205 
206  //! Add constant to both ends of a range: Range<T> += T
207  /*! \relates nrt::Range */
208  template <class T>
209  Range<T> & operator+=(Range<T> & range, T const & scalar);
210 
211  //! Subtract constant from both ends of a range: Range<T> -= T
212  /*! \relates nrt::Range */
213  template <class T>
214  Range<T> & operator-=(Range<T> & range, T const & scalar);
215 
216  //! Multiply both ends of a range by a factor: Range<T> *= T
217  /*! \relates nrt::Range */
218  template <class T>
219  Range<T> & operator*=(Range<T> & range, T const & scalar);
220 
221  //! Divide both ends of a range by a factor: Range<T> /= T
222  /*! \relates nrt::Range */
223  template <class T>
224  Range<T> & operator/=(Range<T> & range, T const & scalar);
225 
226 } // namespace nrt
227 
228 // Include inlined implementation details that are of no interest to the end user
230 
231 
232 #endif // INCLUDE_NRT_CORE_TYPING_RANGE_H
233