STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ... ATLSTL - Template Software for the Active Template Library COMSTL - The Standard Template Library meets the Component Object Model .netSTL - Standard Template Library meets the Microsoft.NET Common Language Runtime InetSTL - The Standard Template Library meets WinInet MFCSTL - Template Software for the Microsoft Foundation Classes UNIXSTL - Template Software for the UNIX Operating System WinSTL - where the Standard Template Library meets the Win32 API

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

random_range.hpp

Go to the documentation of this file.
00001 /* 
00002  * File:        rangelib/random_range.hpp
00003  *
00004  * Purpose:     Random number range class.
00005  *
00006  * Created:     31st May 2004
00007  * Updated:     12th September 2004
00008  *
00009  * Home:        http://stlsoft.org/
00010  *
00011  * Copyright (c) 2004, Matthew Wilson and Synesis Software
00012  * All rights reserved.
00013  *
00014  * Redistribution and use in source and binary forms, with or without
00015  * modification, are permitted provided that the following conditions are met:
00016  *
00017  * - Redistributions of source code must retain the above copyright notice, this
00018  *   list of conditions and the following disclaimer.
00019  * - Redistributions in binary form must reproduce the above copyright notice,
00020  *   this list of conditions and the following disclaimer in the documentation
00021  *   and/or other materials provided with the distribution.
00022  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00023  *   any contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  * POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * 
00039 
00040 
00043 #ifndef STLSOFT_INCL_RANGELIB_HPP_RANDOM_RANGE
00044 #define STLSOFT_INCL_RANGELIB_HPP_RANDOM_RANGE
00045 
00046 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00047 # define STLSOFT_VER_RANGELIB_HPP_RANDOM_RANGE_MAJOR      1
00048 # define STLSOFT_VER_RANGELIB_HPP_RANDOM_RANGE_MINOR      1
00049 # define STLSOFT_VER_RANGELIB_HPP_RANDOM_RANGE_REVISION   1
00050 # define STLSOFT_VER_RANGELIB_HPP_RANDOM_RANGE_EDIT       5
00051 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00052 
00053 /* 
00054  * Includes
00055  */
00056 
00057 #ifndef STLSOFT_INCL_H_STLSOFT
00058 # include <stlsoft.h>                   // Include the STLSoft root header
00059 #endif /* !STLSOFT_INCL_H_STLSOFT */
00060 #ifndef STLSOFT_INCL_RANGELIB_HPP_RANGE_CATEGORIES
00061 # include <rangelib/range_categories.hpp>
00062 #endif /* !STLSOFT_INCL_RANGELIB_HPP_RANGE_CATEGORIES */
00063 #ifndef STLSOFT_INCL_H_STLSOFT_OPERATOR_BOOL
00064 # include <stlsoft_operator_bool.h>     // operator_bool_generator
00065 #endif /* !STLSOFT_INCL_H_STLSOFT_OPERATOR_BOOL */
00066 #include <stdlib.h>                     // rand(), srand()
00067 
00068 /* 
00069  * Namespace
00070  */
00071 
00072 #ifndef _STLSOFT_NO_NAMESPACE
00073 namespace stlsoft
00074 {
00075 #endif /* _STLSOFT_NO_NAMESPACE */
00076 
00077 /* 
00078 
00083 
00084 /* 
00085  * Classes
00086  */
00087 
00104 class random_range
00105     : public notional_range_tag
00106 {
00109 public:
00110     typedef int                 value_type;
00111     typedef notional_range_tag  range_tag_type;
00112     typedef random_range        class_type;
00114 
00117 public:
00123     random_range(ss_size_t numValues, value_type minValue = 0, value_type maxValue = RAND_MAX)
00124         : m_numValues(numValues)
00125         , m_minValue(minValue)
00126         , m_maxValue(maxValue)
00127         , m_position(0)
00128         , m_value(next_value_(minValue, maxValue))
00129     {
00130         stlsoft_assert(minValue <= maxValue);
00131         stlsoft_assert((maxValue - minValue) <= RAND_MAX);
00132     }
00134 
00137 private:
00138     STLSOFT_DEFINE_OPERATOR_BOOL_TYPES(class_type, operator_bool_generator_type, operator_bool_type);
00139 public:
00141     ss_bool_t is_open() const
00142     {
00143         return m_position != m_numValues;
00144     }
00146     value_type current() const
00147     {
00148         stlsoft_message_assert("Attempting to access the value of a closed range", is_open());
00149 
00150         return m_value;
00151     }
00153     class_type &advance()
00154     {
00155         stlsoft_message_assert("Attempting to advance a closed range", is_open());
00156 
00157         ++m_position;
00158         m_value = next_value_(m_minValue, m_maxValue);
00159 
00160         return *this;
00161     }
00162 
00164     operator operator_bool_type() const
00165     {
00166         return operator_bool_generator_type::translate(is_open());
00167     }
00169     value_type operator *() const
00170     {
00171         return current();
00172     }
00174     class_type &operator ++()
00175     {
00176         return advance();
00177     }
00180     class_type operator ++(int)
00181     {
00182         class_type  ret(*this);
00183 
00184         operator ++();
00185 
00186         return ret;
00187     }
00189 
00192 public:
00194     value_type minimum() const
00195     {
00196         return m_minValue;
00197     }
00199     value_type maximum() const
00200     {
00201         return m_maxValue;
00202     }
00204 
00207 public:
00209     bool operator ==(class_type const &/* rhs */) const
00210     {
00211         return false;
00212     }
00214     bool operator !=(class_type const &rhs) const
00215     {
00216         return ! operator ==(rhs);
00217     }
00219 
00221 private:
00222     static value_type next_value_(value_type minValue, value_type maxValue)
00223     {
00224         return (maxValue - minValue) ? minValue + (rand() % (maxValue - minValue)) : 0;
00225     }
00227 
00228 // Members
00229 private:
00230     int const   m_numValues;
00231     int const   m_minValue;
00232     int const   m_maxValue;
00233     int         m_position;
00234     int         m_value;
00235 
00236 // Not to be implemented
00237 private:
00238     class_type &operator =(class_type const&);
00239 };
00240 
00242 // Unit-testing
00243 
00244 #ifdef STLSOFT_UNITTEST
00245 
00246 namespace unittest
00247 {
00248     namespace
00249     {
00250     } // anonymous namespace
00251 
00252     ss_bool_t test_stlsoft_rangelib_random_range(unittest_reporter *r)
00253     {
00254         using stlsoft::unittest::unittest_initialiser;
00255 
00256         ss_bool_t               bSuccess    =   true;
00257 
00258         unittest_initialiser    init(r, "RangeLib", "random_range", __FILE__);
00259 
00260         random_range    r1(10, -10, 10);
00261         int             sum;
00262 
00263         stlsoft_assert(-10 == r1.minimum());
00264         stlsoft_assert(+10 == r1.maximum());
00265 
00266         for(sum = 0; r1; ++r1)
00267         {
00268             stlsoft_assert(*r1 >= r1.minimum());
00269             stlsoft_assert(*r1 <= r1.maximum());
00270 
00271             sum += *r1;
00272         }
00273 
00274         if( sum < 10 * r1.minimum() ||
00275             sum >= 10 * r1.maximum())
00276         {
00277             r->report("manual enumeration failed", __LINE__);
00278             bSuccess = false;
00279         }
00280 
00281         if(r1.is_open())
00282         {
00283             r->report("closed range presents as open (is_open() method)", __LINE__);
00284             bSuccess = false;
00285         }
00286 
00287         if(r1)
00288         {
00289             r->report("closed range presents as open (operator \"bool\"())", __LINE__);
00290             bSuccess = false;
00291         }
00292 
00293         if(random_range(0, 0, 0))
00294         {
00295             r->report("closed range presents as open", __LINE__);
00296             bSuccess = false;
00297         }
00298 
00299         return bSuccess;
00300     }
00301 
00302     unittest_registrar    unittest_stlsoft_rangelib_random_range(test_stlsoft_rangelib_random_range);
00303 
00304 } // namespace unittest
00305 
00306 #endif /* STLSOFT_UNITTEST */
00307 
00308 /* 
00309 
00311 
00312 /* 
00313 
00314 #ifndef _STLSOFT_NO_NAMESPACE
00315 } // namespace stlsoft
00316 #endif /* _STLSOFT_NO_NAMESPACE */
00317 
00318 /* 
00319 
00320 #endif /* !STLSOFT_INCL_RANGELIB_HPP_RANDOM_RANGE */
00321 
00322 /* 

STLSoft Libraries documentation © Synesis Software Pty Ltd, 2001-2004