Hello I'm trying to use Boost.Test
for my unit tests. However some of my functions return a collection of tuples, in a std::vector< std::tuple< TypeA, TypeB > >
.
To work with BOOST_CHECK_EQUALS
and BOOST_CHECK_EQUAL_COLLECTION
, I specialized boost::test_tools::print_log_value
to print nice tuples and vectors as the answer to this question explains. I also provide operator<<
for tuples, so that my vector can use that while printing the whole vector. For cleanness this operator lies in the blank namespace.
However the compilation fails, as the implementation of boost::test_tools::print_log_value
<std::vector<std::tuple<...>>>
cannot find the operator<<
for tuples.
Here is a minimal code which is, sorry, already quite verbose.
#define BOOST_TEST_MODULE my_test
#include <boost/test/included/unit_test.hpp>
#include <tuple>
#include <vector>
/////////////////
// std::vector //
/////////////////
// boost printing method
namespace boost {
namespace test_tools {
template< typename Type >
struct print_log_value< std::vector< Type > > {
void operator()( std::ostream& s, const std::vector< Type > &collection ) {
const int size = collection.size();
if( size == 0 ) {
s << "[]";
}
else {
s << "[ ";
for( int i =0; i <= size-2; ++i ) {
s << collection[i] << ", ";
}
s << collection[size-1] << " ]";
}
return s;
}
};
} //namespace test_tools
} //namespace boost
////////////////
// std::tuple //
////////////////
// recursive calls for printing
namespace tuple_print_aux{
template< int I, int J, typename... Types >
struct recursive_printer {
static void print( std::ostream& s, const std::tuple<Types...> &collection ) {
s << std::get< I >( collection ) << ", ";
recursive_printer< I+1, J-1, Types... >::print( s, collection );
}
};
template< int I, typename... Types >
struct recursive_printer< I, 1, Types... > {
static void print( std::ostream& s, const std::tuple<Types...> &collection ) {
s << std::get< I >( collection );
}
};
template< typename... Types >
void recursive_print( std::ostream& s, const std::tuple<Types...> &collection ) {
recursive_printer< 0, sizeof...(Types), Types... >::print( s, collection );
}
}
// output stream operator
template< typename... Types >
std::ostream& operator<<( std::ostream& s, const std::tuple<Types...> &collection ) {
s << "( ";
tuple_print_aux::recursive_print< Types... >( s, collection );
s << " )";
return s;
}
// boost printing method
namespace boost {
namespace test_tools {
template< typename... Types >
struct print_log_value< std::tuple< Types... > > {
void operator()( std::ostream& s, const std::tuple<Types...> &collection ) {
s << "( ";
tuple_print_aux::recursive_print< Types... >( s, collection );
s << " )";
}
};
} //namespace test_tools
} //namespace boost
BOOST_AUTO_TEST_CASE(my_test_case) {
//builds successfully
BOOST_CHECK_EQUAL( std::make_tuple(1,"a"), std::make_tuple(1,"a") );
//builds successfully
std::vector< int > v( 2, 3 ), w( 2, 7 );
BOOST_CHECK_EQUAL_COLLECTIONS( v.begin(), v.end(), w.begin(), w.end() );
//fails to build
std::vector< std::tuple<int,int> > a( 1, std::make_tuple(1,3) ), b( 1, std::make_tuple(2,2) );
BOOST_CHECK_EQUAL_COLLECTIONS( a.begin(), a.end(), b.begin(), b.end() );
};
Of course, putting the operator<<
for std::tuple
s into the std
namespace solve the problem, but this is a non-standard non-elegant solution. So... how should I approach the problem. ?
Thank you for any help.
Aucun commentaire:
Enregistrer un commentaire