Sprout/sprout/tuple/tuple_comparison.hpp
2011-10-30 23:10:24 +09:00

115 lines
3.4 KiB
C++

#ifndef SPROUT_TUPLE_TUPLE_COMPARISON_HPP
#define SPROUT_TUPLE_TUPLE_COMPARISON_HPP
#include <cstddef>
#include <sprout/config.hpp>
#include <sprout/tuple/tuple.hpp>
namespace sprout {
namespace tuples {
//
// operator==
// operator<
// operator!=
// operator>
// operator>=
// operator<=
//
namespace detail {
template<std::size_t CheckEqualSize, std::size_t I, std::size_t J, typename T, typename U>
struct tuple_compare;
template<std::size_t I, typename T, typename U>
struct tuple_compare<0, I, I, T, U> {
public:
static SPROUT_CONSTEXPR bool eq(T const&, U const&) {
return true;
}
static SPROUT_CONSTEXPR bool less(T const&, U const&) {
return false;
}
};
template<std::size_t I, std::size_t J, typename T, typename U>
struct tuple_compare<0, I, J, T, U> {
public:
static SPROUT_CONSTEXPR bool eq(T const& t, U const& u) {
return (sprout::tuples::get<I>(t) == sprout::tuples::get<I>(u)
&& sprout::tuples::detail::tuple_compare<0, I + 1, J, T, U>::eq(t, u))
;
}
static SPROUT_CONSTEXPR bool less(T const& t, U const& u) {
return (sprout::tuples::get<I>(t) < sprout::tuples::get<I>(u))
|| (!(sprout::tuples::get<I>(u) < sprout::tuples::get<I>(t))
&& sprout::tuples::detail::tuple_compare<0, I + 1, J, T, U>::less(t, u)
)
;
}
};
} // namespace detail
template<typename... TTypes, typename... UTypes>
bool SPROUT_CONSTEXPR inline operator==(
sprout::tuples::tuple<TTypes...> const& lhs,
sprout::tuples::tuple<UTypes...> const& rhs
)
{
typedef sprout::tuples::tuple<TTypes...> T;
typedef sprout::tuples::tuple<UTypes...> U;
return sprout::tuples::detail::tuple_compare<
sprout::tuples::tuple_size<T>::value - sprout::tuples::tuple_size<U>::value,
0,
sprout::tuples::tuple_size<T>::value,
T,
U
>::eq(lhs, rhs);
}
template<typename... TTypes, typename... UTypes>
bool SPROUT_CONSTEXPR inline operator<(
sprout::tuples::tuple<TTypes...> const& lhs,
sprout::tuples::tuple<UTypes...> const& rhs
)
{
typedef sprout::tuples::tuple<TTypes...> T;
typedef sprout::tuples::tuple<UTypes...> U;
return sprout::tuples::detail::tuple_compare<
sprout::tuples::tuple_size<T>::value - sprout::tuples::tuple_size<U>::value,
0,
sprout::tuples::tuple_size<T>::value,
T,
U
>::less(lhs, rhs);
}
template<typename... TTypes, typename... UTypes>
bool SPROUT_CONSTEXPR inline operator!=(
sprout::tuples::tuple<TTypes...> const& lhs,
sprout::tuples::tuple<UTypes...> const& rhs
)
{
return !(lhs == rhs);
}
template<typename... TTypes, typename... UTypes>
bool SPROUT_CONSTEXPR inline operator>(
sprout::tuples::tuple<TTypes...> const& lhs,
sprout::tuples::tuple<UTypes...> const& rhs
)
{
return rhs < lhs;
}
template<typename... TTypes, typename... UTypes>
bool SPROUT_CONSTEXPR inline operator<=(
sprout::tuples::tuple<TTypes...> const& lhs,
sprout::tuples::tuple<UTypes...> const& rhs
)
{
return !(rhs < lhs);
}
template<typename... TTypes, typename... UTypes>
bool SPROUT_CONSTEXPR inline operator>=(
sprout::tuples::tuple<TTypes...> const& lhs,
sprout::tuples::tuple<UTypes...> const& rhs
)
{
return !(lhs < rhs);
}
} // namespace tuples
} // namespace sprout
#endif // #ifndef SPROUT_TUPLE_TUPLE_COMPARISON_HPP