summaryrefslogtreecommitdiff
path: root/boost/test/data/monomorphic/generators/xrange.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/test/data/monomorphic/generators/xrange.hpp')
-rw-r--r--boost/test/data/monomorphic/generators/xrange.hpp221
1 files changed, 221 insertions, 0 deletions
diff --git a/boost/test/data/monomorphic/generators/xrange.hpp b/boost/test/data/monomorphic/generators/xrange.hpp
new file mode 100644
index 0000000000..55a51110b4
--- /dev/null
+++ b/boost/test/data/monomorphic/generators/xrange.hpp
@@ -0,0 +1,221 @@
+// (C) Copyright Gennadiy Rozental 2011-2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/test for the library home page.
+//
+///@file
+///Defines range generator
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER
+#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+
+#include <boost/test/data/monomorphic/generators/keywords.hpp>
+#include <boost/test/data/monomorphic/generate.hpp>
+
+// Boost
+#include <boost/optional.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_unsigned.hpp>
+
+// STL
+#include <limits>
+#include <cmath>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+namespace monomorphic {
+
+// ************************************************************************** //
+// ************** monomorphic::xrange_t ************** //
+// ************************************************************************** //
+
+
+/*!@brief Generator for the range sequences
+ *
+ * This class implements the generator concept (see @ref boost::unit_test::data::monomorphic::generated_by) for implementing
+ * a range like sequence of numbers.
+ */
+template<typename SampleType, typename StepType=SampleType>
+class xrange_t {
+public:
+ typedef SampleType data_type;
+
+ xrange_t( SampleType const& begin, StepType const& step, data::size_t size )
+ : m_begin( begin )
+ , m_curr( begin )
+ , m_step( step )
+ , m_index( 0 )
+ , m_size( size )
+ {}
+
+ // Generator interface
+ data::size_t capacity() const { return m_size; }
+ SampleType next()
+ {
+ if( m_index == m_size )
+ return m_curr;
+
+ SampleType res = m_curr;
+
+ m_curr += m_step;
+ ++m_index;
+
+ return res;
+ }
+ void reset()
+ {
+ m_curr = m_begin;
+ m_index = 0;
+ }
+
+private:
+ // Data members
+ SampleType m_begin;
+ SampleType m_curr;
+ StepType m_step;
+ data::size_t m_index;
+ data::size_t m_size;
+};
+
+//____________________________________________________________________________//
+
+namespace ds_detail {
+
+template<typename SampleType, typename StepType=SampleType>
+struct make_xrange {
+ static StepType abs( StepType s, boost::true_type* ) { return s; }
+ static StepType abs( StepType s, boost::false_type* ) { return std::abs(s); }
+
+ typedef xrange_t<SampleType, StepType> range_gen;
+
+ template<typename Params>
+ static generated_by<range_gen>
+ _( Params const& params )
+ {
+ SampleType begin_val = params.has( data::begin ) ? params[data::begin] : SampleType();
+ optional<SampleType> end_val = params.has( data::end ) ? params[data::end] : optional<SampleType>();
+ StepType step_val = params.has( data::step ) ? params[data::step] : 1;
+
+ BOOST_TEST_DS_ASSERT( step_val != 0, "Range step can't be zero" );
+
+ data::size_t size;
+ if( !end_val.is_initialized() )
+ size = BOOST_TEST_DS_INFINITE_SIZE;
+ else {
+ BOOST_TEST_DS_ASSERT( (step_val < 0) ^ (begin_val < *end_val), "Invalid step direction" );
+
+ SampleType abs_distance = step_val < 0 ? begin_val - *end_val : *end_val-begin_val;
+ StepType abs_step = make_xrange::abs(step_val, (typename boost::is_unsigned<StepType>::type*)0 );
+ std::size_t s = static_cast<std::size_t>(abs_distance/abs_step);
+
+ if( static_cast<SampleType>(s*abs_step) < abs_distance )
+ s++;
+
+ size = s;
+ }
+
+ return generated_by<range_gen>( range_gen( begin_val, step_val, size ) );
+ }
+};
+
+} // namespace ds_detail
+} // namespace monomorphic
+
+//____________________________________________________________________________//
+
+//! Creates a range (sequence) dataset.
+//!
+//! The following overloads are available:
+//! @code
+//! auto d = xrange();
+//! auto d = xrange(end_val);
+//! auto d = xrange(end_val, param);
+//! auto d = xrange(begin_val, end_val);
+//! auto d = xrange(begin_val, end_val, step_val);
+//! auto d = xrange(param);
+//! @endcode
+//!
+//! - @c begin_val indicates the start of the sequence (default to 0).
+//! - @c end_val is the end of the sequence. If ommited, the dataset has infinite size.\n
+//! - @c step_val is the step between two consecutive elements of the sequence, and defaults to 1.\n
+//! - @c param is the named parameters that describe the sequence. The following parameters are accepted:
+//! - @c begin: same meaning @c begin_val
+//! - @c end: same meaning as @c end_val
+//! - @c step: same meaning as @c step_val
+//!
+//!
+//! The returned value is an object that implements the dataset API.
+//!
+//! @note the step size cannot be null, and it should be positive if @c begin_val < @c end_val, negative otherwise.
+template<typename SampleType, typename Params>
+inline monomorphic::generated_by<monomorphic::xrange_t<SampleType> >
+xrange( Params const& params )
+{
+ return monomorphic::ds_detail::make_xrange<SampleType>::_( params );
+}
+
+//____________________________________________________________________________//
+
+/// @overload boost::unit_test::data::xrange()
+template<typename SampleType>
+inline monomorphic::generated_by<monomorphic::xrange_t<SampleType> >
+xrange( SampleType const& end_val )
+{
+ return monomorphic::ds_detail::make_xrange<SampleType>::_( data::end=end_val );
+}
+
+//____________________________________________________________________________//
+
+/// @overload boost::unit_test::data::xrange()
+template<typename SampleType, typename Params>
+inline typename enable_if_c<nfp::is_named_params<Params>::value,monomorphic::generated_by<monomorphic::xrange_t<SampleType> > >::type
+xrange( SampleType const& end_val, Params const& params )
+{
+ return monomorphic::ds_detail::make_xrange<SampleType>::
+ _(( params, data::end=end_val ));
+}
+
+//____________________________________________________________________________//
+
+/// @overload boost::unit_test::data::xrange()
+template<typename SampleType>
+inline monomorphic::generated_by<monomorphic::xrange_t<SampleType> >
+xrange( SampleType const& begin_val, SampleType const& end_val )
+{
+ return monomorphic::ds_detail::make_xrange<SampleType>::
+ _(( data::begin=begin_val, data::end=end_val ));
+}
+
+//____________________________________________________________________________//
+
+
+
+/// @overload boost::unit_test::data::xrange()
+template<typename SampleType,typename StepType>
+inline monomorphic::generated_by<monomorphic::xrange_t<SampleType> >
+xrange( SampleType const& begin_val, SampleType const& end_val, StepType const& step_val )
+{
+ return monomorphic::ds_detail::make_xrange<SampleType,StepType>::
+ _(( data::begin=begin_val, data::end=end_val, data::step=step_val ));
+}
+
+//____________________________________________________________________________//
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER