add tuple: pop_back, pop_front

This commit is contained in:
bolero-MURAKAMI 2012-07-18 21:44:31 +09:00
parent 01ac3f7646
commit d2aec39067
18 changed files with 420 additions and 103 deletions

View file

@ -5,5 +5,7 @@
#include <sprout/tuple/operation/append_front.hpp> #include <sprout/tuple/operation/append_front.hpp>
#include <sprout/tuple/operation/push_back.hpp> #include <sprout/tuple/operation/push_back.hpp>
#include <sprout/tuple/operation/push_front.hpp> #include <sprout/tuple/operation/push_front.hpp>
#include <sprout/tuple/operation/pop_back.hpp>
#include <sprout/tuple/operation/pop_front.hpp>
#endif // #ifndef SPROUT_TUPLE_OPERATION_HPP #endif // #ifndef SPROUT_TUPLE_OPERATION_HPP

View file

@ -0,0 +1,51 @@
#ifndef SPROUT_TUPLE_OPERATION_POP_BACK_HPP
#define SPROUT_TUPLE_OPERATION_POP_BACK_HPP
#include <sprout/config.hpp>
#include <sprout/index_tuple.hpp>
#include <sprout/tuple/tuple.hpp>
#include <sprout/tuple/functions.hpp>
#include <sprout/type/operation/pop_back.hpp>
namespace sprout {
namespace tuples {
namespace result_of {
//
// pop_back
//
template<typename Tuple>
struct pop_back
: public sprout::types::pop_back<Tuple>
{};
} // namespace result_of
namespace detail {
template<typename Result, typename Tuple, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR Result pop_back_impl(
Tuple const& t,
sprout::index_tuple<Indexes...>
)
{
return sprout::tuples::remake<Result>(
t,
sprout::tuples::get<Indexes>(t)...
);
}
} // namespace detail
//
// pop_back
//
template<typename Tuple>
inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::pop_back<Tuple>::type pop_back(
Tuple const& t
)
{
return sprout::tuples::detail::pop_back_impl<typename sprout::tuples::result_of::pop_back<Tuple>::type>(
t,
sprout::index_range<0, sprout::tuples::tuple_size<Tuple>::value - 1>::make()
);
}
} // namespace tuples
} // namespace sprout
#endif // #ifndef SPROUT_TUPLE_OPERATION_POP_BACK_HPP

View file

@ -0,0 +1,51 @@
#ifndef SPROUT_TUPLE_OPERATION_POP_FRONT_HPP
#define SPROUT_TUPLE_OPERATION_POP_FRONT_HPP
#include <sprout/config.hpp>
#include <sprout/index_tuple.hpp>
#include <sprout/tuple/tuple.hpp>
#include <sprout/tuple/functions.hpp>
#include <sprout/type/operation/pop_front.hpp>
namespace sprout {
namespace tuples {
namespace result_of {
//
// pop_front
//
template<typename Tuple>
struct pop_front
: public sprout::types::pop_front<Tuple>
{};
} // namespace result_of
namespace detail {
template<typename Result, typename Tuple, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR Result pop_front_impl(
Tuple const& t,
sprout::index_tuple<Indexes...>
)
{
return sprout::tuples::remake<Result>(
t,
sprout::tuples::get<Indexes>(t)...
);
}
} // namespace detail
//
// pop_front
//
template<typename Tuple>
inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::pop_front<Tuple::type pop_front(
Tuple const& t,
)
{
return sprout::tuples::detail::pop_front_impl<typename sprout::tuples::result_of::pop_front<Tuple>::type>(
t,
sprout::index_range<1, sprout::tuples::tuple_size<Tuple>::value>::make()
);
}
} // namespace tuples
} // namespace sprout
#endif // #ifndef SPROUT_TUPLE_OPERATION_POP_FRONT_HPP

View file

