]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/test/include/boost/test/data/monomorphic/generators/xrange.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / test / include / boost / test / data / monomorphic / generators / xrange.hpp
1 // (C) Copyright Gennadiy Rozental 2001.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5
6 // See http://www.boost.org/libs/test for the library home page.
7 //
8 ///@file
9 ///Defines range generator
10 // ***************************************************************************
11
12 #ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER
13 #define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER
14
15 // Boost.Test
16 #include <boost/test/data/config.hpp>
17
18 #include <boost/test/data/monomorphic/generators/keywords.hpp>
19 #include <boost/test/data/monomorphic/generate.hpp>
20
21 // Boost
22 #include <boost/optional.hpp>
23 #include <boost/utility/enable_if.hpp>
24 #include <boost/type_traits/is_unsigned.hpp>
25
26 // STL
27 #include <limits>
28 #include <cmath>
29
30 #include <boost/test/detail/suppress_warnings.hpp>
31
32 //____________________________________________________________________________//
33
34 namespace boost {
35 namespace unit_test {
36 namespace data {
37 namespace monomorphic {
38
39 // ************************************************************************** //
40 // ************** monomorphic::xrange_t ************** //
41 // ************************************************************************** //
42
43
44 /*!@brief Generator for the range sequences
45 *
46 * This class implements the generator concept (see @ref boost::unit_test::data::monomorphic::generated_by) for implementing
47 * a range like sequence of numbers.
48 */
49 template<typename SampleType, typename StepType=SampleType>
50 class xrange_t {
51 public:
52 typedef SampleType sample;
53
54 xrange_t( SampleType const& begin_, StepType const& step_, data::size_t size_ )
55 : m_begin( begin_ )
56 , m_curr( begin_ )
57 , m_step( step_ )
58 , m_index( 0 )
59 , m_size( size_ )
60 {}
61
62 // Generator interface
63 data::size_t capacity() const { return m_size; }
64 SampleType next()
65 {
66 if( m_index == m_size )
67 return m_curr;
68
69 SampleType res = m_curr;
70
71 m_curr += m_step;
72 ++m_index;
73
74 return res;
75 }
76 void reset()
77 {
78 m_curr = m_begin;
79 m_index = 0;
80 }
81
82 private:
83 // Data members
84 SampleType m_begin;
85 SampleType m_curr;
86 StepType m_step;
87 data::size_t m_index;
88 data::size_t m_size;
89 };
90
91 //____________________________________________________________________________//
92
93 namespace ds_detail {
94
95 template<typename SampleType, typename StepType=SampleType>
96 struct make_xrange {
97 static StepType abs( StepType s, boost::true_type* ) { return s; }
98 static StepType abs( StepType s, boost::false_type* ) { return std::abs(s); }
99
100 typedef xrange_t<SampleType, StepType> range_gen;
101
102 template<typename Params>
103 static generated_by<range_gen>
104 _( Params const& params )
105 {
106 SampleType begin_val = params.has( data::begin ) ? params[data::begin] : SampleType();
107 optional<SampleType> end_val = params.has( data::end ) ? params[data::end] : optional<SampleType>();
108 StepType step_val = params.has( data::step ) ? params[data::step] : 1;
109
110 BOOST_TEST_DS_ASSERT( step_val != 0, "Range step can't be zero" );
111
112 data::size_t size;
113 if( !end_val.is_initialized() )
114 size = BOOST_TEST_DS_INFINITE_SIZE;
115 else {
116 BOOST_TEST_DS_ASSERT( (step_val < 0) ^ (begin_val < *end_val), "Invalid step direction" );
117
118 SampleType abs_distance = step_val < 0 ? begin_val - *end_val : *end_val-begin_val;
119 StepType abs_step = make_xrange::abs(step_val, (typename boost::is_unsigned<StepType>::type*)0 );
120 std::size_t s = static_cast<std::size_t>(abs_distance/abs_step);
121
122 if( static_cast<SampleType>(s*abs_step) < abs_distance )
123 s++;
124
125 size = s;
126 }
127
128 return generated_by<range_gen>( range_gen( begin_val, step_val, size ) );
129 }
130 };
131
132 } // namespace ds_detail
133 } // namespace monomorphic
134
135 //____________________________________________________________________________//
136
137 //! Creates a range (sequence) dataset.
138 //!
139 //! The following overloads are available:
140 //! @code
141 //! auto d = xrange();
142 //! auto d = xrange(end_val);
143 //! auto d = xrange(end_val, param);
144 //! auto d = xrange(begin_val, end_val);
145 //! auto d = xrange(begin_val, end_val, step_val);
146 //! auto d = xrange(param);
147 //! @endcode
148 //!
149 //! - @c begin_val indicates the start of the sequence (default to 0).
150 //! - @c end_val is the end of the sequence. If ommited, the dataset has infinite size.\n
151 //! - @c step_val is the step between two consecutive elements of the sequence, and defaults to 1.\n
152 //! - @c param is the named parameters that describe the sequence. The following parameters are accepted:
153 //! - @c begin: same meaning @c begin_val
154 //! - @c end: same meaning as @c end_val
155 //! - @c step: same meaning as @c step_val
156 //!
157 //!
158 //! The returned value is an object that implements the dataset API.
159 //!
160 //! @note the step size cannot be null, and it should be positive if @c begin_val < @c end_val, negative otherwise.
161 template<typename SampleType, typename Params>
162 inline monomorphic::generated_by<monomorphic::xrange_t<SampleType>>
163 xrange( Params const& params )
164 {
165 return monomorphic::ds_detail::make_xrange<SampleType>::_( params );
166 }
167
168 //____________________________________________________________________________//
169
170 /// @overload boost::unit_test::data::xrange()
171 template<typename SampleType>
172 inline monomorphic::generated_by<monomorphic::xrange_t<SampleType>>
173 xrange( SampleType const& end_val )
174 {
175 return monomorphic::ds_detail::make_xrange<SampleType>::_( data::end=end_val );
176 }
177
178 //____________________________________________________________________________//
179
180 /// @overload boost::unit_test::data::xrange()
181 template<typename SampleType, typename Params>
182 inline typename enable_if_c<nfp::is_named_param_pack<Params>::value,
183 monomorphic::generated_by<monomorphic::xrange_t<SampleType>>>::type
184 xrange( SampleType const& end_val, Params const& params )
185 {
186 return monomorphic::ds_detail::make_xrange<SampleType>::_(( params, data::end=end_val ));
187 }
188
189 //____________________________________________________________________________//
190
191 /// @overload boost::unit_test::data::xrange()
192 template<typename SampleType>
193 inline monomorphic::generated_by<monomorphic::xrange_t<SampleType>>
194 xrange( SampleType const& begin_val, SampleType const& end_val )
195 {
196 return monomorphic::ds_detail::make_xrange<SampleType>::_((
197 data::begin=begin_val,
198 data::end=end_val ));
199 }
200
201 //____________________________________________________________________________//
202
203
204
205 /// @overload boost::unit_test::data::xrange()
206 template<typename SampleType,typename StepType>
207 inline monomorphic::generated_by<monomorphic::xrange_t<SampleType>>
208 xrange( SampleType const& begin_val, SampleType const& end_val, StepType const& step_val )
209 {
210 return monomorphic::ds_detail::make_xrange<SampleType,StepType>::_((
211 data::begin=begin_val,
212 data::end=end_val,
213 data::step=step_val ));
214 }
215
216 //____________________________________________________________________________//
217
218 } // namespace data
219 } // namespace unit_test
220 } // namespace boost
221
222 #include <boost/test/detail/enable_warnings.hpp>
223
224 #endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER