size.hpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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. //!@brief simple dataset size abstraction (can be infinite)
  9. // ***************************************************************************
  10. #ifndef BOOST_TEST_DATA_SIZE_HPP_102211GER
  11. #define BOOST_TEST_DATA_SIZE_HPP_102211GER
  12. // Boost.Test
  13. #include <boost/test/data/config.hpp>
  14. // STL
  15. #include <iosfwd>
  16. #include <boost/test/detail/suppress_warnings.hpp>
  17. //____________________________________________________________________________//
  18. namespace boost {
  19. namespace unit_test {
  20. namespace data {
  21. // ************************************************************************** //
  22. // ************** size_t ************** //
  23. // ************************************************************************** //
  24. //! Utility for handling the size of a datasets
  25. class size_t {
  26. struct dummy { void nonnull() {} };
  27. typedef void (dummy::*safe_bool)();
  28. public:
  29. // Constructors
  30. size_t( std::size_t s = 0 ) : m_value( s ), m_infinity( false ) {}
  31. explicit size_t( bool ) : m_value( 0 ), m_infinity( true ) {}
  32. template<typename T>
  33. size_t( T v ) : m_value( static_cast<std::size_t>(v) ), m_infinity( false ) {}
  34. // Access methods
  35. std::size_t value() const { return m_value; }
  36. bool is_inf() const { return m_infinity; }
  37. operator safe_bool() const { return is_inf() || m_value != 0 ? &dummy::nonnull : 0; }
  38. // Unary operators
  39. data::size_t operator--() { if( !is_inf() ) m_value--; return *this; }
  40. data::size_t operator--(int) { data::size_t res(*this); if( !is_inf() ) m_value--; return res; }
  41. data::size_t operator++() { if( !is_inf() ) m_value++; return *this; }
  42. data::size_t operator++(int) { data::size_t res(*this); if( !is_inf() ) m_value++; return res; }
  43. // Binary operators
  44. data::size_t& operator+=( std::size_t rhs ) { if( !is_inf() ) m_value += rhs; return *this; }
  45. data::size_t& operator+=( data::size_t rhs )
  46. {
  47. if( !is_inf() ) {
  48. if( rhs.is_inf() )
  49. *this = rhs;
  50. else
  51. m_value += rhs.value();
  52. }
  53. return *this;
  54. }
  55. data::size_t& operator-=( std::size_t rhs ) { if( !is_inf() ) m_value -= rhs; return *this; }
  56. data::size_t& operator-=( data::size_t rhs )
  57. {
  58. if( !is_inf() ) {
  59. if( value() < rhs.value() )
  60. m_value = 0;
  61. else
  62. m_value -= rhs.value();
  63. }
  64. return *this;
  65. }
  66. private:
  67. // Data members
  68. std::size_t m_value;
  69. bool m_infinity;
  70. };
  71. namespace { const data::size_t BOOST_TEST_DS_INFINITE_SIZE( true ); }
  72. //____________________________________________________________________________//
  73. // Binary operators
  74. inline bool operator>(data::size_t lhs, std::size_t rhs) { return lhs.is_inf() || (lhs.value() > rhs); }
  75. inline bool operator>(std::size_t lhs, data::size_t rhs) { return !rhs.is_inf() && (lhs > rhs.value()); }
  76. inline bool operator>(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() ? lhs.is_inf() : lhs.value() > rhs.value(); }
  77. inline bool operator>=(data::size_t lhs, std::size_t rhs ) { return lhs.is_inf() || (lhs.value() >= rhs); }
  78. inline bool operator>=(std::size_t lhs, data::size_t rhs) { return !rhs.is_inf() && (lhs >= rhs.value()); }
  79. inline bool operator>=(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() ? lhs.is_inf() : lhs.value() >= rhs.value(); }
  80. inline bool operator<(data::size_t lhs, std::size_t rhs) { return !lhs.is_inf() && (lhs.value() < rhs); }
  81. inline bool operator<(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() || (lhs < rhs.value()); }
  82. inline bool operator<(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() ? rhs.is_inf() : lhs.value() < rhs.value(); }
  83. inline bool operator<=(data::size_t lhs, std::size_t rhs) { return !lhs.is_inf() && (lhs.value() <= rhs); }
  84. inline bool operator<=(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() || (lhs <= rhs.value()); }
  85. inline bool operator<=(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() ? rhs.is_inf() : lhs.value() <= rhs.value(); }
  86. inline bool operator==(data::size_t lhs, std::size_t rhs) { return !lhs.is_inf() && (lhs.value() == rhs); }
  87. inline bool operator==(std::size_t lhs, data::size_t rhs) { return !rhs.is_inf() && (lhs == rhs.value()); }
  88. inline bool operator==(data::size_t lhs, data::size_t rhs) { return !(lhs.is_inf() ^ rhs.is_inf()) && lhs.value() == rhs.value(); }
  89. inline bool operator!=(data::size_t lhs, std::size_t rhs) { return lhs.is_inf() || (lhs.value() != rhs); }
  90. inline bool operator!=(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() || (lhs != rhs.value()); }
  91. inline bool operator!=(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() || lhs.value() != rhs.value(); }
  92. inline data::size_t operator+(data::size_t lhs, std::size_t rhs) { return lhs.is_inf() ? lhs : data::size_t( lhs.value()+rhs ); }
  93. inline data::size_t operator+(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() ? rhs : data::size_t( lhs+rhs.value() ); }
  94. inline data::size_t operator+(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() || rhs.is_inf() ? data::size_t(true) : data::size_t( lhs.value()+rhs.value() ); }
  95. inline data::size_t operator*(data::size_t lhs, std::size_t rhs) { return lhs.is_inf() ? lhs : data::size_t( lhs.value()*rhs ); }
  96. inline data::size_t operator*(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() ? rhs : data::size_t( lhs*rhs.value() ); }
  97. inline data::size_t operator*(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() || rhs.is_inf() ? data::size_t(true) : data::size_t( lhs.value()*rhs.value() ); }
  98. //____________________________________________________________________________//
  99. template<typename CharT1, typename Tr>
  100. inline std::basic_ostream<CharT1,Tr>&
  101. operator<<( std::basic_ostream<CharT1,Tr>& os, data::size_t const& s )
  102. {
  103. if( s.is_inf() )
  104. os << "infinity";
  105. else
  106. os << s.value();
  107. return os;
  108. }
  109. //____________________________________________________________________________//
  110. } // namespace data
  111. } // namespace unit_test
  112. } // namespace boost
  113. #include <boost/test/detail/enable_warnings.hpp>
  114. #endif // BOOST_TEST_DATA_SIZE_HPP_102211GER