@ -13,40 +13,40 @@ namespace sprout {
// //
// push_back // push_back
// //
template<typename Tuple, typename T> template<typename Tuple, typename... Args>
struct push_back struct push_back
: public sprout::types::push_back<Tuple, T> : public sprout::types::push_back<Tuple, Args...>
{}; {};
} // namespace result_of } // namespace result_of
namespace detail { namespace detail {
template<typename Result, typename Tuple, typename T, sprout::index_t... Indexes> template<typename Result, typename Tuple, typename... Args, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR Result push_back_impl( inline SPROUT_CONSTEXPR Result push_back_impl(
Tuple const& t, Tuple const& t,
T const& v, sprout::index_tuple<Indexes...>,
sprout::index_tuple<Indexes...> Args const&... args
) )
{ {
return sprout::tuples::remake<Result>( return sprout::tuples::remake<Result>(
t, t,
sprout::tuples::get<Indexes>(t)..., sprout::tuples::get<Indexes>(t)...,
v args...
); );
} }
} // namespace detail } // namespace detail
// //
// push_back // push_back
// //
template<typename Tuple, typename T> template<typename Tuple, typename... Args>
inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::push_back<Tuple, T>::type push_back( inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::push_back<Tuple, Args...>::type push_back(
Tuple const& t, Tuple const& t,
T const& v Args const&... args
) )
{ {
return sprout::tuples::detail::push_back_impl<typename sprout::tuples::result_of::push_back<Tuple, T>::type>( return sprout::tuples::detail::push_back_impl<typename sprout::tuples::result_of::push_back<Tuple, Args...>::type>(
t, t,
v, sprout::index_range<0, sprout::tuples::tuple_size<Tuple>::value>::make(),
sprout::index_range<0, sprout::tuples::tuple_size<Tuple>::value>::make() args...
); );
} }
} // namespace tuples } // namespace tuples

View file

