From f905d1f02a04c3867e416253d2e1efb7cd4c2d09 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Wed, 27 Mar 2013 17:55:14 +0900 Subject: [PATCH] add tuple construction (from pair) --- sprout/tuple/tuple.hpp | 1 + sprout/tuple/tuple/tuple.hpp | 475 ++++++++---------------------- sprout/tuple/tuple/tuple_decl.hpp | 382 ++++++++++++++++++++++++ sprout/tuple/tuple/tuple_fwd.hpp | 3 + sprout/utility/pack.hpp | 5 +- sprout/utility/pair.hpp | 2 + sprout/utility/pair/pair.hpp | 182 ++++++------ sprout/utility/pair/pair_decl.hpp | 68 +++++ sprout/utility/pair/pair_fwd.hpp | 14 + 9 files changed, 685 insertions(+), 447 deletions(-) create mode 100644 sprout/tuple/tuple/tuple_decl.hpp create mode 100644 sprout/utility/pair/pair_decl.hpp create mode 100644 sprout/utility/pair/pair_fwd.hpp diff --git a/sprout/tuple/tuple.hpp b/sprout/tuple/tuple.hpp index e59f8fa2..448fb9f2 100644 --- a/sprout/tuple/tuple.hpp +++ b/sprout/tuple/tuple.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include diff --git a/sprout/tuple/tuple/tuple.hpp b/sprout/tuple/tuple/tuple.hpp index ddc90233..bafddac3 100644 --- a/sprout/tuple/tuple/tuple.hpp +++ b/sprout/tuple/tuple/tuple.hpp @@ -1,328 +1,149 @@ #ifndef SPROUT_TUPLE_TUPLE_TUPLE_HPP #define SPROUT_TUPLE_TUPLE_TUPLE_HPP -#include #include #include -#include #include #include #include #include +#include #include #include -#include +#include #include namespace sprout { namespace tuples { - namespace detail { - template - class head_base; - // EBO disabled -// template -// class head_base -// : public Head -// { -// public: -// static SPROUT_CONSTEXPR Head& head(head_base& t) SPROUT_NOEXCEPT { -// return t; -// } -// static SPROUT_CONSTEXPR Head const& head(head_base const& t) SPROUT_NOEXCEPT { -// return t; -// } -// public: -// SPROUT_CONSTEXPR head_base() -// : Head() -// {} -// SPROUT_CONSTEXPR head_base(Head const& v) -// : Head(v) -// {} -// template -// SPROUT_CONSTEXPR head_base(UHead&& v) -// : Head(sprout::forward(v)) -// {} -// }; - template - class head_base { - public: - static SPROUT_CONSTEXPR Head& head(head_base& t) SPROUT_NOEXCEPT { - return t.head_; - } - static SPROUT_CONSTEXPR Head const& head(head_base const& t) SPROUT_NOEXCEPT { - return t.head_; - } - private: - Head head_; - public: - SPROUT_CONSTEXPR head_base() - : head_() - {} - SPROUT_CONSTEXPR head_base(Head const& v) - : head_(v) - {} - template - SPROUT_CONSTEXPR head_base(UHead&& v) - : head_(sprout::forward(v)) - {} - }; - template - class head_base { - public: - static SPROUT_CONSTEXPR Head& head(head_base& t) SPROUT_NOEXCEPT { - return t.head_; - } - static SPROUT_CONSTEXPR Head const& head(head_base const& t) SPROUT_NOEXCEPT { - return t.head_; - } - private: - Head head_; - public: - SPROUT_CONSTEXPR head_base() - : head_() - {} - SPROUT_CONSTEXPR head_base(Head const& v) - : head_(v) - {} - template - SPROUT_CONSTEXPR head_base(UHead&& v) - : head_(sprout::forward(v)) - {} - }; - - template - class tuple_impl; - template - class tuple_impl { - public: - template - friend class tuple; - template - friend class sprout::tuples::detail::tuple_impl; - protected: - void swap(tuple_impl&) SPROUT_NOEXCEPT {} - public: - tuple_impl() = default; - template - explicit SPROUT_CONSTEXPR tuple_impl(UTypes&&... args) SPROUT_NOEXCEPT {} - SPROUT_CONSTEXPR tuple_impl(tuple_impl const&) = default; - SPROUT_CONSTEXPR tuple_impl(tuple_impl&&) = default; - template - SPROUT_CONSTEXPR tuple_impl(tuple_impl const& t) SPROUT_NOEXCEPT {} - template - SPROUT_CONSTEXPR tuple_impl(tuple_impl&& t) SPROUT_NOEXCEPT {} - tuple_impl& operator=(tuple_impl const&) = default; - tuple_impl& operator=(tuple_impl&& t) = default; - template - tuple_impl& operator=(sprout::tuples::detail::tuple_impl const&) SPROUT_NOEXCEPT { - return *this; - } - template - tuple_impl& operator=(sprout::tuples::detail::tuple_impl&&) SPROUT_NOEXCEPT { - return *this; - } - }; - template - class tuple_impl - : public sprout::tuples::detail::tuple_impl - , private sprout::tuples::detail::head_base::value> - { - public: - template - friend class tuple; - template - friend class sprout::tuples::detail::tuple_impl; - public: - typedef sprout::tuples::detail::tuple_impl inherited_type; - typedef sprout::tuples::detail::head_base::value> base_type; - public: - static SPROUT_CONSTEXPR Head& head(tuple_impl& t) SPROUT_NOEXCEPT { - return base_type::head(t); - } - static SPROUT_CONSTEXPR Head const& head(tuple_impl const& t) SPROUT_NOEXCEPT { - return base_type::head(t); - } - static SPROUT_CONSTEXPR inherited_type& tail(tuple_impl& t) SPROUT_NOEXCEPT { - return t; - } - static SPROUT_CONSTEXPR inherited_type const& tail(tuple_impl const& t) SPROUT_NOEXCEPT { - return t; - } - public: - void swap(tuple_impl& t) - SPROUT_NOEXCEPT_EXPR( - SPROUT_NOEXCEPT_EXPR(sprout::swap(head(std::declval()), head(t))) - && SPROUT_NOEXCEPT_EXPR(std::declval().swap(tail(t))) - ) - { - sprout::swap(head(*this), head(t)); - inherited_type::swap(tail(t)); - } - public: - SPROUT_CONSTEXPR tuple_impl() - : inherited_type() - , base_type() - {} - explicit SPROUT_CONSTEXPR tuple_impl(Head const& h, Tail const&... tail) - : inherited_type(tail...) - , base_type(h) - {} - template - explicit SPROUT_CONSTEXPR tuple_impl(UHead&& h, UTail&&... tail) - : inherited_type(sprout::forward(tail)...) - , base_type(sprout::forward(h)) - {} - SPROUT_CONSTEXPR tuple_impl(tuple_impl const&) = default; - SPROUT_CONSTEXPR tuple_impl(tuple_impl&& t) - SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_constructible::value && std::is_nothrow_move_constructible::value) - : inherited_type(sprout::move(tail(t))) - , base_type(sprout::forward(head(t))) - {} - template - SPROUT_CONSTEXPR tuple_impl(tuple_impl const& t) - : inherited_type(sprout::tuples::detail::tuple_impl::tail(t)) - , base_type(sprout::tuples::detail::tuple_impl::head(t)) - {} - template - SPROUT_CONSTEXPR tuple_impl(tuple_impl&& t) - : inherited_type(sprout::move(sprout::tuples::detail::tuple_impl::tail(t))) - , base_type(sprout::forward(sprout::tuples::detail::tuple_impl::head(t))) - {} - SPROUT_CONSTEXPR tuple_impl(tuple_impl const& t) - : inherited_type() - , base_type() - {} - SPROUT_CONSTEXPR tuple_impl(tuple_impl&& t) - : inherited_type() - , base_type() - {} - tuple_impl& operator=(tuple_impl const& t) { - head(*this) = head(t); - tail(*this) = tail(t); - return *this; - } - tuple_impl& operator=(tuple_impl&& t) - SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_assignable::value && std::is_nothrow_move_assignable::value) - { - head(*this) = sprout::forward(head(t)); - tail(*this) = sprout::move(tail(t)); - return *this; - } - template - tuple_impl& operator=(sprout::tuples::detail::tuple_impl const& t) { - head(*this) = sprout::tuples::detail::tuple_impl::head(t); - tail(*this) = sprout::tuples::detail::tuple_impl::tail(t); - return *this; - } - template - tuple_impl& operator=(sprout::tuples::detail::tuple_impl&& t) { - head(*this) = sprout::forward(sprout::tuples::detail::tuple_impl::head(t)); - tail(*this) = sprout::move(sprout::tuples::detail::tuple_impl::tail(t)); - return *this; - } - tuple_impl& operator=(sprout::tuples::detail::tuple_impl const& t) { - *this = sprout::move(tuple_impl()); - return *this; - } - tuple_impl& operator=(sprout::tuples::detail::tuple_impl&& t) { - *this = sprout::move(tuple_impl()); - return *this; - } - }; - } // namespace detail + // + // tuple + // + // tuple construction + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple() + : impl_type() + {} + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(Types const&... elements) + : impl_type(elements...) + {} + template + template< + typename... UTypes, + typename + > + inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(UTypes&&... elements) + : impl_type(sprout::forward(elements)...) + {} + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(tuple const&) = default; + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(tuple&&) = default; + template + template< + typename... UTypes, + typename + > + inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::tuples::tuple const& t) + : impl_type(static_cast const&>(t)) + {} + template + template< + typename... UTypes, + typename + > + inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::tuples::tuple&& t) + : impl_type(static_cast&&>(t)) + {} + template + template< + typename... UTypes, + typename + > + inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::pair const& t) + : impl_type(t.first, t.second) + {} + template + template< + typename... UTypes, + typename + > + inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::pair&& t) + : impl_type(sprout::move(t.first), sprout::move(t.second)) + {} + template + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::tuples::flexibly_construct_t, UTypes&&... elements) + : impl_type(sprout::forward(elements)...) + {} + template + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple const& t) + : impl_type(static_cast const&>(t)) + {} + template + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple&& t) + : impl_type(static_cast&&>(t)) + {} + template + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::tuples::flexibly_construct_t, sprout::pair const& t) + : impl_type(t.first, t.second) + {} + template + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple::tuple(sprout::tuples::flexibly_construct_t, sprout::pair&& t) + : impl_type(sprout::move(t.first), sprout::move(t.second)) + {} + // tuple assignment + template + sprout::tuples::tuple& sprout::tuples::tuple::operator=(tuple const& rhs) { + static_cast(*this) = rhs; + return *this; + } + template + sprout::tuples::tuple& sprout::tuples::tuple::operator=(tuple&& rhs) + SPROUT_NOEXCEPT_EXPR(sprout::tpp::all_of...>::value) + { + static_cast(*this) = sprout::move(rhs); + return *this; + } + template + template + sprout::tuples::tuple& sprout::tuples::tuple::operator=(sprout::tuples::tuple const& rhs) { + static_cast(*this) = rhs; + return *this; + } + template + template + sprout::tuples::tuple& sprout::tuples::tuple::operator=(sprout::tuples::tuple&& rhs) { + static_cast(*this) = sprout::move(rhs); + return *this; + } + // tuple swap + template + inline void sprout::tuples::tuple::swap(tuple& other) + SPROUT_NOEXCEPT_EXPR(has_nothrow_swap::value) + { + impl_type::swap(other); + } // // tuple // - template - class tuple - : public sprout::tuples::detail::tuple_impl<0, Types...> - { - private: - typedef sprout::tuples::detail::tuple_impl<0, Types...> inherited_type; - public: - // tuple construction - SPROUT_CONSTEXPR tuple() - : inherited_type() - {} - explicit SPROUT_CONSTEXPR tuple(Types const&... elements) - : inherited_type(elements...) - {} - template< - typename... UTypes, - typename = typename std::enable_if< - sizeof...(Types) == sizeof...(UTypes) && sprout::tpp::all_of...>::value - >::type - > - explicit SPROUT_CONSTEXPR tuple(UTypes&&... elements) - : inherited_type(sprout::forward(elements)...) - {} - template - explicit SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, UTypes&&... elements) - : inherited_type(sprout::forward(elements)...) - {} - SPROUT_CONSTEXPR tuple(tuple const&) = default; - SPROUT_CONSTEXPR tuple(tuple&&) = default; - template< - typename... UTypes, - typename = typename std::enable_if< - sizeof...(Types) == sizeof...(UTypes) && sprout::tpp::all_of...>::value - >::type - > - SPROUT_CONSTEXPR tuple(sprout::tuples::tuple const& t) - : inherited_type(static_cast const&>(t)) - {} - template< - typename... UTypes, - typename = typename std::enable_if< - sizeof...(Types) == sizeof...(UTypes) && sprout::tpp::all_of...>::value - >::type - > - SPROUT_CONSTEXPR tuple(sprout::tuples::tuple&& t) - : inherited_type(static_cast&&>(t)) - {} - template - SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple const& t) - : inherited_type(static_cast const&>(t)) - {} - template - SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple&& t) - : inherited_type(static_cast&&>(t)) - {} - // tuple assignment - tuple& operator=(tuple const& rhs) { - static_cast(*this) = rhs; - return *this; - } - tuple& operator=(tuple&& rhs) - SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_assignable::value) - { - static_cast(*this) = sprout::move(rhs); - return *this; - } - template - tuple& operator=(sprout::tuples::tuple const& rhs) { - static_cast(*this) = rhs; - return *this; - } - template - tuple& operator=(sprout::tuples::tuple&& rhs) { - static_cast(*this) = sprout::move(rhs); - return *this; - } - // tuple swap - void swap(tuple& other) - SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(std::declval().swap(other))) - { - inherited_type::swap(other); - } - }; - template<> - class tuple<> { - public: - // tuple swap - void swap(tuple&) SPROUT_NOEXCEPT {} - }; + // tuple construction + inline SPROUT_CONSTEXPR sprout::tuples::tuple<>::tuple() = default; + inline SPROUT_CONSTEXPR sprout::tuples::tuple<>::tuple(tuple const&) = default; + inline SPROUT_CONSTEXPR sprout::tuples::tuple<>::tuple(tuple&&) = default; + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple<>::tuple(sprout::tuples::flexibly_construct_t, UTypes&&... elements) {} + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple<>::tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple const& t) {} + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple<>::tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple&& t) {} + // tuple swap + inline void sprout::tuples::tuple<>::swap(tuple&) SPROUT_NOEXCEPT {} // // swap @@ -334,49 +155,7 @@ namespace sprout { { lhs.swap(rhs); } - - namespace detail { - template - struct tuple_element_impl; - template - struct tuple_element_impl<0, sprout::tuples::tuple > { - public: - typedef Head type; - }; - template - struct tuple_element_impl > - : public sprout::tuples::detail::tuple_element_impl > - {}; - } // namespace detail } // namespace tuples - - using sprout::tuples::tuple; - using sprout::tuples::swap; } // namespace sprout -namespace std { -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wmismatched-tags" -#endif - // - // tuple_size - // - template - struct tuple_size > - : public std::integral_constant - {}; - - // - // tuple_element - // - template - struct tuple_element > - : public sprout::tuples::detail::tuple_element_impl > - {}; -#if defined(__clang__) -# pragma clang diagnostic pop -#endif -} // namespace std - #endif // #ifndef SPROUT_TUPLE_TUPLE_TUPLE_HPP diff --git a/sprout/tuple/tuple/tuple_decl.hpp b/sprout/tuple/tuple/tuple_decl.hpp new file mode 100644 index 00000000..150aadba --- /dev/null +++ b/sprout/tuple/tuple/tuple_decl.hpp @@ -0,0 +1,382 @@ +#ifndef SPROUT_TUPLE_TUPLE_TUPLE_DECL_HPP +#define SPROUT_TUPLE_TUPLE_TUPLE_DECL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace tuples { + namespace detail { + template + class head_base; + // EBO disabled +// template +// class head_base +// : public Head +// { +// public: +// static SPROUT_CONSTEXPR Head& head(head_base& t) SPROUT_NOEXCEPT { +// return t; +// } +// static SPROUT_CONSTEXPR Head const& head(head_base const& t) SPROUT_NOEXCEPT { +// return t; +// } +// public: +// SPROUT_CONSTEXPR head_base() +// : Head() +// {} +// SPROUT_CONSTEXPR head_base(Head const& v) +// : Head(v) +// {} +// template +// SPROUT_CONSTEXPR head_base(UHead&& v) +// : Head(sprout::forward(v)) +// {} +// }; + template + class head_base { + public: + static SPROUT_CONSTEXPR Head& head(head_base& t) SPROUT_NOEXCEPT { + return t.head_; + } + static SPROUT_CONSTEXPR Head const& head(head_base const& t) SPROUT_NOEXCEPT { + return t.head_; + } + private: + Head head_; + public: + SPROUT_CONSTEXPR head_base() + : head_() + {} + SPROUT_CONSTEXPR head_base(Head const& v) + : head_(v) + {} + template + SPROUT_CONSTEXPR head_base(UHead&& v) + : head_(sprout::forward(v)) + {} + }; + template + class head_base { + public: + static SPROUT_CONSTEXPR Head& head(head_base& t) SPROUT_NOEXCEPT { + return t.head_; + } + static SPROUT_CONSTEXPR Head const& head(head_base const& t) SPROUT_NOEXCEPT { + return t.head_; + } + private: + Head head_; + public: + SPROUT_CONSTEXPR head_base() + : head_() + {} + SPROUT_CONSTEXPR head_base(Head const& v) + : head_(v) + {} + template + SPROUT_CONSTEXPR head_base(UHead&& v) + : head_(sprout::forward(v)) + {} + }; + + template + class tuple_impl; + template + class tuple_impl { + public: + template + friend class tuple; + template + friend class sprout::tuples::detail::tuple_impl; + protected: + void swap(tuple_impl&) SPROUT_NOEXCEPT {} + public: + tuple_impl() = default; + template + explicit SPROUT_CONSTEXPR tuple_impl(UTypes&&... args) SPROUT_NOEXCEPT {} + SPROUT_CONSTEXPR tuple_impl(tuple_impl const&) = default; + SPROUT_CONSTEXPR tuple_impl(tuple_impl&&) = default; + template + SPROUT_CONSTEXPR tuple_impl(tuple_impl const& t) SPROUT_NOEXCEPT {} + template + SPROUT_CONSTEXPR tuple_impl(tuple_impl&& t) SPROUT_NOEXCEPT {} + tuple_impl& operator=(tuple_impl const&) = default; + tuple_impl& operator=(tuple_impl&& t) = default; + template + tuple_impl& operator=(sprout::tuples::detail::tuple_impl const&) SPROUT_NOEXCEPT { + return *this; + } + template + tuple_impl& operator=(sprout::tuples::detail::tuple_impl&&) SPROUT_NOEXCEPT { + return *this; + } + }; + template + class tuple_impl + : public sprout::tuples::detail::tuple_impl + , private sprout::tuples::detail::head_base::value> + { + public: + template + friend class tuple; + template + friend class sprout::tuples::detail::tuple_impl; + public: + typedef sprout::tuples::detail::tuple_impl inherited_type; + typedef sprout::tuples::detail::head_base::value> base_type; + public: + static SPROUT_CONSTEXPR Head& head(tuple_impl& t) SPROUT_NOEXCEPT { + return base_type::head(t); + } + static SPROUT_CONSTEXPR Head const& head(tuple_impl const& t) SPROUT_NOEXCEPT { + return base_type::head(t); + } + static SPROUT_CONSTEXPR inherited_type& tail(tuple_impl& t) SPROUT_NOEXCEPT { + return t; + } + static SPROUT_CONSTEXPR inherited_type const& tail(tuple_impl const& t) SPROUT_NOEXCEPT { + return t; + } + public: + void swap(tuple_impl& t) + SPROUT_NOEXCEPT_EXPR( + SPROUT_NOEXCEPT_EXPR(sprout::swap(head(std::declval()), head(t))) + && SPROUT_NOEXCEPT_EXPR(std::declval().swap(tail(t))) + ) + { + sprout::swap(head(*this), head(t)); + inherited_type::swap(tail(t)); + } + public: + SPROUT_CONSTEXPR tuple_impl() + : inherited_type() + , base_type() + {} + explicit SPROUT_CONSTEXPR tuple_impl(Head const& h, Tail const&... tail) + : inherited_type(tail...) + , base_type(h) + {} + template + explicit SPROUT_CONSTEXPR tuple_impl(UHead&& h, UTail&&... tail) + : inherited_type(sprout::forward(tail)...) + , base_type(sprout::forward(h)) + {} + SPROUT_CONSTEXPR tuple_impl(tuple_impl const&) = default; + SPROUT_CONSTEXPR tuple_impl(tuple_impl&& t) + SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_constructible::value && std::is_nothrow_move_constructible::value) + : inherited_type(sprout::move(tail(t))) + , base_type(sprout::forward(head(t))) + {} + template + SPROUT_CONSTEXPR tuple_impl(tuple_impl const& t) + : inherited_type(sprout::tuples::detail::tuple_impl::tail(t)) + , base_type(sprout::tuples::detail::tuple_impl::head(t)) + {} + template + SPROUT_CONSTEXPR tuple_impl(tuple_impl&& t) + : inherited_type(sprout::move(sprout::tuples::detail::tuple_impl::tail(t))) + , base_type(sprout::forward(sprout::tuples::detail::tuple_impl::head(t))) + {} + SPROUT_CONSTEXPR tuple_impl(tuple_impl const& t) + : inherited_type() + , base_type() + {} + SPROUT_CONSTEXPR tuple_impl(tuple_impl&& t) + : inherited_type() + , base_type() + {} + tuple_impl& operator=(tuple_impl const& t) { + head(*this) = head(t); + tail(*this) = tail(t); + return *this; + } + tuple_impl& operator=(tuple_impl&& t) + SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_assignable::value && std::is_nothrow_move_assignable::value) + { + head(*this) = sprout::forward(head(t)); + tail(*this) = sprout::move(tail(t)); + return *this; + } + template + tuple_impl& operator=(sprout::tuples::detail::tuple_impl const& t) { + head(*this) = sprout::tuples::detail::tuple_impl::head(t); + tail(*this) = sprout::tuples::detail::tuple_impl::tail(t); + return *this; + } + template + tuple_impl& operator=(sprout::tuples::detail::tuple_impl&& t) { + head(*this) = sprout::forward(sprout::tuples::detail::tuple_impl::head(t)); + tail(*this) = sprout::move(sprout::tuples::detail::tuple_impl::tail(t)); + return *this; + } + tuple_impl& operator=(sprout::tuples::detail::tuple_impl const& t) { + *this = sprout::move(tuple_impl()); + return *this; + } + tuple_impl& operator=(sprout::tuples::detail::tuple_impl&& t) { + *this = sprout::move(tuple_impl()); + return *this; + } + }; + } // namespace detail + + // + // tuple + // + template + class tuple + : public sprout::tuples::detail::tuple_impl<0, Types...> + { + private: + typedef sprout::tuples::detail::tuple_impl<0, Types...> impl_type; + public: + struct has_nothrow_swap + : public sprout::tpp::all_of_c< + SPROUT_NOEXCEPT_EXPR_OR_DEFAULT(sprout::swap(std::declval(), std::declval()), false)... + > + {}; + public: + // tuple construction + SPROUT_CONSTEXPR tuple(); + explicit SPROUT_CONSTEXPR tuple(Types const&... elements); + template< + typename... UTypes, + typename = typename std::enable_if< + sizeof...(Types) == sizeof...(UTypes) && sprout::tpp::all_of...>::value + >::type + > + explicit SPROUT_CONSTEXPR tuple(UTypes&&... elements); + SPROUT_CONSTEXPR tuple(tuple const&); + SPROUT_CONSTEXPR tuple(tuple&&); + template< + typename... UTypes, + typename = typename std::enable_if< + sizeof...(Types) == sizeof...(UTypes) && sprout::tpp::all_of...>::value + >::type + > + SPROUT_CONSTEXPR tuple(sprout::tuples::tuple const& t); + template< + typename... UTypes, + typename = typename std::enable_if< + sizeof...(Types) == sizeof...(UTypes) && sprout::tpp::all_of...>::value + >::type + > + SPROUT_CONSTEXPR tuple(sprout::tuples::tuple&& t); + template< + typename... UTypes, + typename = typename std::enable_if< + sizeof...(Types) == 2 && sprout::tpp::all_of...>::value + >::type + > + SPROUT_CONSTEXPR tuple(sprout::pair const& t); + template< + typename... UTypes, + typename = typename std::enable_if< + sizeof...(Types) == 2 && sprout::tpp::all_of...>::value + >::type + > + SPROUT_CONSTEXPR tuple(sprout::pair&& t); + template + explicit SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, UTypes&&... elements); + template + SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple const& t); + template + SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple&& t); + template + SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair const& t); + template + SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::pair&& t); + // tuple assignment + tuple& operator=(tuple const& rhs); + tuple& operator=(tuple&& rhs) + SPROUT_NOEXCEPT_EXPR(sprout::tpp::all_of...>::value); + template + tuple& operator=(sprout::tuples::tuple const& rhs); + template + tuple& operator=(sprout::tuples::tuple&& rhs); + // tuple swap + void swap(tuple& other) + SPROUT_NOEXCEPT_EXPR(has_nothrow_swap::value); + }; + template<> + class tuple<> { + public: + // tuple construction + SPROUT_CONSTEXPR tuple(); + SPROUT_CONSTEXPR tuple(tuple const&); + SPROUT_CONSTEXPR tuple(tuple&&); + template + explicit SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, UTypes&&... elements); + template + SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple const& t); + template + SPROUT_CONSTEXPR tuple(sprout::tuples::flexibly_construct_t, sprout::tuples::tuple&& t); + // tuple swap + void swap(tuple&) SPROUT_NOEXCEPT; + }; + + // + // swap + // + template + inline void + swap(sprout::tuples::tuple& lhs, sprout::tuples::tuple& rhs) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))); + + namespace detail { + template + struct tuple_element_impl; + template + struct tuple_element_impl<0, sprout::tuples::tuple > { + public: + typedef Head type; + }; + template + struct tuple_element_impl > + : public sprout::tuples::detail::tuple_element_impl > + {}; + } // namespace detail + } // namespace tuples + + using sprout::tuples::tuple; + using sprout::tuples::swap; +} // namespace sprout + +namespace std { +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wmismatched-tags" +#endif + // + // tuple_size + // + template + struct tuple_size > + : public std::integral_constant + {}; + + // + // tuple_element + // + template + struct tuple_element > + : public sprout::tuples::detail::tuple_element_impl > + {}; +#if defined(__clang__) +# pragma clang diagnostic pop +#endif +} // namespace std + +#endif // #ifndef SPROUT_TUPLE_TUPLE_TUPLE_DECL_HPP diff --git a/sprout/tuple/tuple/tuple_fwd.hpp b/sprout/tuple/tuple/tuple_fwd.hpp index 96480adb..a250b2dd 100644 --- a/sprout/tuple/tuple/tuple_fwd.hpp +++ b/sprout/tuple/tuple/tuple_fwd.hpp @@ -5,6 +5,9 @@ namespace sprout { namespace tuples { + // + // tuple + // template class tuple; } // namespace tuples diff --git a/sprout/utility/pack.hpp b/sprout/utility/pack.hpp index 76aac868..aa2d5586 100644 --- a/sprout/utility/pack.hpp +++ b/sprout/utility/pack.hpp @@ -21,10 +21,7 @@ namespace sprout { public: typedef Head type; }; - template< - std::size_t N, - typename... Args - > + template struct tppack_at_impl : public sprout::detail::tppack_at_impl_1 { diff --git a/sprout/utility/pair.hpp b/sprout/utility/pair.hpp index 8dbdf4e5..51584ca7 100644 --- a/sprout/utility/pair.hpp +++ b/sprout/utility/pair.hpp @@ -2,6 +2,8 @@ #define SPROUT_UTILITY_PAIR_HPP #include +#include +#include #include #include #include diff --git a/sprout/utility/pair/pair.hpp b/sprout/utility/pair/pair.hpp index edda5ef0..1110d6f3 100644 --- a/sprout/utility/pair/pair.hpp +++ b/sprout/utility/pair/pair.hpp @@ -1,121 +1,113 @@ #ifndef SPROUT_UTILITY_PAIR_PAIR_HPP #define SPROUT_UTILITY_PAIR_PAIR_HPP -#include #include #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)) - {} + template + inline SPROUT_CONSTEXPR sprout::pair::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)...) + {} + template + inline SPROUT_CONSTEXPR sprout::pair::pair(pair const&) = default; + template + inline SPROUT_CONSTEXPR sprout::pair::pair(pair&&) = default; + template + inline SPROUT_CONSTEXPR sprout::pair::pair() + : first() + , second() + {} + template + inline SPROUT_CONSTEXPR sprout::pair::pair(T1 const& x, T2 const& y) + : first(x) + , second(y) + {} + template + template + inline SPROUT_CONSTEXPR sprout::pair::pair(U&& x, V&& y) + : first(sprout::forward(x)) + , second(sprout::forward(y)) + {} + template + template + inline SPROUT_CONSTEXPR sprout::pair::pair(sprout::pair const& other) + : first(other.first) + , second(other.second) + {} + template + template + inline SPROUT_CONSTEXPR sprout::pair::pair(sprout::pair&& other) + : first(sprout::move(other.first)) + , second(sprout::move(other.second)) + {} #if SPROUT_USE_DELEGATING_CONSTRUCTORS - template - SPROUT_CONSTEXPR pair( - sprout::tuples::tuple first_args, - sprout::tuples::tuple second_args + template + template + inline SPROUT_CONSTEXPR sprout::pair::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() ) - : 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)) - ) - { - sprout::swap(first, p.first); - sprout::swap(second, p.second); - } - }; + template + inline sprout::pair& sprout::pair::operator=(pair const& other) = default; + template + template + inline sprout::pair& sprout::pair::operator=(sprout::pair const& other) { + first = other.first; + second = other.second; + return *this; + } + template + inline sprout::pair& sprout::pair::operator=(pair&& other) + SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_assignable::value && std::is_nothrow_move_assignable::value) + { + first = sprout::move(other.first); + second = sprout::move(other.second); + return *this; + } + template + template + inline sprout::pair& sprout::pair::operator=(sprout::pair&& other) { + first = sprout::move(other.first); + second = sprout::move(other.second); + return *this; + } + template + inline void sprout::pair::swap(pair& other) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::swap(first, other.first)) && SPROUT_NOEXCEPT_EXPR(sprout::swap(second, other.second))) { + sprout::swap(first, other.first); + sprout::swap(second, other.second); + } // // swap // - template + template inline void swap(sprout::pair& lhs, sprout::pair& rhs) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) diff --git a/sprout/utility/pair/pair_decl.hpp b/sprout/utility/pair/pair_decl.hpp new file mode 100644 index 00000000..124fae1b --- /dev/null +++ b/sprout/utility/pair/pair_decl.hpp @@ -0,0 +1,68 @@ +#ifndef SPROUT_UTILITY_PAIR_PAIR_DECL_HPP +#define SPROUT_UTILITY_PAIR_PAIR_DECL_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // 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 + ); + public: + SPROUT_CONSTEXPR pair(pair const&); + SPROUT_CONSTEXPR pair(pair&&); + SPROUT_CONSTEXPR pair(); + SPROUT_CONSTEXPR pair(T1 const& x, T2 const& y); + template + SPROUT_CONSTEXPR pair(U&& x, V&& y); + template + SPROUT_CONSTEXPR pair(sprout::pair const& other); + template + SPROUT_CONSTEXPR pair(sprout::pair&& other); + template + SPROUT_CONSTEXPR pair( + sprout::tuples::tuple first_args, + sprout::tuples::tuple second_args + ); + pair& operator=(pair const& other); + template + pair& operator=(sprout::pair const& other); + pair& operator=(pair&& other) + SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_assignable::value && std::is_nothrow_move_assignable::value); + template + pair& operator=(sprout::pair&& other); + void swap(pair& other) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::swap(first, other.first)) && SPROUT_NOEXCEPT_EXPR(sprout::swap(second, other.second))); + }; + + // + // swap + // + template + inline void + swap(sprout::pair& lhs, sprout::pair& rhs) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))); +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_PAIR_PAIR_DECL_HPP diff --git a/sprout/utility/pair/pair_fwd.hpp b/sprout/utility/pair/pair_fwd.hpp new file mode 100644 index 00000000..213906a7 --- /dev/null +++ b/sprout/utility/pair/pair_fwd.hpp @@ -0,0 +1,14 @@ +#ifndef SPROUT_UTILITY_PAIR_PAIR_FWD_HPP +#define SPROUT_UTILITY_PAIR_PAIR_FWD_HPP + +#include + +namespace sprout { + // + // pair + // + template + struct pair; +} // namespace sprout + +#endif // #ifndef SPROUT_UTILITY_PAIR_PAIR_FWD_HPP