1
// tuple_comparison.hpp -----------------------------------------------------
3
// Copyright (C) 2001 Jaakko J�rvi (jaakko.jarvi@cs.utu.fi)
4
// Copyright (C) 2001 Gary Powell (gary.powell@sierra.com)
6
// Permission to copy, use, sell and distribute this software is granted
7
// provided this copyright notice appears in all copies.
8
// Permission to modify the code and to distribute modified code is granted
9
// provided this copyright notice appears in all copies, and a notice
10
// that the code was modified is included with the copyright notice.
12
// This software is provided "as is" without express or implied warranty,
13
// and with no claim as to its suitability for any purpose.
15
// For more information, see http://www.boost.org
17
// (The idea and first impl. of comparison operators was from Doug Gregor)
19
// -----------------------------------------------------------------
21
#ifndef BOOST_TUPLE_COMPARISON_HPP
22
#define BOOST_TUPLE_COMPARISON_HPP
24
#include "boost/tuple/tuple.hpp"
26
// -------------------------------------------------------------
27
// equality and comparison operators
29
// == and != compare tuples elementwise
30
// <, >, <= and >= use lexicographical ordering
32
// Any operator between tuples of different length fails at compile time
33
// No dependencies between operators are assumed
34
// (i.e. !(a<b) does not imply a>=b, a!=b does not imply a==b etc.
35
// so any weirdnesses of elementary operators are respected).
37
// -------------------------------------------------------------
43
inline bool operator==(const null_type&, const null_type&) { return true; }
44
inline bool operator>=(const null_type&, const null_type&) { return true; }
45
inline bool operator<=(const null_type&, const null_type&) { return true; }
46
inline bool operator!=(const null_type&, const null_type&) { return false; }
47
inline bool operator<(const null_type&, const null_type&) { return false; }
48
inline bool operator>(const null_type&, const null_type&) { return false; }
52
// comparison operators check statically the length of its operands and
53
// delegate the comparing task to the following functions. Hence
54
// the static check is only made once (should help the compiler).
55
// These functions assume tuples to be of the same length.
58
template<class T1, class T2>
59
inline bool eq(const T1& lhs, const T2& rhs) {
60
return lhs.get_head() == rhs.get_head() &&
61
eq(lhs.get_tail(), rhs.get_tail());
64
inline bool eq<null_type,null_type>(const null_type&, const null_type&) { return true; }
66
template<class T1, class T2>
67
inline bool neq(const T1& lhs, const T2& rhs) {
68
return lhs.get_head() != rhs.get_head() ||
69
neq(lhs.get_tail(), rhs.get_tail());
72
inline bool neq<null_type,null_type>(const null_type&, const null_type&) { return false; }
74
template<class T1, class T2>
75
inline bool lt(const T1& lhs, const T2& rhs) {
76
return lhs.get_head() < rhs.get_head() ||
77
!(rhs.get_head() < lhs.get_head()) &&
78
lt(lhs.get_tail(), rhs.get_tail());
81
inline bool lt<null_type,null_type>(const null_type&, const null_type&) { return false; }
83
template<class T1, class T2>
84
inline bool gt(const T1& lhs, const T2& rhs) {
85
return lhs.get_head() > rhs.get_head() ||
86
!(rhs.get_head() > lhs.get_head()) &&
87
gt(lhs.get_tail(), rhs.get_tail());
90
inline bool gt<null_type,null_type>(const null_type&, const null_type&) { return false; }
92
template<class T1, class T2>
93
inline bool lte(const T1& lhs, const T2& rhs) {
94
return lhs.get_head() <= rhs.get_head() &&
95
( !(rhs.get_head() <= lhs.get_head()) ||
96
lte(lhs.get_tail(), rhs.get_tail()));
99
inline bool lte<null_type,null_type>(const null_type&, const null_type&) { return true; }
101
template<class T1, class T2>
102
inline bool gte(const T1& lhs, const T2& rhs) {
103
return lhs.get_head() >= rhs.get_head() &&
104
( !(rhs.get_head() >= lhs.get_head()) ||
105
gte(lhs.get_tail(), rhs.get_tail()));
108
inline bool gte<null_type,null_type>(const null_type&, const null_type&) { return true; }
110
} // end of namespace detail
115
template<class T1, class T2, class S1, class S2>
116
inline bool operator==(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
118
// check that tuple lengths are equal
119
BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
121
return detail::eq(lhs, rhs);
126
template<class T1, class T2, class S1, class S2>
127
inline bool operator!=(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
130
// check that tuple lengths are equal
131
BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
133
return detail::neq(lhs, rhs);
137
template<class T1, class T2, class S1, class S2>
138
inline bool operator<(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
140
// check that tuple lengths are equal
141
BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
143
return detail::lt(lhs, rhs);
147
template<class T1, class T2, class S1, class S2>
148
inline bool operator>(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
150
// check that tuple lengths are equal
151
BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
153
return detail::gt(lhs, rhs);
157
template<class T1, class T2, class S1, class S2>
158
inline bool operator<=(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
160
// check that tuple lengths are equal
161
BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
163
return detail::lte(lhs, rhs);
167
template<class T1, class T2, class S1, class S2>
168
inline bool operator>=(const cons<T1, T2>& lhs, const cons<S1, S2>& rhs)
170
// check that tuple lengths are equal
171
BOOST_STATIC_ASSERT(length<T2>::value == length<S2>::value);
173
return detail::gte(lhs, rhs);
176
} // end of namespace tuples
177
} // end of namespace boost
180
#endif // BOOST_TUPLE_COMPARISON_HPP