From 2fa0ad1fe4a6bff85f5a56de6b1dee07fed01c4b Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Thu, 12 Apr 2012 23:41:06 +0900 Subject: [PATCH] add make_pair, rel_ops, and others... --- sprout/auto_config.hpp | 4 + sprout/config.hpp | 6 + sprout/functional/ref.hpp | 26 +++++ sprout/utility.hpp | 1 + sprout/utility/pair.hpp | 227 ++++++++++++++++++++++++++++++++++++- sprout/utility/rel_ops.hpp | 30 +++++ 6 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 sprout/utility/rel_ops.hpp diff --git a/sprout/auto_config.hpp b/sprout/auto_config.hpp index 268962ee..90e95165 100644 --- a/sprout/auto_config.hpp +++ b/sprout/auto_config.hpp @@ -43,6 +43,10 @@ // SPROUT_USE_USER_DEFINED_LITERALS // +// +// SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS +// + // // SPROUT_CONFIG_USE_SSCRISK_CEL // diff --git a/sprout/config.hpp b/sprout/config.hpp index 85ad4ed2..8856a75e 100644 --- a/sprout/config.hpp +++ b/sprout/config.hpp @@ -31,6 +31,12 @@ # define SPROUT_USE_USER_DEFINED_LITERALS 0 #endif // #ifndef SPROUT_CONFIG_DISABLE_USER_DEFINED_LITERALS +#ifndef SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS +# define SPROUT_USE_DELEGATING_CONSTRUCTORS 1 +#else // #ifndef SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS +# define SPROUT_USE_DELEGATING_CONSTRUCTORS 0 +#endif // #ifndef SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS + #ifndef SPROUT_CONFIG_USE_SSCRISK_CEL # define HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT # define HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT diff --git a/sprout/functional/ref.hpp b/sprout/functional/ref.hpp index 8937fcfd..ba051d03 100644 --- a/sprout/functional/ref.hpp +++ b/sprout/functional/ref.hpp @@ -238,6 +238,32 @@ namespace sprout { : public sprout::unwrap_reference {}; + // + // strip_reference + // + template + struct strip_reference { + public: + typedef T type; + }; + template + struct strip_reference > { + public: + typedef T& type; + }; + template + struct strip_reference + : public sprout::strip_reference + {}; + template + struct strip_reference + : public sprout::strip_reference + {}; + template + struct strip_reference + : public sprout::strip_reference + {}; + // // unwrap_ref // diff --git a/sprout/utility.hpp b/sprout/utility.hpp index f0f83a14..ec762fd6 100644 --- a/sprout/utility.hpp +++ b/sprout/utility.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include diff --git a/sprout/utility/pair.hpp b/sprout/utility/pair.hpp index aea4f4fb..2e1ccbf4 100644 --- a/sprout/utility/pair.hpp +++ b/sprout/utility/pair.hpp @@ -1,7 +1,13 @@ #ifndef SPROUT_UTILITY_PAIR_HPP #define SPROUT_UTILITY_PAIR_HPP +#include +#include #include +#include +#include +#include +#include namespace sprout { // Copyright (C) 2011 RiSK (sscrisk) @@ -17,8 +23,20 @@ namespace sprout { public: T1 first; T2 second; + private: + template + SPROUT_CONSTEXPR pair( + sprout::tuples::tuple first_args, + sprout::tuples::tuple second_args, + sprout::index_tuple, + sprout::index_tuple + ) + : first(sprout::tuples::get(first_args)...) + , second(sprout::tuples::get(second_args)...) + {} public: - SPROUT_CONSTEXPR pair(pair const&) = default; + pair(pair const&) = default; + pair(pair&&) = default; SPROUT_CONSTEXPR pair() : first() , second() @@ -28,11 +46,218 @@ namespace sprout { , second(y) {} template + SPROUT_CONSTEXPR pair(U&& x, V&& y) + : first(sprout::forward(x)) + , second(sprout::forward(y)) + {} + template SPROUT_CONSTEXPR pair(sprout::pair const& p) : first(p.first) , second(p.second) {} + template + SPROUT_CONSTEXPR pair(sprout::pair&& p) + : first(sprout::forward(p.first)) + , second(sprout::forward(p.second)) + {} +#if SPROUT_USE_DELEGATING_CONSTRUCTORS + template + SPROUT_CONSTEXPR pair( + sprout::tuples::tuple first_args, + sprout::tuples::tuple second_args + ) + : pair( + first_args, + second_args, + sprout::index_range<0, sizeof...(Args1)>::make(), + sprout::index_range<0, sizeof...(Args2)>::make() + ) + {} +#else // #if SPROUT_USE_DELEGATING_CONSTRUCTORS + template + SPROUT_CONSTEXPR pair( + sprout::tuples::tuple first_args, + sprout::tuples::tuple second_args + ); +#endif // #if SPROUT_USE_DELEGATING_CONSTRUCTORS + pair& operator=(pair const& p) = default; + template + pair& operator=(sprout::pair const& p) { + first = p.first; + second = p.second; + return *this; + } + pair& operator=(pair&& p) SPROUT_NOEXCEPT_EXPR( + std::is_nothrow_move_assignable::value && std::is_nothrow_move_assignable::value + ) + { + first = sprout::forward(p.first); + second = std::forward(p.second); + return *this; + } + template + pair& operator=(sprout::pair&& p) { + first = std::forward(p.first); + second = std::forward(p.second); + return *this; + } + void swap(pair& p) SPROUT_NOEXCEPT_EXPR( + SPROUT_NOEXCEPT_EXPR(swap(first, p.first)) && SPROUT_NOEXCEPT_EXPR(swap(second, p.second)) + ) + { + using std::swap; + swap(first, p.first); + swap(second, p.second); + } }; + + template + inline SPROUT_CONSTEXPR bool operator==(sprout::pair const& x, sprout::pair const& y) { + return x.first == y.first && x.second == y.second; + } + template + inline SPROUT_CONSTEXPR bool operator!=(sprout::pair const& x, sprout::pair const& y) { + return !(x == y); + } + template + inline SPROUT_CONSTEXPR bool operator<(sprout::pair const& x, sprout::pair const& y) { + return x.first < y.first + || (!(y.first < x.first) && x.second < y.second) + ; + } + template + inline SPROUT_CONSTEXPR bool operator>(sprout::pair const& x, sprout::pair const& y) { + return y < x; + } + template + inline SPROUT_CONSTEXPR bool operator<=(sprout::pair const& x, sprout::pair const& y) { + return !(y < x); + } + template + inline SPROUT_CONSTEXPR bool operator>=(sprout::pair const& x, sprout::pair const& y) { + return !(x < y); + } + + // + // swap + // + template + inline void swap(pair& x, pair& y) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(x.swap(y))) { + x.swap(y); + } + + // + // make_pair + // + template + SPROUT_CONSTEXPR sprout::pair< + typename sprout::strip_reference::type>::type, + typename sprout::strip_reference::type>::type + > + make_pair(T1&& x, T2&& y) { + return sprout::pair< + typename sprout::strip_reference::type>::type, + typename sprout::strip_reference::type>::type + >( + sprout::forward(x), + sprout::forward(y) + ); + } +} // namespace sprout + +namespace sprout { + namespace tuples { + namespace detail { + template + struct tuple_element_impl; + template + struct tuple_element_impl<0, sprout::pair > { + public: + typedef T1 type; + }; + template + struct tuple_element_impl<1, sprout::pair > { + public: + typedef T2 type; + }; + } // namespace detail + } // namespace tuples +} // namespace sprout + +namespace std { + // + // tuple_size + // + template + struct tuple_size > + : public std::integral_constant + {}; + + // + // tuple_element + // + template + struct tuple_element > + : public sprout::tuples::detail::tuple_element_impl > + {}; +} // namespace std + +namespace sprout { + namespace tuples { + // + // get + // + namespace detail { + template + struct get_impl; + template + struct get_impl<0, sprout::pair > { + public: + T1& operator()(sprout::pair& t) const { + return t.first; + } + T1 const& operator()(sprout::pair const& t) const { + return t.first; + } + }; + template + struct get_impl<1, sprout::pair > { + public: + public: + T2& operator()(sprout::pair& t) const { + return t.second; + } + T2 const& operator()(sprout::pair const& t) const { + return t.second; + } + }; + } // namespace detail + template + typename sprout::tuples::tuple_element >::type& get( + sprout::pair& t + ) SPROUT_NOEXCEPT + { + static_assert(I < 2, "get: index out of range"); + return sprout::tuples::detail::get_impl >()(t); + } + template + SPROUT_CONSTEXPR typename sprout::tuples::tuple_element >::type const& get( + sprout::pair const& t + ) SPROUT_NOEXCEPT + { + static_assert(I < 2, "get: index out of range"); + return sprout::tuples::detail::get_impl >()(t); + } + template + typename sprout::tuples::tuple_element >::type&& get( + sprout::pair&& t + ) SPROUT_NOEXCEPT + { + return std::move(sprout::tuples::get(t)); + } + } // namespace tuples + + using sprout::tuples::get; } // namespace sprout #endif // #ifndef SPROUT_UTILITY_PAIR_HPP diff --git a/sprout/utility/rel_ops.hpp b/sprout/utility/rel_ops.hpp new file mode 100644 index 00000000..2c9d0873 --- /dev/null +++ b/sprout/utility/rel_ops.hpp @@ -0,0 +1,30 @@ +#ifndef SPROUT_UTILITY_REL_OPS_HPP +#define SPROUT_UTILITY_REL_OPS_HPP + +#include + +namespace sprout { + namespace rel_ops { + template + inline SPROUT_CONSTEXPR bool operator!=(T const& x, T const& y) { + return !(x == y); + } + + template + inline SPROUT_CONSTEXPR bool operator>(T const& x, T const& y) { + return y < x; + } + + template + inline SPROUT_CONSTEXPR bool operator<=(T const& x, T const& y) { + return !(y < x); + } + + template + inline SPROUT_CONSTEXPR bool operator>=(T const& x, T const& y) { + return !(x < y); + } + } // namespace rel_ops +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_REL_OPS_HPP