// (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 #include #include //____________________________________________________________________________// 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 class join : public monomorphic::dataset::type::data_type> { typedef typename boost::decay::type::data_type T; typedef monomorphic::dataset 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::type::arity }; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES // Constructor join( DS1&& ds1, DS2&& ds2 ) : m_ds1( std::forward( ds1 ) ) , m_ds2( std::forward( ds2 ) ) {} // Move constructor join( join&& j ) : m_ds1( std::forward( j.m_ds1 ) ) , m_ds2( std::forward( 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( 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 struct is_dataset > : mpl::true_ {}; //____________________________________________________________________________// namespace result_of { //! Result type of the join operation on datasets. template struct join { typedef monomorphic::join type; }; } // namespace result_of //____________________________________________________________________________// template inline typename boost::lazy_enable_if_c::value && is_dataset::value, result_of::join,mpl::identity > >::type #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES operator+( DS1&& ds1, DS2&& ds2 ) { return join( std::forward( ds1 ), std::forward( ds2 ) ); } #else operator+( DS1 const& ds1, DS2 const& ds2 ) { return join( ds1, ds2 ); } #endif //____________________________________________________________________________// #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template inline typename boost::lazy_enable_if_c::value && !is_dataset::value, result_of::join,data::result_of::make > >::type operator+( DS1&& ds1, DS2&& ds2 ) { return std::forward(ds1) + data::make(std::forward(ds2)); } #else template inline typename boost::lazy_enable_if_c::value && !is_dataset::value, result_of::join,data::result_of::make > >::type operator+( DS1 const& ds1, DS2 const& ds2 ) { return ds1 + data::make(ds2); } #endif //____________________________________________________________________________// #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template inline typename boost::lazy_enable_if_c::value && is_dataset::value, result_of::join,mpl::identity > >::type operator+( DS1&& ds1, DS2&& ds2 ) { return data::make(std::forward(ds1)) + std::forward(ds2); } #else template inline typename boost::lazy_enable_if_c::value && is_dataset::value, result_of::join,mpl::identity > >::type operator+( DS1 const& ds1, DS2 const& ds2 ) { return data::make(ds1) + ds2; } #endif } // namespace monomorphic } // namespace data } // namespace unit_test } // namespace boost #include #endif // BOOST_TEST_DATA_MONOMORPHIC_JOIN_HPP_112711GER