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