diff options
Diffstat (limited to 'boost/test/tools/collection_comparison_op.hpp')
-rw-r--r-- | boost/test/tools/collection_comparison_op.hpp | 100 |
1 files changed, 65 insertions, 35 deletions
diff --git a/boost/test/tools/collection_comparison_op.hpp b/boost/test/tools/collection_comparison_op.hpp index 396de502f8..864103fb4a 100644 --- a/boost/test/tools/collection_comparison_op.hpp +++ b/boost/test/tools/collection_comparison_op.hpp @@ -38,6 +38,15 @@ namespace assertion { template<typename T> struct specialized_compare : public mpl::false_ {}; +template <typename T> +struct is_c_array : public mpl::false_ {}; + +template<typename T, std::size_t N> +struct is_c_array<T [N]> : public mpl::true_ {}; + +template<typename T, std::size_t N> +struct is_c_array<T (&)[N]> : public mpl::true_ {}; + #define BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE(Col) \ namespace boost { namespace test_tools { namespace assertion { \ template<> \ @@ -55,17 +64,21 @@ template <typename OP, bool can_be_equal, bool prefer_shorter, typename Lhs, typename Rhs> inline typename boost::enable_if_c< - unit_test::is_forward_iterable<Lhs>::value && unit_test::is_forward_iterable<Rhs>::value, + unit_test::is_forward_iterable<Lhs>::value && !unit_test::is_cstring<Lhs>::value + && unit_test::is_forward_iterable<Rhs>::value && !unit_test::is_cstring<Rhs>::value, assertion_result>::type lexicographic_compare( Lhs const& lhs, Rhs const& rhs ) { assertion_result ar( true ); - typename Lhs::const_iterator first1 = lhs.begin(); - typename Rhs::const_iterator first2 = rhs.begin(); - typename Lhs::const_iterator last1 = lhs.end(); - typename Rhs::const_iterator last2 = rhs.end(); - std::size_t pos = 0; + typedef unit_test::bt_iterator_traits<Lhs> t_Lhs_iterator; + typedef unit_test::bt_iterator_traits<Rhs> t_Rhs_iterator; + + typename t_Lhs_iterator::const_iterator first1 = t_Lhs_iterator::begin(lhs); + typename t_Rhs_iterator::const_iterator first2 = t_Rhs_iterator::begin(rhs); + typename t_Lhs_iterator::const_iterator last1 = t_Lhs_iterator::end(lhs); + typename t_Rhs_iterator::const_iterator last2 = t_Rhs_iterator::end(rhs); + std::size_t pos = 0; for( ; (first1 != last1) && (first2 != last2); ++first1, ++first2, ++pos ) { assertion_result const& element_ar = OP::eval(*first1, *first2); @@ -113,8 +126,7 @@ template <typename OP, bool can_be_equal, bool prefer_shorter, typename Lhs, typename Rhs> inline typename boost::enable_if_c< - (!unit_test::is_forward_iterable<Lhs>::value && unit_test::is_cstring<Lhs>::value) || - (!unit_test::is_forward_iterable<Rhs>::value && unit_test::is_cstring<Rhs>::value), + (unit_test::is_cstring<Lhs>::value || unit_test::is_cstring<Rhs>::value), assertion_result>::type lexicographic_compare( Lhs const& lhs, Rhs const& rhs ) { @@ -122,8 +134,8 @@ lexicographic_compare( Lhs const& lhs, Rhs const& rhs ) typedef typename unit_test::deduce_cstring<Rhs>::type rhs_char_type; return lexicographic_compare<OP, can_be_equal, prefer_shorter>( - boost::unit_test::basic_cstring<lhs_char_type>(lhs), - boost::unit_test::basic_cstring<rhs_char_type>(rhs)); + lhs_char_type(lhs), + rhs_char_type(rhs)); } //____________________________________________________________________________// @@ -135,23 +147,27 @@ lexicographic_compare( Lhs const& lhs, Rhs const& rhs ) template <typename OP, typename Lhs, typename Rhs> inline typename boost::enable_if_c< - unit_test::is_forward_iterable<Lhs>::value && unit_test::is_forward_iterable<Rhs>::value, + unit_test::is_forward_iterable<Lhs>::value && !unit_test::is_cstring<Lhs>::value + && unit_test::is_forward_iterable<Rhs>::value && !unit_test::is_cstring<Rhs>::value, assertion_result>::type element_compare( Lhs const& lhs, Rhs const& rhs ) { + typedef unit_test::bt_iterator_traits<Lhs> t_Lhs_iterator; + typedef unit_test::bt_iterator_traits<Rhs> t_Rhs_iterator; + assertion_result ar( true ); - if( lhs.size() != rhs.size() ) { + if( t_Lhs_iterator::size(lhs) != t_Rhs_iterator::size(rhs) ) { ar = false; - ar.message() << "\nCollections size mismatch: " << lhs.size() << " != " << rhs.size(); + ar.message() << "\nCollections size mismatch: " << t_Lhs_iterator::size(lhs) << " != " << t_Rhs_iterator::size(rhs); return ar; } - typename Lhs::const_iterator left = lhs.begin(); - typename Rhs::const_iterator right = rhs.begin(); - std::size_t pos = 0; + typename t_Lhs_iterator::const_iterator left = t_Lhs_iterator::begin(lhs); + typename t_Rhs_iterator::const_iterator right = t_Rhs_iterator::begin(rhs); + std::size_t pos = 0; - for( ; pos < lhs.size(); ++left, ++right, ++pos ) { + for( ; pos < t_Lhs_iterator::size(lhs); ++left, ++right, ++pos ) { assertion_result const element_ar = OP::eval( *left, *right ); if( element_ar ) continue; @@ -171,16 +187,15 @@ element_compare( Lhs const& lhs, Rhs const& rhs ) template <typename OP, typename Lhs, typename Rhs> inline typename boost::enable_if_c< - (!unit_test::is_forward_iterable<Lhs>::value && unit_test::is_cstring<Lhs>::value) || - (!unit_test::is_forward_iterable<Rhs>::value && unit_test::is_cstring<Rhs>::value), + (unit_test::is_cstring<Lhs>::value || unit_test::is_cstring<Rhs>::value), assertion_result>::type element_compare( Lhs const& lhs, Rhs const& rhs ) { typedef typename unit_test::deduce_cstring<Lhs>::type lhs_char_type; typedef typename unit_test::deduce_cstring<Rhs>::type rhs_char_type; - return element_compare<OP>(boost::unit_test::basic_cstring<lhs_char_type>(lhs), - boost::unit_test::basic_cstring<rhs_char_type>(rhs)); + return element_compare<OP>(lhs_char_type(lhs), + rhs_char_type(rhs)); } //____________________________________________________________________________// @@ -193,14 +208,17 @@ template <typename OP, typename Lhs, typename Rhs> inline assertion_result non_equality_compare( Lhs const& lhs, Rhs const& rhs ) { + typedef unit_test::bt_iterator_traits<Lhs> t_Lhs_iterator; + typedef unit_test::bt_iterator_traits<Rhs> t_Rhs_iterator; + assertion_result ar( true ); - if( lhs.size() != rhs.size() ) + if( t_Lhs_iterator::size(lhs) != t_Rhs_iterator::size(rhs) ) return ar; - typename Lhs::const_iterator left = lhs.begin(); - typename Rhs::const_iterator right = rhs.begin(); - typename Lhs::const_iterator end = lhs.end(); + typename t_Lhs_iterator::const_iterator left = t_Lhs_iterator::begin(lhs); + typename t_Rhs_iterator::const_iterator right = t_Rhs_iterator::begin(rhs); + typename t_Lhs_iterator::const_iterator end = t_Lhs_iterator::end(lhs); for( ; left != end; ++left, ++right ) { if( OP::eval( *left, *right ) ) @@ -367,22 +385,34 @@ compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::GE<L, R> >* #define DEFINE_COLLECTION_COMPARISON( oper, name, rev ) \ template<typename Lhs,typename Rhs> \ struct name<Lhs,Rhs,typename boost::enable_if_c< \ - unit_test::is_forward_iterable<Lhs>::value \ - && !unit_test::is_cstring<Lhs>::value \ - && unit_test::is_forward_iterable<Rhs>::value \ - && !unit_test::is_cstring<Rhs>::value>::type> { \ + unit_test::is_forward_iterable<Lhs>::value \ + && !unit_test::is_cstring_comparable<Lhs>::value \ + && unit_test::is_forward_iterable<Rhs>::value \ + && !unit_test::is_cstring_comparable<Rhs>::value>::type> { \ public: \ typedef assertion_result result_type; \ + typedef unit_test::bt_iterator_traits<Lhs> t_Lhs_iterator_helper; \ + typedef unit_test::bt_iterator_traits<Rhs> t_Rhs_iterator_helper; \ \ typedef name<Lhs, Rhs> OP; \ + \ typedef typename \ - mpl::if_c<is_same<typename decay<Lhs>::type, \ - typename decay<Rhs>::type>::value, \ - typename cctraits<OP>::is_specialized, \ - mpl::false_>::type is_specialized; \ + mpl::if_c< \ + mpl::or_< \ + typename is_c_array<Lhs>::type, \ + typename is_c_array<Rhs>::type \ + >::value, \ + mpl::true_, \ + typename \ + mpl::if_c<is_same<typename decay<Lhs>::type, \ + typename decay<Rhs>::type>::value, \ + typename cctraits<OP>::is_specialized, \ + mpl::false_>::type \ + >::type is_specialized; \ \ - typedef name<typename Lhs::value_type, \ - typename Rhs::value_type> elem_op; \ + typedef name<typename t_Lhs_iterator_helper::value_type, \ + typename t_Rhs_iterator_helper::value_type \ + > elem_op; \ \ static assertion_result \ eval( Lhs const& lhs, Rhs const& rhs) \ |