From 4dd6a253545aec3384b8b6ed436085cdaaa8ebd6 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Wed, 1 Nov 2017 09:36:37 +0900 Subject: [PATCH] add utility/comparison.hpp --- sprout/utility.hpp | 1 + sprout/utility/comparison.hpp | 530 +++++++++++++++++++++++++++++ sprout/valarray/gslice_array.hpp | 2 +- sprout/valarray/indirect_array.hpp | 2 +- sprout/valarray/mask_array.hpp | 2 +- sprout/valarray/slice_array.hpp | 2 +- 6 files changed, 535 insertions(+), 4 deletions(-) create mode 100644 sprout/utility/comparison.hpp diff --git a/sprout/utility.hpp b/sprout/utility.hpp index 418342bb..79752496 100644 --- a/sprout/utility.hpp +++ b/sprout/utility.hpp @@ -22,5 +22,6 @@ #include #include #include +#include #endif // #ifndef SPROUT_UTILITY_HPP diff --git a/sprout/utility/comparison.hpp b/sprout/utility/comparison.hpp new file mode 100644 index 00000000..e772c572 --- /dev/null +++ b/sprout/utility/comparison.hpp @@ -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 +#include + +namespace sprout { + // + // comparison_forwarder + // + template + class comparison_forwarder { + public: + typedef Compare compare_type; + private: + sprout::value_holder 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 {}; + // + // operator->* + // + template + inline SPROUT_CONSTEXPR sprout::comparison_forwarder + operator->*(sprout::comparison_forwarder<>, Compare const& comp) { + return sprout::comparison_forwarder(comp); + } + + // + // comp + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::comparison_forwarder<> comp = {}; + } // anonymous-namespace + + // + // comparison_holder + // + template + class comparison_holder { + public: + typedef T value_type; + typedef Compare compare_type; + private: + sprout::value_holder value_; + sprout::value_holder 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 + class comparison_holder { + public: + typedef T value_type; + private: + sprout::value_holder value_; + public: + explicit SPROUT_CONSTEXPR comparison_holder(value_type const& value) + : value_(value) + {} + SPROUT_CONSTEXPR value_type const& get() const { + return value_; + } + }; + + // + // operator% + // + template + inline SPROUT_CONSTEXPR sprout::comparison_holder + operator%(sprout::comparison_forwarder const& lhs, T const& rhs) { + return sprout::comparison_holder(rhs, lhs.comp()); + } + template + inline SPROUT_CONSTEXPR sprout::comparison_holder + operator%(sprout::comparison_forwarder<>, T const& rhs) { + return sprout::comparison_holder(rhs); + } + + // + // comparison_base + // + template + class comparison_base { + public: + typedef T value_type; + typedef Compare compare_type; + private: + sprout::value_holder value_; + sprout::value_holder 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 + class comparison_base { + public: + typedef T value_type; + private: + sprout::value_holder 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 + class less_comparison + : public sprout::comparison_base + { + public: + typedef sprout::comparison_base 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 + class less_comparison + : public sprout::comparison_base + { + public: + typedef sprout::comparison_base 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 + inline SPROUT_CONSTEXPR sprout::less_comparison + operator<(sprout::comparison_forwarder const& lhs, T const& rhs) { + return sprout::less_comparison(rhs, lhs.comp()); + } + template + inline SPROUT_CONSTEXPR sprout::less_comparison + operator<(sprout::comparison_forwarder<>, T const& rhs) { + return sprout::less_comparison(rhs); + } + template + inline SPROUT_CONSTEXPR sprout::less_comparison + operator<=(sprout::comparison_forwarder const& lhs, T const& rhs) { + return sprout::less_comparison(rhs, lhs.comp()); + } + template + inline SPROUT_CONSTEXPR sprout::less_comparison + operator<=(sprout::comparison_forwarder<>, T const& rhs) { + return sprout::less_comparison(rhs); + } + // + // operator< + // + template + inline SPROUT_CONSTEXPR sprout::less_comparison + operator<(sprout::comparison_holder const& lhs, U const& rhs) { + return lhs.comp()(lhs.get(), rhs) ? sprout::less_comparison(rhs, lhs.comp()) + : sprout::less_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::less_comparison + operator<(sprout::comparison_holder const& lhs, U const& rhs) { + return lhs.get() < rhs ? sprout::less_comparison(rhs) + : sprout::less_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::less_comparison + operator<(sprout::less_comparison const& lhs, U const& rhs) { + return lhs.comp()(lhs.get(), rhs) ? sprout::less_comparison(rhs, lhs.comp()) + : sprout::less_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::less_comparison + operator<(sprout::less_comparison const& lhs, U const& rhs) { + return lhs && lhs.get() < rhs ? sprout::less_comparison(rhs) + : sprout::less_comparison() + ; + } + // + // operator<= + // + template + inline SPROUT_CONSTEXPR sprout::less_comparison + operator<=(sprout::comparison_holder const& lhs, U const& rhs) { + return !lhs.comp()(rhs, lhs.get()) ? sprout::less_comparison(rhs, lhs.comp()) + : sprout::less_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::less_comparison + operator<=(sprout::comparison_holder const& lhs, U const& rhs) { + return lhs.get() <= rhs ? sprout::less_comparison(rhs) + : sprout::less_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::less_comparison + operator<=(sprout::less_comparison const& lhs, U const& rhs) { + return !lhs.comp()(rhs, lhs.get()) ? sprout::less_comparison(rhs, lhs.comp()) + : sprout::less_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::less_comparison + operator<=(sprout::less_comparison const& lhs, U const& rhs) { + return lhs && lhs.get() <= rhs ? sprout::less_comparison(rhs) + : sprout::less_comparison() + ; + } + // + // operator> + // operator>= + // operator== + // operator!= + // + template + SPROUT_NON_CONSTEXPR void + operator>(sprout::less_comparison const&, U const&) SPROUT_DELETED_FUNCTION_DECL + template + SPROUT_NON_CONSTEXPR void + operator>=(sprout::less_comparison const&, U const&) SPROUT_DELETED_FUNCTION_DECL + template + SPROUT_NON_CONSTEXPR void + operator==(sprout::less_comparison const&, U const&) SPROUT_DELETED_FUNCTION_DECL + template + SPROUT_NON_CONSTEXPR void + operator!=(sprout::less_comparison const&, U const&) SPROUT_DELETED_FUNCTION_DECL + + // + // greater_comparison + // + template + class greater_comparison + : public sprout::comparison_base + { + public: + typedef sprout::comparison_base 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 + class greater_comparison + : public sprout::comparison_base + { + public: + typedef sprout::comparison_base 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 + inline SPROUT_CONSTEXPR sprout::greater_comparison + operator>(sprout::comparison_forwarder const& lhs, T const& rhs) { + return sprout::greater_comparison(rhs, lhs.comp()); + } + template + inline SPROUT_CONSTEXPR sprout::greater_comparison + operator>(sprout::comparison_forwarder<>, T const& rhs) { + return sprout::greater_comparison(rhs); + } + template + inline SPROUT_CONSTEXPR sprout::greater_comparison + operator>=(sprout::comparison_forwarder const& lhs, T const& rhs) { + return sprout::greater_comparison(rhs, lhs.comp()); + } + template + inline SPROUT_CONSTEXPR sprout::greater_comparison + operator>=(sprout::comparison_forwarder<>, T const& rhs) { + return sprout::greater_comparison(rhs); + } + // + // operator> + // + template + inline SPROUT_CONSTEXPR sprout::greater_comparison + operator>(sprout::comparison_holder const& lhs, U const& rhs) { + return lhs.comp()(rhs, lhs.get()) ? sprout::greater_comparison(rhs, lhs.comp()) + : sprout::greater_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::greater_comparison + operator>(sprout::comparison_holder const& lhs, U const& rhs) { + return rhs < lhs.get() ? sprout::greater_comparison(rhs) + : sprout::greater_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::greater_comparison + operator>(sprout::greater_comparison const& lhs, U const& rhs) { + return lhs.comp()(rhs, lhs.get()) ? sprout::greater_comparison(rhs, lhs.comp()) + : sprout::greater_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::greater_comparison + operator>(sprout::greater_comparison const& lhs, U const& rhs) { + return lhs && rhs < lhs.get() ? sprout::greater_comparison(rhs) + : sprout::greater_comparison() + ; + } + // + // operator>= + // + template + inline SPROUT_CONSTEXPR sprout::greater_comparison + operator>=(sprout::comparison_holder const& lhs, U const& rhs) { + return !lhs.comp()(lhs.get(), rhs) ? sprout::greater_comparison(rhs, lhs.comp()) + : sprout::greater_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::greater_comparison + operator>=(sprout::comparison_holder const& lhs, U const& rhs) { + return !(lhs.get() < rhs) ? sprout::greater_comparison(rhs) + : sprout::greater_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::greater_comparison + operator>=(sprout::greater_comparison const& lhs, U const& rhs) { + return !lhs.comp()(lhs.get(), rhs) ? sprout::greater_comparison(rhs, lhs.comp()) + : sprout::greater_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::greater_comparison + operator>=(sprout::greater_comparison const& lhs, U const& rhs) { + return lhs && !(lhs.get() < rhs) ? sprout::greater_comparison(rhs) + : sprout::greater_comparison() + ; + } + // + // operator< + // operator<= + // operator== + // operator!= + // + template + SPROUT_NON_CONSTEXPR void + operator<(sprout::greater_comparison const&, U const&) SPROUT_DELETED_FUNCTION_DECL + template + SPROUT_NON_CONSTEXPR void + operator<=(sprout::greater_comparison const&, U const&) SPROUT_DELETED_FUNCTION_DECL + template + SPROUT_NON_CONSTEXPR void + operator==(sprout::greater_comparison const&, U const&) SPROUT_DELETED_FUNCTION_DECL + template + SPROUT_NON_CONSTEXPR void + operator!=(sprout::greater_comparison const&, U const&) SPROUT_DELETED_FUNCTION_DECL + + // + // equal_comparison + // + template + class equal_comparison + : public sprout::comparison_base + { + public: + typedef sprout::comparison_base 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 + class equal_comparison + : public sprout::comparison_base + { + public: + typedef sprout::comparison_base 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 + inline SPROUT_CONSTEXPR sprout::equal_comparison + operator==(sprout::comparison_forwarder const& lhs, T const& rhs) { + return sprout::equal_comparison(rhs, lhs.comp()); + } + template + inline SPROUT_CONSTEXPR sprout::equal_comparison + operator==(sprout::comparison_forwarder<>, T const& rhs) { + return sprout::equal_comparison(rhs); + } + // + // operator== + // + template + inline SPROUT_CONSTEXPR sprout::equal_comparison + operator==(sprout::comparison_holder const& lhs, U const& rhs) { + return !lhs.comp()(lhs.get(), rhs) && !lhs.comp()(rhs, lhs.get()) ? sprout::equal_comparison(rhs, lhs.comp()) + : sprout::equal_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::equal_comparison + operator==(sprout::comparison_holder const& lhs, U const& rhs) { + return !(lhs.get() < rhs) && !(rhs < lhs.get()) ? sprout::equal_comparison(rhs) + : sprout::equal_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::equal_comparison + operator==(sprout::equal_comparison const& lhs, U const& rhs) { + return !lhs.comp()(lhs.get(), rhs) && !lhs.comp()(rhs, lhs.get()) ? sprout::equal_comparison(rhs, lhs.comp()) + : sprout::equal_comparison() + ; + } + template + inline SPROUT_CONSTEXPR sprout::equal_comparison + operator==(sprout::equal_comparison const& lhs, U const& rhs) { + return lhs && !(lhs.get() < rhs) && !(rhs < lhs.get()) ? sprout::equal_comparison(rhs) + : sprout::equal_comparison() + ; + } + // + // operator< + // operator<= + // operator> + // operator>= + // operator!= + // + template + SPROUT_NON_CONSTEXPR void + operator<(sprout::equal_comparison const&, U const&) SPROUT_DELETED_FUNCTION_DECL + template + SPROUT_NON_CONSTEXPR void + operator<=(sprout::equal_comparison const&, U const&) SPROUT_DELETED_FUNCTION_DECL + template + SPROUT_NON_CONSTEXPR void + operator>(sprout::equal_comparison const&, U const&) SPROUT_DELETED_FUNCTION_DECL + template + SPROUT_NON_CONSTEXPR void + operator>=(sprout::equal_comparison const&, U const&) SPROUT_DELETED_FUNCTION_DECL + template + SPROUT_NON_CONSTEXPR void + operator!=(sprout::equal_comparison const&, U const&) SPROUT_DELETED_FUNCTION_DECL +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_COMPARISON_HPP diff --git a/sprout/valarray/gslice_array.hpp b/sprout/valarray/gslice_array.hpp index d6504ab8..2b24cd3e 100644 --- a/sprout/valarray/gslice_array.hpp +++ b/sprout/valarray/gslice_array.hpp @@ -81,7 +81,7 @@ namespace sprout { sprout::valarray size_; sprout::valarray stride_; private: - gslice_array() = delete; + gslice_array() SPROUT_DELETED_FUNCTION_DECL SPROUT_CONSTEXPR gslice_array(sprout::valarray& arr, gslice_type const& gslice) : arr_(arr) , start_(gslice.start()) diff --git a/sprout/valarray/indirect_array.hpp b/sprout/valarray/indirect_array.hpp index df739f71..6151bf88 100644 --- a/sprout/valarray/indirect_array.hpp +++ b/sprout/valarray/indirect_array.hpp @@ -42,7 +42,7 @@ namespace sprout { sprout::value_holder arr_; indexes_type indexes_; private: - indirect_array() = delete; + indirect_array() SPROUT_DELETED_FUNCTION_DECL SPROUT_CONSTEXPR indirect_array(sprout::valarray& arr, indexes_type const& indexes) : arr_(arr) , indexes_(indexes) diff --git a/sprout/valarray/mask_array.hpp b/sprout/valarray/mask_array.hpp index 208592c8..90fa8b9f 100644 --- a/sprout/valarray/mask_array.hpp +++ b/sprout/valarray/mask_array.hpp @@ -45,7 +45,7 @@ namespace sprout { sprout::value_holder arr_; indexes_type indexes_; private: - mask_array() = delete; + mask_array() SPROUT_DELETED_FUNCTION_DECL SPROUT_CONSTEXPR mask_array(sprout::valarray& arr, mask_type const& mask) : arr_(arr) , indexes_( diff --git a/sprout/valarray/slice_array.hpp b/sprout/valarray/slice_array.hpp index 4b0bc11d..9cb6d37e 100644 --- a/sprout/valarray/slice_array.hpp +++ b/sprout/valarray/slice_array.hpp @@ -66,7 +66,7 @@ namespace sprout { sprout::value_holder arr_; sprout::slice slice_; private: - slice_array() = delete; + slice_array() SPROUT_DELETED_FUNCTION_DECL SPROUT_CONSTEXPR slice_array(sprout::valarray& arr, sprout::slice const& slice) : arr_(arr), slice_(slice) {}