join.hpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // (C) Copyright Gennadiy Rozental 2001.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // See http://www.boost.org/libs/test for the library home page.
  6. //
  7. //! @file
  8. //! Defines dataset join operation
  9. // ***************************************************************************
  10. #ifndef BOOST_TEST_DATA_MONOMORPHIC_JOIN_HPP_112711GER
  11. #define BOOST_TEST_DATA_MONOMORPHIC_JOIN_HPP_112711GER
  12. // Boost.Test
  13. #include <boost/test/data/config.hpp>
  14. #include <boost/test/data/monomorphic/fwd.hpp>
  15. #include <boost/test/detail/suppress_warnings.hpp>
  16. //____________________________________________________________________________//
  17. namespace boost {
  18. namespace unit_test {
  19. namespace data {
  20. namespace monomorphic {
  21. // ************************************************************************** //
  22. // ************** join ************** //
  23. // ************************************************************************** //
  24. //! Defines a new dataset from the concatenation of two datasets
  25. //!
  26. //! The size of the resulting dataset is the sum of the two underlying datasets. The arity of the datasets
  27. //! should match.
  28. template<typename DataSet1, typename DataSet2>
  29. class join {
  30. typedef typename boost::decay<DataSet1>::type dataset1_decay;
  31. typedef typename boost::decay<DataSet2>::type dataset2_decay;
  32. typedef typename dataset1_decay::iterator dataset1_iter;
  33. typedef typename dataset2_decay::iterator dataset2_iter;
  34. public:
  35. typedef typename dataset1_decay::sample sample;
  36. enum { arity = dataset1_decay::arity };
  37. struct iterator {
  38. // Constructor
  39. explicit iterator( dataset1_iter it1, dataset2_iter it2, data::size_t first_size )
  40. : m_it1( std::move( it1 ) )
  41. , m_it2( std::move( it2 ) )
  42. , m_first_size( first_size )
  43. {}
  44. // forward iterator interface
  45. sample const& operator*() const { return m_first_size > 0 ? *m_it1 : *m_it2; }
  46. void operator++() { if( m_first_size > 0 ) { --m_first_size; ++m_it1; } else ++m_it2; }
  47. private:
  48. // Data members
  49. dataset1_iter m_it1;
  50. dataset2_iter m_it2;
  51. data::size_t m_first_size;
  52. };
  53. //! Constructor
  54. join( DataSet1&& ds1, DataSet2&& ds2 )
  55. : m_ds1( std::forward<DataSet1>( ds1 ) )
  56. , m_ds2( std::forward<DataSet2>( ds2 ) )
  57. {}
  58. //! Move constructor
  59. join( join&& j )
  60. : m_ds1( std::forward<DataSet1>( j.m_ds1 ) )
  61. , m_ds2( std::forward<DataSet2>( j.m_ds2 ) )
  62. {}
  63. //! dataset interface
  64. data::size_t size() const { return m_ds1.size() + m_ds2.size(); }
  65. iterator begin() const { return iterator( m_ds1.begin(), m_ds2.begin(), m_ds1.size() ); }
  66. private:
  67. // Data members
  68. DataSet1 m_ds1;
  69. DataSet2 m_ds2;
  70. };
  71. //____________________________________________________________________________//
  72. // A joined dataset is a dataset.
  73. template<typename DataSet1, typename DataSet2>
  74. struct is_dataset<join<DataSet1,DataSet2>> : mpl::true_ {};
  75. //____________________________________________________________________________//
  76. namespace result_of {
  77. //! Result type of the join operation on datasets.
  78. template<typename DataSet1Gen, typename DataSet2Gen>
  79. struct join {
  80. typedef monomorphic::join<typename DataSet1Gen::type,typename DataSet2Gen::type> type;
  81. };
  82. } // namespace result_of
  83. //____________________________________________________________________________//
  84. template<typename DataSet1, typename DataSet2>
  85. inline typename boost::lazy_enable_if_c<is_dataset<DataSet1>::value && is_dataset<DataSet2>::value,
  86. result_of::join<mpl::identity<DataSet1>,mpl::identity<DataSet2>>
  87. >::type
  88. operator+( DataSet1&& ds1, DataSet2&& ds2 )
  89. {
  90. return join<DataSet1,DataSet2>( std::forward<DataSet1>( ds1 ), std::forward<DataSet2>( ds2 ) );
  91. }
  92. //____________________________________________________________________________//
  93. template<typename DataSet1, typename DataSet2>
  94. inline typename boost::lazy_enable_if_c<is_dataset<DataSet1>::value && !is_dataset<DataSet2>::value,
  95. result_of::join<mpl::identity<DataSet1>,data::result_of::make<DataSet2>>
  96. >::type
  97. operator+( DataSet1&& ds1, DataSet2&& ds2 )
  98. {
  99. return std::forward<DataSet1>( ds1 ) + data::make( std::forward<DataSet2>( ds2 ) );
  100. }
  101. //____________________________________________________________________________//
  102. template<typename DataSet1, typename DataSet2>
  103. inline typename boost::lazy_enable_if_c<!is_dataset<DataSet1>::value && is_dataset<DataSet2>::value,
  104. result_of::join<data::result_of::make<DataSet1>,mpl::identity<DataSet2>>
  105. >::type
  106. operator+( DataSet1&& ds1, DataSet2&& ds2 )
  107. {
  108. return data::make( std::forward<DataSet1>(ds1) ) + std::forward<DataSet2>( ds2 );
  109. }
  110. } // namespace monomorphic
  111. } // namespace data
  112. } // namespace unit_test
  113. } // namespace boost
  114. #include <boost/test/detail/enable_warnings.hpp>
  115. #endif // BOOST_TEST_DATA_MONOMORPHIC_JOIN_HPP_112711GER