size.hpp 6.6 KB

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