diff --git a/sprout/tuple/operation.hpp b/sprout/tuple/operation.hpp index dc06f029..d53480b3 100644 --- a/sprout/tuple/operation.hpp +++ b/sprout/tuple/operation.hpp @@ -5,5 +5,7 @@ #include #include #include +#include +#include #endif // #ifndef SPROUT_TUPLE_OPERATION_HPP diff --git a/sprout/tuple/operation/pop_back.hpp b/sprout/tuple/operation/pop_back.hpp new file mode 100644 index 00000000..a4c6cb90 --- /dev/null +++ b/sprout/tuple/operation/pop_back.hpp @@ -0,0 +1,51 @@ +#ifndef SPROUT_TUPLE_OPERATION_POP_BACK_HPP +#define SPROUT_TUPLE_OPERATION_POP_BACK_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace tuples { + namespace result_of { + // + // pop_back + // + template + struct pop_back + : public sprout::types::pop_back + {}; + } // namespace result_of + + namespace detail { + template + inline SPROUT_CONSTEXPR Result pop_back_impl( + Tuple const& t, + sprout::index_tuple + ) + { + return sprout::tuples::remake( + t, + sprout::tuples::get(t)... + ); + } + } // namespace detail + // + // pop_back + // + template + inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::pop_back::type pop_back( + Tuple const& t + ) + { + return sprout::tuples::detail::pop_back_impl::type>( + t, + sprout::index_range<0, sprout::tuples::tuple_size::value - 1>::make() + ); + } + } // namespace tuples +} // namespace sprout + +#endif // #ifndef SPROUT_TUPLE_OPERATION_POP_BACK_HPP diff --git a/sprout/tuple/operation/pop_front.hpp b/sprout/tuple/operation/pop_front.hpp new file mode 100644 index 00000000..d7044b42 --- /dev/null +++ b/sprout/tuple/operation/pop_front.hpp @@ -0,0 +1,51 @@ +#ifndef SPROUT_TUPLE_OPERATION_POP_FRONT_HPP +#define SPROUT_TUPLE_OPERATION_POP_FRONT_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace tuples { + namespace result_of { + // + // pop_front + // + template + struct pop_front + : public sprout::types::pop_front + {}; + } // namespace result_of + + namespace detail { + template + inline SPROUT_CONSTEXPR Result pop_front_impl( + Tuple const& t, + sprout::index_tuple + ) + { + return sprout::tuples::remake( + t, + sprout::tuples::get(t)... + ); + } + } // namespace detail + // + // pop_front + // + template + inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::pop_front::type>( + t, + sprout::index_range<1, sprout::tuples::tuple_size::value>::make() + ); + } + } // namespace tuples +} // namespace sprout + +#endif // #ifndef SPROUT_TUPLE_OPERATION_POP_FRONT_HPP diff --git a/sprout/tuple/operation/push_back.hpp b/sprout/tuple/operation/push_back.hpp index dc8f5383..50bbf60e 100644 --- a/sprout/tuple/operation/push_back.hpp +++ b/sprout/tuple/operation/push_back.hpp @@ -13,40 +13,40 @@ namespace sprout { // // push_back // - template + template struct push_back - : public sprout::types::push_back + : public sprout::types::push_back {}; } // namespace result_of namespace detail { - template + template inline SPROUT_CONSTEXPR Result push_back_impl( Tuple const& t, - T const& v, - sprout::index_tuple + sprout::index_tuple, + Args const&... args ) { return sprout::tuples::remake( t, sprout::tuples::get(t)..., - v + args... ); } } // namespace detail // // push_back // - template - inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::push_back::type push_back( + template + inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::push_back::type push_back( Tuple const& t, - T const& v + Args const&... args ) { - return sprout::tuples::detail::push_back_impl::type>( + return sprout::tuples::detail::push_back_impl::type>( t, - v, - sprout::index_range<0, sprout::tuples::tuple_size::value>::make() + sprout::index_range<0, sprout::tuples::tuple_size::value>::make(), + args... ); } } // namespace tuples diff --git a/sprout/tuple/operation/push_front.hpp b/sprout/tuple/operation/push_front.hpp index 6b7032bb..47f02b57 100644 --- a/sprout/tuple/operation/push_front.hpp +++ b/sprout/tuple/operation/push_front.hpp @@ -13,23 +13,23 @@ namespace sprout { // // push_front // - template + template struct push_front - : public sprout::types::push_front + : public sprout::types::push_front {}; } // namespace result_of namespace detail { - template + template inline SPROUT_CONSTEXPR Result push_front_impl( Tuple const& t, - T const& v, - sprout::index_tuple + sprout::index_tuple, + Args const&... args ) { return sprout::tuples::remake( t, - v, + args..., sprout::tuples::get(t)... ); } @@ -37,16 +37,16 @@ namespace sprout { // // push_front // - template - inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::push_front::type push_front( + template + inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::push_front::type push_front( Tuple const& t, - T const& v + Args const&... args ) { - return sprout::tuples::detail::push_front_impl::type>( + return sprout::tuples::detail::push_front_impl::type>( t, - v, - sprout::index_range<0, sprout::tuples::tuple_size::value>::make() + sprout::index_range<0, sprout::tuples::tuple_size::value>::make(), + args... ); } } // namespace tuples diff --git a/sprout/type/boost/mpl/v_iter.hpp b/sprout/type/boost/mpl/v_iter.hpp index 1c66c3ba..4c6a5eed 100644 --- a/sprout/type/boost/mpl/v_iter.hpp +++ b/sprout/type/boost/mpl/v_iter.hpp @@ -4,8 +4,10 @@ #include #include #include +#include #include #include +#include namespace sprout { namespace types { @@ -23,6 +25,13 @@ namespace sprout { struct prev > : public boost::mpl::prior > {}; + // + // advance + // + template + struct advance, Disatnce> + : public boost::mpl::advance_c, Disatnce> + {}; } // namespace types } // namespace sprout diff --git a/sprout/type/iterator.hpp b/sprout/type/iterator.hpp index 2809eb9f..1aed23fd 100644 --- a/sprout/type/iterator.hpp +++ b/sprout/type/iterator.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include diff --git a/sprout/type/iterator/advance.hpp b/sprout/type/iterator/advance.hpp new file mode 100644 index 00000000..95a887a0 --- /dev/null +++ b/sprout/type/iterator/advance.hpp @@ -0,0 +1,32 @@ +#ifndef SPROUT_TYPE_ITERATOR_ADVANCE_HPP +#define SPROUT_TYPE_ITERATOR_ADVANCE_HPP + +#include + +namespace sprout { + namespace types { + // + // advance + // + template + struct advance { + public: + typedef typename Iterator::template advance::type type; + }; + + template + struct advance + : public sprout::types::advance + {}; + template + struct advance + : public sprout::types::advance + {}; + template + struct advance + : public sprout::types::advance + {}; + } // namespace types +} // namespace sprout + +#endif // #ifndef SPROUT_TYPE_ITERATOR_ADVANCE_HPP diff --git a/sprout/type/iterator/index_iterator.hpp b/sprout/type/iterator/index_iterator.hpp index 07f1ca99..ad6f3d7d 100644 --- a/sprout/type/iterator/index_iterator.hpp +++ b/sprout/type/iterator/index_iterator.hpp @@ -9,84 +9,123 @@ namespace sprout { namespace types { - template - struct index_iterator; - - namespace detail { - // - // index_iterator_impl - // - template - struct index_iterator_impl; - template - struct index_iterator_impl< - Tuple, - Index, - typename std::enable_if< - sprout::types::tuple_size::value == 0 - || (Index < 0) - || (Index > sprout::types::tuple_size::value) - >::type - > { - public: - typedef sprout::types::void_ type; - typedef sprout::types::void_ next; - typedef sprout::types::void_ prev; - }; - template - struct index_iterator_impl< - Tuple, - Index, - typename std::enable_if< - sprout::types::tuple_size::value != 0 - && Index == 0 - >::type - > { - public: - typedef typename sprout::types::tuple_element::type type; - typedef sprout::types::index_iterator next; - typedef sprout::types::void_ prev; - }; - template - struct index_iterator_impl< - Tuple, - Index, - typename std::enable_if< - sprout::types::tuple_size::value != 0 - && Index == sprout::types::tuple_size::value - >::type - > { - public: - typedef sprout::types::void_ type; - typedef sprout::types::void_ next; - typedef sprout::types::index_iterator::value - 1> prev; - }; - template - struct index_iterator_impl< - Tuple, - Index, - typename std::enable_if< - sprout::types::tuple_size::value != 0 - && (Index > 0) - && (Index < sprout::types::tuple_size::value) - >::type - > { - public: - typedef typename sprout::types::tuple_element::type type; - typedef sprout::types::index_iterator next; - typedef sprout::types::index_iterator prev; - }; - } // namespace detail +// template +// struct index_iterator; +// +// namespace detail { +// // +// // index_iterator_impl +// // +// template +// struct index_iterator_impl; +// template +// struct index_iterator_impl< +// Tuple, +// Index, +// typename std::enable_if< +// sprout::types::tuple_size::value == 0 +// || (Index < 0) +// || (Index > sprout::types::tuple_size::value) +// >::type +// > { +// public: +// typedef sprout::types::void_ type; +// typedef sprout::types::void_ next; +// typedef sprout::types::void_ prev; +// public: +// template +// struct advance { +// public: +// typedef sprout::types::index_iterator type; +// }; +// }; +// template +// struct index_iterator_impl< +// Tuple, +// Index, +// typename std::enable_if< +// sprout::types::tuple_size::value != 0 +// && Index == 0 +// >::type +// > { +// public: +// typedef typename sprout::types::tuple_element::type type; +// typedef sprout::types::index_iterator next; +// typedef sprout::types::void_ prev; +// public: +// template +// struct advance { +// public: +// typedef sprout::types::index_iterator type; +// }; +// }; +// template +// struct index_iterator_impl< +// Tuple, +// Index, +// typename std::enable_if< +// sprout::types::tuple_size::value != 0 +// && Index == sprout::types::tuple_size::value +// >::type +// > { +// public: +// typedef sprout::types::void_ type; +// typedef sprout::types::void_ next; +// typedef sprout::types::index_iterator::value - 1> prev; +// public: +// template +// struct advance { +// public: +// typedef sprout::types::index_iterator type; +// }; +// }; +// template +// struct index_iterator_impl< +// Tuple, +// Index, +// typename std::enable_if< +// sprout::types::tuple_size::value != 0 +// && (Index > 0) +// && (Index < sprout::types::tuple_size::value) +// >::type +// > { +// public: +// typedef typename sprout::types::tuple_element::type type; +// typedef sprout::types::index_iterator next; +// typedef sprout::types::index_iterator prev; +// public: +// template +// struct advance { +// public: +// typedef sprout::types::index_iterator type; +// }; +// }; +// } // namespace detail // // index_iterator // +// template +// struct index_iterator +// : public sprout::types::detail::index_iterator_impl +// , public std::integral_constant +// { +// public: +// typedef typename sprout::types::detail::index_iterator_impl::type type; +// }; template struct index_iterator - : public sprout::types::detail::index_iterator_impl - , public std::integral_constant + : public std::integral_constant { public: - typedef typename sprout::types::detail::index_iterator_impl::type type; + typedef typename sprout::types::tuple_element::type type; + typedef sprout::types::index_iterator next; + typedef sprout::types::index_iterator prev; + public: + template + struct advance { + public: + typedef sprout::types::index_iterator type; + }; }; } // namespace types } // namespace sprout diff --git a/sprout/type/iterator/next.hpp b/sprout/type/iterator/next.hpp index 7b2b61d0..b877ade5 100644 --- a/sprout/type/iterator/next.hpp +++ b/sprout/type/iterator/next.hpp @@ -13,6 +13,19 @@ namespace sprout { public: typedef typename Iterator::next type; }; + + template + struct next + : public sprout::types::next + {}; + template + struct next + : public sprout::types::next + {}; + template + struct next + : public sprout::types::next + {}; } // namespace types } // namespace sprout diff --git a/sprout/type/iterator/prev.hpp b/sprout/type/iterator/prev.hpp index 13a5558d..c1323e71 100644 --- a/sprout/type/iterator/prev.hpp +++ b/sprout/type/iterator/prev.hpp @@ -13,6 +13,19 @@ namespace sprout { public: typedef typename Iterator::prev type; }; + + template + struct prev + : public sprout::types::prev + {}; + template + struct prev + : public sprout::types::prev + {}; + template + struct prev + : public sprout::types::prev + {}; } // namespace types } // namespace sprout diff --git a/sprout/type/operation.hpp b/sprout/type/operation.hpp index 387e3e5c..ad3a142e 100644 --- a/sprout/type/operation.hpp +++ b/sprout/type/operation.hpp @@ -6,5 +6,7 @@ #include #include #include +#include +#include #endif // #ifndef SPROUT_TYPE_OPERATION_HPP diff --git a/sprout/type/operation/pop_back.hpp b/sprout/type/operation/pop_back.hpp new file mode 100644 index 00000000..a1bfa46f --- /dev/null +++ b/sprout/type/operation/pop_back.hpp @@ -0,0 +1,35 @@ +#ifndef SPROUT_TYPE_OPERATION_POP_BACK_HPP +#define SPROUT_TYPE_OPERATION_POP_BACK_HPP + +#include +#include +#include +#include + +namespace sprout { + namespace types { + // + // pop_back + // + template + struct pop_back { + private: + template + struct apply_impl; + template + struct apply_impl > + : public sprout::types::rebind_types< + Tuple + >::template apply< + typename sprout::types::tuple_element::type... + > + {}; + public: + typedef typename apply_impl< + typename sprout::index_range<0, sprout::types::tuple_size::value - 1>::type + >::type type; + }; + } // namespace types +} // namespace sprout + +#endif // #ifndef SPROUT_TYPE_OPERATION_POP_BACK_HPP diff --git a/sprout/type/operation/pop_front.hpp b/sprout/type/operation/pop_front.hpp new file mode 100644 index 00000000..976ccb46 --- /dev/null +++ b/sprout/type/operation/pop_front.hpp @@ -0,0 +1,35 @@ +#ifndef SPROUT_TYPE_OPERATION_POP_FRONT_HPP +#define SPROUT_TYPE_OPERATION_POP_FRONT_HPP + +#include +#include +#include +#include + +namespace sprout { + namespace types { + // + // pop_front + // + template + struct pop_front { + private: + template + struct apply_impl; + template + struct apply_impl > + : public sprout::types::rebind_types< + Tuple + >::template apply< + typename sprout::types::tuple_element::type... + > + {}; + public: + typedef typename apply_impl< + typename sprout::index_range<1, sprout::types::tuple_size::value>::type + >::type type; + }; + } // namespace types +} // namespace sprout + +#endif // #ifndef SPROUT_TYPE_OPERATION_POP_FRONT_HPP diff --git a/sprout/type/operation/push_back.hpp b/sprout/type/operation/push_back.hpp index 37e4b3e6..5e7c6b41 100644 --- a/sprout/type/operation/push_back.hpp +++ b/sprout/type/operation/push_back.hpp @@ -11,8 +11,9 @@ namespace sprout { // // push_back // - template + template struct push_back { + static_assert(sizeof...(Ts) >= 1, "sizeof...(Ts) >= 1"); private: template struct apply_impl; @@ -22,7 +23,7 @@ namespace sprout { Tuple >::template apply< typename sprout::types::tuple_element::type..., - T + Ts... > {}; public: diff --git a/sprout/type/operation/push_front.hpp b/sprout/type/operation/push_front.hpp index 59177793..4a204de0 100644 --- a/sprout/type/operation/push_front.hpp +++ b/sprout/type/operation/push_front.hpp @@ -11,8 +11,9 @@ namespace sprout { // // push_front // - template + template struct push_front { + static_assert(sizeof...(Ts) >= 1, "sizeof...(Ts) >= 1"); private: template struct apply_impl; @@ -21,7 +22,7 @@ namespace sprout { : public sprout::types::rebind_types< Tuple >::template apply< - T, + Ts..., typename sprout::types::tuple_element::type... > {}; diff --git a/sprout/type/rebind_types.hpp b/sprout/type/rebind_types.hpp index 0c8b339a..24587c62 100644 --- a/sprout/type/rebind_types.hpp +++ b/sprout/type/rebind_types.hpp @@ -2,7 +2,6 @@ #define SPROUT_TYPE_REBIND_TYPES_HPP #include -#include namespace sprout { namespace types { @@ -26,13 +25,31 @@ namespace sprout { }; }; - template - struct rebind_types > { + template + struct rebind_types { public: template struct apply { public: - typedef sprout::types::type_tuple type; + typedef typename sprout::types::rebind_types< + Tuple + >::template apply< + Types... + >::type volatile type; + }; + }; + + template + struct rebind_types { + public: + template + struct apply { + public: + typedef typename sprout::types::rebind_types< + Tuple + >::template apply< + Types... + >::type const volatile type; }; }; } // namespace types diff --git a/sprout/type/type_tuple.hpp b/sprout/type/type_tuple.hpp index 9ddafdb5..2cddb8d1 100644 --- a/sprout/type/type_tuple.hpp +++ b/sprout/type/type_tuple.hpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace sprout { namespace types { @@ -21,6 +22,19 @@ namespace sprout { typedef sprout::types::index_iterator end; }; + // + // rebind_types + // + template + struct rebind_types > { + public: + template + struct apply { + public: + typedef sprout::types::type_tuple type; + }; + }; + namespace detail { template struct tuple_element_impl; @@ -37,6 +51,7 @@ namespace sprout { } // namespace types using sprout::types::type_tuple; + using sprout::types::rebind_types; } // namespace sprout namespace std {