Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:02:49

0001 //  (C) Copyright Gennadiy Rozental 2001.
0002 //  Distributed under the Boost Software License, Version 1.0.
0003 //  (See accompanying file LICENSE_1_0.txt or copy at
0004 //  http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 //  See http://www.boost.org/libs/test for the library home page.
0007 //
0008 ///@file
0009 ///Defines range generator
0010 // ***************************************************************************
0011 
0012 #ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER
0013 #define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER
0014 
0015 // Boost.Test
0016 #include <boost/test/data/config.hpp>
0017 
0018 #include <boost/test/data/monomorphic/generators/keywords.hpp>
0019 #include <boost/test/data/monomorphic/generate.hpp>
0020 
0021 // Boost
0022 #include <boost/optional.hpp>
0023 #include <boost/utility/enable_if.hpp>
0024 #include <boost/type_traits/is_unsigned.hpp>
0025 
0026 // STL
0027 #include <limits>
0028 #include <cmath>
0029 
0030 #include <boost/test/detail/suppress_warnings.hpp>
0031 
0032 //____________________________________________________________________________//
0033 
0034 namespace boost {
0035 namespace unit_test {
0036 namespace data {
0037 namespace monomorphic {
0038 
0039 // ************************************************************************** //
0040 // **************             monomorphic::xrange_t            ************** //
0041 // ************************************************************************** //
0042 
0043 
0044 /*!@brief Generator for the range sequences
0045  *
0046  * This class implements the generator concept (see @ref boost::unit_test::data::monomorphic::generated_by) for implementing
0047  * a range like sequence of numbers.
0048  */
0049 template<typename SampleType, typename StepType=SampleType>
0050 class xrange_t {
0051 public:
0052     typedef SampleType sample;
0053 
0054     xrange_t( SampleType const& begin_, StepType const& step_, data::size_t size_ )
0055     : m_begin( begin_ )
0056     , m_curr( begin_ )
0057     , m_step( step_ )
0058     , m_index( 0 )
0059     , m_size( size_ )
0060     {}
0061 
0062     // Generator interface
0063     data::size_t    capacity() const { return m_size; }
0064     SampleType      next()
0065     {
0066         if( m_index == m_size )
0067             return m_curr;
0068 
0069         SampleType res = m_curr;
0070 
0071         m_curr += m_step;
0072         ++m_index;
0073 
0074         return res;
0075     }
0076     void                reset()
0077     {
0078         m_curr  = m_begin;
0079         m_index = 0;
0080     }
0081 
0082 private:
0083     // Data members
0084     SampleType      m_begin;
0085     SampleType      m_curr;
0086     StepType        m_step;
0087     data::size_t    m_index;
0088     data::size_t    m_size;
0089 };
0090 
0091 //____________________________________________________________________________//
0092 
0093 namespace ds_detail {
0094 
0095 template<typename SampleType, typename StepType=SampleType>
0096 struct make_xrange {
0097     static StepType    abs( StepType s, boost::true_type* )   { return s; }
0098     static StepType    abs( StepType s, boost::false_type* )  { return std::abs(s); }
0099 
0100     typedef xrange_t<SampleType, StepType> range_gen;
0101 
0102     template<typename Params>
0103     static generated_by<range_gen>
0104     _( Params const& params )
0105     {
0106         SampleType           begin_val  = params.has( data::begin )  ? params[data::begin] : SampleType();
0107         optional<SampleType> end_val    = params.has( data::end )    ? params[data::end]   : optional<SampleType>();
0108         StepType             step_val   = params.has( data::step )   ? params[data::step]  : 1;
0109 
0110         BOOST_TEST_DS_ASSERT( step_val != 0, "Range step can't be zero" );
0111 
0112         data::size_t size;
0113         if( !end_val.is_initialized() )
0114             size = BOOST_TEST_DS_INFINITE_SIZE;
0115         else {
0116             BOOST_TEST_DS_ASSERT( (step_val < 0) ^ (begin_val < *end_val), "Invalid step direction" );
0117 
0118             SampleType  abs_distance    = step_val < 0 ? begin_val - *end_val : *end_val-begin_val;
0119             StepType    abs_step        = make_xrange::abs(step_val, (typename boost::is_unsigned<StepType>::type*)0 );
0120             std::size_t s = static_cast<std::size_t>(abs_distance/abs_step);
0121 
0122             if( static_cast<SampleType>(s*abs_step) < abs_distance )
0123                 s++;
0124 
0125             size = s;
0126         }
0127 
0128         return generated_by<range_gen>( range_gen( begin_val, step_val, size ) );
0129     }
0130 };
0131 
0132 } // namespace ds_detail
0133 } // namespace monomorphic
0134 
0135 //____________________________________________________________________________//
0136 
0137 //! Creates a range (sequence) dataset.
0138 //!
0139 //! The following overloads are available:
0140 //! @code
0141 //! auto d = xrange();
0142 //! auto d = xrange(end_val);
0143 //! auto d = xrange(end_val, param);
0144 //! auto d = xrange(begin_val, end_val);
0145 //! auto d = xrange(begin_val, end_val, step_val);
0146 //! auto d = xrange(param);
0147 //! @endcode
0148 //!
0149 //! - @c begin_val indicates the start of the sequence (default to 0).
0150 //! - @c end_val is the end of the sequence. If ommited, the dataset has infinite size.\n
0151 //! - @c step_val is the step between two consecutive elements of the sequence, and defaults to 1.\n
0152 //! - @c param is the named parameters that describe the sequence. The following parameters are accepted:
0153 //!   - @c begin: same meaning @c begin_val
0154 //!   - @c end: same meaning as @c end_val
0155 //!   - @c step: same meaning as @c step_val
0156 //!
0157 //!
0158 //! The returned value is an object that implements the dataset API.
0159 //!
0160 //! @note the step size cannot be null, and it should be positive if @c begin_val < @c end_val, negative otherwise.
0161 template<typename SampleType, typename Params>
0162 inline monomorphic::generated_by<monomorphic::xrange_t<SampleType>>
0163 xrange( Params const& params )
0164 {
0165     return monomorphic::ds_detail::make_xrange<SampleType>::_( params );
0166 }
0167 
0168 //____________________________________________________________________________//
0169 
0170 /// @overload boost::unit_test::data::xrange()
0171 template<typename SampleType>
0172 inline monomorphic::generated_by<monomorphic::xrange_t<SampleType>>
0173 xrange( SampleType const& end_val )
0174 {
0175     return monomorphic::ds_detail::make_xrange<SampleType>::_( data::end=end_val );
0176 }
0177 
0178 //____________________________________________________________________________//
0179 
0180 /// @overload boost::unit_test::data::xrange()
0181 template<typename SampleType, typename Params>
0182 inline typename enable_if_c<nfp::is_named_param_pack<Params>::value,
0183                             monomorphic::generated_by<monomorphic::xrange_t<SampleType>>>::type
0184 xrange( SampleType const& end_val, Params const& params )
0185 {
0186     return monomorphic::ds_detail::make_xrange<SampleType>::_(( params, data::end=end_val ));
0187 }
0188 
0189 //____________________________________________________________________________//
0190 
0191 /// @overload boost::unit_test::data::xrange()
0192 template<typename SampleType>
0193 inline monomorphic::generated_by<monomorphic::xrange_t<SampleType>>
0194 xrange( SampleType const& begin_val, SampleType const& end_val )
0195 {
0196     return monomorphic::ds_detail::make_xrange<SampleType>::_((
0197                 data::begin=begin_val,
0198                 data::end=end_val ));
0199 }
0200 
0201 //____________________________________________________________________________//
0202 
0203 
0204 
0205 /// @overload boost::unit_test::data::xrange()
0206 template<typename SampleType,typename StepType>
0207 inline monomorphic::generated_by<monomorphic::xrange_t<SampleType>>
0208 xrange( SampleType const& begin_val, SampleType const& end_val, StepType const& step_val )
0209 {
0210     return monomorphic::ds_detail::make_xrange<SampleType,StepType>::_(( 
0211                 data::begin=begin_val, 
0212                 data::end=end_val,
0213                 data::step=step_val ));
0214 }
0215 
0216 //____________________________________________________________________________//
0217 
0218 } // namespace data
0219 } // namespace unit_test
0220 } // namespace boost
0221 
0222 #include <boost/test/detail/enable_warnings.hpp>
0223 
0224 #endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER