zip.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  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 monomorphic dataset based on zipping of 2 other monomorphic datasets
  9. // ***************************************************************************
  10. #ifndef BOOST_TEST_DATA_MONOMORPHIC_ZIP_HPP_102211GER
  11. #define BOOST_TEST_DATA_MONOMORPHIC_ZIP_HPP_102211GER
  12. // Boost.Test
  13. #include <boost/test/data/config.hpp>
  14. #if !defined(BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE) || defined(BOOST_TEST_DOXYGEN_DOC__)
  15. #include <boost/test/data/monomorphic/fwd.hpp>
  16. #include <boost/test/data/monomorphic/sample_merge.hpp>
  17. #include <boost/core/enable_if.hpp>
  18. #include <boost/mpl/identity.hpp>
  19. #include <boost/test/detail/suppress_warnings.hpp>
  20. namespace boost {
  21. namespace unit_test {
  22. namespace data {
  23. namespace monomorphic {
  24. // ************************************************************************** //
  25. // ************** zip ************** //
  26. // ************************************************************************** //
  27. //! Zip datasets
  28. //!
  29. //! A zip of two datasets is a dataset whose arity is the sum of the operand datasets arity. The size is given by
  30. //! the function creating the instance (see @c operator^ on datasets).
  31. template<typename DataSet1, typename DataSet2>
  32. class zip {
  33. typedef typename boost::decay<DataSet1>::type dataset1_decay;
  34. typedef typename boost::decay<DataSet2>::type dataset2_decay;
  35. typedef typename dataset1_decay::iterator dataset1_iter;
  36. typedef typename dataset2_decay::iterator dataset2_iter;
  37. public:
  38. enum { arity = dataset1_decay::arity + dataset2_decay::arity };
  39. struct iterator {
  40. // Constructor
  41. explicit iterator( dataset1_iter iter1, dataset2_iter iter2 )
  42. : m_iter1( std::move( iter1 ) )
  43. , m_iter2( std::move( iter2 ) )
  44. {}
  45. using iterator_sample = decltype(
  46. sample_merge( *std::declval<dataset1_iter>(),
  47. *std::declval<dataset2_iter>()) );
  48. // forward iterator interface
  49. auto operator*() const -> iterator_sample {
  50. return sample_merge( *m_iter1, *m_iter2 );
  51. }
  52. void operator++() { ++m_iter1; ++m_iter2; }
  53. private:
  54. // Data members
  55. dataset1_iter m_iter1;
  56. dataset2_iter m_iter2;
  57. };
  58. //! Constructor
  59. //!
  60. //! The datasets are moved and not copied.
  61. zip( DataSet1&& ds1, DataSet2&& ds2/*, data::size_t size*/ )
  62. : m_ds1( std::forward<DataSet1>( ds1 ) )
  63. , m_ds2( std::forward<DataSet2>( ds2 ) )
  64. //, m_size( size )
  65. {}
  66. //! Move constructor
  67. zip( zip&& j )
  68. : m_ds1( std::forward<DataSet1>( j.m_ds1 ) )
  69. , m_ds2( std::forward<DataSet2>( j.m_ds2 ) )
  70. //, m_size( j.m_size )
  71. {}
  72. // dataset interface
  73. data::size_t size() const { return zip_size(); }
  74. iterator begin() const { return iterator( m_ds1.begin(), m_ds2.begin() ); }
  75. private:
  76. // Data members
  77. DataSet1 m_ds1;
  78. DataSet2 m_ds2;
  79. //data::size_t m_size;
  80. //! Handles the sise of the resulting zipped dataset.
  81. data::size_t zip_size() const
  82. {
  83. data::size_t ds1_size = m_ds1.size();
  84. data::size_t ds2_size = m_ds2.size();
  85. if( ds1_size == ds2_size )
  86. return ds1_size;
  87. if( ds1_size == 1 || ds1_size.is_inf() )
  88. return ds2_size;
  89. if( ds2_size == 1 || ds2_size.is_inf() )
  90. return ds1_size;
  91. BOOST_TEST_DS_ERROR( "Can't zip datasets of different sizes" );
  92. }
  93. };
  94. //____________________________________________________________________________//
  95. //! Zipped datasets results in a dataset.
  96. template<typename DataSet1, typename DataSet2>
  97. struct is_dataset<zip<DataSet1,DataSet2>> : mpl::true_ {};
  98. //____________________________________________________________________________//
  99. namespace result_of {
  100. //! Result type of the zip operator.
  101. template<typename DS1Gen, typename DS2Gen>
  102. struct zip {
  103. typedef monomorphic::zip<typename DS1Gen::type,typename DS2Gen::type> type;
  104. };
  105. } // namespace result_of
  106. //____________________________________________________________________________//
  107. //! Overload operator for zip support
  108. template<typename DataSet1, typename DataSet2>
  109. inline typename boost::lazy_enable_if_c<is_dataset<DataSet1>::value && is_dataset<DataSet2>::value,
  110. result_of::zip<mpl::identity<DataSet1>,mpl::identity<DataSet2>>
  111. >::type
  112. operator^( DataSet1&& ds1, DataSet2&& ds2 )
  113. {
  114. return zip<DataSet1,DataSet2>( std::forward<DataSet1>( ds1 ),
  115. std::forward<DataSet2>( ds2 )/*,
  116. ds_detail::zip_size( ds1, ds2 )*/ );
  117. }
  118. //____________________________________________________________________________//
  119. //! @overload boost::unit_test::data::monomorphic::operator^()
  120. template<typename DataSet1, typename DataSet2>
  121. inline typename boost::lazy_enable_if_c<is_dataset<DataSet1>::value && !is_dataset<DataSet2>::value,
  122. result_of::zip<mpl::identity<DataSet1>,data::result_of::make<DataSet2>>
  123. >::type
  124. operator^( DataSet1&& ds1, DataSet2&& ds2 )
  125. {
  126. return std::forward<DataSet1>( ds1 ) ^ data::make( std::forward<DataSet2>( ds2 ) );
  127. }
  128. //____________________________________________________________________________//
  129. //! @overload boost::unit_test::data::monomorphic::operator^()
  130. template<typename DataSet1, typename DataSet2>
  131. inline typename boost::lazy_enable_if_c<!is_dataset<DataSet1>::value && is_dataset<DataSet2>::value,
  132. result_of::zip<data::result_of::make<DataSet1>,mpl::identity<DataSet2>>
  133. >::type
  134. operator^( DataSet1&& ds1, DataSet2&& ds2 )
  135. {
  136. return data::make( std::forward<DataSet1>( ds1 ) ) ^ std::forward<DataSet2>( ds2 );
  137. }
  138. } // namespace monomorphic
  139. } // namespace data
  140. } // namespace unit_test
  141. } // namespace boost
  142. #include <boost/test/detail/enable_warnings.hpp>
  143. #endif // BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE
  144. #endif // BOOST_TEST_DATA_MONOMORPHIC_ZIP_HPP_102211GER