#ifndef SPROUT_UTILITY_PAIR_HPP #define SPROUT_UTILITY_PAIR_HPP #include #include #include #include #include #include #include #include namespace sprout { // Copyright (C) 2011 RiSK (sscrisk) // // pair // template struct pair { public: typedef T1 first_type; typedef T2 second_type; 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: pair(pair const&) = default; pair(pair&&) = default; SPROUT_CONSTEXPR pair() : first() , second() {} SPROUT_CONSTEXPR pair(T1 const& x, T2 const& y) : first(x) , 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 inline SPROUT_CONSTEXPR 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 inline 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 inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element >::type&& get(sprout::pair&& t) SPROUT_NOEXCEPT { return sprout::move(sprout::tuples::get(t)); } } // namespace tuples using sprout::tuples::get; } // namespace sprout #endif // #ifndef SPROUT_UTILITY_PAIR_HPP