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