@ -13,23 +13,23 @@ namespace sprout {
// //
// push_front // push_front
// //
template<typename Tuple, typename T> template<typename Tuple, typename... Args>
struct push_front struct push_front
: public sprout::types::push_front<Tuple, T> : public sprout::types::push_front<Tuple, Args...>
{}; {};
} // namespace result_of } // namespace result_of
namespace detail { namespace detail {
template<typename Result, typename Tuple, typename T, sprout::index_t... Indexes> template<typename Result, typename Tuple, typename... Args, sprout::index_t... Indexes>
inline SPROUT_CONSTEXPR Result push_front_impl( inline SPROUT_CONSTEXPR Result push_front_impl(
Tuple const& t, Tuple const& t,
T const& v, sprout::index_tuple<Indexes...>,
sprout::index_tuple<Indexes...> Args const&... args
) )
{ {
return sprout::tuples::remake<Result>( return sprout::tuples::remake<Result>(
t, t,
v, args...,
sprout::tuples::get<Indexes>(t)... sprout::tuples::get<Indexes>(t)...
); );
} }
@ -37,16 +37,16 @@ namespace sprout {
// //
// push_front // push_front
// //
template<typename Tuple, typename T> template<typename Tuple, typename... Args>
inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::push_front<Tuple, T>::type push_front( inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::push_front<Tuple, Args...>::type push_front(
Tuple const& t, Tuple const& t,
T const& v Args const&... args
) )
{ {
return sprout::tuples::detail::push_front_impl<typename sprout::tuples::result_of::push_front<Tuple, T>::type>( return sprout::tuples::detail::push_front_impl<typename sprout::tuples::result_of::push_front<Tuple, Args...>::type>(
t, t,
v, sprout::index_range<0, sprout::tuples::tuple_size<Tuple>::value>::make(),
sprout::index_range<0, sprout::tuples::tuple_size<Tuple>::value>::make() args...
); );
} }
} // namespace tuples } // namespace tuples

View file

@ -4,8 +4,10 @@
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <boost/mpl/vector.hpp> #include <boost/mpl/vector.hpp>
#include <boost/mpl/next_prior.hpp> #include <boost/mpl/next_prior.hpp>
#include <boost/mpl/advance.hpp>
#include <sprout/type/iterator/next.hpp> #include <sprout/type/iterator/next.hpp>
#include <sprout/type/iterator/prev.hpp> #include <sprout/type/iterator/prev.hpp>
#include <sprout/type/iterator/advance.hpp>
namespace sprout { namespace sprout {
namespace types { namespace types {
@ -23,6 +25,13 @@ namespace sprout {
struct prev<boost::mpl::v_iter<Seq, N> > struct prev<boost::mpl::v_iter<Seq, N> >
: public boost::mpl::prior<boost::mpl::v_iter<Seq, N> > : public boost::mpl::prior<boost::mpl::v_iter<Seq, N> >
{}; {};
//
// advance
//
template<typename Seq, long N, std::ptrdiff_t Disatnce>
struct advance<boost::mpl::v_iter<Seq, N>, Disatnce>
: public boost::mpl::advance_c<boost::mpl::v_iter<Seq, N>, Disatnce>
{};
} // namespace types } // namespace types
} // namespace sprout } // namespace sprout

View file

@ -4,6 +4,7 @@
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/type/iterator/next.hpp> #include <sprout/type/iterator/next.hpp>
#include <sprout/type/iterator/prev.hpp> #include <sprout/type/iterator/prev.hpp>
#include <sprout/type/iterator/advance.hpp>
#include <sprout/type/iterator/deref.hpp> #include <sprout/type/iterator/deref.hpp>
#include <sprout/type/iterator/distance.hpp> #include <sprout/type/iterator/distance.hpp>

View file

@ -0,0 +1,32 @@
#ifndef SPROUT_TYPE_ITERATOR_ADVANCE_HPP
#define SPROUT_TYPE_ITERATOR_ADVANCE_HPP
#include <sprout/config.hpp>
namespace sprout {
namespace types {
//
// advance
//
template<typename Iterator, std::ptrdiff_t Disatnce, typename Enable = void>
struct advance {
public:
typedef typename Iterator::template advance<Disatnce>::type type;
};
template<typename Iterator, std::ptrdiff_t Disatnce>
struct advance<Iterator const, Disatnce>
: public sprout::types::advance<Iterator, Disatnce>
{};
template<typename Iterator, std::ptrdiff_t Disatnce>
struct advance<Iterator volatile, Disatnce>
: public sprout::types::advance<Iterator, Disatnce>
{};
template<typename Iterator, std::ptrdiff_t Disatnce>
struct advance<Iterator const volatile, Disatnce>
: public sprout::types::advance<Iterator, Disatnce>
{};
} // namespace types
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_ITERATOR_ADVANCE_HPP

View file

@ -9,84 +9,123 @@
namespace sprout { namespace sprout {
namespace types { namespace types {
template<typename Tuple, std::ptrdiff_t Index> // template<typename Tuple, std::ptrdiff_t Index>
struct index_iterator; // struct index_iterator;
//
namespace detail { // namespace detail {
// // //
// index_iterator_impl // // index_iterator_impl
// // //
template<typename Tuple, std::ptrdiff_t Index, typename = void> // template<typename Tuple, std::ptrdiff_t Index, typename = void>
struct index_iterator_impl; // struct index_iterator_impl;
template<typename Tuple, std::ptrdiff_t Index> // template<typename Tuple, std::ptrdiff_t Index>
struct index_iterator_impl< // struct index_iterator_impl<
Tuple, // Tuple,
Index, // Index,
typename std::enable_if< // typename std::enable_if<
sprout::types::tuple_size<Tuple>::value == 0 // sprout::types::tuple_size<Tuple>::value == 0
|| (Index < 0) // || (Index < 0)
|| (Index > sprout::types::tuple_size<Tuple>::value) // || (Index > sprout::types::tuple_size<Tuple>::value)
>::type // >::type
> { // > {
public: // public:
typedef sprout::types::void_ type; // typedef sprout::types::void_ type;
typedef sprout::types::void_ next; // typedef sprout::types::void_ next;
typedef sprout::types::void_ prev; // typedef sprout::types::void_ prev;
}; // public:
template<typename Tuple, std::ptrdiff_t Index> // template<std::ptrdiff_t Disatnce>
struct index_iterator_impl< // struct advance {
Tuple, // public:
Index, // typedef sprout::types::index_iterator<Tuple, Index + Disatnce> type;
typename std::enable_if< // };
sprout::types::tuple_size<Tuple>::value != 0 // };
&& Index == 0 // template<typename Tuple, std::ptrdiff_t Index>
>::type // struct index_iterator_impl<
> { // Tuple,
public: // Index,
typedef typename sprout::types::tuple_element<Index, Tuple>::type type; // typename std::enable_if<
typedef sprout::types::index_iterator<Tuple, Index + 1> next; // sprout::types::tuple_size<Tuple>::value != 0
typedef sprout::types::void_ prev; // && Index == 0
}; // >::type
template<typename Tuple, std::ptrdiff_t Index> // > {
struct index_iterator_impl< // public:
Tuple, // typedef typename sprout::types::tuple_element<Index, Tuple>::type type;
Index, // typedef sprout::types::index_iterator<Tuple, Index + 1> next;
typename std::enable_if< // typedef sprout::types::void_ prev;
sprout::types::tuple_size<Tuple>::value != 0 // public:
&& Index == sprout::types::tuple_size<Tuple>::value // template<std::ptrdiff_t Disatnce>
>::type // struct advance {
> { // public:
public: // typedef sprout::types::index_iterator<Tuple, Index + Disatnce> type;
typedef sprout::types::void_ type; // };
typedef sprout::types::void_ next; // };
typedef sprout::types::index_iterator<Tuple, sprout::types::tuple_size<Tuple>::value - 1> prev; // template<typename Tuple, std::ptrdiff_t Index>
}; // struct index_iterator_impl<
template<typename Tuple, std::ptrdiff_t Index> // Tuple,
struct index_iterator_impl< // Index,
Tuple, // typename std::enable_if<
Index, // sprout::types::tuple_size<Tuple>::value != 0
typename std::enable_if< // && Index == sprout::types::tuple_size<Tuple>::value
sprout::types::tuple_size<Tuple>::value != 0 // >::type
&& (Index > 0) // > {
&& (Index < sprout::types::tuple_size<Tuple>::value) // public:
>::type // typedef sprout::types::void_ type;
> { // typedef sprout::types::void_ next;
public: // typedef sprout::types::index_iterator<Tuple, sprout::types::tuple_size<Tuple>::value - 1> prev;
typedef typename sprout::types::tuple_element<Index, Tuple>::type type; // public:
typedef sprout::types::index_iterator<Tuple, Index + 1> next; // template<std::ptrdiff_t Disatnce>
typedef sprout::types::index_iterator<Tuple, Index - 1> prev; // struct advance {
}; // public:
} // namespace detail // typedef sprout::types::index_iterator<Tuple, Index + Disatnce> type;
// };
// };
// template<typename Tuple, std::ptrdiff_t Index>
// struct index_iterator_impl<
// Tuple,
// Index,
// typename std::enable_if<
// sprout::types::tuple_size<Tuple>::value != 0
// && (Index > 0)
// && (Index < sprout::types::tuple_size<Tuple>::value)
// >::type
// > {
// public:
// typedef typename sprout::types::tuple_element<Index, Tuple>::type type;
// typedef sprout::types::index_iterator<Tuple, Index + 1> next;
// typedef sprout::types::index_iterator<Tuple, Index - 1> prev;
// public:
// template<std::ptrdiff_t Disatnce>
// struct advance {
// public:
// typedef sprout::types::index_iterator<Tuple, Index + Disatnce> type;
// };
// };
// } // namespace detail
// //
// index_iterator // index_iterator
// //
// template<typename Tuple, std::ptrdiff_t Index>
// struct index_iterator
// : public sprout::types::detail::index_iterator_impl<Tuple, Index>
// , public std::integral_constant<std::ptrdiff_t, Index>
// {
// public:
// typedef typename sprout::types::detail::index_iterator_impl<Tuple, Index>::type type;
// };
template<typename Tuple, std::ptrdiff_t Index> template<typename Tuple, std::ptrdiff_t Index>
struct index_iterator struct index_iterator
: public sprout::types::detail::index_iterator_impl<Tuple, Index> : public std::integral_constant<std::ptrdiff_t, Index>
, public std::integral_constant<std::ptrdiff_t, Index>
{ {
public: public:
typedef typename sprout::types::detail::index_iterator_impl<Tuple, Index>::type type; typedef typename sprout::types::tuple_element<Index, Tuple>::type type;
typedef sprout::types::index_iterator<Tuple, Index + 1> next;
typedef sprout::types::index_iterator<Tuple, Index - 1> prev;
public:
template<std::ptrdiff_t Disatnce>
struct advance {
public:
typedef sprout::types::index_iterator<Tuple, Index + Disatnce> type;
};
}; };
} // namespace types } // namespace types
} // namespace sprout } // namespace sprout

View file

@ -13,6 +13,19 @@ namespace sprout {
public: public:
typedef typename Iterator::next type; typedef typename Iterator::next type;
}; };
template<typename Iterator>
struct next<Iterator const>
: public sprout::types::next<Iterator>
{};
template<typename Iterator>
struct next<Iterator volatile>
: public sprout::types::next<Iterator>
{};
template<typename Iterator>
struct next<Iterator const volatile>
: public sprout::types::next<Iterator>
{};
} // namespace types } // namespace types
} // namespace sprout } // namespace sprout

View file

@ -13,6 +13,19 @@ namespace sprout {
public: public:
typedef typename Iterator::prev type; typedef typename Iterator::prev type;
}; };
template<typename Iterator>
struct prev<Iterator const>
: public sprout::types::prev<Iterator>
{};
template<typename Iterator>
struct prev<Iterator volatile>
: public sprout::types::prev<Iterator>
{};
template<typename Iterator>
struct prev<Iterator const volatile>
: public sprout::types::prev<Iterator>
{};
} // namespace types } // namespace types
} // namespace sprout } // namespace sprout

View file

@ -6,5 +6,7 @@
#include <sprout/type/operation/append_front.hpp> #include <sprout/type/operation/append_front.hpp>
#include <sprout/type/operation/push_back.hpp> #include <sprout/type/operation/push_back.hpp>
#include <sprout/type/operation/push_front.hpp> #include <sprout/type/operation/push_front.hpp>
#include <sprout/type/operation/pop_back.hpp>
#include <sprout/type/operation/pop_front.hpp>
#endif // #ifndef SPROUT_TYPE_OPERATION_HPP #endif // #ifndef SPROUT_TYPE_OPERATION_HPP

View file

@ -0,0 +1,35 @@
#ifndef SPROUT_TYPE_OPERATION_POP_BACK_HPP
#define SPROUT_TYPE_OPERATION_POP_BACK_HPP
#include <sprout/config.hpp>
#include <sprout/index_tuple.hpp>
#include <sprout/type/tuple.hpp>
#include <sprout/type/rebind_types.hpp>
namespace sprout {
namespace types {
//
// pop_back
//
template<typename Tuple>
struct pop_back {
private:
template<typename IndexTuple>
struct apply_impl;
template<sprout::index_t... Indexes>
struct apply_impl<sprout::index_tuple<Indexes...> >
: public sprout::types::rebind_types<
Tuple
>::template apply<
typename sprout::types::tuple_element<Indexes, Tuple>::type...
>
{};
public:
typedef typename apply_impl<
typename sprout::index_range<0, sprout::types::tuple_size<Tuple>::value - 1>::type
>::type type;
};
} // namespace types
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_OPERATION_POP_BACK_HPP

View file

@ -0,0 +1,35 @@
#ifndef SPROUT_TYPE_OPERATION_POP_FRONT_HPP
#define SPROUT_TYPE_OPERATION_POP_FRONT_HPP
#include <sprout/config.hpp>
#include <sprout/index_tuple.hpp>
#include <sprout/type/tuple.hpp>
#include <sprout/type/rebind_types.hpp>
namespace sprout {
namespace types {
//
// pop_front
//
template<typename Tuple>
struct pop_front {
private:
template<typename IndexTuple>
struct apply_impl;
template<sprout::index_t... Indexes>
struct apply_impl<sprout::index_tuple<Indexes...> >
: public sprout::types::rebind_types<
Tuple
>::template apply<
typename sprout::types::tuple_element<Indexes, Tuple>::type...
>
{};
public:
typedef typename apply_impl<
typename sprout::index_range<1, sprout::types::tuple_size<Tuple>::value>::type
>::type type;
};
} // namespace types
} // namespace sprout
#endif // #ifndef SPROUT_TYPE_OPERATION_POP_FRONT_HPP

View file

@ -11,8 +11,9 @@ namespace sprout {
// //
// push_back // push_back
// //
template<typename Tuple, typename T> template<typename Tuple, typename... Ts>
struct push_back { struct push_back {
static_assert(sizeof...(Ts) >= 1, "sizeof...(Ts) >= 1");
private: private:
template<typename IndexTuple> template<typename IndexTuple>
struct apply_impl; struct apply_impl;
@ -22,7 +23,7 @@ namespace sprout {
Tuple Tuple
>::template apply< >::template apply<
typename sprout::types::tuple_element<Indexes, Tuple>::type..., typename sprout::types::tuple_element<Indexes, Tuple>::type...,
T Ts...
> >
{}; {};
public: public:

View file

@ -11,8 +11,9 @@ namespace sprout {
// //
// push_front // push_front
// //
template<typename Tuple, typename T> template<typename Tuple, typename... Ts>
struct push_front { struct push_front {
static_assert(sizeof...(Ts) >= 1, "sizeof...(Ts) >= 1");
private: private:
template<typename IndexTuple> template<typename IndexTuple>
struct apply_impl; struct apply_impl;
@ -21,7 +22,7 @@ namespace sprout {
: public sprout::types::rebind_types< : public sprout::types::rebind_types<
Tuple Tuple
>::template apply< >::template apply<
T, Ts...,
typename sprout::types::tuple_element<Indexes, Tuple>::type... typename sprout::types::tuple_element<Indexes, Tuple>::type...
> >
{}; {};

View file

@ -2,7 +2,6 @@
#define SPROUT_TYPE_REBIND_TYPES_HPP #define SPROUT_TYPE_REBIND_TYPES_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/type/type_tuple.hpp>
namespace sprout { namespace sprout {
namespace types { namespace types {
@ -26,13 +25,31 @@ namespace sprout {
}; };
}; };
template<typename... Ts> template<typename Tuple>
struct rebind_types<sprout::types::type_tuple<Ts...> > { struct rebind_types<Tuple volatile> {
public: public:
template<typename... Types> template<typename... Types>
struct apply { struct apply {
public: public:
typedef sprout::types::type_tuple<Types...> type; typedef typename sprout::types::rebind_types<
Tuple
>::template apply<
Types...
>::type volatile type;
};
};
template<typename Tuple>
struct rebind_types<Tuple const volatile> {
public:
template<typename... Types>
struct apply {
public:
typedef typename sprout::types::rebind_types<
Tuple
>::template apply<
Types...
>::type const volatile type;
}; };
}; };
} // namespace types } // namespace types

View file

@ -8,6 +8,7 @@
#include <sprout/type/tuple.hpp> #include <sprout/type/tuple.hpp>
#include <sprout/type/iterator.hpp> #include <sprout/type/iterator.hpp>
#include <sprout/type/iterator/index_iterator.hpp> #include <sprout/type/iterator/index_iterator.hpp>
#include <sprout/type/rebind_types.hpp>
namespace sprout { namespace sprout {
namespace types { namespace types {
@ -21,6 +22,19 @@ namespace sprout {
typedef sprout::types::index_iterator<type_tuple, sizeof...(Types)> end; typedef sprout::types::index_iterator<type_tuple, sizeof...(Types)> end;
}; };
//
// rebind_types
//
template<typename... Ts>
struct rebind_types<sprout::types::type_tuple<Ts...> > {
public:
template<typename... Types>
struct apply {
public:
typedef sprout::types::type_tuple<Types...> type;
};
};
namespace detail { namespace detail {
template<std::size_t I, typename T> template<std::size_t I, typename T>
struct tuple_element_impl; struct tuple_element_impl;
@ -37,6 +51,7 @@ namespace sprout {
} // namespace types } // namespace types
using sprout::types::type_tuple; using sprout::types::type_tuple;
using sprout::types::rebind_types;
} // namespace sprout } // namespace sprout
namespace std { namespace std {