diff options
Diffstat (limited to 'boost/test/data/monomorphic')
-rw-r--r-- | boost/test/data/monomorphic/array.hpp | 113 | ||||
-rw-r--r-- | boost/test/data/monomorphic/collection.hpp | 125 | ||||
-rw-r--r-- | boost/test/data/monomorphic/dataset.hpp | 174 | ||||
-rw-r--r-- | boost/test/data/monomorphic/fwd.hpp | 314 | ||||
-rw-r--r-- | boost/test/data/monomorphic/generate.hpp | 116 | ||||
-rw-r--r-- | boost/test/data/monomorphic/generators.hpp | 20 | ||||
-rw-r--r-- | boost/test/data/monomorphic/generators/keywords.hpp | 39 | ||||
-rw-r--r-- | boost/test/data/monomorphic/generators/random.hpp | 198 | ||||
-rw-r--r-- | boost/test/data/monomorphic/generators/xrange.hpp | 221 | ||||
-rw-r--r-- | boost/test/data/monomorphic/grid.hpp | 226 | ||||
-rw-r--r-- | boost/test/data/monomorphic/join.hpp | 194 | ||||
-rw-r--r-- | boost/test/data/monomorphic/singleton.hpp | 137 | ||||
-rw-r--r-- | boost/test/data/monomorphic/zip.hpp | 240 |
13 files changed, 2117 insertions, 0 deletions
diff --git a/boost/test/data/monomorphic/array.hpp b/boost/test/data/monomorphic/array.hpp new file mode 100644 index 0000000000..87c55e7653 --- /dev/null +++ b/boost/test/data/monomorphic/array.hpp @@ -0,0 +1,113 @@ +// (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 monomorphic dataset based on C type arrays +// *************************************************************************** + +#ifndef BOOST_TEST_DATA_MONOMORPHIC_ARRAY_HPP_121411GER +#define BOOST_TEST_DATA_MONOMORPHIC_ARRAY_HPP_121411GER + +// Boost.Test +#include <boost/test/data/config.hpp> +#include <boost/test/data/monomorphic/dataset.hpp> + +#include <boost/test/detail/suppress_warnings.hpp> + +//____________________________________________________________________________// + +namespace boost { +namespace unit_test { +namespace data { +namespace monomorphic { + +// ************************************************************************** // +// ************** array ************** // +// ************************************************************************** // + +/// Dataset view of an C array +template<typename T> +class array : public monomorphic::dataset<T> { + typedef monomorphic::dataset<T> base; + typedef typename base::iter_ptr iter_ptr; + + struct iterator : public base::iterator { + // Constructor + explicit iterator( T const* begin, data::size_t size ) + : m_it( begin ) + , m_singleton( size == 1 ) + {} + + // forward iterator interface + virtual T const& operator*() { return *m_it; } + virtual void operator++() { if( !m_singleton ) ++m_it; } + + private: + // Data members + T const* m_it; + bool m_singleton; + }; + +public: + enum { arity = 1 }; + + // Constructor + array( T const* arr, std::size_t size ) + : m_arr( arr ) + , m_size( size ) + {} + + // dataset interface + virtual data::size_t size() const { return m_size; } + virtual iter_ptr begin() const { return boost::make_shared<iterator>( m_arr, m_size ); } + +private: + // Data members + T const* m_arr; + std::size_t m_size; +}; + +//____________________________________________________________________________// + +//! An array dataset is a dataset +template<typename T> +struct is_dataset<array<T> > : mpl::true_ {}; + +} // namespace monomorphic + + +//! @overload boost::unit_test::data::make() +template<typename T, std::size_t size> +inline monomorphic::array< typename boost::remove_const<T>::type > make( T (&a)[size] ) +{ + return monomorphic::array< typename boost::remove_const<T>::type >( a, size ); +} + +//! @overload boost::unit_test::data::make() +template<typename T, std::size_t size> +inline monomorphic::array< typename boost::remove_const<T>::type > make( T const (&a)[size] ) +{ + return monomorphic::array<T>( a, size ); +} + +template<typename T, std::size_t size> +inline monomorphic::array< typename boost::remove_const<T>::type > make( T a[size] ) +{ + return monomorphic::array<T>( a, size ); +} + + +//____________________________________________________________________________// + +} // namespace data +} // namespace unit_test +} // namespace boost + +#include <boost/test/detail/enable_warnings.hpp> + +#endif // BOOST_TEST_DATA_MONOMORPHIC_ARRAY_HPP_121411GER + diff --git a/boost/test/data/monomorphic/collection.hpp b/boost/test/data/monomorphic/collection.hpp new file mode 100644 index 0000000000..5666a62f8d --- /dev/null +++ b/boost/test/data/monomorphic/collection.hpp @@ -0,0 +1,125 @@ +// (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 monomorphic dataset based on forward iterable sequence +// *************************************************************************** + +#ifndef BOOST_TEST_DATA_MONOMORPHIC_COLLECTION_HPP_102211GER +#define BOOST_TEST_DATA_MONOMORPHIC_COLLECTION_HPP_102211GER + +// Boost.Test +#include <boost/test/data/config.hpp> +#include <boost/test/data/monomorphic/dataset.hpp> + +#include <boost/test/detail/suppress_warnings.hpp> + +//____________________________________________________________________________// + +namespace boost { +namespace unit_test { +namespace data { +namespace monomorphic { + +// ************************************************************************** // +// ************** collection ************** // +// ************************************************************************** // + + +//!@brief Dataset from a forward iterable container (collection) +//! +//! This dataset is applicable to any container implementing a forward iterator. Note that +//! container with one element will be considered as singletons. +//! This dataset is constructible with the @ref boost::unit_test::data::make function. +//! +//! For compilers supporting r-value references, the collection is moved instead of copied. +template<typename C> +class collection : public monomorphic::dataset<typename boost::decay<C>::type::value_type> { + typedef typename boost::decay<C>::type col_type; + typedef typename col_type::value_type T; + typedef monomorphic::dataset<T> base; + typedef typename base::iter_ptr iter_ptr; + + struct iterator : public base::iterator { + // Constructor + explicit iterator( collection<C> const& owner ) + : m_iter( owner.col().begin() ) + , m_singleton( owner.col().size() == 1 ) + {} + + // forward iterator interface + virtual T const& operator*() { return *m_iter; } + virtual void operator++() { if( !m_singleton ) ++m_iter; } + + private: + // Data members + typename col_type::const_iterator m_iter; + bool m_singleton; + }; + +public: + enum { arity = 1 }; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + //! Constructor + //! The collection is moved + explicit collection( C&& col ) : m_col( std::forward<C>(col) ) {} + + //! Move constructor + collection( collection&& c ) : m_col( std::forward<C>( c.m_col ) ) {} +#else + //! Constructor + //! The collection is copied + explicit collection( C const& col ) : m_col( col ) {} +#endif + + //! Returns the underlying collection + C const& col() const { return m_col; } + + // dataset interface + virtual data::size_t size() const { return m_col.size(); } + virtual iter_ptr begin() const { return boost::make_shared<iterator>( *this ); } + +private: + // Data members + C m_col; +}; + +//____________________________________________________________________________// + +//! A collection from a forward iterable container is a dataset. +template<typename C> +struct is_dataset<collection<C> > : mpl::true_ {}; + +} // namespace monomorphic + +//! @overload boost::unit_test::data::make() +template<typename C> +inline typename BOOST_TEST_ENABLE_IF<is_forward_iterable<C>::value, + monomorphic::collection<C> >::type +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +make( C&& c ) +{ + return monomorphic::collection<C>( std::forward<C>(c) ); +} +#else +make( C const& c ) +{ + return monomorphic::collection<C>( c ); +} +#endif + +//____________________________________________________________________________// + +} // namespace data +} // namespace unit_test +} // namespace boost + +#include <boost/test/detail/enable_warnings.hpp> + +#endif // BOOST_TEST_DATA_MONOMORPHIC_COLLECTION_HPP_102211GER + diff --git a/boost/test/data/monomorphic/dataset.hpp b/boost/test/data/monomorphic/dataset.hpp new file mode 100644 index 0000000000..122dbea8c5 --- /dev/null +++ b/boost/test/data/monomorphic/dataset.hpp @@ -0,0 +1,174 @@ +// (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 monomorphic dataset interface +// +// *************************************************************************** + +#ifndef BOOST_TEST_DATA_MONOMORPHIC_DATASET_HPP_102211GER +#define BOOST_TEST_DATA_MONOMORPHIC_DATASET_HPP_102211GER + +// Boost.Test +#include <boost/test/data/config.hpp> +#include <boost/test/data/monomorphic/fwd.hpp> + +// STL +#ifndef BOOST_NO_CXX11_HDR_TUPLE +#include <tuple> +#endif +//#include <stdexcept> + +#include <boost/test/detail/suppress_warnings.hpp> + +//____________________________________________________________________________// + +namespace boost { +namespace unit_test { +namespace data { +namespace monomorphic { + +// ************************************************************************** // +// ************** monomorphic::traits ************** // +// ************************************************************************** // + +template<typename T> +struct traits { + // type of the reference to sample returned by iterator + typedef T const& ref_type; + + template<typename Action> + static void + invoke_action( ref_type arg, Action const& action ) + { + action( arg ); + } +}; + +//____________________________________________________________________________// + +#ifndef BOOST_NO_CXX11_HDR_TUPLE +// !! ?? reimplement using variadics +template<typename T1, typename T2> +struct traits<std::tuple<T1,T2>> { + // type of the reference to sample returned by iterator + typedef std::tuple<T1 const&,T2 const&> ref_type; + + template<typename Action> + static void + invoke_action( ref_type arg, Action const& action ) + { + action( std::get<0>(arg), std::get<1>(arg) ); + } +}; + +//____________________________________________________________________________// + +template<typename T1, typename T2, typename T3> +struct traits<std::tuple<T1,T2,T3>> { + // type of the reference to sample returned by iterator + typedef std::tuple<T1 const&,T2 const&,T3 const&> ref_type; + + template<typename Action> + static void + invoke_action( ref_type arg, Action const& action ) + { + action( std::get<0>(arg), std::get<1>(arg), std::get<2>(arg) ); + } +}; + +//____________________________________________________________________________// + +#endif + +// ************************************************************************** // +// ************** monomorphic::dataset ************** // +// ************************************************************************** // + +//!@brief Dataset base class +//! +//! This class defines the dataset concept, which is an implementation of a sequence. +//! Each dataset should implement +//! - the @c size +//! - the @c begin function, which provides a forward iterator on the beginning of the sequence. The returned +//! iterator should be incrementable a number of times corresponding to the returned size. +//! +template<typename T> +class dataset { +public: + //! Type of the samples in this dataset + typedef T data_type; + + virtual ~dataset() + {} + + //! Interface of the dataset iterator + class iterator { + public: + typedef typename monomorphic::traits<T>::ref_type ref_type; + + virtual ~iterator() {} + + // forward iterator interface + virtual ref_type operator*() = 0; + virtual void operator++() = 0; + }; + + //! Type of the iterator + typedef boost::shared_ptr<iterator> iter_ptr; + + //! Dataset size + virtual data::size_t size() const = 0; + + //! Iterator to use to iterate over this dataset + virtual iter_ptr begin() const = 0; +}; + +} // namespace monomorphic + +// ************************************************************************** // +// ************** for_each_sample ************** // +// ************************************************************************** // + +template<typename SampleType, typename Action> +inline void +for_each_sample( monomorphic::dataset<SampleType> const& ds, + Action const& act, + data::size_t number_of_samples = BOOST_TEST_DS_INFINITE_SIZE ) +{ + data::size_t size = (std::min)( ds.size(), number_of_samples ); + BOOST_TEST_DS_ASSERT( !size.is_inf(), "Dataset has infinite size. Please specify the number of samples" ); + + typename monomorphic::dataset<SampleType>::iter_ptr it = ds.begin(); + + while( size-- > 0 ) { + monomorphic::traits<SampleType>::invoke_action( **it, act ); + ++(*it); + } +} + +//____________________________________________________________________________// + +template<typename SampleType, typename Action> +inline typename BOOST_TEST_ENABLE_IF<!monomorphic::is_dataset<SampleType>::value,void>::type +for_each_sample( SampleType const& samples, + Action const& act, + data::size_t number_of_samples = BOOST_TEST_DS_INFINITE_SIZE ) +{ + data::for_each_sample( data::make( samples ), act, number_of_samples ); +} + +//____________________________________________________________________________// + +} // namespace data +} // namespace unit_test +} // namespace boost + +#include <boost/test/detail/enable_warnings.hpp> + +#endif // BOOST_TEST_DATA_MONOMORPHIC_DATASET_HPP_102211GER + diff --git a/boost/test/data/monomorphic/fwd.hpp b/boost/test/data/monomorphic/fwd.hpp new file mode 100644 index 0000000000..9ff4955432 --- /dev/null +++ b/boost/test/data/monomorphic/fwd.hpp @@ -0,0 +1,314 @@ +// (C) Copyright Gennadiy Rozental 2012-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 +/// Forward declares monomorphic datasets interfaces +// *************************************************************************** + +#ifndef BOOST_TEST_DATA_MONOMORPHIC_FWD_HPP_102212GER +#define BOOST_TEST_DATA_MONOMORPHIC_FWD_HPP_102212GER + +// Boost.Test +#include <boost/test/data/config.hpp> +#include <boost/test/data/size.hpp> + +#include <boost/test/utils/is_forward_iterable.hpp> + + +// Boost +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES +#include <boost/utility/enable_if.hpp> +#include <boost/type_traits/add_const.hpp> +#else +#include <boost/utility/declval.hpp> +#endif +#include <boost/type_traits/remove_const.hpp> +#include <boost/mpl/bool.hpp> +#include <boost/smart_ptr/make_shared.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/type_traits/decay.hpp> + +#include <boost/test/detail/suppress_warnings.hpp> + +//____________________________________________________________________________// + +namespace boost { +namespace unit_test { +namespace data { + +namespace monomorphic { + + +#if !defined(BOOST_TEST_DOXYGEN_DOC__) +template<typename T> +struct traits; + +template<typename T> +class dataset; + +template<typename T> +class singleton; + +template<typename C> +class collection; + +template<typename T> +class array; +#endif + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_TEST_ENABLE_IF std::enable_if +#else +# define BOOST_TEST_ENABLE_IF boost::enable_if_c +#endif + +// ************************************************************************** // +// ************** monomorphic::is_dataset ************** // +// ************************************************************************** // + +//! Helper metafunction indicating if the specified type is a dataset. +template<typename DataSet> +struct is_dataset : mpl::false_ {}; + +//! A reference to a dataset is a dataset +template<typename DataSet> +struct is_dataset<DataSet&> : is_dataset<DataSet> {}; + +//! A const dataset is a dataset +template<typename DataSet> +struct is_dataset<DataSet const> : is_dataset<DataSet> {}; + +//____________________________________________________________________________// + +} // namespace monomorphic + +// ************************************************************************** // +// ************** data::make ************** // +// ************************************************************************** // + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + + +//! @brief Creates a dataset from a value, a collection or an array +//! +//! This function has several overloads: +//! @code +//! // returns ds if ds is already a dataset +//! template <typename DataSet> DataSet make(DataSet&& ds); +//! +//! // creates a singleton dataset, for non forward iterable and non dataset type T +//! // (a C string is not considered as a sequence). +//! template <typename T> monomorphic::singleton<T> make(T&& v); +//! monomorphic::singleton<char*> make( char* str ); +//! monomorphic::singleton<char const*> make( char const* str ); +//! +//! // creates a collection dataset, for forward iterable and non dataset type C +//! template <typename C> monomorphic::collection<C> make(C && c); +//! +//! // creates an array dataset +//! template<typename T, std::size_t size> monomorphic::array<T> make( T (&a)[size] ); +//! @endcode +template<typename DataSet> +inline typename BOOST_TEST_ENABLE_IF<monomorphic::is_dataset<DataSet>::value,DataSet>::type +make(DataSet&& ds) +{ + return std::forward<DataSet>( ds ); +} + + +// warning: doxygen is apparently unable to handle @overload from different files, so if the overloads +// below are not declared with @overload in THIS file, they do not appear in the documentation. + +// fwrd declaration for singletons +//! @overload boost::unit_test::data::make() +template<typename T> +inline typename BOOST_TEST_ENABLE_IF<!is_forward_iterable<T>::value && + !monomorphic::is_dataset<T>::value && + !boost::is_array< typename boost::remove_reference<T>::type >::value, + monomorphic::singleton<T> >::type +make( T&& v ); + + +//! @overload boost::unit_test::data::make() +template<typename C> +inline typename BOOST_TEST_ENABLE_IF<is_forward_iterable<C>::value, + monomorphic::collection<C> >::type +make( C&& c ); + + +#else // !BOOST_NO_CXX11_RVALUE_REFERENCES + +//! @overload boost::unit_test:data::make() +template<typename DataSet> +inline typename BOOST_TEST_ENABLE_IF<monomorphic::is_dataset<DataSet>::value,DataSet const&>::type +make(DataSet const& ds) +{ + return ds; +} + + +// fwrd declaration for singletons +#if !(defined(BOOST_MSVC) && (BOOST_MSVC < 1600)) +//! @overload boost::unit_test::data::make() +template<typename T> +inline typename BOOST_TEST_ENABLE_IF<!is_forward_iterable<T>::value && + !monomorphic::is_dataset<T>::value && + !boost::is_array< typename boost::remove_reference<T>::type >::value, + monomorphic::singleton<T> >::type +make( T const& v ); +#endif + + +// fwrd declaration for collections +//! @overload boost::unit_test::data::make() +template<typename C> +inline typename BOOST_TEST_ENABLE_IF<is_forward_iterable<C>::value, + monomorphic::collection<C> >::type +make( C const& c ); + +//____________________________________________________________________________// + + + +#endif // !BOOST_NO_CXX11_RVALUE_REFERENCES + + + + +// fwrd declarations +//! @overload boost::unit_test::data::make() +template<typename T, std::size_t size> +inline monomorphic::array< typename boost::remove_const<T>::type > +make( T (&a)[size] ); + +// apparently some compilers (eg clang-3.4 on linux) have trouble understanding +// the previous line for T being const +//! @overload boost::unit_test::data::make() +template<typename T, std::size_t size> +inline monomorphic::array< typename boost::remove_const<T>::type > +make( T const (&)[size] ); + +template<typename T, std::size_t size> +inline monomorphic::array< typename boost::remove_const<T>::type > +make( T a[size] ); + + + +//! @overload boost::unit_test::data::make() +inline monomorphic::singleton<char*> +make( char* str ); + +//! @overload boost::unit_test::data::make() +inline monomorphic::singleton<char const*> +make( char const* str ); + + + +//____________________________________________________________________________// + + + +namespace result_of { + +#ifndef BOOST_NO_CXX11_DECLTYPE +//! Result of the make call. +template<typename DataSet> +struct make +{ + typedef decltype(data::make(boost::declval<DataSet>())) type; +}; +#else + +// explicit specialisation, cumbersome + +template <typename DataSet, typename Enable = void> +struct make; + +template <typename DataSet> +struct make< + DataSet const&, + typename BOOST_TEST_ENABLE_IF<monomorphic::is_dataset<DataSet>::value>::type + > +{ + typedef DataSet const& type; +}; + +template <typename T> +struct make< + T, + typename BOOST_TEST_ENABLE_IF< (!is_forward_iterable<T>::value && + !monomorphic::is_dataset<T>::value && + !boost::is_array< typename boost::remove_reference<T>::type >::value) + >::type + > +{ + typedef monomorphic::singleton<T> type; +}; + +template <typename C> +struct make< + C, + typename BOOST_TEST_ENABLE_IF< is_forward_iterable<C>::value>::type + > +{ + typedef monomorphic::collection<C> type; +}; + +#if 1 +template <typename T, std::size_t size> +struct make<T [size]> +{ + typedef monomorphic::array<typename boost::remove_const<T>::type> type; +}; +#endif + +template <typename T, std::size_t size> +struct make<T (&)[size]> +{ + typedef monomorphic::array<typename boost::remove_const<T>::type> type; +}; + +template <typename T, std::size_t size> +struct make<T const (&)[size]> +{ + typedef monomorphic::array<typename boost::remove_const<T>::type> type; +}; + +template <> +struct make<char*> +{ + typedef monomorphic::singleton<char*> type; +}; + +template <> +struct make<char const*> +{ + typedef monomorphic::singleton<char const*> type; +}; + +#endif // BOOST_NO_CXX11_DECLTYPE + + +} // namespace result_of + + + + +//____________________________________________________________________________// + +} // namespace data +} // namespace unit_test +} // namespace boost + + + + + +#include <boost/test/detail/enable_warnings.hpp> + +#endif // BOOST_TEST_DATA_MONOMORPHIC_FWD_HPP_102212GER + diff --git a/boost/test/data/monomorphic/generate.hpp b/boost/test/data/monomorphic/generate.hpp new file mode 100644 index 0000000000..c5ff1d699b --- /dev/null +++ b/boost/test/data/monomorphic/generate.hpp @@ -0,0 +1,116 @@ +// (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 generic interface for monomorphic dataset based on generator +// *************************************************************************** + +#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATE_HPP_112011GER +#define BOOST_TEST_DATA_MONOMORPHIC_GENERATE_HPP_112011GER + +// Boost.Test +#include <boost/test/data/config.hpp> +#include <boost/test/data/monomorphic/dataset.hpp> + +#include <boost/test/detail/suppress_warnings.hpp> + +//____________________________________________________________________________// + +namespace boost { +namespace unit_test { +namespace data { +namespace monomorphic { + +// ************************************************************************** // +// ************** generated_by ************** // +// ************************************************************************** // + +/*!@brief Generators interface + * + * This class implements the dataset concept over a generator. Examples of generators are: + * - xrange_t + * - random_t + * + * The generator concept is the following: + * - the type of the generated samples is given by field @c data_type + * - the member function @c capacity should return the size of the collection being generated (potentially infinite) + * - the member function @c next should change the state of the generator to the next generated value + * - the member function @c reset should put the state of the object in the same state as right after its instanciation + */ +template<typename Generator> +class generated_by : public monomorphic::dataset<typename Generator::data_type> { + typedef typename Generator::data_type T; + typedef monomorphic::dataset<T> base; + typedef typename base::iter_ptr iter_ptr; + + struct iterator : public base::iterator { + // Constructor + explicit iterator( Generator& gen ) + : m_gen( gen ) + { + if(m_gen.capacity() > 0) { + m_gen.reset(); + ++*this; + } + } + + // forward iterator interface + virtual T const& operator*() { return m_curr_sample; } + virtual void operator++() { m_curr_sample = m_gen.next(); } + + private: + // Data members + Generator& m_gen; + T m_curr_sample; + }; +public: + enum { arity = 1 }; + typedef Generator generator_type; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + // Constructor + explicit generated_by( Generator&& G ) + : m_generator( std::forward<Generator>(G) ) + {} + + // Move constructor + generated_by( generated_by&& rhs ) + : m_generator( std::forward<Generator>(rhs.m_generator) ) + {} +#else + // Constructor + explicit generated_by( Generator const& G ) + : m_generator( G ) + {} +#endif + + //! Size of the underlying dataset + data::size_t size() const { return m_generator.capacity(); } + + //! Iterator on the beginning of the dataset + virtual iter_ptr begin() const { return boost::make_shared<iterator>( boost::ref(const_cast<Generator&>(m_generator)) ); } + +private: + // Data members + Generator m_generator; +}; + + +//! A generated dataset is a dataset. +template<typename Generator> +struct is_dataset<generated_by<Generator> > : mpl::true_ {}; + + +} // namespace monomorphic +} // namespace data +} // namespace unit_test +} // namespace boost + +#include <boost/test/detail/enable_warnings.hpp> + +#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATE_HPP_112011GER + diff --git a/boost/test/data/monomorphic/generators.hpp b/boost/test/data/monomorphic/generators.hpp new file mode 100644 index 0000000000..aa74d7abb1 --- /dev/null +++ b/boost/test/data/monomorphic/generators.hpp @@ -0,0 +1,20 @@ +// (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 specific generators +// *************************************************************************** + +#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER +#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER + +// Boost.Test +#include <boost/test/data/monomorphic/generators/xrange.hpp> +#include <boost/test/data/monomorphic/generators/random.hpp> + +#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER + diff --git a/boost/test/data/monomorphic/generators/keywords.hpp b/boost/test/data/monomorphic/generators/keywords.hpp new file mode 100644 index 0000000000..4983678f95 --- /dev/null +++ b/boost/test/data/monomorphic/generators/keywords.hpp @@ -0,0 +1,39 @@ +// (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 +/// Keywords used in generator interfaces +// *************************************************************************** + +#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_KEYWORDS_HPP_101512GER +#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_KEYWORDS_HPP_101512GER + +// Boost.Test +#include <boost/test/data/config.hpp> +#include <boost/test/utils/named_params.hpp> + +#include <boost/test/detail/suppress_warnings.hpp> + +//____________________________________________________________________________// + +namespace boost { +namespace unit_test { +namespace data { + +namespace { +nfp::keyword<struct begin_t> begin; +nfp::keyword<struct end_t> end; +nfp::keyword<struct step_t> step; +} // local namespace + +} // namespace data +} // namespace unit_test +} // namespace boost + +#include <boost/test/detail/enable_warnings.hpp> + +#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_KEYWORDS_HPP_101512GER diff --git a/boost/test/data/monomorphic/generators/random.hpp b/boost/test/data/monomorphic/generators/random.hpp new file mode 100644 index 0000000000..a82eef103d --- /dev/null +++ b/boost/test/data/monomorphic/generators/random.hpp @@ -0,0 +1,198 @@ +// (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 +//!@brief Random generator +// *************************************************************************** + +#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER +#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER + +// Boost.Test +#include <boost/test/data/config.hpp> + + + + +#if !defined(BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE) || defined(BOOST_TEST_DOXYGEN_DOC__) + +#include <boost/test/data/monomorphic/generate.hpp> +#include <boost/test/data/monomorphic/generators/keywords.hpp> + +// STL +#include <random> + +#include <boost/test/detail/suppress_warnings.hpp> + +//____________________________________________________________________________// + +namespace boost { +namespace unit_test { +namespace data { + +namespace { +nfp::keyword<struct seed_t> seed; +nfp::keyword<struct distrbution_t> distribution; +nfp::keyword<struct engine_t> engine; +} // local namespace + +namespace monomorphic { + +namespace ds_detail { +template<typename SampleType> +struct default_distribution { + typedef typename mpl::if_<std::is_integral<SampleType>, + std::uniform_int_distribution<SampleType>, + std::uniform_real_distribution<SampleType> >::type type; +}; + +} // namespace ds_detail + +// ************************************************************************** // +// ************** random_t ************** // +// ************************************************************************** // + +/*!@brief Generator for the random sequences + * + * This class implements the generator concept (see @ref boost::unit_test::data::monomorphic::generated_by) for implementing + * a random number generator. + */ +template<typename SampleType = double, + typename DistributionType = typename ds_detail::default_distribution<SampleType>::type, + typename EngineType = std::default_random_engine> +class random_t { +public: + typedef SampleType data_type; + typedef DistributionType distr_type; + typedef EngineType engine_type; + + random_t() + : m_distribution() + , m_engine( std::random_device()() ) + {} + explicit random_t( distr_type&& d ) + : m_distribution( std::forward<distr_type>(d) ) + , m_engine( std::random_device()() ){} + random_t( engine_type&& e, distr_type&& d ) + : m_distribution( std::forward<distr_type>(d) ) + , m_engine( std::forward<engine_type>(e) ){} + + // Generator interface + data::size_t capacity() const { return BOOST_TEST_DS_INFINITE_SIZE; } + SampleType next() + { + return m_distribution( m_engine ); + } + void reset() {} + + //! Sets the seed of the pseudo-random number engine. + template<typename SeedType> + void seed( SeedType&& seed ) { m_engine.seed( std::forward<SeedType>( seed ) ); } + +private: + // Data members + DistributionType m_distribution; + EngineType m_engine; +}; + +//____________________________________________________________________________// + +} // namespace monomorphic + + +//! @brief Returns an infinite sequence of random numbers. +//! +//! The following overloads are available: +//! @code +//! auto d = random(); +//! auto d = random(begin, end); +//! auto d = random(params); +//! @endcode +//! +//! +//! - The first overload uses the default distribution, which is uniform and which elements +//! are @c double type (the values are in [0, 1) ). +//! - The second overload generates numbers in the given interval. The distribution is uniform (in [begin, end) +//! for real numbers, and in [begin, end] for integers). The type of the distribution is deduced from the type +//! of the @c begin and @c end parameters. +//! - The third overload generates numbers using the named parameter inside @c params , which are: +//! - @c distribution: the distribution used. In this overload, since the type of the samples cannot be deduced, +//! the samples are of type @c double and the distribution is uniform real in [0, 1). +//! - @c seed: the seed for generating the values +//! - @c engine: the random number generator engine +//! +//! The function returns an object that implements the dataset API. +//! @note This function is available only for C++11 capable compilers. +inline monomorphic::generated_by< monomorphic::random_t<> > random() +{ + return monomorphic::generated_by<monomorphic::random_t<>>( monomorphic::random_t<>() ); +} + +//____________________________________________________________________________// + +/// @overload boost::unit_test::data::random() +template<typename SampleType> +inline monomorphic::generated_by< monomorphic::random_t<SampleType> > +random( SampleType begin, SampleType end ) +{ + typedef monomorphic::random_t<SampleType> Gen; + typedef typename Gen::distr_type distr_type; + return monomorphic::generated_by<Gen>( Gen( distr_type(begin,end) ) ); +} + +//____________________________________________________________________________// + +namespace ds_detail { +template<typename Params> +struct random_gen_type { + typedef typename nfp::param_type<Params,decltype(distribution),std::uniform_real_distribution<>>::type distr_type; + typedef typename nfp::param_type<Params,decltype(engine),std::default_random_engine>::type engine_type; + typedef typename distr_type::result_type sample_type; + + typedef monomorphic::random_t<sample_type,distr_type,engine_type> type; +}; + +} + + +/// @overload boost::unit_test::data::random() +template<typename Params> +inline monomorphic::generated_by<typename ds_detail::random_gen_type<Params>::type> +random( Params const& params ) +{ + typedef typename ds_detail::random_gen_type<Params>::type Gen; + typedef typename Gen::distr_type distr_type; + typedef typename Gen::engine_type engine_type; + + std::random_device rd; + engine_type E; +// engine_type E( rd ); + if( params.has(engine) ) + E = params[engine]; + + distr_type D; + if( params.has(distribution) ) + D = params[distribution]; + + Gen G( std::move(E), std::move(D) ); + + if( params.has(seed) ) + G.seed( params[seed] ); + + return monomorphic::generated_by<Gen>( std::move(G) ); +} + +} // namespace data +} // namespace unit_test +} // namespace boost + +#include <boost/test/detail/enable_warnings.hpp> + +#endif // BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE + + +#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER 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 diff --git a/boost/test/data/monomorphic/grid.hpp b/boost/test/data/monomorphic/grid.hpp new file mode 100644 index 0000000000..00aaa56cd1 --- /dev/null +++ b/boost/test/data/monomorphic/grid.hpp @@ -0,0 +1,226 @@ +// (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 monomorphic dataset n+m dimentional *. Samples in this +/// dataset is grid of elements in DS1 and DS2. There will be total +/// |DS1| * |DS2| samples +// *************************************************************************** + +#ifndef BOOST_TEST_DATA_MONOMORPHIC_GRID_HPP_101512GER +#define BOOST_TEST_DATA_MONOMORPHIC_GRID_HPP_101512GER + +// Boost.Test +#include <boost/test/data/config.hpp> + + +#if !defined(BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE) || defined(BOOST_TEST_DOXYGEN_DOC__) + +#include <boost/test/data/monomorphic/dataset.hpp> +#include <boost/test/detail/suppress_warnings.hpp> + +//____________________________________________________________________________// + +namespace boost { +namespace unit_test { +namespace data { +namespace monomorphic { + +namespace ds_detail { + +// !! ?? variadic template implementation; use forward_as_tuple? +template<typename T1, typename T2> +struct grid_traits { + typedef std::tuple<T1,T2> type; + typedef typename monomorphic::traits<type>::ref_type ref_type; + + static ref_type + tuple_merge(T1 const& a1, T2 const& a2) + { + return ref_type(a1,a2); + } +}; + +//____________________________________________________________________________// + +template<typename T1, typename T2,typename T3> +struct grid_traits<T1,std::tuple<T2,T3>> { + typedef std::tuple<T1,T2,T3> type; + typedef typename monomorphic::traits<type>::ref_type ref_type; + + static ref_type + tuple_merge(T1 const& a1, std::tuple<T2 const&,T3 const&> const& a2) + { + return ref_type(a1,get<0>(a2),get<1>(a2)); + } +}; + +//____________________________________________________________________________// + +template<typename T1, typename T2,typename T3> +struct grid_traits<std::tuple<T1,T2>,T3> { + typedef std::tuple<T1,T2,T3> type; + typedef typename monomorphic::traits<type>::ref_type ref_type; + + static ref_type + tuple_merge(std::tuple<T1 const&,T2 const&> const& a1, T3 const& a2) + { + return ref_type(get<0>(a1),get<1>(a1),a2); + } +}; + +//____________________________________________________________________________// + +} // namespace ds_detail + +// ************************************************************************** // +// ************** grid ************** // +// ************************************************************************** // + + +//! Implements the dataset resulting from a cartesian product/grid operation on datasets. +//! +//! The arity of the resulting dataset is the sum of the arity of its operands. +template<typename DS1, typename DS2> +class grid : public monomorphic::dataset<typename ds_detail::grid_traits<typename boost::decay<DS1>::type::data_type, + typename boost::decay<DS2>::type::data_type>::type> { + typedef typename boost::decay<DS1>::type::data_type T1; + typedef typename boost::decay<DS2>::type::data_type T2; + + typedef typename monomorphic::dataset<T1>::iter_ptr ds1_iter_ptr; + typedef typename monomorphic::dataset<T2>::iter_ptr ds2_iter_ptr; + + typedef typename ds_detail::grid_traits<T1,T2>::type T; + typedef monomorphic::dataset<T> base; + typedef typename base::iter_ptr iter_ptr; + + struct iterator : public base::iterator { + typedef typename monomorphic::traits<T>::ref_type ref_type; + + // Constructor + explicit iterator( ds1_iter_ptr iter1, DS2 const& ds2 ) + : m_iter1( iter1 ) + , m_iter2( ds2.begin() ) + , m_ds2( ds2 ) + , m_ds2_pos( 0 ) + {} + + // forward iterator interface + virtual ref_type operator*() { return ds_detail::grid_traits<T1,T2>::tuple_merge( **m_iter1, **m_iter2 ); } + virtual void operator++() + { + ++m_ds2_pos; + if( m_ds2_pos != m_ds2.size() ) + ++(*m_iter2); + else { + m_ds2_pos = 0; + ++(*m_iter1); + m_iter2 = m_ds2.begin(); + } + } + + private: + // Data members + ds1_iter_ptr m_iter1; + ds2_iter_ptr m_iter2; + DS2 const& m_ds2; + data::size_t m_ds2_pos; + }; + +public: + enum { arity = boost::decay<DS1>::type::arity + boost::decay<DS2>::type::arity }; + + //! Constructor + grid( DS1&& ds1, DS2&& ds2 ) + : m_ds1( std::forward<DS1>( ds1 ) ) + , m_ds2( std::forward<DS2>( ds2 ) ) + {} + + //! Move constructor + grid( grid&& j ) + : m_ds1( std::forward<DS1>( j.m_ds1 ) ) + , m_ds2( std::forward<DS2>( j.m_ds2 ) ) + {} + + // dataset interface + virtual data::size_t size() const { return m_ds1.size() * m_ds2.size(); } + virtual iter_ptr begin() const { return boost::make_shared<iterator>( m_ds1.begin(), m_ds2 ); } + +private: + // Data members + DS1 m_ds1; + DS2 m_ds2; +}; + +//____________________________________________________________________________// + +// A grid dataset is a dataset +template<typename DS1, typename DS2> +struct is_dataset<grid<DS1,DS2> > : mpl::true_ {}; + +//____________________________________________________________________________// + +namespace result_of { + +/// Result type of the grid operation on dataset. +template<typename DS1Gen, typename DS2Gen> +struct grid { + typedef monomorphic::grid<typename DS1Gen::type,typename DS2Gen::type> type; +}; + +} // namespace result_of + +//____________________________________________________________________________// + + + +//! Grid operation +template<typename DS1, typename DS2> +inline typename boost::lazy_enable_if_c<is_dataset<DS1>::value && is_dataset<DS2>::value, + result_of::grid<mpl::identity<DS1>,mpl::identity<DS2>> +>::type +operator*( DS1&& ds1, DS2&& ds2 ) +{ + BOOST_TEST_DS_ASSERT( !ds1.size().is_inf() && !ds2.size().is_inf(), "Grid dimension can't have infinite size" ); + + return grid<DS1,DS2>( std::forward<DS1>( ds1 ), std::forward<DS2>( ds2 ) ); +} + +//! @overload boost::unit_test::data::operator* +template<typename DS1, typename DS2> +inline typename boost::lazy_enable_if_c<is_dataset<DS1>::value && !is_dataset<DS2>::value, + result_of::grid<mpl::identity<DS1>,data::result_of::make<DS2>> +>::type +operator*( DS1&& ds1, DS2&& ds2 ) +{ + return std::forward<DS1>(ds1) * data::make(std::forward<DS2>(ds2)); +} + +//! @overload boost::unit_test::data::operator* +template<typename DS1, typename DS2> +inline typename boost::lazy_enable_if_c<!is_dataset<DS1>::value && is_dataset<DS2>::value, + result_of::grid<data::result_of::make<DS1>,mpl::identity<DS2>> +>::type +operator*( DS1&& ds1, DS2&& ds2 ) +{ + return data::make(std::forward<DS1>(ds1)) * std::forward<DS2>(ds2); +} + +//____________________________________________________________________________// + +} // namespace monomorphic + +} // namespace data +} // namespace unit_test +} // namespace boost + +#include <boost/test/detail/enable_warnings.hpp> + +#endif // BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE + +#endif // BOOST_TEST_DATA_MONOMORPHIC_GRID_HPP_101512GER + diff --git a/boost/test/data/monomorphic/join.hpp b/boost/test/data/monomorphic/join.hpp new file mode 100644 index 0000000000..94b25c78e2 --- /dev/null +++ b/boost/test/data/monomorphic/join.hpp @@ -0,0 +1,194 @@ +// (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 dataset join operation +// *************************************************************************** + +#ifndef BOOST_TEST_DATA_MONOMORPHIC_JOIN_HPP_112711GER +#define BOOST_TEST_DATA_MONOMORPHIC_JOIN_HPP_112711GER + +// Boost.Test +#include <boost/test/data/config.hpp> +#include <boost/test/data/monomorphic/dataset.hpp> + +#include <boost/test/detail/suppress_warnings.hpp> + +//____________________________________________________________________________// + +namespace boost { +namespace unit_test { +namespace data { +namespace monomorphic { + +// ************************************************************************** // +// ************** join ************** // +// ************************************************************************** // + +//! Defines a new dataset from the concatenation of two datasets +//! +//! The size of the resulting dataset is the sum of the two underlying datasets. The arity of the datasets +//! should match. +template<typename DS1, typename DS2> +class join : public monomorphic::dataset<typename boost::decay<DS1>::type::data_type> { + typedef typename boost::decay<DS1>::type::data_type T; + typedef monomorphic::dataset<T> base; + typedef typename base::iter_ptr iter_ptr; + + struct iterator : public base::iterator { + // Constructor + explicit iterator( iter_ptr it1, iter_ptr it2, data::size_t first_size ) +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + : m_it1( std::move(it1) ) + , m_it2( std::move(it2) ) +#else + : m_it1( it1 ) + , m_it2( it2 ) +#endif + , m_first_size( first_size ) + {} + + // forward iterator interface + virtual T const& operator*() { return m_first_size > 0 ? **m_it1 : **m_it2; } + virtual void operator++() { m_first_size > 0 ? (--m_first_size,++(*m_it1)) : ++(*m_it2); } + + private: + // Data members + iter_ptr m_it1; + iter_ptr m_it2; + data::size_t m_first_size; + }; + +public: + enum { arity = boost::decay<DS1>::type::arity }; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + // Constructor + join( DS1&& ds1, DS2&& ds2 ) + : m_ds1( std::forward<DS1>( ds1 ) ) + , m_ds2( std::forward<DS2>( ds2 ) ) + {} + + // Move constructor + join( join&& j ) + : m_ds1( std::forward<DS1>( j.m_ds1 ) ) + , m_ds2( std::forward<DS2>( j.m_ds2 ) ) + {} +#else + // Constructor + join( DS1 const& ds1, DS2 const& ds2 ) + : m_ds1( ds1 ) + , m_ds2( ds2 ) + {} +#endif + + // dataset interface + virtual data::size_t size() const { return m_ds1.size() + m_ds2.size(); } + virtual iter_ptr begin() const { return boost::make_shared<iterator>( m_ds1.begin(), + m_ds2.begin(), + m_ds1.size() ); } + +private: + // Data members + DS1 m_ds1; + DS2 m_ds2; +}; + +//____________________________________________________________________________// + +// A joined dataset is a dataset. +template<typename DS1, typename DS2> +struct is_dataset<join<DS1,DS2> > : mpl::true_ {}; + +//____________________________________________________________________________// + +namespace result_of { + +//! Result type of the join operation on datasets. +template<typename DS1Gen, typename DS2Gen> +struct join { + typedef monomorphic::join<typename DS1Gen::type,typename DS2Gen::type> type; +}; + +} // namespace result_of + +//____________________________________________________________________________// + +template<typename DS1, typename DS2> +inline typename boost::lazy_enable_if_c<is_dataset<DS1>::value && is_dataset<DS2>::value, + result_of::join<mpl::identity<DS1>,mpl::identity<DS2> > +>::type +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +operator+( DS1&& ds1, DS2&& ds2 ) +{ + return join<DS1,DS2>( std::forward<DS1>( ds1 ), std::forward<DS2>( ds2 ) ); +} +#else +operator+( DS1 const& ds1, DS2 const& ds2 ) +{ + return join<DS1,DS2>( ds1, ds2 ); +} +#endif + +//____________________________________________________________________________// + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template<typename DS1, typename DS2> +inline typename boost::lazy_enable_if_c<is_dataset<DS1>::value && !is_dataset<DS2>::value, + result_of::join<mpl::identity<DS1>,data::result_of::make<DS2> > +>::type +operator+( DS1&& ds1, DS2&& ds2 ) +{ + return std::forward<DS1>(ds1) + data::make(std::forward<DS2>(ds2)); +} +#else +template<typename DS1, typename DS2> +inline typename boost::lazy_enable_if_c<is_dataset<DS1>::value && !is_dataset<DS2>::value, + result_of::join<mpl::identity<DS1>,data::result_of::make<DS2> > +>::type +operator+( DS1 const& ds1, DS2 const& ds2 ) +{ + return ds1 + data::make(ds2); +} +#endif + +//____________________________________________________________________________// + + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +template<typename DS1, typename DS2> +inline typename boost::lazy_enable_if_c<!is_dataset<DS1>::value && is_dataset<DS2>::value, + result_of::join<data::result_of::make<DS1>,mpl::identity<DS2> > +>::type +operator+( DS1&& ds1, DS2&& ds2 ) +{ + return data::make(std::forward<DS1>(ds1)) + std::forward<DS2>(ds2); +} +#else +template<typename DS1, typename DS2> +inline typename boost::lazy_enable_if_c<!is_dataset<DS1>::value && is_dataset<DS2>::value, + result_of::join<data::result_of::make<DS1>,mpl::identity<DS2> > +>::type +operator+( DS1 const& ds1, DS2 const& ds2 ) +{ + return data::make(ds1) + ds2; +} + +#endif + + +} // namespace monomorphic + +} // namespace data +} // namespace unit_test +} // namespace boost + +#include <boost/test/detail/enable_warnings.hpp> + +#endif // BOOST_TEST_DATA_MONOMORPHIC_JOIN_HPP_112711GER + diff --git a/boost/test/data/monomorphic/singleton.hpp b/boost/test/data/monomorphic/singleton.hpp new file mode 100644 index 0000000000..4d305c2546 --- /dev/null +++ b/boost/test/data/monomorphic/singleton.hpp @@ -0,0 +1,137 @@ +// (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 single element monomorphic dataset +// *************************************************************************** + +#ifndef BOOST_TEST_DATA_MONOMORPHIC_SINGLETON_HPP_102211GER +#define BOOST_TEST_DATA_MONOMORPHIC_SINGLETON_HPP_102211GER + +// Boost.Test +#include <boost/test/data/config.hpp> +#include <boost/test/data/monomorphic/dataset.hpp> + +#include <boost/test/detail/suppress_warnings.hpp> + +//____________________________________________________________________________// + +namespace boost { +namespace unit_test { +namespace data { +namespace monomorphic { + +// ************************************************************************** // +// ************** singleton ************** // +// ************************************************************************** // + +/// Models a single element data set +template<typename T> +class singleton : public monomorphic::dataset<typename boost::decay<T>::type> { + typedef monomorphic::dataset<typename boost::decay<T>::type> base; + typedef typename base::iter_ptr iter_ptr; + + struct iterator : public base::iterator { + // Constructor + explicit iterator( singleton<T> const& owner ) + : m_owner( owner ) + {} + + // forward iterator interface + virtual typename base::data_type const& + operator*() { return m_owner.value(); } + virtual void operator++() {} + + private: + singleton<T> const& m_owner; + }; + +public: + enum { arity = 1 }; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + //! Constructor + explicit singleton( T&& value ) : m_value( std::forward<T>( value ) ) {} + + //! Move constructor + singleton( singleton&& s ) : m_value( std::forward<T>( s.m_value ) ) {} +#else + // Constructor + explicit singleton( T const& value ) : m_value( value ) {} +#endif + + // Access methods + T const& value() const { return m_value; } + + // dataset interface + virtual data::size_t size() const { return 1; } + virtual iter_ptr begin() const { return boost::make_shared<iterator>( *this ); } + +private: + // Data members + T m_value; +}; + +// a singleton is a dataset +template<typename T> +struct is_dataset<singleton<T> > : mpl::true_ {}; + +} // namespace monomorphic + + + +/// @overload boost::unit_test::data::make() +template<typename T> +inline typename BOOST_TEST_ENABLE_IF<!is_forward_iterable<T>::value && + !monomorphic::is_dataset<T>::value && + !boost::is_array< typename boost::remove_reference<T>::type >::value, + monomorphic::singleton<T> +>::type +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +make( T&& v ) +{ + return monomorphic::singleton<T>( std::forward<T>( v ) ); +} +#else +make( T const& v ) +{ + return monomorphic::singleton<T>( v ); +} +#endif + + +/// @overload boost::unit_test::data::make +inline monomorphic::singleton<char*> make( char* str ) +{ +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + return monomorphic::singleton<char*>( std::move(str) ); +#else + return monomorphic::singleton<char*>( str ); +#endif +} + + +/// @overload boost::unit_test::data::make +inline monomorphic::singleton<char const*> make( char const* str ) +{ +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + return monomorphic::singleton<char const*>( std::move(str) ); +#else + return monomorphic::singleton<char const*>( str ); +#endif +} + + + +} // namespace data +} // namespace unit_test +} // namespace boost + +#include <boost/test/detail/enable_warnings.hpp> + +#endif // BOOST_TEST_DATA_MONOMORPHIC_SINGLETON_HPP_102211GER + diff --git a/boost/test/data/monomorphic/zip.hpp b/boost/test/data/monomorphic/zip.hpp new file mode 100644 index 0000000000..3ee91817a9 --- /dev/null +++ b/boost/test/data/monomorphic/zip.hpp @@ -0,0 +1,240 @@ +// (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 monomorphic dataset based on zipping of 2 other monomorphic datasets +// *************************************************************************** + +#ifndef BOOST_TEST_DATA_MONOMORPHIC_ZIP_HPP_102211GER +#define BOOST_TEST_DATA_MONOMORPHIC_ZIP_HPP_102211GER + +#include <boost/test/data/config.hpp> + +#if !defined(BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE) || defined(BOOST_TEST_DOXYGEN_DOC__) + +// Boost.Test +#include <boost/test/data/monomorphic/dataset.hpp> +#include <boost/test/detail/suppress_warnings.hpp> + + +namespace boost { +namespace unit_test { +namespace data { +namespace monomorphic { + +namespace ds_detail { + + +//____________________________________________________________________________// + +// !! ?? variadic template implementation; use forward_as_tuple? +template<typename T1, typename T2> +struct zip_traits { + typedef std::tuple<T1,T2> type; + typedef typename monomorphic::traits<type>::ref_type ref_type; + + static ref_type + tuple_merge(T1 const& a1, T2 const& a2) + { + return ref_type(a1,a2); + } +}; + +//____________________________________________________________________________// + +template<typename T1, typename T2,typename T3> +struct zip_traits<T1,std::tuple<T2,T3>> { + typedef std::tuple<T1,T2,T3> type; + typedef typename monomorphic::traits<type>::ref_type ref_type; + + static ref_type + tuple_merge(T1 const& a1, std::tuple<T2 const&,T3 const&> const& a2) + { + return ref_type(a1,std::get<0>(a2),std::get<1>(a2)); + } +}; + +//____________________________________________________________________________// + +template<typename T1, typename T2,typename T3> +struct zip_traits<std::tuple<T1,T2>,T3> { + typedef std::tuple<T1,T2,T3> type; + typedef typename monomorphic::traits<type>::ref_type ref_type; + + static ref_type + tuple_merge(std::tuple<T1 const&,T2 const&> const& a1, T3 const& a2) + { + return ref_type(std::get<0>(a1),std::get<1>(a1),a2); + } +}; + +//____________________________________________________________________________// + +} // namespace ds_detail + +// ************************************************************************** // +// ************** zip ************** // +// ************************************************************************** // + +//! Zip datasets +//! +//! A zip of two datasets is a dataset whose arity is the sum of the operand datasets arity. The size is given by +//! the function creating the instance (see @c operator^ on datasets). +template<typename DS1, typename DS2> +class zip : public monomorphic::dataset<typename ds_detail::zip_traits<typename boost::decay<DS1>::type::data_type, + typename boost::decay<DS2>::type::data_type>::type> { + typedef typename boost::decay<DS1>::type::data_type T1; + typedef typename boost::decay<DS2>::type::data_type T2; + + typedef typename monomorphic::dataset<T1>::iter_ptr ds1_iter_ptr; + typedef typename monomorphic::dataset<T2>::iter_ptr ds2_iter_ptr; + + typedef typename ds_detail::zip_traits<T1,T2>::type T; + typedef monomorphic::dataset<T> base; + typedef typename base::iter_ptr iter_ptr; + + struct iterator : public base::iterator { + typedef typename monomorphic::traits<T>::ref_type ref_type; + + // Constructor + explicit iterator( ds1_iter_ptr iter1, ds2_iter_ptr iter2 ) + : m_iter1( iter1 ) + , m_iter2( iter2 ) + {} + + // forward iterator interface + virtual ref_type operator*() { return ds_detail::zip_traits<T1,T2>::tuple_merge( **m_iter1, **m_iter2 ); } + virtual void operator++() { ++(*m_iter1); ++(*m_iter2); } + + private: + // Data members + ds1_iter_ptr m_iter1; + ds2_iter_ptr m_iter2; + }; + +public: + enum { arity = boost::decay<DS1>::type::arity + boost::decay<DS2>::type::arity }; + + //! Constructor + //! + //! The datasets are moved and not copied. + zip( DS1&& ds1, DS2&& ds2, data::size_t size ) + : m_ds1( std::forward<DS1>( ds1 ) ) + , m_ds2( std::forward<DS2>( ds2 ) ) + , m_size( size ) + {} + + //! Move constructor + zip( zip&& j ) + : m_ds1( std::forward<DS1>( j.m_ds1 ) ) + , m_ds2( std::forward<DS2>( j.m_ds2 ) ) + , m_size( j.m_size ) + {} + + // dataset interface + virtual data::size_t size() const { return m_size; } + virtual iter_ptr begin() const { return boost::make_shared<iterator>( m_ds1.begin(), m_ds2.begin() ); } + +private: + // Data members + DS1 m_ds1; + DS2 m_ds2; + data::size_t m_size; +}; + +//____________________________________________________________________________// + +//! Zipped datasets results in a dataset. +template<typename DS1, typename DS2> +struct is_dataset<zip<DS1,DS2> > : mpl::true_ {}; + +//____________________________________________________________________________// + +namespace ds_detail { + +//! Handles the sise of the resulting zipped dataset. +template<typename DS1, typename DS2> +inline data::size_t +zip_size( DS1&& ds1, DS2&& ds2 ) +{ + data::size_t ds1_size = ds1.size(); + data::size_t ds2_size = ds2.size(); + + if( ds1_size == ds2_size ) + return ds1_size; + + if( ds1_size == 1 || ds1_size.is_inf() ) + return ds2_size; + + if( ds2_size == 1 || ds2_size.is_inf() ) + return ds1_size; + + BOOST_TEST_DS_ERROR( "Can't zip datasets of different sizes" ); +} + +} // namespace ds_detail + +//____________________________________________________________________________// + +namespace result_of { + +//! Result type of the zip operator. +template<typename DS1Gen, typename DS2Gen> +struct zip { + typedef monomorphic::zip<typename DS1Gen::type,typename DS2Gen::type> type; +}; + +} // namespace result_of + + +//____________________________________________________________________________// + + +//! Overload operator for zip support +template<typename DS1, typename DS2> +inline typename boost::lazy_enable_if_c<is_dataset<DS1>::value && is_dataset<DS2>::value, + result_of::zip<mpl::identity<DS1>,mpl::identity<DS2>> +>::type +operator^( DS1&& ds1, DS2&& ds2 ) +{ + return zip<DS1,DS2>( std::forward<DS1>( ds1 ), std::forward<DS2>( ds2 ), ds_detail::zip_size( ds1, ds2 ) ); +} + +//! @overload boost::unit_test::data::monomorphic::operator^() +template<typename DS1, typename DS2> +inline typename boost::lazy_enable_if_c<is_dataset<DS1>::value && !is_dataset<DS2>::value, + result_of::zip<mpl::identity<DS1>,data::result_of::make<DS2>> +>::type +operator^( DS1&& ds1, DS2&& ds2 ) +{ + return std::forward<DS1>(ds1) ^ data::make(std::forward<DS2>(ds2)); +} + +//! @overload boost::unit_test::data::monomorphic::operator^() +template<typename DS1, typename DS2> +inline typename boost::lazy_enable_if_c<!is_dataset<DS1>::value && is_dataset<DS2>::value, + result_of::zip<data::result_of::make<DS1>,mpl::identity<DS2>> +>::type +operator^( DS1&& ds1, DS2&& ds2 ) +{ + return data::make(std::forward<DS1>(ds1)) ^ std::forward<DS2>(ds2); +} + +//____________________________________________________________________________// + +} // namespace monomorphic + +} // namespace data +} // namespace unit_test +} // namespace boost + +#include <boost/test/detail/enable_warnings.hpp> + +#endif // BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE + +#endif // BOOST_TEST_DATA_MONOMORPHIC_ZIP_HPP_102211GER + |