summaryrefslogtreecommitdiff
path: root/boost/test/data/monomorphic
diff options
context:
space:
mode:
Diffstat (limited to 'boost/test/data/monomorphic')
-rw-r--r--boost/test/data/monomorphic/array.hpp113
-rw-r--r--boost/test/data/monomorphic/collection.hpp125
-rw-r--r--boost/test/data/monomorphic/dataset.hpp174
-rw-r--r--boost/test/data/monomorphic/fwd.hpp314
-rw-r--r--boost/test/data/monomorphic/generate.hpp116
-rw-r--r--boost/test/data/monomorphic/generators.hpp20
-rw-r--r--boost/test/data/monomorphic/generators/keywords.hpp39
-rw-r--r--boost/test/data/monomorphic/generators/random.hpp198
-rw-r--r--boost/test/data/monomorphic/generators/xrange.hpp221
-rw-r--r--boost/test/data/monomorphic/grid.hpp226
-rw-r--r--boost/test/data/monomorphic/join.hpp194
-rw-r--r--boost/test/data/monomorphic/singleton.hpp137
-rw-r--r--boost/test/data/monomorphic/zip.hpp240
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
+