diff --git a/sprout/tuple/sub_array.hpp b/sprout/tuple/sub_array.hpp deleted file mode 100644 index e6ddf407..00000000 --- a/sprout/tuple/sub_array.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef SPROUT_TUPLE_SUB_ARRAY_HPP -#define SPROUT_TUPLE_SUB_ARRAY_HPP - -#include -#include -#include -#include -#include -#include -#include - -namespace sprout { - namespace tuples { - // - // get - // - template - inline SPROUT_CONSTEXPR typename sprout::container_traits >::value_type& - get(sprout::sub_array& t) - SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(*sprout::next(sprout::internal_begin(t), I))) - { - static_assert(I < sprout::container_traits >::static_size, "get: index out of range"); - return *sprout::next(sprout::internal_begin(t), I); - } - template - inline SPROUT_CONSTEXPR typename sprout::container_traits >::value_type const& - get(sprout::sub_array const& t) - SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(*sprout::next(sprout::internal_begin(t), I))) - { - static_assert(I < sprout::container_traits >::static_size, "get: index out of range"); - return *sprout::next(sprout::internal_begin(t), I); - } - template - inline SPROUT_CONSTEXPR typename sprout::container_traits >::value_type&& - get(sprout::sub_array&& t) - SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(sprout::move(sprout::tuples::get(t)))) - { - return sprout::move(sprout::tuples::get(t)); - } - } // namespace tuples - - using sprout::tuples::get; -} // namespace sprout - -#endif // #ifndef SPROUT_TUPLE_SUB_ARRAY_HPP diff --git a/sprout/tuple/traits.hpp b/sprout/tuple/traits.hpp index 49c11b58..7861e1d4 100644 --- a/sprout/tuple/traits.hpp +++ b/sprout/tuple/traits.hpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace sprout { namespace types { diff --git a/sprout/tuple/tuple.hpp b/sprout/tuple/tuple.hpp index abd15dc0..101edf4f 100644 --- a/sprout/tuple/tuple.hpp +++ b/sprout/tuple/tuple.hpp @@ -1,551 +1,13 @@ #ifndef SPROUT_TUPLE_TUPLE_HPP #define SPROUT_TUPLE_TUPLE_HPP -#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 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 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; - } - protected: - void swap(tuple_impl& t) SPROUT_NOEXCEPT_EXPR( - SPROUT_NOEXCEPT_EXPR(swap(std::declval(), std::declval())) - && SPROUT_NOEXCEPT_EXPR(tail(t).swap(tail(t))) - ) - { - using std::swap; - 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; - } - }; - - template - struct and_impl; - template<> - struct and_impl - : public std::true_type - {}; - template<> - struct and_impl - : public std::false_type - {}; - template - struct and_impl - : public std::integral_constant::value> - {}; - template - struct and_impl - : public std::false_type - {}; - template - struct and_ - : public sprout::tuples::detail::and_impl - {}; - - template - struct or_impl; - template<> - struct or_impl - : public std::true_type - {}; - template<> - struct or_impl - : public std::false_type - {}; - template - struct or_impl - : public std::true_type - {}; - template - struct or_impl - : public std::integral_constant::value> - {}; - template - struct or_ - : public sprout::tuples::detail::and_impl - {}; - } // namespace detail - - template - class tuple; - - // - // is_tuple - // - template - struct is_tuple - : public std::false_type - {}; - template - struct is_tuple - : public sprout::tuples::is_tuple - {}; - template - struct is_tuple - : public sprout::tuples::is_tuple - {}; - template - struct is_tuple > - : public std::true_type - {}; - - // - // tuple - // - template - class tuple - : public sprout::tuples::detail::tuple_impl<0, Types...> - { - public: - 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 U, - typename = typename std::enable_if< - !sprout::tuples::is_tuple::type>::value - >::type - > - explicit SPROUT_CONSTEXPR tuple(U&& elem) - : inherited_type(sprout::forward(elem)) - {} - template< - typename U1, - typename U2, - typename... UTypes - > - explicit SPROUT_CONSTEXPR tuple(U1&& elem1, U2&& elem2, UTypes&&... elements) - : inherited_type(sprout::forward(elem1), sprout::forward(elem2), sprout::forward(elements)...) - {} - SPROUT_CONSTEXPR tuple(tuple const&) = default; - SPROUT_CONSTEXPR tuple(tuple&&) = default; - template - SPROUT_CONSTEXPR tuple(sprout::tuples::tuple const& t) - : inherited_type(static_cast const&>(t)) - {} - template - SPROUT_CONSTEXPR tuple(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(inherited_type::swap(other))) { - inherited_type::swap(other); - } - }; - template<> - class tuple<> { - public: - // tuple swap - void swap(tuple&) SPROUT_NOEXCEPT {} - }; - - // - // ignore_t - // - struct ignore_t { - template - ignore_t const& operator=(T const&) const { - return *this; - } - }; - // - // ignore - // - SPROUT_STATIC_CONSTEXPR ignore_t ignore{}; - - // - // make_tuple - // - template - inline SPROUT_CONSTEXPR sprout::tuples::tuple::type...> make_tuple(Types&&... args) { - return sprout::tuples::tuple::type...>(sprout::forward(args)...); - } - // - // forward_as_tuple - // - template - inline SPROUT_CONSTEXPR sprout::tuples::tuple forward_as_tuple(Types&&... args) SPROUT_NOEXCEPT { - return sprout::tuples::tuple(sprout::forward(args)...); - } - // - // tie - // - template - inline sprout::tuples::tuple tie(Types&... args) SPROUT_NOEXCEPT { - return sprout::tuples::tuple(args...); - } - - // - // swap - // - template - inline void swap( - sprout::tuples::tuple& lhs, - sprout::tuples::tuple& rhs - ) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) - { - 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::ignore; - using sprout::tuples::make_tuple; - using sprout::tuples::forward_as_tuple; - using sprout::tuples::tie; - using sprout::tuples::swap; -} // 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 { - // - // tuple_size - // - template - struct tuple_size - : public std::tuple_size - {}; - template - struct tuple_size - : public sprout::tuples::tuple_size - {}; - template - struct tuple_size - : public sprout::tuples::tuple_size - {}; - template - struct tuple_size - : public sprout::tuples::tuple_size - {}; - - // - // tuple_element - // - template - struct tuple_element - : public std::tuple_element - {}; - template - struct tuple_element - : public sprout::tuples::tuple_element - {}; - template - struct tuple_element - : public sprout::tuples::tuple_element - {}; - template - struct tuple_element - : public sprout::tuples::tuple_element - {}; - - // - // get - // - template - inline SPROUT_CONSTEXPR auto - get(T&& t) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(std::get(sprout::forward(t)))) - -> decltype(std::get(sprout::forward(t))) - { - return std::get(sprout::forward(t)); - } - // - // get - // - namespace detail { - template - inline SPROUT_CONSTEXPR typename std::add_lvalue_reference::type - get_helper(sprout::tuples::detail::tuple_impl& t) SPROUT_NOEXCEPT { - return sprout::tuples::detail::tuple_impl::head(t); - } - template - inline SPROUT_CONSTEXPR typename std::add_lvalue_reference::type>::type - get_helper(sprout::tuples::detail::tuple_impl const& t) SPROUT_NOEXCEPT { - return sprout::tuples::detail::tuple_impl::head(t); - } - } // namespace detail - template - inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element >::type& - get(sprout::tuples::tuple& t) SPROUT_NOEXCEPT { - return sprout::tuples::detail::get_helper(t); - } - template - inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element >::type&& - get(sprout::tuples::tuple&& t) SPROUT_NOEXCEPT { - return sprout::forward >::type&&>( - sprout::tuples::get(t) - ); - } - template - inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element >::type const& - get(sprout::tuples::tuple const& t) SPROUT_NOEXCEPT { - return sprout::tuples::detail::get_helper(t); - } - } // namespace tuples - - using sprout::tuples::tuple_size; - using sprout::tuples::tuple_element; - using sprout::tuples::get; -} // namespace sprout - -#include +#include +#include +#include +#include +#include +#include +#include #endif // #ifndef SPROUT_TUPLE_TUPLE_HPP diff --git a/sprout/tuple/tuple_comparison.hpp b/sprout/tuple/tuple/comparison.hpp similarity index 94% rename from sprout/tuple/tuple_comparison.hpp rename to sprout/tuple/tuple/comparison.hpp index 95047fdc..17712adb 100644 --- a/sprout/tuple/tuple_comparison.hpp +++ b/sprout/tuple/tuple/comparison.hpp @@ -3,7 +3,8 @@ #include #include -#include +#include +#include namespace sprout { namespace tuples { diff --git a/sprout/tuple/tuple/get.hpp b/sprout/tuple/tuple/get.hpp new file mode 100644 index 00000000..8b8897f1 --- /dev/null +++ b/sprout/tuple/tuple/get.hpp @@ -0,0 +1,102 @@ +#ifndef SPROUT_TUPLE_TUPLE_GET_HPP +#define SPROUT_TUPLE_TUPLE_GET_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace tuples { + // + // tuple_size + // + template + struct tuple_size + : public std::tuple_size + {}; + template + struct tuple_size + : public sprout::tuples::tuple_size + {}; + template + struct tuple_size + : public sprout::tuples::tuple_size + {}; + template + struct tuple_size + : public sprout::tuples::tuple_size + {}; + + // + // tuple_element + // + template + struct tuple_element + : public std::tuple_element + {}; + template + struct tuple_element + : public sprout::tuples::tuple_element + {}; + template + struct tuple_element + : public sprout::tuples::tuple_element + {}; + template + struct tuple_element + : public sprout::tuples::tuple_element + {}; + + // + // get + // + template + inline SPROUT_CONSTEXPR auto + get(T&& t) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(std::get(sprout::forward(t)))) + -> decltype(std::get(sprout::forward(t))) + { + return std::get(sprout::forward(t)); + } + // + // get + // + namespace detail { + template + inline SPROUT_CONSTEXPR typename std::add_lvalue_reference::type + get_helper(sprout::tuples::detail::tuple_impl& t) SPROUT_NOEXCEPT { + return sprout::tuples::detail::tuple_impl::head(t); + } + template + inline SPROUT_CONSTEXPR typename std::add_lvalue_reference::type>::type + get_helper(sprout::tuples::detail::tuple_impl const& t) SPROUT_NOEXCEPT { + return sprout::tuples::detail::tuple_impl::head(t); + } + } // namespace detail + template + inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element >::type& + get(sprout::tuples::tuple& t) SPROUT_NOEXCEPT { + return sprout::tuples::detail::get_helper(t); + } + template + inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element >::type&& + get(sprout::tuples::tuple&& t) SPROUT_NOEXCEPT { + return sprout::forward >::type&&>( + sprout::tuples::get(t) + ); + } + template + inline SPROUT_CONSTEXPR typename sprout::tuples::tuple_element >::type const& + get(sprout::tuples::tuple const& t) SPROUT_NOEXCEPT { + return sprout::tuples::detail::get_helper(t); + } + } // namespace tuples + + using sprout::tuples::tuple_size; + using sprout::tuples::tuple_element; + using sprout::tuples::get; +} // namespace sprout + +#endif // #ifndef SPROUT_TUPLE_TUPLE_GET_HPP diff --git a/sprout/tuple/tuple/ignore.hpp b/sprout/tuple/tuple/ignore.hpp new file mode 100644 index 00000000..3d0a6f43 --- /dev/null +++ b/sprout/tuple/tuple/ignore.hpp @@ -0,0 +1,28 @@ +#ifndef SPROUT_TUPLE_TUPLE_IGNORE_HPP +#define SPROUT_TUPLE_TUPLE_IGNORE_HPP + +#include + +namespace sprout { + namespace tuples { + // + // ignore_t + // + struct ignore_t { + public: + template + ignore_t const& operator=(T const&) const { + return *this; + } + }; + // + // ignore + // + SPROUT_STATIC_CONSTEXPR ignore_t ignore{}; + } // namespace tuples + + using sprout::tuples::ignore_t; + using sprout::tuples::ignore; +} // namespace sprout + +#endif // #ifndef SPROUT_TUPLE_TUPLE_IGNORE_HPP diff --git a/sprout/tuple/tuple/make_tuple.hpp b/sprout/tuple/tuple/make_tuple.hpp new file mode 100644 index 00000000..30f2491e --- /dev/null +++ b/sprout/tuple/tuple/make_tuple.hpp @@ -0,0 +1,163 @@ +#ifndef SPROUT_TUPLE_TUPLE_MAKE_TUPLE_HPP +#define SPROUT_TUPLE_TUPLE_MAKE_TUPLE_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace tuples { + // + // make_tuple + // + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple::type...> make_tuple(Types&&... args) { + return sprout::tuples::tuple::type...>(sprout::forward(args)...); + } + + // + // forward_as_tuple + // + template + inline SPROUT_CONSTEXPR sprout::tuples::tuple forward_as_tuple(Types&&... args) SPROUT_NOEXCEPT { + return sprout::tuples::tuple(sprout::forward(args)...); + } + + // + // tie + // + template + inline sprout::tuples::tuple tie(Types&... args) SPROUT_NOEXCEPT { + return sprout::tuples::tuple(args...); + } + + namespace result_of { + namespace detail { + template + struct tuple_cat_impl; + template<> + struct tuple_cat_impl<> { + typedef sprout::tuples::tuple<> type; + }; + template + struct tuple_cat_impl { + private: + template + struct make; + template + struct make > { + public: + typedef sprout::tuples::tuple::type...> type; + }; + public: + typedef typename make< + Tuple, typename sprout::index_range<0, sprout::tuples::tuple_size::value>::type + >::type type; + }; + template + struct tuple_cat_impl { + private: + template + struct make; + template + struct make, Tup2, sprout::index_tuple > { + public: + typedef sprout::tuples::tuple< + typename sprout::tuples::tuple_element::type..., + typename sprout::tuples::tuple_element::type... + > type; + }; + public: + typedef typename sprout::tuples::result_of::detail::tuple_cat_impl< + typename make< + T, typename sprout::index_range<0, sprout::tuples::tuple_size::value>::type, + U, typename sprout::index_range<0, sprout::tuples::tuple_size::value>::type + >::type, + Tuples... + >::type type; + }; + } // namespace detail + // + // tuple_cat + // + template + struct tuple_cat + : public sprout::tuples::result_of::detail::tuple_cat_impl< + typename std::remove_reference::type... + > + {}; + } // namespace result_of + + namespace detail { + template + struct tuple_cat_1st_indexes; + template<> + struct tuple_cat_1st_indexes<> { + public: + typedef sprout::index_tuple<> type; + }; + template + struct tuple_cat_1st_indexes { + public: + typedef typename sprout::index_range< + 0, sprout::tuples::tuple_size::type>::value + >::type type; + }; + + template + struct tuple_cat_impl; + template + struct tuple_cat_impl, Head, Tail...> { + public: + template + static SPROUT_CONSTEXPR Result + call(Head&& head, Tail&&... tail, Args&&... args) { + return sprout::tuples::detail::tuple_cat_impl< + Result, + typename sprout::tuples::detail::tuple_cat_1st_indexes::type, + Tail... + >::call( + sprout::forward(tail)..., + sprout::forward(args)..., + sprout::tuples::get(sprout::forward(head))... + ); + } + }; + template + struct tuple_cat_impl > { + public: + template + static SPROUT_CONSTEXPR Result + call(Args&&... args) { + return Result(sprout::forward(args)...); + } + }; + } // namespace detail + // + // tuple_cat + // + template + inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::tuple_cat::type + tuple_cat(Tuples&&... tuples) { + return sprout::tuples::detail::tuple_cat_impl< + typename sprout::tuples::result_of::tuple_cat::type, + typename sprout::tuples::detail::tuple_cat_1st_indexes::type, + Tuples... + >::call(sprout::forward(tuples)...); + } + } // namespace tuples + + namespace result_of { + using sprout::tuples::result_of::tuple_cat; + } // namespace result_of + + using sprout::tuples::make_tuple; + using sprout::tuples::forward_as_tuple; + using sprout::tuples::tie; + using sprout::tuples::tuple_cat; +} // namespace sprout + +#endif // #ifndef SPROUT_TUPLE_TUPLE_MAKE_TUPLE_HPP diff --git a/sprout/tuple/tuple/tuple.hpp b/sprout/tuple/tuple/tuple.hpp new file mode 100644 index 00000000..4245299c --- /dev/null +++ b/sprout/tuple/tuple/tuple.hpp @@ -0,0 +1,397 @@ +#ifndef SPROUT_TUPLE_TUPLE_TUPLE_HPP +#define SPROUT_TUPLE_TUPLE_TUPLE_HPP + +#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 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 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; + } + protected: + void swap(tuple_impl& t) SPROUT_NOEXCEPT_EXPR( + SPROUT_NOEXCEPT_EXPR(swap(std::declval(), std::declval())) + && SPROUT_NOEXCEPT_EXPR(tail(t).swap(tail(t))) + ) + { + using std::swap; + 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; + } + }; + + template + struct and_impl; + template<> + struct and_impl + : public std::true_type + {}; + template<> + struct and_impl + : public std::false_type + {}; + template + struct and_impl + : public std::integral_constant::value> + {}; + template + struct and_impl + : public std::false_type + {}; + template + struct and_ + : public sprout::tuples::detail::and_impl + {}; + + template + struct or_impl; + template<> + struct or_impl + : public std::true_type + {}; + template<> + struct or_impl + : public std::false_type + {}; + template + struct or_impl + : public std::true_type + {}; + template + struct or_impl + : public std::integral_constant::value> + {}; + template + struct or_ + : public sprout::tuples::detail::and_impl + {}; + } // namespace detail + + // + // tuple + // + template + class tuple + : public sprout::tuples::detail::tuple_impl<0, Types...> + { + public: + 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 U, + typename = typename std::enable_if< + !sprout::tuples::is_tuple::type>::value + >::type + > + explicit SPROUT_CONSTEXPR tuple(U&& elem) + : inherited_type(sprout::forward(elem)) + {} + template< + typename U1, + typename U2, + typename... UTypes + > + explicit SPROUT_CONSTEXPR tuple(U1&& elem1, U2&& elem2, UTypes&&... elements) + : inherited_type(sprout::forward(elem1), sprout::forward(elem2), sprout::forward(elements)...) + {} + SPROUT_CONSTEXPR tuple(tuple const&) = default; + SPROUT_CONSTEXPR tuple(tuple&&) = default; + template + SPROUT_CONSTEXPR tuple(sprout::tuples::tuple const& t) + : inherited_type(static_cast const&>(t)) + {} + template + SPROUT_CONSTEXPR tuple(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(inherited_type::swap(other))) { + inherited_type::swap(other); + } + }; + template<> + class tuple<> { + public: + // 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))) + { + 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 { + // + // 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 + +#endif // #ifndef SPROUT_TUPLE_TUPLE_TUPLE_HPP diff --git a/sprout/tuple/tuple/tuple_fwd.hpp b/sprout/tuple/tuple/tuple_fwd.hpp new file mode 100644 index 00000000..96480adb --- /dev/null +++ b/sprout/tuple/tuple/tuple_fwd.hpp @@ -0,0 +1,13 @@ +#ifndef SPROUT_TUPLE_TUPLE_TUPLE_FWD_HPP +#define SPROUT_TUPLE_TUPLE_TUPLE_FWD_HPP + +#include + +namespace sprout { + namespace tuples { + template + class tuple; + } // namespace tuples +} // namespace sprout + +#endif // #ifndef SPROUT_TUPLE_TUPLE_TUPLE_FWD_HPP diff --git a/sprout/tuple/tuple/type_traits.hpp b/sprout/tuple/tuple/type_traits.hpp new file mode 100644 index 00000000..290b653b --- /dev/null +++ b/sprout/tuple/tuple/type_traits.hpp @@ -0,0 +1,34 @@ +#ifndef SPROUT_TUPLE_TUPLE_TYPE_TRAITS_HPP +#define SPROUT_TUPLE_TUPLE_TYPE_TRAITS_HPP + +#include +#include +#include + +namespace sprout { + namespace tuples { + // + // is_tuple + // + template + struct is_tuple + : public std::false_type + {}; + template + struct is_tuple + : public sprout::tuples::is_tuple + {}; + template + struct is_tuple + : public sprout::tuples::is_tuple + {}; + template + struct is_tuple > + : public std::true_type + {}; + } // namespace tuples + + using sprout::tuples::is_tuple; +} // namespace sprout + +#endif // #ifndef SPROUT_TUPLE_TUPLE_TYPE_TRAITS_HPP diff --git a/sprout/type/string.hpp b/sprout/type/string.hpp index a3001631..0c1145d8 100644 --- a/sprout/type/string.hpp +++ b/sprout/type/string.hpp @@ -1,42 +1,7 @@ #ifndef SPROUT_TYPE_STRING_HPP #define SPROUT_TYPE_STRING_HPP -#include -#include -#include -#include -#include - -namespace sprout { - namespace types { - // - // basic_string - // - template - struct basic_string - : public sprout::types::integral_array - {}; - } // namespace types -} // namespace sprout - -namespace std { - // - // tuple_size - // - template - struct tuple_size > - : public std::tuple_size > - {}; - - // - // tuple_element - // - template - struct tuple_element > - : public std::tuple_element > - {}; -} // namespace std - +#include #include #include #include diff --git a/sprout/type/string/alias.hpp b/sprout/type/string/alias.hpp index 04e4863c..63f77d63 100644 --- a/sprout/type/string/alias.hpp +++ b/sprout/type/string/alias.hpp @@ -2,7 +2,7 @@ #define SPROUT_TYPE_STRING_ALIAS_HPP #include -#include +#include #if SPROUT_USE_TEMPLATE_ALIASES diff --git a/sprout/type/string/string.hpp b/sprout/type/string/string.hpp new file mode 100644 index 00000000..7b8ac5d6 --- /dev/null +++ b/sprout/type/string/string.hpp @@ -0,0 +1,40 @@ +#ifndef SPROUT_TYPE_STRING_STRING_HPP +#define SPROUT_TYPE_STRING_STRING_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace types { + // + // basic_string + // + template + struct basic_string + : public sprout::types::integral_array + {}; + } // namespace types +} // namespace sprout + +namespace std { + // + // tuple_size + // + template + struct tuple_size > + : public std::tuple_size > + {}; + + // + // tuple_element + // + template + struct tuple_element > + : public std::tuple_element > + {}; +} // namespace std + +#endif // #ifndef SPROUT_TYPE_STRING_STRING_HPP diff --git a/sprout/type/string/to_string.hpp b/sprout/type/string/to_string.hpp index ed944459..d14570b8 100644 --- a/sprout/type/string/to_string.hpp +++ b/sprout/type/string/to_string.hpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/sprout/type/string/to_string_constant.hpp b/sprout/type/string/to_string_constant.hpp index 80791f60..cd7134c0 100644 --- a/sprout/type/string/to_string_constant.hpp +++ b/sprout/type/string/to_string_constant.hpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/sprout/uuid.hpp b/sprout/uuid.hpp index b66a707d..dbca076b 100644 --- a/sprout/uuid.hpp +++ b/sprout/uuid.hpp @@ -3,10 +3,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #endif // #ifndef SPROUT_UUID_HPP diff --git a/sprout/uuid/uuid_generators.hpp b/sprout/uuid/generators.hpp similarity index 59% rename from sprout/uuid/uuid_generators.hpp rename to sprout/uuid/generators.hpp index 8bd675e2..a3eed792 100644 --- a/sprout/uuid/uuid_generators.hpp +++ b/sprout/uuid/generators.hpp @@ -1,5 +1,5 @@ -#ifndef SPROUT_UUID_UUID_GENERATORS_HPP -#define SPROUT_UUID_UUID_GENERATORS_HPP +#ifndef SPROUT_UUID_GENERATORS_HPP +#define SPROUT_UUID_GENERATORS_HPP #include #include @@ -7,4 +7,4 @@ #include #include -#endif // #ifndef SPROUT_UUID_UUID_GENERATORS_HPP +#endif // #ifndef SPROUT_UUID_GENERATORS_HPP diff --git a/sprout/uuid/uuid_hash.hpp b/sprout/uuid/hash.hpp similarity index 70% rename from sprout/uuid/uuid_hash.hpp rename to sprout/uuid/hash.hpp index fff4ce5c..73c23a1f 100644 --- a/sprout/uuid/uuid_hash.hpp +++ b/sprout/uuid/hash.hpp @@ -1,5 +1,5 @@ -#ifndef SPROUT_UUID_UUID_HASH_HPP -#define SPROUT_UUID_UUID_HASH_HPP +#ifndef SPROUT_UUID_HASH_HPP +#define SPROUT_UUID_HASH_HPP #include #include @@ -12,4 +12,4 @@ namespace sprout { } } // namespace sprout -#endif // #ifndef SPROUT_UUID_UUID_HASH_HPP +#endif // #ifndef SPROUT_UUID_HASH_HPP diff --git a/sprout/uuid/uuid_io.hpp b/sprout/uuid/io.hpp similarity index 95% rename from sprout/uuid/uuid_io.hpp rename to sprout/uuid/io.hpp index 35fa446b..454aa2e2 100644 --- a/sprout/uuid/uuid_io.hpp +++ b/sprout/uuid/io.hpp @@ -1,5 +1,5 @@ -#ifndef SPROUT_UUID_UUID_IO_HPP -#define SPROUT_UUID_UUID_IO_HPP +#ifndef SPROUT_UUID_IO_HPP +#define SPROUT_UUID_IO_HPP #include #include @@ -181,4 +181,4 @@ namespace sprout { } // namespace uuids } // namespace sprout -#endif // #ifndef SPROUT_UUID_UUID_IO_HPP +#endif // #ifndef SPROUT_UUID_IO_HPP diff --git a/sprout/uuid/uuid_tuple.hpp b/sprout/uuid/tuple.hpp similarity index 88% rename from sprout/uuid/uuid_tuple.hpp rename to sprout/uuid/tuple.hpp index 7aee7043..40be87d9 100644 --- a/sprout/uuid/uuid_tuple.hpp +++ b/sprout/uuid/tuple.hpp @@ -1,5 +1,5 @@ -#ifndef SPROUT_UUID_UUID_TUPLE_HPP -#define SPROUT_UUID_UUID_TUPLE_HPP +#ifndef SPROUT_UUID_TUPLE_HPP +#define SPROUT_UUID_TUPLE_HPP #include #include @@ -57,4 +57,4 @@ namespace std { }; } // namespace std -#endif // #ifndef SPROUT_UUID_UUID_TUPLE_HPP +#endif // #ifndef SPROUT_UUID_TUPLE_HPP