1
0
Fork 0
mirror of https://github.com/bolero-MURAKAMI/Sprout synced 2024-11-12 21:09:01 +00:00

add utility/comparison.hpp

This commit is contained in:
bolero-MURAKAMI 2017-11-01 09:36:37 +09:00
parent ffe6ec780b
commit 4dd6a25354
6 changed files with 535 additions and 4 deletions

View file

@ -22,5 +22,6 @@
#include <sprout/utility/any_convertible.hpp> #include <sprout/utility/any_convertible.hpp>
#include <sprout/utility/use_default.hpp> #include <sprout/utility/use_default.hpp>
#include <sprout/utility/loop.hpp> #include <sprout/utility/loop.hpp>
#include <sprout/utility/comparison.hpp>
#endif // #ifndef SPROUT_UTILITY_HPP #endif // #ifndef SPROUT_UTILITY_HPP

View file

@ -0,0 +1,530 @@
/*=============================================================================
Copyright (c) 2011-2017 Bolero MURAKAMI
https://github.com/bolero-MURAKAMI/Sprout
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#ifndef SPROUT_UTILITY_COMPARISON_HPP
#define SPROUT_UTILITY_COMPARISON_HPP
#include <sprout/config.hpp>
#include <sprout/utility/value_holder.hpp>
namespace sprout {
//
// comparison_forwarder
//
template<typename Compare = void>
class comparison_forwarder {
public:
typedef Compare compare_type;
private:
sprout::value_holder<compare_type const&> comp_;
public:
explicit SPROUT_CONSTEXPR comparison_forwarder(compare_type const& comp)
: comp_(comp)
{}
SPROUT_CONSTEXPR compare_type const& comp() const {
return comp_;
}
};
template<>
class comparison_forwarder<void> {};
//
// operator->*
//
template<typename Compare>
inline SPROUT_CONSTEXPR sprout::comparison_forwarder<Compare>
operator->*(sprout::comparison_forwarder<>, Compare const& comp) {
return sprout::comparison_forwarder<Compare>(comp);
}
//
// comp
//
namespace {
SPROUT_STATIC_CONSTEXPR sprout::comparison_forwarder<> comp = {};
} // anonymous-namespace
//
// comparison_holder
//
template<typename T, typename Compare = void>
class comparison_holder {
public:
typedef T value_type;
typedef Compare compare_type;
private:
sprout::value_holder<value_type const&> value_;
sprout::value_holder<compare_type const&> comp_;
public:
SPROUT_CONSTEXPR comparison_holder(value_type const& value, compare_type const& comp)
: value_(value), comp_(comp)
{}
SPROUT_CONSTEXPR value_type const& get() const {
return value_;
}
SPROUT_CONSTEXPR compare_type const& comp() const {
return comp_;
}
};
template<typename T>
class comparison_holder<T, void> {
public:
typedef T value_type;
private:
sprout::value_holder<value_type const&> value_;
public:
explicit SPROUT_CONSTEXPR comparison_holder(value_type const& value)
: value_(value)
{}
SPROUT_CONSTEXPR value_type const& get() const {
return value_;
}
};
//
// operator%
//
template<typename T, typename Compare>
inline SPROUT_CONSTEXPR sprout::comparison_holder<T, Compare>
operator%(sprout::comparison_forwarder<Compare> const& lhs, T const& rhs) {
return sprout::comparison_holder<T, Compare>(rhs, lhs.comp());
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::comparison_holder<T>
operator%(sprout::comparison_forwarder<>, T const& rhs) {
return sprout::comparison_holder<T>(rhs);
}
//
// comparison_base
//
template<typename T, typename Compare = void>
class comparison_base {
public:
typedef T value_type;
typedef Compare compare_type;
private:
sprout::value_holder<value_type const&> value_;
sprout::value_holder<compare_type const&> comp_;
bool cond_;
public:
SPROUT_CONSTEXPR comparison_base() SPROUT_DEFAULTED_DEFAULT_CONSTRUCTOR_DECL
comparison_base(comparison_base const&) = default;
SPROUT_CONSTEXPR comparison_base(value_type const& value, compare_type const& comp)
: value_(value), comp_(comp), cond_(true)
{}
SPROUT_CONSTEXPR value_type const& get() const {
return value_;
}
SPROUT_CONSTEXPR compare_type const& comp() const {
return comp_;
}
SPROUT_CONSTEXPR operator bool() const {
return cond_;
}
SPROUT_CONSTEXPR bool operator!() const {
return !cond_;
}
};
template<typename T>
class comparison_base<T, void> {
public:
typedef T value_type;
private:
sprout::value_holder<value_type const&> value_;
bool cond_;
public:
SPROUT_CONSTEXPR comparison_base() SPROUT_DEFAULTED_DEFAULT_CONSTRUCTOR_DECL
comparison_base(comparison_base const&) = default;
explicit SPROUT_CONSTEXPR comparison_base(value_type const& value)
: value_(value), cond_(true)
{}
SPROUT_CONSTEXPR value_type const& get() const {
return value_;
}
SPROUT_CONSTEXPR operator bool() const {
return cond_;
}
SPROUT_CONSTEXPR bool operator!() const {
return !cond_;
}
};
//
// less_comparison
//
template<typename T, typename Compare = void>
class less_comparison
: public sprout::comparison_base<T, Compare>
{
public:
typedef sprout::comparison_base<T, Compare> base_type;
typedef typename base_type::value_type value_type;
typedef typename base_type::compare_type compare_type;
public:
SPROUT_CONSTEXPR less_comparison() SPROUT_DEFAULTED_DEFAULT_CONSTRUCTOR_DECL
less_comparison(less_comparison const&) = default;
SPROUT_CONSTEXPR less_comparison(value_type const& value, compare_type const& comp)
: base_type(value, comp)
{}
};
template<typename T>
class less_comparison<T, void>
: public sprout::comparison_base<T>
{
public:
typedef sprout::comparison_base<T> base_type;
typedef typename base_type::value_type value_type;
public:
SPROUT_CONSTEXPR less_comparison() SPROUT_DEFAULTED_DEFAULT_CONSTRUCTOR_DECL
less_comparison(less_comparison const&) = default;
explicit SPROUT_CONSTEXPR less_comparison(value_type const& value)
: base_type(value)
{}
};
//
// operator<
// operator<=
//
template<typename T, typename Compare>
inline SPROUT_CONSTEXPR sprout::less_comparison<T, Compare>
operator<(sprout::comparison_forwarder<Compare> const& lhs, T const& rhs) {
return sprout::less_comparison<T, Compare>(rhs, lhs.comp());
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::less_comparison<T>
operator<(sprout::comparison_forwarder<>, T const& rhs) {
return sprout::less_comparison<T>(rhs);
}
template<typename T, typename Compare>
inline SPROUT_CONSTEXPR sprout::less_comparison<T, Compare>
operator<=(sprout::comparison_forwarder<Compare> const& lhs, T const& rhs) {
return sprout::less_comparison<T, Compare>(rhs, lhs.comp());
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::less_comparison<T>
operator<=(sprout::comparison_forwarder<>, T const& rhs) {
return sprout::less_comparison<T>(rhs);
}
//
// operator<
//
template<typename T, typename Compare, typename U>
inline SPROUT_CONSTEXPR sprout::less_comparison<U, Compare>
operator<(sprout::comparison_holder<T, Compare> const& lhs, U const& rhs) {
return lhs.comp()(lhs.get(), rhs) ? sprout::less_comparison<U, Compare>(rhs, lhs.comp())
: sprout::less_comparison<U, Compare>()
;
}
template<typename T, typename U>
inline SPROUT_CONSTEXPR sprout::less_comparison<U>
operator<(sprout::comparison_holder<T> const& lhs, U const& rhs) {
return lhs.get() < rhs ? sprout::less_comparison<U>(rhs)
: sprout::less_comparison<U>()
;
}
template<typename T, typename Compare, typename U>
inline SPROUT_CONSTEXPR sprout::less_comparison<U, Compare>
operator<(sprout::less_comparison<T, Compare> const& lhs, U const& rhs) {
return lhs.comp()(lhs.get(), rhs) ? sprout::less_comparison<U, Compare>(rhs, lhs.comp())
: sprout::less_comparison<U, Compare>()
;
}
template<typename T, typename U>
inline SPROUT_CONSTEXPR sprout::less_comparison<U>
operator<(sprout::less_comparison<T> const& lhs, U const& rhs) {
return lhs && lhs.get() < rhs ? sprout::less_comparison<U>(rhs)
: sprout::less_comparison<U>()
;
}
//
// operator<=
//
template<typename T, typename Compare, typename U>
inline SPROUT_CONSTEXPR sprout::less_comparison<U, Compare>
operator<=(sprout::comparison_holder<T, Compare> const& lhs, U const& rhs) {
return !lhs.comp()(rhs, lhs.get()) ? sprout::less_comparison<U, Compare>(rhs, lhs.comp())
: sprout::less_comparison<U, Compare>()
;
}
template<typename T, typename U>
inline SPROUT_CONSTEXPR sprout::less_comparison<U>
operator<=(sprout::comparison_holder<T> const& lhs, U const& rhs) {
return lhs.get() <= rhs ? sprout::less_comparison<U>(rhs)
: sprout::less_comparison<U>()
;
}
template<typename T, typename Compare, typename U>
inline SPROUT_CONSTEXPR sprout::less_comparison<U, Compare>
operator<=(sprout::less_comparison<T, Compare> const& lhs, U const& rhs) {
return !lhs.comp()(rhs, lhs.get()) ? sprout::less_comparison<U, Compare>(rhs, lhs.comp())
: sprout::less_comparison<U, Compare>()
;
}
template<typename T, typename U>
inline SPROUT_CONSTEXPR sprout::less_comparison<U>
operator<=(sprout::less_comparison<T> const& lhs, U const& rhs) {
return lhs && lhs.get() <= rhs ? sprout::less_comparison<U>(rhs)
: sprout::less_comparison<U>()
;
}
//
// operator>
// operator>=
// operator==
// operator!=
//
template<typename T, typename Compare, typename U>
SPROUT_NON_CONSTEXPR void
operator>(sprout::less_comparison<T, Compare> const&, U const&) SPROUT_DELETED_FUNCTION_DECL
template<typename T, typename Compare, typename U>
SPROUT_NON_CONSTEXPR void
operator>=(sprout::less_comparison<T, Compare> const&, U const&) SPROUT_DELETED_FUNCTION_DECL
template<typename T, typename Compare, typename U>
SPROUT_NON_CONSTEXPR void
operator==(sprout::less_comparison<T, Compare> const&, U const&) SPROUT_DELETED_FUNCTION_DECL
template<typename T, typename Compare, typename U>
SPROUT_NON_CONSTEXPR void
operator!=(sprout::less_comparison<T, Compare> const&, U const&) SPROUT_DELETED_FUNCTION_DECL
//
// greater_comparison
//
template<typename T, typename Compare = void>
class greater_comparison
: public sprout::comparison_base<T, Compare>
{
public:
typedef sprout::comparison_base<T, Compare> base_type;
typedef typename base_type::value_type value_type;
typedef typename base_type::compare_type compare_type;
public:
SPROUT_CONSTEXPR greater_comparison() SPROUT_DEFAULTED_DEFAULT_CONSTRUCTOR_DECL
greater_comparison(greater_comparison const&) = default;
SPROUT_CONSTEXPR greater_comparison(value_type const& value, compare_type const& comp)
: base_type(value, comp)
{}
};
template<typename T>
class greater_comparison<T, void>
: public sprout::comparison_base<T>
{
public:
typedef sprout::comparison_base<T> base_type;
typedef typename base_type::value_type value_type;
public:
SPROUT_CONSTEXPR greater_comparison() SPROUT_DEFAULTED_DEFAULT_CONSTRUCTOR_DECL
greater_comparison(greater_comparison const&) = default;
explicit SPROUT_CONSTEXPR greater_comparison(value_type const& value)
: base_type(value)
{}
};
//
// operator>
// operator>=
//
template<typename T, typename Compare>
inline SPROUT_CONSTEXPR sprout::greater_comparison<T, Compare>
operator>(sprout::comparison_forwarder<Compare> const& lhs, T const& rhs) {
return sprout::greater_comparison<T>(rhs, lhs.comp());
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::greater_comparison<T>
operator>(sprout::comparison_forwarder<>, T const& rhs) {
return sprout::greater_comparison<T>(rhs);
}
template<typename T, typename Compare>
inline SPROUT_CONSTEXPR sprout::greater_comparison<T, Compare>
operator>=(sprout::comparison_forwarder<Compare> const& lhs, T const& rhs) {
return sprout::greater_comparison<T>(rhs, lhs.comp());
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::greater_comparison<T>
operator>=(sprout::comparison_forwarder<>, T const& rhs) {
return sprout::greater_comparison<T>(rhs);
}
//
// operator>
//
template<typename T, typename Compare, typename U>
inline SPROUT_CONSTEXPR sprout::greater_comparison<U, Compare>
operator>(sprout::comparison_holder<T, Compare> const& lhs, U const& rhs) {
return lhs.comp()(rhs, lhs.get()) ? sprout::greater_comparison<U, Compare>(rhs, lhs.comp())
: sprout::greater_comparison<U, Compare>()
;
}
template<typename T, typename U>
inline SPROUT_CONSTEXPR sprout::greater_comparison<U>
operator>(sprout::comparison_holder<T> const& lhs, U const& rhs) {
return rhs < lhs.get() ? sprout::greater_comparison<U>(rhs)
: sprout::greater_comparison<U>()
;
}
template<typename T, typename Compare, typename U>
inline SPROUT_CONSTEXPR sprout::greater_comparison<U, Compare>
operator>(sprout::greater_comparison<T, Compare> const& lhs, U const& rhs) {
return lhs.comp()(rhs, lhs.get()) ? sprout::greater_comparison<U, Compare>(rhs, lhs.comp())
: sprout::greater_comparison<U, Compare>()
;
}
template<typename T, typename U>
inline SPROUT_CONSTEXPR sprout::greater_comparison<U>
operator>(sprout::greater_comparison<T> const& lhs, U const& rhs) {
return lhs && rhs < lhs.get() ? sprout::greater_comparison<U>(rhs)
: sprout::greater_comparison<U>()
;
}
//
// operator>=
//
template<typename T, typename Compare, typename U>
inline SPROUT_CONSTEXPR sprout::greater_comparison<U, Compare>
operator>=(sprout::comparison_holder<T, Compare> const& lhs, U const& rhs) {
return !lhs.comp()(lhs.get(), rhs) ? sprout::greater_comparison<U, Compare>(rhs, lhs.comp())
: sprout::greater_comparison<U, Compare>()
;
}
template<typename T, typename U>
inline SPROUT_CONSTEXPR sprout::greater_comparison<U>
operator>=(sprout::comparison_holder<T> const& lhs, U const& rhs) {
return !(lhs.get() < rhs) ? sprout::greater_comparison<U>(rhs)
: sprout::greater_comparison<U>()
;
}
template<typename T, typename Compare, typename U>
inline SPROUT_CONSTEXPR sprout::greater_comparison<U, Compare>
operator>=(sprout::greater_comparison<T, Compare> const& lhs, U const& rhs) {
return !lhs.comp()(lhs.get(), rhs) ? sprout::greater_comparison<U, Compare>(rhs, lhs.comp())
: sprout::greater_comparison<U, Compare>()
;
}
template<typename T, typename U>
inline SPROUT_CONSTEXPR sprout::greater_comparison<U>
operator>=(sprout::greater_comparison<T> const& lhs, U const& rhs) {
return lhs && !(lhs.get() < rhs) ? sprout::greater_comparison<U>(rhs)
: sprout::greater_comparison<U>()
;
}
//
// operator<
// operator<=
// operator==
// operator!=
//
template<typename T, typename Compare, typename U>
SPROUT_NON_CONSTEXPR void
operator<(sprout::greater_comparison<T, Compare> const&, U const&) SPROUT_DELETED_FUNCTION_DECL
template<typename T, typename Compare, typename U>
SPROUT_NON_CONSTEXPR void
operator<=(sprout::greater_comparison<T, Compare> const&, U const&) SPROUT_DELETED_FUNCTION_DECL
template<typename T, typename Compare, typename U>
SPROUT_NON_CONSTEXPR void
operator==(sprout::greater_comparison<T, Compare> const&, U const&) SPROUT_DELETED_FUNCTION_DECL
template<typename T, typename Compare, typename U>
SPROUT_NON_CONSTEXPR void
operator!=(sprout::greater_comparison<T, Compare> const&, U const&) SPROUT_DELETED_FUNCTION_DECL
//
// equal_comparison
//
template<typename T, typename Compare = void>
class equal_comparison
: public sprout::comparison_base<T, Compare>
{
public:
typedef sprout::comparison_base<T, Compare> base_type;
typedef typename base_type::value_type value_type;
typedef typename base_type::compare_type compare_type;
public:
SPROUT_CONSTEXPR equal_comparison() SPROUT_DEFAULTED_DEFAULT_CONSTRUCTOR_DECL
equal_comparison(equal_comparison const&) = default;
SPROUT_CONSTEXPR equal_comparison(value_type const& value, compare_type const& comp)
: base_type(value, comp)
{}
};
template<typename T>
class equal_comparison<T, void>
: public sprout::comparison_base<T>
{
public:
typedef sprout::comparison_base<T> base_type;
typedef typename base_type::value_type value_type;
public:
SPROUT_CONSTEXPR equal_comparison() SPROUT_DEFAULTED_DEFAULT_CONSTRUCTOR_DECL
equal_comparison(equal_comparison const&) = default;
explicit SPROUT_CONSTEXPR equal_comparison(value_type const& value)
: base_type(value)
{}
};
//
// operator==
//
template<typename T, typename Compare>
inline SPROUT_CONSTEXPR sprout::equal_comparison<T, Compare>
operator==(sprout::comparison_forwarder<Compare> const& lhs, T const& rhs) {
return sprout::equal_comparison<T>(rhs, lhs.comp());
}
template<typename T>
inline SPROUT_CONSTEXPR sprout::equal_comparison<T>
operator==(sprout::comparison_forwarder<>, T const& rhs) {
return sprout::equal_comparison<T>(rhs);
}
//
// operator==
//
template<typename T, typename Compare, typename U>
inline SPROUT_CONSTEXPR sprout::equal_comparison<U, Compare>
operator==(sprout::comparison_holder<T, Compare> const& lhs, U const& rhs) {
return !lhs.comp()(lhs.get(), rhs) && !lhs.comp()(rhs, lhs.get()) ? sprout::equal_comparison<U, Compare>(rhs, lhs.comp())
: sprout::equal_comparison<U, Compare>()
;
}
template<typename T, typename U>
inline SPROUT_CONSTEXPR sprout::equal_comparison<U>
operator==(sprout::comparison_holder<T> const& lhs, U const& rhs) {
return !(lhs.get() < rhs) && !(rhs < lhs.get()) ? sprout::equal_comparison<U>(rhs)
: sprout::equal_comparison<U>()
;
}
template<typename T, typename Compare, typename U>
inline SPROUT_CONSTEXPR sprout::equal_comparison<U, Compare>
operator==(sprout::equal_comparison<T, Compare> const& lhs, U const& rhs) {
return !lhs.comp()(lhs.get(), rhs) && !lhs.comp()(rhs, lhs.get()) ? sprout::equal_comparison<U, Compare>(rhs, lhs.comp())
: sprout::equal_comparison<U, Compare>()
;
}
template<typename T, typename U>
inline SPROUT_CONSTEXPR sprout::equal_comparison<U>
operator==(sprout::equal_comparison<T> const& lhs, U const& rhs) {
return lhs && !(lhs.get() < rhs) && !(rhs < lhs.get()) ? sprout::equal_comparison<U>(rhs)
: sprout::equal_comparison<U>()
;
}
//
// operator<
// operator<=
// operator>
// operator>=
// operator!=
//
template<typename T, typename Compare, typename U>
SPROUT_NON_CONSTEXPR void
operator<(sprout::equal_comparison<T, Compare> const&, U const&) SPROUT_DELETED_FUNCTION_DECL
template<typename T, typename Compare, typename U>
SPROUT_NON_CONSTEXPR void
operator<=(sprout::equal_comparison<T, Compare> const&, U const&) SPROUT_DELETED_FUNCTION_DECL
template<typename T, typename Compare, typename U>
SPROUT_NON_CONSTEXPR void
operator>(sprout::equal_comparison<T, Compare> const&, U const&) SPROUT_DELETED_FUNCTION_DECL
template<typename T, typename Compare, typename U>
SPROUT_NON_CONSTEXPR void
operator>=(sprout::equal_comparison<T, Compare> const&, U const&) SPROUT_DELETED_FUNCTION_DECL
template<typename T, typename Compare, typename U>
SPROUT_NON_CONSTEXPR void
operator!=(sprout::equal_comparison<T, Compare> const&, U const&) SPROUT_DELETED_FUNCTION_DECL
} // namespace sprout
#endif // #ifndef SPROUT_UTILITY_COMPARISON_HPP

View file

@ -81,7 +81,7 @@ namespace sprout {
sprout::valarray<std::size_t, M> size_; sprout::valarray<std::size_t, M> size_;
sprout::valarray<std::size_t, M> stride_; sprout::valarray<std::size_t, M> stride_;
private: private:
gslice_array() = delete; gslice_array() SPROUT_DELETED_FUNCTION_DECL
SPROUT_CONSTEXPR gslice_array(sprout::valarray<T, N>& arr, gslice_type const& gslice) SPROUT_CONSTEXPR gslice_array(sprout::valarray<T, N>& arr, gslice_type const& gslice)
: arr_(arr) : arr_(arr)
, start_(gslice.start()) , start_(gslice.start())

View file

@ -42,7 +42,7 @@ namespace sprout {
sprout::value_holder<valarray_type&> arr_; sprout::value_holder<valarray_type&> arr_;
indexes_type indexes_; indexes_type indexes_;
private: private:
indirect_array() = delete; indirect_array() SPROUT_DELETED_FUNCTION_DECL
SPROUT_CONSTEXPR indirect_array(sprout::valarray<T, N>& arr, indexes_type const& indexes) SPROUT_CONSTEXPR indirect_array(sprout::valarray<T, N>& arr, indexes_type const& indexes)
: arr_(arr) : arr_(arr)
, indexes_(indexes) , indexes_(indexes)

View file

@ -45,7 +45,7 @@ namespace sprout {
sprout::value_holder<valarray_type&> arr_; sprout::value_holder<valarray_type&> arr_;
indexes_type indexes_; indexes_type indexes_;
private: private:
mask_array() = delete; mask_array() SPROUT_DELETED_FUNCTION_DECL
SPROUT_CONSTEXPR mask_array(sprout::valarray<T, N>& arr, mask_type const& mask) SPROUT_CONSTEXPR mask_array(sprout::valarray<T, N>& arr, mask_type const& mask)
: arr_(arr) : arr_(arr)
, indexes_( , indexes_(

View file

@ -66,7 +66,7 @@ namespace sprout {
sprout::value_holder<valarray_type&> arr_; sprout::value_holder<valarray_type&> arr_;
sprout::slice slice_; sprout::slice slice_;
private: private:
slice_array() = delete; slice_array() SPROUT_DELETED_FUNCTION_DECL
SPROUT_CONSTEXPR slice_array(sprout::valarray<T, N>& arr, sprout::slice const& slice) SPROUT_CONSTEXPR slice_array(sprout::valarray<T, N>& arr, sprout::slice const& slice)
: arr_(arr), slice_(slice) : arr_(arr), slice_(slice)
{} {}