tuple_comparison.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // tuple_comparison.hpp -----------------------------------------------------
  2. //
  3. // Copyright (C) 2001 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
  4. // Copyright (C) 2001 Gary Powell (gary.powell@sierra.com)
  5. //
  6. // Distributed under the Boost Software License, Version 1.0. (See
  7. // accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // For more information, see http://www.boost.org
  11. //
  12. // (The idea and first impl. of comparison operators was from Doug Gregor)
  13. // -----------------------------------------------------------------
  14. #ifndef BOOST_TUPLE_COMPARISON_HPP
  15. #define BOOST_TUPLE_COMPARISON_HPP
  16. #include <boost/tuple/tuple.hpp>
  17. // -------------------------------------------------------------
  18. // equality and comparison operators
  19. //
  20. // == and != compare tuples elementwise
  21. // <, >, <= and >= use lexicographical ordering
  22. //
  23. // Any operator between tuples of different length fails at compile time
  24. // No dependencies between operators are assumed
  25. // (i.e. !(a<b) does not imply a>=b, a!=b does not imply a==b etc.
  26. // so any weirdnesses of elementary operators are respected).
  27. //
  28. // -------------------------------------------------------------
  29. namespace boost {
  30. namespace tuples {
  31. inline bool operator==(const null_type&, const null_type&) { return true; }
  32. inline bool operator>=(const null_type&, const null_type&) { return true; }
  33. inline bool operator<=(const null_type&, const null_type&) { return true; }
  34. inline bool operator!=(const null_type&, const null_type&) { return false; }
  35. inline bool operator<(const null_type&, const null_type&) { return false; }
  36. inline bool operator>(const null_type&, const null_type&) { return false; }
  37. namespace detail {
  38. // comparison operators check statically the length of its operands and
  39. // delegate the comparing task to the following functions. Hence
  40. // the static check is only made once (should help the compiler).
  41. // These functions assume tuples to be of the same length.
  42. template<class T1, class T2>
  43. inline bool eq(const T1& lhs, const T2& rhs) {
  44. return lhs.get_head() == rhs.get_head() &&
  45. eq(lhs.get_tail(), rhs.get_tail());
  46. }
  47. template<>
  48. inline bool eq<null_type,null_type>(const null_type&, const null_type&) { return true; }
  49. template<class T1, class T2>
  50. inline bool neq(const T1& lhs, const T2& rhs) {
  51. return lhs.get_head() != rhs.get_head() ||
  52. neq(lhs.get_tail(), rhs.get_tail());
  53. }
  54. template<>
  55. inline bool neq<null_type,null_type>(const null_type&, const null_type&) { return false; }
  56. template<class T1, class T2>
  57. inline bool lt(const T1& lhs, const T2& rhs) {
  58. return lhs.get_head() < rhs.get_head() ||
  59. ( !(rhs.get_head() < lhs.get_head()) &&
  60. lt(lhs.get_tail(), rhs.get_tail()));
  61. }
  62. template<>
  63. inline bool lt<null_type,null_type>(const null_type&, const null_type&) { return false; }
  64. template<class T1, class T2>
  65. inline bool gt(const T1& lhs, const T2& rhs) {
  66. return lhs.get_head() > rhs.get_head() ||
  67. ( !(rhs.get_head() > lhs.get_head()) &&
  68. gt(lhs.get_tail(), rhs.get_tail()));
  69. }
  70. template<>
  71. inline bool gt<null_type,null_type>(const null_type&, const null_type&) { return false; }
  72. template<class T1, class T2>
  73. inline bool lte(const T1& lhs, const T2& rhs) {
  74. return lhs.get_head() <= rhs.get_head() &&
  75. ( !(rhs.get_head() <= lhs.get_head()) ||
  76. lte(lhs.get_tail(), rhs.get_tail()));
  77. }
  78. template<>
  79. inline bool lte<null_type,null_type>(const null_type&, const null_type&) { return true; }
  80. template<class T1, class T2>
  81. inline bool gte(const T1& lhs, const T2& rhs) {
  82. return lhs.get_head() >= rhs.get_head() &&
  83. ( !(rhs.get_head() >= lhs.get_head()) ||
  84. gte(lhs.get_tail(), rhs.get_tail()));
  85. }
  86. template<>
  87. inline bool gte<null_type,null_type>(const null_type&, const null_type&) { return true; }
  88. } // end of namespace detail
  89. // equal ----
  90. template<class T1, class T2, class S1, class S2>
  91. inline bool operator==(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
  92. {
  93. // check that tuple lengths are equal
  94. BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
  95. return detail::eq(lhs, rhs);
  96. }
  97. // not equal -----
  98. template<class T1, class T2, class S1, class S2>
  99. inline bool operator!=(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
  100. {
  101. // check that tuple lengths are equal
  102. BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
  103. return detail::neq(lhs, rhs);
  104. }
  105. // <
  106. template<class T1, class T2, class S1, class S2>
  107. inline bool operator<(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
  108. {
  109. // check that tuple lengths are equal
  110. BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
  111. return detail::lt(lhs, rhs);
  112. }
  113. // >
  114. template<class T1, class T2, class S1, class S2>
  115. inline bool operator>(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
  116. {
  117. // check that tuple lengths are equal
  118. BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
  119. return detail::gt(lhs, rhs);
  120. }
  121. // <=
  122. template<class T1, class T2, class S1, class S2>
  123. inline bool operator<=(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
  124. {
  125. // check that tuple lengths are equal
  126. BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
  127. return detail::lte(lhs, rhs);
  128. }
  129. // >=
  130. template<class T1, class T2, class S1, class S2>
  131. inline bool operator>=(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
  132. {
  133. // check that tuple lengths are equal
  134. BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
  135. return detail::gte(lhs, rhs);
  136. }
  137. } // end of namespace tuples
  138. } // end of namespace boost
  139. #endif // BOOST_TUPLE_COMPARISON_HPP