$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r81009 - in trunk/boost/test/data: . monomorphic monomorphic/generators
From: gennadiy.rozental_at_[hidden]
Date: 2012-10-18 03:43:46
Author: rogeeff
Date: 2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
New Revision: 81009
URL: http://svn.boost.org/trac/boost/changeset/81009
Log:
new "data driven test case" subsystem
Added:
   trunk/boost/test/data/
   trunk/boost/test/data/config.hpp   (contents, props changed)
   trunk/boost/test/data/dataset.hpp   (contents, props changed)
   trunk/boost/test/data/generators.hpp   (contents, props changed)
   trunk/boost/test/data/monomorphic/
   trunk/boost/test/data/monomorphic.hpp   (contents, props changed)
   trunk/boost/test/data/monomorphic/array.hpp   (contents, props changed)
   trunk/boost/test/data/monomorphic/collection.hpp   (contents, props changed)
   trunk/boost/test/data/monomorphic/dataset.hpp   (contents, props changed)
   trunk/boost/test/data/monomorphic/generate.hpp   (contents, props changed)
   trunk/boost/test/data/monomorphic/generators/
   trunk/boost/test/data/monomorphic/generators.hpp   (contents, props changed)
   trunk/boost/test/data/monomorphic/generators/keywords.hpp   (contents, props changed)
   trunk/boost/test/data/monomorphic/generators/random.hpp   (contents, props changed)
   trunk/boost/test/data/monomorphic/generators/xrange.hpp   (contents, props changed)
   trunk/boost/test/data/monomorphic/grid.hpp   (contents, props changed)
   trunk/boost/test/data/monomorphic/join.hpp   (contents, props changed)
   trunk/boost/test/data/monomorphic/singleton.hpp   (contents, props changed)
   trunk/boost/test/data/monomorphic/zip.hpp   (contents, props changed)
   trunk/boost/test/data/size.hpp   (contents, props changed)
   trunk/boost/test/data/test_case.hpp   (contents, props changed)
