oteststream.hpp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #ifndef BOOST_CONTRACT_TEST_DETAIL_OTESTSTREAM_HPP_
  2. #define BOOST_CONTRACT_TEST_DETAIL_OTESTSTREAM_HPP_
  3. // Copyright (C) 2008-2018 Lorenzo Caminiti
  4. // Distributed under the Boost Software License, Version 1.0 (see accompanying
  5. // file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
  6. // See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html
  7. #include <boost/iostreams/tee.hpp>
  8. #include <boost/iostreams/stream.hpp>
  9. #include <string>
  10. #include <sstream>
  11. #include <iostream>
  12. #include <algorithm>
  13. namespace boost { namespace contract { namespace test { namespace detail {
  14. namespace oteststream_ {
  15. struct oss_base { // Wrap oss data member for proper initialization order.
  16. protected:
  17. std::ostringstream oss_;
  18. };
  19. }
  20. // Print to clog plus build internal string (using ostringstream) for checking.
  21. struct oteststream :
  22. private oteststream_::oss_base,
  23. public boost::iostreams::stream<boost::iostreams::tee_device<std::ostream,
  24. std::ostringstream> >
  25. {
  26. oteststream() :
  27. oteststream_::oss_base(),
  28. boost::iostreams::stream<boost::iostreams::tee_device<
  29. std::ostream, std::ostringstream> >(
  30. boost::iostreams::tee_device<std::ostream, std::ostringstream>(
  31. std::clog, oss_)
  32. )
  33. {}
  34. std::string str() const { return oss_.str(); }
  35. void str(std::string const& s) { oss_.str(s); }
  36. bool eq(std::string const& s) { return eq(str(), s); }
  37. // Also display mismatching characters.
  38. static bool eq(std::string const& r, std::string const& s) {
  39. std::string::size_type i = 0;
  40. for(; i < r.size() && i < s.size(); ++i) if(r[i] != s[i]) break;
  41. if(i < r.size() || i < s.size()) {
  42. std::cout << std::endl;
  43. std::cout <<
  44. "Error: Following strings differ at position " << i <<
  45. ", because '" << r[i] << "' != '" << s[i] << "':" << std::endl
  46. ;
  47. std::cout << std::endl;
  48. std::cout
  49. << r.substr(0, i)
  50. << "(((" << r[i] << ")))"
  51. // Extra () to avoid clashes with MSVC min macro.
  52. << r.substr((std::min)(i + 1, r.size()), r.size())
  53. << std::endl
  54. ;
  55. std::cout << std::endl;
  56. std::cout
  57. << s.substr(0, i)
  58. << "(((" << s[i] << ")))"
  59. // Extra () to avoid clashes with MSVC min macro.
  60. << s.substr((std::min)(i + 1, s.size()), s.size())
  61. << std::endl
  62. ;
  63. std::cout << std::endl;
  64. return false;
  65. }
  66. return true;
  67. }
  68. };
  69. } } } } // namespace
  70. #endif // #include guard