1 //=================================================================================================
2 /*!
3 //  \file blaze/util/UnsignedValue.h
4 //  \brief Header file for the UnsignedValue class
5 //
6 //  Copyright (C) 2012-2020 Klaus Iglberger - All Rights Reserved
7 //
8 //  This file is part of the Blaze library. You can redistribute it and/or modify it under
9 //  the terms of the New (Revised) BSD License. Redistribution and use in source and binary
10 //  forms, with or without modification, are permitted provided that the following conditions
11 //  are met:
12 //
13 //  1. Redistributions of source code must retain the above copyright notice, this list of
14 //     conditions and the following disclaimer.
15 //  2. Redistributions in binary form must reproduce the above copyright notice, this list
16 //     of conditions and the following disclaimer in the documentation and/or other materials
17 //     provided with the distribution.
18 //  3. Neither the names of the Blaze development group nor the names of its contributors
19 //     may be used to endorse or promote products derived from this software without specific
20 //     prior written permission.
21 //
22 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
23 //  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 //  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 //  SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 //  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 //  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 //  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 //  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 //  DAMAGE.
32 */
33 //=================================================================================================
34 
35 #ifndef _BLAZE_UTIL_UNSIGNEDVALUE_H_
36 #define _BLAZE_UTIL_UNSIGNEDVALUE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iosfwd>
44 #include <blaze/util/constraints/Unsigned.h>
45 
46 
47 namespace blaze {
48 
49 //=================================================================================================
50 //
51 //  CLASS DEFINITION
52 //
53 //=================================================================================================
54 
55 //*************************************************************************************************
56 /*!\brief Implementation of a wrapper for built-in unsigned integral values.
57 // \ingroup util
58 //
59 // This class wraps a value of built-in unsigned integral type in order to be able to extract
60 // non-negative unsigned integral values from an input stream.
61 */
62 template< typename T >  // Type of the unsigned value
63 class UnsignedValue
64 {
65  public:
66    //**Constructors********************************************************************************
67    /*!\name Constructors */
68    //@{
69    explicit inline UnsignedValue( T value=0 );
70    //@}
71    //**********************************************************************************************
72 
73    //**Assignment operators************************************************************************
74    /*!\name Assignment operators */
75    //@{
76    inline UnsignedValue& operator=( T value );
77    //@}
78    //**********************************************************************************************
79 
80    //**Conversion operators************************************************************************
81    /*!\name Conversion operators */
82    //@{
83    inline operator T() const;
84    //@}
85    //**********************************************************************************************
86 
87    //**Access function*****************************************************************************
88    /*!\name Access functions */
89    //@{
90    inline T get() const;
91    //@}
92    //**********************************************************************************************
93 
94  private:
95    //**Member variables****************************************************************************
96    /*!\name Member variables */
97    //@{
98    T value_;  //!< The wrapped built-in unsigned integral value.
99    //@}
100    //**********************************************************************************************
101 
102    //**Compile time checks*************************************************************************
103    /*! \cond BLAZE_INTERNAL */
104    BLAZE_CONSTRAINT_MUST_BE_UNSIGNED_TYPE( T );
105    /*! \endcond */
106    //**********************************************************************************************
107 };
108 //*************************************************************************************************
109 
110 
111 
112 
113 //=================================================================================================
114 //
115 //  CONSTRUCTORS
116 //
117 //=================================================================================================
118 
119 //*************************************************************************************************
120 /*!\brief The default constructor for UnsignedInt.
121 //
122 // \param value The initial value for the unsigned integer.
123 */
124 template< typename T >  // Type of the unsigned value
UnsignedValue(T value)125 inline UnsignedValue<T>::UnsignedValue( T value )
126    : value_( value )  // The wrapped built-in unsigned integral value
127 {}
128 //*************************************************************************************************
129 
130 
131 
132 
133 //=================================================================================================
134 //
135 //  ASSIGNMENT OPERATOR
136 //
137 //=================================================================================================
138 
139 //*************************************************************************************************
140 /*!\brief Assignment of a built-in unsigned integral value.
141 //
142 // \param value The unsigned integral value.
143 // \return Reference to the assigned UnsignedValue object.
144 */
145 template< typename T >  // Type of the unsigned value
146 inline UnsignedValue<T>& UnsignedValue<T>::operator=( T value )
147 {
148    value_ = value;
149    return *this;
150 }
151 //*************************************************************************************************
152 
153 
154 
155 
156 //=================================================================================================
157 //
158 //  CONVERSION OPERATOR
159 //
160 //=================================================================================================
161 
162 //*************************************************************************************************
163 /*!\brief Conversion to the built-in unsigned integral type.
164 //
165 // \return The wrapped built-in unsigned integral value.
166 */
167 template< typename T >  // Type of the unsigned value
T()168 inline UnsignedValue<T>::operator T() const
169 {
170    return value_;
171 }
172 //*************************************************************************************************
173 
174 
175 
176 
177 //=================================================================================================
178 //
179 //  ACCESS FUNCTIONS
180 //
181 //=================================================================================================
182 
183 //*************************************************************************************************
184 /*!\brief Access to the wrapped built-in unsigned integral value.
185 //
186 // \return The wrapped built-in unsigned integral value.
187 */
188 template< typename T >  // Type of the unsigned value
get()189 inline T UnsignedValue<T>::get() const
190 {
191    return value_;
192 }
193 //*************************************************************************************************
194 
195 
196 
197 
198 //=================================================================================================
199 //
200 //  GLOBAL OPERATORS
201 //
202 //=================================================================================================
203 
204 //*************************************************************************************************
205 /*!\name UnsignedValue operators */
206 //@{
207 template< typename T1, typename T2 >
208 inline bool operator==( const UnsignedValue<T1>& lhs, const UnsignedValue<T2>& rhs );
209 
210 template< typename T1, typename T2 >
211 inline bool operator!=( const UnsignedValue<T1>& lhs, const UnsignedValue<T2>& rhs );
212 
213 template< typename T1, typename T2 >
214 inline bool operator< ( const UnsignedValue<T1>& lhs, const UnsignedValue<T2>& rhs );
215 
216 template< typename T1, typename T2 >
217 inline bool operator> ( const UnsignedValue<T1>& lhs, const UnsignedValue<T2>& rhs );
218 
219 template< typename T1, typename T2 >
220 inline bool operator<=( const UnsignedValue<T1>& lhs, const UnsignedValue<T2>& rhs );
221 
222 template< typename T1, typename T2 >
223 inline bool operator>=( const UnsignedValue<T1>& lhs, const UnsignedValue<T2>& rhs );
224 
225 template< typename T >
226 inline std::ostream& operator<<( std::ostream& os, const UnsignedValue<T>& uv );
227 
228 template< typename T >
229 std::istream& operator>>( std::istream& is, UnsignedValue<T>& uv );
230 //@}
231 //*************************************************************************************************
232 
233 
234 //*************************************************************************************************
235 /*!\brief Equality comparison between two UnsignedValue objects.
236 //
237 // \param lhs The left-hand side UnsignedValue wrapper.
238 // \param rhs The right-hand side UnsignedValue wrapper.
239 // \return \a true if the two values are equal, \a false if not.
240 */
241 template< typename T1    // Type of the left-hand side unsigned value
242         , typename T2 >  // Type of the right-hand side unsigned value
243 inline bool operator==( const UnsignedValue<T1>& lhs, const UnsignedValue<T2>& rhs )
244 {
245    return lhs.get() == rhs.get();
246 }
247 //*************************************************************************************************
248 
249 
250 //*************************************************************************************************
251 /*!\brief Inequality comparison between two UnsignedValue objects.
252 //
253 // \param lhs The left-hand side UnsignedValue wrapper.
254 // \param rhs The right-hand side UnsignedValue wrapper.
255 // \return \a true if the two values are not equal, \a true if they are equal.
256 */
257 template< typename T1    // Type of the left-hand side unsigned value
258         , typename T2 >  // Type of the right-hand side unsigned value
259 inline bool operator!=( const UnsignedValue<T1>& lhs, const UnsignedValue<T2>& rhs )
260 {
261    return lhs.get() != rhs.get();
262 }
263 //*************************************************************************************************
264 
265 
266 //*************************************************************************************************
267 /*!\brief Less-than comparison between two UnsignedValue objects.
268 //
269 // \param lhs The left-hand side UnsignedValue wrapper.
270 // \param rhs The right-hand side UnsignedValue wrapper.
271 // \return \a true if the left value is less than the right value, \a false if not.
272 */
273 template< typename T1    // Type of the left-hand side unsigned value
274         , typename T2 >  // Type of the right-hand side unsigned value
275 inline bool operator<( const UnsignedValue<T1>& lhs, const UnsignedValue<T2>& rhs )
276 {
277    return lhs.get() < rhs.get();
278 }
279 //*************************************************************************************************
280 
281 
282 //*************************************************************************************************
283 /*!\brief Greater-than comparison between two UnsignedValue objects.
284 //
285 // \param lhs The left-hand side UnsignedValue wrapper.
286 // \param rhs The right-hand side UnsignedValue wrapper.
287 // \return \a true if the left value if greater than the right value, \a false if not.
288 */
289 template< typename T1    // Type of the left-hand side unsigned value
290         , typename T2 >  // Type of the right-hand side unsigned value
291 inline bool operator>( const UnsignedValue<T1>& lhs, const UnsignedValue<T2>& rhs )
292 {
293    return lhs.get() > rhs.get();
294 }
295 //*************************************************************************************************
296 
297 
298 //*************************************************************************************************
299 /*!\brief Less-or-equal-than comparison between two UnsignedValue objects.
300 //
301 // \param lhs The left-hand side UnsignedValue wrapper.
302 // \param rhs The right-hand side UnsignedValue wrapper.
303 // \return \a true if the left value is less or equal than the right value, \a false if not.
304 */
305 template< typename T1    // Type of the left-hand side unsigned value
306         , typename T2 >  // Type of the right-hand side unsigned value
307 inline bool operator<=( const UnsignedValue<T1>& lhs, const UnsignedValue<T2>& rhs )
308 {
309    return lhs.get() <= rhs.get();
310 }
311 //*************************************************************************************************
312 
313 
314 //*************************************************************************************************
315 /*!\brief Greater-or-equal-than comparison between two UnsignedValue objects.
316 //
317 // \param lhs The left-hand side UnsignedValue wrapper.
318 // \param rhs The right-hand side UnsignedValue wrapper.
319 // \return \a true if the left value is greater or equal than the right value, \a false if not.
320 */
321 template< typename T1    // Type of the left-hand side unsigned value
322         , typename T2 >  // Type of the right-hand side unsigned value
323 inline bool operator>=( const UnsignedValue<T1>& lhs, const UnsignedValue<T2>& rhs )
324 {
325    return lhs.get() >= rhs.get();
326 }
327 //*************************************************************************************************
328 
329 
330 //*************************************************************************************************
331 /*!\brief Global output operator for the UnsignedValue wrapper.
332 //
333 // \param os Reference to the output stream.
334 // \param uv Reference to a UnsignedValue object.
335 // \return The output stream.
336 */
337 template< typename T >  // Type of the unsigned value
338 inline std::ostream& operator<<( std::ostream& os, const UnsignedValue<T>& uv )
339 {
340    return os << uv.get();
341 }
342 //*************************************************************************************************
343 
344 
345 //*************************************************************************************************
346 /*!\brief Global input operator for the UnsignedValue wrapper.
347 //
348 // \param is Reference to the input stream.
349 // \param uv Reference to a UnsignedValue object.
350 // \return The input stream.
351 //
352 // The input operator guarantees that this object is not changed in the case of an input error.
353 // Only values suitable for the according built-in unsigned integral data type \a T are allowed.
354 // Otherwise, the input stream's position is returned to its previous position and the
355 // \a std::istream::failbit is set.
356 */
357 template< typename T >  // Type of the unsigned value
358 std::istream& operator>>( std::istream& is, UnsignedValue<T>& uv )
359 {
360    T tmp;
361    const std::istream::pos_type pos( is.tellg() );
362 
363    // Skipping any leading whitespaces
364    is >> std::ws;
365 
366    // Extracting the value
367    if( is.peek() == '-' || !(is >> tmp) )
368    {
369       is.clear();
370       is.seekg( pos );
371       is.setstate( std::istream::failbit );
372       return is;
373    }
374 
375    // Transfering the input to the unsigned integer value
376    uv = tmp;
377 
378    return is;
379 }
380 //*************************************************************************************************
381 
382 } // namespace blaze
383 
384 #endif
385