Added: trunk/boost/test/data/config.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/config.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,27 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : defines common dataset macros
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_CONFIG_HPP_112611GER
+#define BOOST_TEST_DATA_CONFIG_HPP_112611GER
+
+// Boost.Test
+#include <boost/test/detail/config.hpp>
+
+//____________________________________________________________________________//
+
+#define BOOST_TEST_DS_ERROR( msg ) throw std::logic_error( msg )
+#define BOOST_TEST_DS_ASSERT( cond, msg ) if( cond ) {} else BOOST_TEST_DS_ERROR( msg )
+
+#endif // BOOST_TEST_DATA_CONFIG_HPP_112611GER
+
Added: trunk/boost/test/data/dataset.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/dataset.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,22 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : defines dataset interfaces
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_DATASET_HPP_102211GER
+#define BOOST_TEST_DATA_DATASET_HPP_102211GER
+
+// Boost.Test
+#include <boost/test/data/monomorphic.hpp>
+
+#endif // BOOST_TEST_DATA_DATASET_HPP_102211GER
+
Added: trunk/boost/test/data/generators.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/generators.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,22 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : 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>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
+
Added: trunk/boost/test/data/monomorphic.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/monomorphic.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,29 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : defines monomorphic dataset interfaces
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_HPP_102211GER
+#define BOOST_TEST_DATA_MONOMORPHIC_HPP_102211GER
+
+// Boost.Test
+#include <boost/test/data/monomorphic/array.hpp>
+#include <boost/test/data/monomorphic/collection.hpp>
+#include <boost/test/data/monomorphic/generate.hpp>
+#include <boost/test/data/monomorphic/generators.hpp>
+#include <boost/test/data/monomorphic/grid.hpp>
+#include <boost/test/data/monomorphic/join.hpp>
+#include <boost/test/data/monomorphic/singleton.hpp>
+#include <boost/test/data/monomorphic/zip.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_HPP_102211GER
+
Added: trunk/boost/test/data/monomorphic/array.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/monomorphic/array.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,99 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : defines monomorphic dataset based on stl sequence
+// ***************************************************************************
+
+#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/size.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                    ************** //
+// ************************************************************************** //
+
+template<typename T>
+class array : public monomorphic::dataset<T> {
+    typedef monomorphic::dataset<T> base;
+
+    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
+        typename 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 std::make_shared<iterator>( m_arr, m_size ); }
+
+private:
+    // Data members
+    T const*        m_arr;
+    std::size_t     m_size;
+};
+
+//____________________________________________________________________________//
+
+template<typename T>
+struct is_dataset<array<T>> : std::true_type {};
+
+} // namespace monomorphic
+
+template<typename T, std::size_t size>
+inline monomorphic::array<T>
+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
+
Added: trunk/boost/test/data/monomorphic/collection.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/monomorphic/collection.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,102 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : defines monomorphic dataset based on stl 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                  ************** //
+// ************************************************************************** //
+
+template<typename C>
+class collection : public monomorphic::dataset<typename std::decay<C>::type::value_type> {
+    typedef typename std::decay<C>::type col_type;
+    typedef typename col_type::value_type T;
+    typedef monomorphic::dataset<T> base;
+
+    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 };
+
+    // Constructor
+    explicit        collection( C&& col ) : m_col( std::forward<C>(col) ) {}
+
+    // Move constructor
+    collection( collection&& c ) : m_col( std::forward<C>( c.m_col ) ) {}
+
+    // Access methods
+    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 std::make_shared<iterator>( *this ); }
+
+private:
+    // Data members
+    C               m_col;
+};
+
+//____________________________________________________________________________//
+
+template<typename C>
+struct is_dataset<collection<C>> : std::true_type {};
+
+} // namespace monomorphic
+
+template<typename C>
+inline monomorphic::collection<typename std::enable_if<ds_detail::is_std_collection<C>::value,C>::type>
+make( C&& c )
+{
+    return monomorphic::collection<C>( std::forward<C>(c) );
+}
+
+//____________________________________________________________________________//
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_COLLECTION_HPP_102211GER
+
Added: trunk/boost/test/data/monomorphic/dataset.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/monomorphic/dataset.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,214 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : 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/size.hpp>
+
+// STL
+#include <vector>
+#include <list>
+#include <tuple>
+
+#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 );
+    }
+};
+
+//____________________________________________________________________________//
+
+// !! ?? 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( get<0>(arg), 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( get<0>(arg), get<1>(arg), get<2>(arg) );
+    }
+};
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// **************             monomorphic::dataset             ************** //
+// ************************************************************************** //
+
+template<typename T>
+class dataset {
+public:
+    // type of the data in this dataset
+    typedef T data_type;
+
+    // type of 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;
+    };
+
+    typedef std::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;
+};
+
+// ************************************************************************** //
+// **************            monomorphic::is_dataset           ************** //
+// ************************************************************************** //
+
+template<typename DS>
+struct is_dataset : std::false_type {};
+
+//____________________________________________________________________________//
+
+template<typename DS>
+struct is_dataset<DS&> : is_dataset<DS> {};
+
+//____________________________________________________________________________//
+
+template<typename DS>
+struct is_dataset<DS const> : is_dataset<DS> {};
+
+//____________________________________________________________________________//
+
+} // namespace monomorphic
+
+// ************************************************************************** //
+// **************                  data::make                  ************** //
+// ************************************************************************** //
+
+template<typename DS>
+inline typename std::enable_if<monomorphic::is_dataset<DS>::value,DS>::type
+make(DS&& ds)
+{
+    return std::move( ds );
+}
+
+//____________________________________________________________________________//
+
+// ************************************************************************** //
+// **************                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 )
+{
+    auto 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" );
+
+    auto it = ds.begin();
+
+    while( size-- > 0 ) {
+        monomorphic::traits<SampleType>::invoke_action( **it, act );
+        ++(*it);
+    }
+}
+
+//____________________________________________________________________________//
+
+template<typename SampleType, typename Action>
+inline typename std::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 ds_detail {
+
+// ************************************************************************** //
+// **************              is_std_collection               ************** //
+// ************************************************************************** //
+
+template<typename T>
+struct is_std_collection : std::false_type {};
+
+template<typename T>
+struct is_std_collection<T const> : is_std_collection<T> {};
+
+template<typename T>
+struct is_std_collection<T&> : is_std_collection<T> {};
+
+template<typename T>
+struct is_std_collection<std::vector<T>> : std::true_type {};
+
+template<typename T>
+struct is_std_collection<std::list<T>> : std::true_type {};
+
+} // namespace ds_detail
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_DATASET_HPP_102211GER
+
Added: trunk/boost/test/data/monomorphic/generate.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/monomorphic/generate.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,89 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : 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/size.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                ************** //
+// ************************************************************************** //
+
+template<typename Generator>
+class generated_by : public monomorphic::dataset<typename Generator::data_type> {
+    typedef typename Generator::data_type T;
+    typedef monomorphic::dataset<T> base;
+
+    struct iterator : public base::iterator {
+        // Constructor
+        explicit    iterator( Generator& gen )
+        : m_gen( gen )
+        {}
+
+        // forward iterator interface 
+        virtual T const&    operator*()     { m_curr_sample = m_gen.next(); return m_curr_sample; }
+        virtual void        operator++()    {}
+
+    private:
+        // Data members
+        Generator&          m_gen;
+        T                   m_curr_sample;
+    };
+public:
+    enum { arity = 1 };
+    typedef Generator generator_type;
+
+    // Constructor
+    explicit                generated_by( Generator&& G )
+    : m_generator( std::forward<Generator>(G) )
+    {}
+
+    // Access methods
+    data::size_t            size() const            { return m_generator.capacity(); }
+    virtual iter_ptr        begin() const           { return std::make_shared<iterator>( const_cast<Generator&>(m_generator) ); }
+
+private:
+    // Data members
+    Generator               m_generator;
+};
+
+//____________________________________________________________________________//
+
+template<typename Generator>
+struct is_dataset<generated_by<Generator>> : std::true_type {};
+
+//____________________________________________________________________________//
+
+} // namespace monomorphic
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATE_HPP_112011GER
+
Added: trunk/boost/test/data/monomorphic/generators.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/monomorphic/generators.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,23 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : 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
+
Added: trunk/boost/test/data/monomorphic/generators/keywords.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/monomorphic/generators/keywords.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,45 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : 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;
+
+//check_is_close_t const& check_is_close = unit_test::ut_detail::static_constant<check_is_close_t>::value;
+
+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
Added: trunk/boost/test/data/monomorphic/generators/random.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/monomorphic/generators/random.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,159 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : defines range generator
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER
+#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+
+#include <boost/test/data/monomorphic/generate.hpp>
+#include <boost/test/data/monomorphic/generators/keywords.hpp>
+
+// Boost
+
+// 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                   ************** //
+// ************************************************************************** //
+
+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 );
+    }
+    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
+
+inline monomorphic::generated_by<monomorphic::random_t<>>
+random()
+{
+    return monomorphic::generated_by<monomorphic::random_t<>>( monomorphic::random_t<>() );
+}
+
+//____________________________________________________________________________//
+
+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;
+};
+
+}
+
+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;
+
+    engine_type E((std::random_device()()));
+    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_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER
Added: trunk/boost/test/data/monomorphic/generators/xrange.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/monomorphic/generators/xrange.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,186 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : 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/size.hpp>
+
+#include <boost/test/data/monomorphic/generate.hpp>
+
+#include <boost/test/utils/named_params.hpp>
+
+// Boost
+#include <boost/optional.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/type_traits/is_unsigned.hpp>
+
+// STL
+#include <limits>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+namespace monomorphic {
+
+// ************************************************************************** //
+// **************             monomorphic::xrange_t            ************** //
+// ************************************************************************** //
+
+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_curr( begin )
+    , m_step( step )
+    , m_size( size )
+    {}
+
+    // Generator interface
+    data::size_t    capacity() const { return m_size; }
+    SampleType      next() 
+    {
+        BOOST_TEST_DS_ASSERT( m_size != 0, "No more elements in range" );
+
+        SampleType res = m_curr;
+
+        m_curr += m_step;
+        --m_size;
+
+        return res;
+    }
+private:
+    // Data members
+    SampleType      m_curr;
+    StepType        m_step;
+    data::size_t    m_size;
+};
+
+//____________________________________________________________________________//
+
+namespace {
+nfp::keyword<struct begin_t >   begin;
+nfp::keyword<struct end_t >     end;
+nfp::keyword<struct step_t >    step;
+}
+
+//____________________________________________________________________________//
+
+namespace ds_detail {
+
+template<typename SampleType, typename StepType=SampleType>
+struct make_xrange {
+    static StepType    abs( StepType s, mpl::true_* )   { return s; }
+    static StepType    abs( StepType s, mpl::false_* )  { 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( monomorphic::begin )  ? params[monomorphic::begin] : SampleType();
+        optional<SampleType> end_val    = params.has( monomorphic::end )    ? params[monomorphic::end]   : optional<SampleType>();
+        StepType             step_val   = params.has( monomorphic::step )   ? params[monomorphic::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, (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
+
+//____________________________________________________________________________//
+
+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 );
+}
+
+//____________________________________________________________________________//
+
+template<typename SampleType>
+inline monomorphic::generated_by<monomorphic::xrange_t<SampleType> >
+xrange( SampleType const& end_val )
+{
+    return monomorphic::ds_detail::make_xrange<SampleType>::_( monomorphic::end=end_val );
+}
+
+//____________________________________________________________________________//
+
+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, monomorphic::end=end_val ));
+}
+
+//____________________________________________________________________________//
+
+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>::
+            _(( monomorphic::begin=begin_val, monomorphic::end=end_val ));
+}
+
+//____________________________________________________________________________//
+
+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>::
+            _(( monomorphic::begin=begin_val, monomorphic::end=end_val, monomorphic::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
Added: trunk/boost/test/data/monomorphic/grid.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/monomorphic/grid.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,215 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : 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>
+#include <boost/test/data/monomorphic/dataset.hpp>
+
+// Boost
+#include <boost/utility/enable_if.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                    ************** //
+// ************************************************************************** //
+
+template<typename DS1, typename DS2>
+class grid : public monomorphic::dataset<typename ds_detail::grid_traits<typename std::decay<DS1>::type::data_type,
+                                                                         typename std::decay<DS2>::type::data_type>::type> {
+    typedef typename std::decay<DS1>::type::data_type T1;
+    typedef typename std::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;
+
+    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 = std::decay<DS1>::type::arity + std::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 std::make_shared<iterator>( m_ds1.begin(), m_ds2 ); }
+
+private:
+    // Data members
+    DS1             m_ds1;
+    DS2             m_ds2;
+};
+
+//____________________________________________________________________________//
+
+template<typename DS1, typename DS2>
+struct is_dataset<grid<DS1,DS2>> : std::true_type {};
+
+//____________________________________________________________________________//
+
+namespace ds_detail {
+
+template<typename DS1, typename DS2>
+struct explicit_grid_type
+{
+    typedef grid<DS1,DS2> type;
+};
+
+} // ds_detail
+
+template<typename DS1, typename DS2>
+inline typename boost::lazy_enable_if<mpl::and_<is_dataset<DS1>,is_dataset<DS2>>, 
+                                      ds_detail::explicit_grid_type<DS1,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 ) );
+}
+
+//____________________________________________________________________________//
+
+template<typename DS1, typename DS2>
+inline auto 
+operator*( DS1&& ds1, DS2&& ds2 ) ->
+typename std::enable_if<is_dataset<DS1>::value && !is_dataset<DS2>::value, decltype(ds1 * data::make(ds2))>::type
+{
+    return ds1 * data::make(ds2);
+}
+
+//____________________________________________________________________________//
+
+template<typename DS1, typename DS2>
+inline auto 
+operator*( DS1&& ds1, DS2&& ds2 ) ->
+typename std::enable_if<!is_dataset<DS1>::value && is_dataset<DS2>::value, decltype(data::make(ds1) * ds2)>::type
+{
+    return data::make(ds1) * ds2;
+}
+
+//____________________________________________________________________________//
+
+} // namespace monomorphic
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_GRID_HPP_101512GER
+
Added: trunk/boost/test/data/monomorphic/join.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/monomorphic/join.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,146 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : 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/size.hpp>
+#include <boost/test/data/monomorphic/dataset.hpp>
+
+// Boost
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+namespace monomorphic {
+
+// ************************************************************************** //
+// **************                      join                    ************** //
+// ************************************************************************** //
+
+template<typename DS1, typename DS2>
+class join : public monomorphic::dataset<typename std::decay<DS1>::type::data_type> {
+    typedef typename std::decay<DS1>::type::data_type T;
+    typedef monomorphic::dataset<T> base;
+
+    struct iterator : public base::iterator {
+        // Constructor
+        explicit    iterator( iter_ptr it1, iter_ptr it2, data::size_t first_size )
+        : m_it1( std::move(it1) )
+        , m_it2( std::move(it2) )
+        , 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 = std::decay<DS1>::type::arity };
+
+    // 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 ) )
+    {}
+
+    // dataset interface
+    virtual data::size_t    size() const            { return m_ds1.size() + m_ds2.size(); } 
+    virtual iter_ptr        begin() const           { return std::make_shared<iterator>( m_ds1.begin(), 
+                                                                                         m_ds2.begin(),
+                                                                                         m_ds1.size() ); }
+
+private:
+    // Data members
+    DS1 m_ds1;
+    DS2 m_ds2;
+};
+
+//____________________________________________________________________________//
+
+template<typename DS1, typename DS2>
+struct is_dataset<join<DS1,DS2>> : std::true_type {};
+
+//____________________________________________________________________________//
+
+namespace ds_detail {
+
+template<typename DS1, typename DS2>
+struct explicit_join_type
+{
+    typedef join<DS1,DS2> type;
+};
+
+} // ds_detail
+
+template<typename DS1, typename DS2>
+inline typename boost::lazy_enable_if<mpl::and_<is_dataset<DS1>,is_dataset<DS2>>, 
+                                      ds_detail::explicit_join_type<DS1,DS2>>::type
+operator+( DS1&& ds1, DS2&& ds2 )
+{
+    return join<DS1,DS2>( std::forward<DS1>( ds1 ),  std::forward<DS2>( ds2 ) );
+}
+
+//____________________________________________________________________________//
+
+template<typename DS1, typename DS2>
+inline auto 
+operator+( DS1&& ds1, DS2&& ds2 ) ->
+typename std::enable_if<is_dataset<DS1>::value && !is_dataset<DS2>::value, decltype(ds1 + data::make(ds2))>::type
+{
+    return ds1 + data::make(ds2);
+}
+
+//____________________________________________________________________________//
+
+template<typename DS1, typename DS2>
+inline auto 
+operator+( DS1&& ds1, DS2&& ds2 ) ->
+typename std::enable_if<!is_dataset<DS1>::value && is_dataset<DS2>::value, decltype(data::make(ds1) + ds2)>::type
+{
+    return data::make(ds1) + ds2;
+}
+
+//____________________________________________________________________________//
+
+} // namespace monomorphic
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_JOIN_HPP_112711GER
+
Added: trunk/boost/test/data/monomorphic/singleton.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/monomorphic/singleton.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,115 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : 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/size.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 single element data set
+
+template<typename T>
+class singleton : public monomorphic::dataset<T> {
+    typedef monomorphic::dataset<T> base;
+
+    struct iterator : public base::iterator {
+        // Constructor
+        explicit            iterator( singleton<T> const& owner ) : m_owner( owner ) {}
+
+        // forward iterator interface 
+        virtual T const&    operator*()     { return m_owner.value(); }
+        virtual void        operator++()    {}
+
+    private:
+        singleton<T> const& m_owner;
+    };
+
+public:
+    enum { arity = 1 };
+
+    // Constructor
+    explicit        singleton( T&& value ) : m_value( std::forward<T>( value ) ) {}
+
+    // Move constructor
+    singleton( singleton&& s ) : m_value( std::forward<T>( s.m_value ) ) {}
+
+    // 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 std::make_shared<iterator>( *this ); }
+
+private:
+    // Data members
+    T               m_value;
+};
+
+//____________________________________________________________________________//
+
+template<typename T>
+struct is_dataset<singleton<T>> : std::true_type {};
+
+} // namespace monomorphic
+
+template<typename T>
+inline typename std::enable_if<!ds_detail::is_std_collection<T>::value && 
+                               !monomorphic::is_dataset<T>::value, 
+                               monomorphic::singleton<T> >::type
+make( T&& v )
+{
+    return monomorphic::singleton<T>( std::forward<T>( v ) );
+}
+
+//____________________________________________________________________________//
+
+inline monomorphic::singleton<char*>
+make( char* str )
+{
+    return monomorphic::singleton<char*>( std::forward<char*>( str ) );
+}
+
+//____________________________________________________________________________//
+
+inline monomorphic::singleton<char const*>
+make( char const* str )
+{
+    return monomorphic::singleton<char const*>( std::forward<char const*>( str ) );
+}
+
+//____________________________________________________________________________//
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_SINGLETON_HPP_102211GER
+
Added: trunk/boost/test/data/monomorphic/zip.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/monomorphic/zip.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,221 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : 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
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+#include <boost/test/data/monomorphic/dataset.hpp>
+
+// Boost
+#include <boost/utility/enable_if.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,get<0>(a2),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(get<0>(a1),get<1>(a1),a2);
+    }
+};
+
+//____________________________________________________________________________//
+
+} // namespace ds_detail
+
+// ************************************************************************** //
+// **************                       zip                    ************** //
+// ************************************************************************** //
+
+template<typename DS1, typename DS2>
+class zip : public monomorphic::dataset<typename ds_detail::zip_traits<typename std::decay<DS1>::type::data_type,
+                                                                       typename std::decay<DS2>::type::data_type>::type> {
+    typedef typename std::decay<DS1>::type::data_type T1;
+    typedef typename std::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;
+
+    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 = std::decay<DS1>::type::arity + std::decay<DS2>::type::arity };
+
+    // Constructor
+    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 std::make_shared<iterator>( m_ds1.begin(), m_ds2.begin() ); }
+
+private:
+    // Data members
+    DS1             m_ds1;
+    DS2             m_ds2;
+    data::size_t    m_size;
+};
+
+//____________________________________________________________________________//
+
+template<typename DS1, typename DS2>
+struct is_dataset<zip<DS1,DS2>> : std::true_type {};
+
+//____________________________________________________________________________//
+
+namespace ds_detail {
+
+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" );
+}
+
+//____________________________________________________________________________//
+
+template<typename DS1, typename DS2>
+struct explicit_zip_type
+{
+    typedef zip<DS1,DS2> type;
+};
+
+} // ds_detail
+
+template<typename DS1, typename DS2>
+inline typename boost::lazy_enable_if<mpl::and_<is_dataset<DS1>,is_dataset<DS2>>, 
+                                      ds_detail::explicit_zip_type<DS1,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 ) );
+}
+
+//____________________________________________________________________________//
+
+template<typename DS1, typename DS2>
+inline auto 
+operator^( DS1&& ds1, DS2&& ds2 ) ->
+typename std::enable_if<is_dataset<DS1>::value && !is_dataset<DS2>::value, decltype(ds1 ^ data::make(ds2))>::type
+{
+    return ds1 ^ data::make(ds2);
+}
+
+//____________________________________________________________________________//
+
+template<typename DS1, typename DS2>
+inline auto 
+operator^( DS1&& ds1, DS2&& ds2 ) ->
+typename std::enable_if<!is_dataset<DS1>::value && is_dataset<DS2>::value, decltype(data::make(ds1) ^ ds2)>::type
+{
+    return data::make(ds1) ^ ds2;
+}
+
+//____________________________________________________________________________//
+
+} // namespace monomorphic
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_MONOMORPHIC_ZIP_HPP_102211GER
+
Added: trunk/boost/test/data/size.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/size.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,147 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : defines simple dataset size abstraction (can be infinite)
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_SIZE_HPP_102211GER
+#define BOOST_TEST_DATA_SIZE_HPP_102211GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+
+// STL
+#include <iosfwd>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+
+// ************************************************************************** //
+// **************                    size_t                    ************** //
+// ************************************************************************** //
+
+class size_t {
+    struct dummy { void nonnull() {} };
+    typedef void (dummy::*safe_bool)();
+public:
+    // Constructors
+    size_t( std::size_t s = 0 )         : m_value( s ), m_infinity( false ) {}
+    explicit        size_t( bool )      : m_value( 0 ), m_infinity( true ) {}
+    template<typename T>
+    size_t( T v )                       : m_value( static_cast<std::size_t>(v) ), m_infinity( false ) {}
+
+    // Access methods
+    std::size_t     value() const       { return m_value; }
+    bool            is_inf() const      { return m_infinity; }
+    operator        safe_bool() const   { return is_inf() || m_value != 0 ? &dummy::nonnull : 0; }
+
+    // Unary operators
+    data::size_t    operator--()        { if( !is_inf() ) m_value--; return *this; }
+    data::size_t    operator--(int)     { data::size_t res(*this); if( !is_inf() ) m_value--; return res; }
+    data::size_t    operator++()        { if( !is_inf() ) m_value++; return *this; }
+    data::size_t    operator++(int)     { data::size_t res(*this); if( !is_inf() ) m_value++; return res; }
+
+    // Binary operators
+    data::size_t&   operator+=( std::size_t rhs ) { if( !is_inf() ) m_value += rhs; return *this; }
+    data::size_t&   operator+=( data::size_t rhs )
+    {
+        if( !is_inf() ) {
+            if( rhs.is_inf() )
+                *this = rhs;
+            else
+                m_value += rhs.value();
+        }
+        return *this;
+    }
+    data::size_t&   operator-=( std::size_t rhs ) { if( !is_inf() ) m_value -= rhs; return *this; }
+    data::size_t&   operator-=( data::size_t rhs )
+    {
+        if( !is_inf() ) {
+            if( value() < rhs.value() )
+                m_value = 0;
+            else
+                m_value -= rhs.value();
+        }
+        return *this;
+    }
+
+private:
+    // Data members
+    std::size_t     m_value;
+    bool            m_infinity;
+};
+
+namespace { const data::size_t BOOST_TEST_DS_INFINITE_SIZE( true ); }
+
+//____________________________________________________________________________//
+
+// Binary operators
+inline bool operator>(data::size_t lhs, std::size_t rhs)    { return lhs.is_inf()  || (lhs.value() > rhs); }
+inline bool operator>(std::size_t lhs, data::size_t rhs)    { return !rhs.is_inf() && (lhs > rhs.value()); }
+inline bool operator>(data::size_t lhs, data::size_t rhs)   { return lhs.is_inf() ^ rhs.is_inf() ? lhs.is_inf() : lhs.value() > rhs.value(); }
+
+inline bool operator>=(data::size_t lhs, std::size_t rhs )  { return lhs.is_inf()  || (lhs.value() >= rhs); }
+inline bool operator>=(std::size_t lhs, data::size_t rhs)   { return !rhs.is_inf() && (lhs >= rhs.value()); }
+inline bool operator>=(data::size_t lhs, data::size_t rhs)  { return lhs.is_inf() ^ rhs.is_inf() ? lhs.is_inf() : lhs.value() >= rhs.value(); }
+
+inline bool operator<(data::size_t lhs, std::size_t rhs)    { return !lhs.is_inf() && (lhs.value() < rhs); }
+inline bool operator<(std::size_t lhs, data::size_t rhs)    { return rhs.is_inf()  || (lhs < rhs.value()); }
+inline bool operator<(data::size_t lhs, data::size_t rhs)   { return lhs.is_inf() ^ rhs.is_inf() ? rhs.is_inf() : lhs.value() < rhs.value(); }
+
+inline bool operator<=(data::size_t lhs, std::size_t rhs)   { return !lhs.is_inf() && (lhs.value() <= rhs); }
+inline bool operator<=(std::size_t lhs, data::size_t rhs)   { return rhs.is_inf()  || (lhs <= rhs.value()); }
+inline bool operator<=(data::size_t lhs, data::size_t rhs)  { return lhs.is_inf() ^ rhs.is_inf() ? rhs.is_inf() : lhs.value() <= rhs.value(); }
+
+inline bool operator==(data::size_t lhs, std::size_t rhs)   { return !lhs.is_inf() && (lhs.value() == rhs); }
+inline bool operator==(std::size_t lhs, data::size_t rhs)   { return !rhs.is_inf() && (lhs == rhs.value()); }
+inline bool operator==(data::size_t lhs, data::size_t rhs)  { return !(lhs.is_inf() ^ rhs.is_inf()) && lhs.value() == rhs.value(); }
+
+inline bool operator!=(data::size_t lhs, std::size_t rhs)   { return lhs.is_inf() || (lhs.value() != rhs); }
+inline bool operator!=(std::size_t lhs, data::size_t rhs)   { return rhs.is_inf() || (lhs != rhs.value()); }
+inline bool operator!=(data::size_t lhs, data::size_t rhs)  { return lhs.is_inf() ^ rhs.is_inf() || lhs.value() != rhs.value(); }
+
+inline data::size_t operator+(data::size_t lhs, std::size_t rhs)  { return lhs.is_inf() ? lhs : data::size_t( lhs.value()+rhs ); }
+inline data::size_t operator+(std::size_t lhs, data::size_t rhs)  { return rhs.is_inf() ? rhs : data::size_t( lhs+rhs.value() ); }
+inline data::size_t operator+(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() || rhs.is_inf() ? data::size_t(true) : data::size_t( lhs.value()+rhs.value() ); }
+
+inline data::size_t operator*(data::size_t lhs, std::size_t rhs)  { return lhs.is_inf() ? lhs : data::size_t( lhs.value()*rhs ); }
+inline data::size_t operator*(std::size_t lhs, data::size_t rhs)  { return rhs.is_inf() ? rhs : data::size_t( lhs*rhs.value() ); }
+inline data::size_t operator*(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() || rhs.is_inf() ? data::size_t(true) : data::size_t( lhs.value()*rhs.value() ); }
+
+//____________________________________________________________________________//
+
+template<typename CharT1, typename Tr>
+inline std::basic_ostream<CharT1,Tr>&
+operator<<( std::basic_ostream<CharT1,Tr>& os, data::size_t const& s )
+{
+    if( s.is_inf() )
+        os << "infinity";
+    else
+        os << s.value();
+
+    return os;
+}
+
+//____________________________________________________________________________//
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_SIZE_HPP_102211GER
+
Added: trunk/boost/test/data/test_case.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/test/data/test_case.hpp	2012-10-18 03:43:44 EDT (Thu, 18 Oct 2012)
@@ -0,0 +1,145 @@
+//  (C) Copyright Gennadiy Rozental 2011-2012.
+//  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        : $RCSfile$
+//
+//  Version     : $Revision$
+//
+//  Description : defines test case family based on data generator
+// ***************************************************************************
+
+#ifndef BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
+#define BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
+
+// Boost.Test
+#include <boost/test/data/config.hpp>
+#include <boost/test/data/dataset.hpp>
+
+// Boost
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_shifted_binary_params.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/preprocessor/comparison/equal.hpp>
+#include <boost/preprocessor/control/iif.hpp>
+#include <boost/preprocessor/punctuation/comma.hpp>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
+//____________________________________________________________________________//
+
+namespace boost {
+namespace unit_test {
+namespace data {
+
+// ************************************************************************** //
+// **************              test_case_template              ************** //
+// ************************************************************************** //
+
+namespace ds_detail {
+
+template<typename TestCase,typename DS>
+class test_case_gen : public test_unit_generator {
+public:
+    // Constructor
+    test_case_gen( const_string tc_name, DS&& ds )
+    : m_tc_name( ut_detail::normalize_test_case_name( tc_name ) )
+    {
+        data::for_each_sample( ds, *this );
+    }
+    test_case_gen( test_case_gen&& gen )
+    : m_tc_name( gen.m_tc_name )
+    , m_test_cases( std::move(gen.m_test_cases) )
+    {}
+
+    virtual test_unit* next() const
+    {
+        if( m_test_cases.empty() )
+            return 0;
+    
+        test_unit* res = m_test_cases.front();
+        m_test_cases.pop_front();
+
+        return res;
+    }
+
+    // !! ?? variadics based implementation 
+#define TC_MAKE(z,arity,_)                                                          \
+    template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)>                             \
+    void    operator()( BOOST_PP_ENUM_BINARY_PARAMS(arity, Arg, const& arg) ) const \
+    {                                                                               \
+        m_test_cases.push_back( new test_case( m_tc_name,                           \
+            std::bind( &TestCase::test_method<BOOST_PP_ENUM_PARAMS(arity,Arg)>,     \
+            BOOST_PP_ENUM_PARAMS(arity, arg) ) ) );                                 \
+    }                                                                               \
+
+    BOOST_PP_REPEAT_FROM_TO(1, 4, TC_MAKE, _)
+
+private:
+    // Data members
+    std::string                     m_tc_name;
+    mutable std::list<test_unit*>   m_test_cases;
+};
+
+//____________________________________________________________________________//
+
+template<typename TestCase,typename DS>
+test_case_gen<TestCase,DS>
+make_test_case_gen( const_string tc_name, DS&& ds )
+{
+    return test_case_gen<TestCase,DS>( tc_name, std::forward<DS>(ds) );
+}
+
+//____________________________________________________________________________//
+
+} // namespace ds_detail
+
+// ************************************************************************** //
+// **************            BOOST_DATA_TEST_CASE_N            ************** //
+// ************************************************************************** //
+
+#define BOOST_DATA_TEST_CASE_N_ARGS( arity )                            \
+    BOOST_PP_IIF(BOOST_PP_EQUAL(arity, 1),                              \
+        Arg0 const& sample,                                             \
+        Arg0 const& sample0 )                                           \
+    BOOST_PP_IIF(BOOST_PP_EQUAL(arity, 1),                              \
+        BOOST_PP_EMPTY,                                                 \
+        BOOST_PP_COMMA )()                                              \
+    BOOST_PP_ENUM_SHIFTED_BINARY_PARAMS(arity, Arg, const& sample)      \
+/**/
+
+#define BOOST_DATA_TEST_CASE_N( arity, test_name, dataset )             \
+struct test_name                                                        \
+{                                                                       \
+    template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)>                 \
+    static void test_method( BOOST_DATA_TEST_CASE_N_ARGS( arity ) );    \
+};                                                                      \
+                                                                        \
+BOOST_AUTO_TU_REGISTRAR( test_name )(                                   \
+    boost::unit_test::data::ds_detail::make_test_case_gen<test_name>(   \
+          BOOST_STRINGIZE( test_name ), data::make(dataset) ),          \
+    boost::unit_test::decorator::collector::instance() );               \
+                                                                        \
+    template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)>                 \
+    void test_name::test_method( BOOST_DATA_TEST_CASE_N_ARGS( arity ) ) \
+/**/
+
+// ************************************************************************** //
+// **************             BOOST_DATA_TEST_CASE             ************** //
+// ************************************************************************** //
+
+#define BOOST_DATA_TEST_CASE( test_name, dataset )                      \
+    BOOST_DATA_TEST_CASE_N( 1, test_name, dataset )
+
+} // namespace data
+} // namespace unit_test
+} // namespace boost
+
+#include <boost/test/detail/enable_warnings.hpp>
+
+#endif // BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
+