bitwise_manip.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. //! Bitwise comparison manipulator implementation
  9. // ***************************************************************************
  10. #ifndef BOOST_TEST_TOOLS_DETAIL_BITWISE_MANIP_HPP_012705GER
  11. #define BOOST_TEST_TOOLS_DETAIL_BITWISE_MANIP_HPP_012705GER
  12. // Boost Test
  13. #include <boost/test/tools/detail/fwd.hpp>
  14. #include <boost/test/tools/detail/indirections.hpp>
  15. #include <boost/test/tools/assertion_result.hpp>
  16. #include <boost/test/tools/assertion.hpp>
  17. // STL
  18. #include <climits> // for CHAR_BIT
  19. #include <boost/test/detail/suppress_warnings.hpp>
  20. //____________________________________________________________________________//
  21. namespace boost {
  22. namespace test_tools {
  23. // ************************************************************************** //
  24. // ************** bitwise comparison manipulator ************** //
  25. // ************************************************************************** //
  26. //! Bitwise comparison manipulator
  27. //! This is a terminal for the expression
  28. struct bitwise {};
  29. //____________________________________________________________________________//
  30. inline unit_test::lazy_ostream &
  31. operator<<( unit_test::lazy_ostream &o, bitwise ) { return o; }
  32. // needed for the lazy evaluation in lazy_ostream as bitwise is a terminal
  33. inline std::ostream&
  34. operator<<( std::ostream& o, bitwise ) { return o; }
  35. //____________________________________________________________________________//
  36. namespace tt_detail {
  37. /*!@brief Bitwise comparison of two operands
  38. *
  39. * This class constructs an @ref assertion_result that contains precise bit comparison information.
  40. * In particular the location of the mismatches (if any) are printed in the assertion result.
  41. */
  42. template<typename Lhs, typename Rhs, typename E>
  43. inline assertion_result
  44. bitwise_compare(Lhs const& lhs, Rhs const& rhs, E const& expr )
  45. {
  46. assertion_result pr( true );
  47. std::size_t left_bit_size = sizeof(Lhs)*CHAR_BIT;
  48. std::size_t right_bit_size = sizeof(Rhs)*CHAR_BIT;
  49. static Lhs const leftOne( 1 );
  50. static Rhs const rightOne( 1 );
  51. std::size_t total_bits = left_bit_size < right_bit_size ? left_bit_size : right_bit_size;
  52. for( std::size_t counter = 0; counter < total_bits; ++counter ) {
  53. if( (lhs & ( leftOne << counter )) != (rhs & (rightOne << counter)) ) {
  54. if( pr ) {
  55. pr.message() << " [";
  56. expr.report( pr.message().stream() );
  57. pr.message() << "]. Bitwise comparison failed";
  58. pr = false;
  59. }
  60. pr.message() << "\nMismatch at position " << counter;
  61. }
  62. }
  63. if( left_bit_size != right_bit_size ) {
  64. if( pr ) {
  65. pr.message() << " [";
  66. expr.report( pr.message().stream() );
  67. pr.message() << "]. Bitwise comparison failed";
  68. pr = false;
  69. }
  70. pr.message() << "\nOperands bit sizes mismatch: " << left_bit_size << " != " << right_bit_size;
  71. }
  72. return pr;
  73. }
  74. //____________________________________________________________________________//
  75. //! Returns an assertion_result using the bitwise comparison out of an expression
  76. //!
  77. //! This is used as a modifer of the normal operator<< on expressions to use the
  78. //! bitwise comparison.
  79. //!
  80. //! @note Available only for compilers supporting the @c auto declaration.
  81. template<typename T1, typename T2, typename T3, typename T4>
  82. inline assertion_result
  83. operator<<(assertion_evaluate_t<assertion::binary_expr<T1,T2,assertion::op::EQ<T3,T4> > > const& ae, bitwise )
  84. {
  85. return bitwise_compare( ae.m_e.lhs().value(), ae.m_e.rhs(), ae.m_e );
  86. }
  87. //____________________________________________________________________________//
  88. inline assertion_type
  89. operator<<( assertion_type const& , bitwise )
  90. {
  91. return assertion_type(CHECK_BUILT_ASSERTION);
  92. }
  93. //____________________________________________________________________________//
  94. } // namespace tt_detail
  95. } // namespace test_tools
  96. } // namespace boost
  97. #include <boost/test/detail/enable_warnings.hpp>
  98. #endif // BOOST_TEST_TOOLS_DETAIL_BITWISE_MANIP_HPP_012705GER