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/push_back.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

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
//
template<typename Tuple, typename T>
template<typename Tuple, typename... Args>
struct push_back
: public sprout::types::push_back<Tuple, T>
: public sprout::types::push_back<Tuple, Args...>
{};
} // namespace result_of
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(
Tuple const& t,
T const& v,
sprout::index_tuple<Indexes...>
sprout::index_tuple<Indexes...>,
Args const&... args
)
{
return sprout::tuples::remake<Result>(
t,
sprout::tuples::get<Indexes>(t)...,
v
args...
);
}
} // namespace detail
//
// push_back
//
template<typename Tuple, typename T>
inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::push_back<Tuple, T>::type push_back(
template<typename Tuple, typename... Args>
inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::push_back<Tuple, Args...>::type push_back(
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,
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

View file

@ -13,23 +13,23 @@ namespace sprout {
//
// push_front
//
template<typename Tuple, typename T>
template<typename Tuple, typename... Args>
struct push_front
: public sprout::types::push_front<Tuple, T>
: public sprout::types::push_front<Tuple, Args...>
{};
} // namespace result_of
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(
Tuple const& t,
T const& v,
sprout::index_tuple<Indexes...>
sprout::index_tuple<Indexes...>,
Args const&... args
)
{
return sprout::tuples::remake<Result>(
t,
v,
args...,
sprout::tuples::get<Indexes>(t)...
);
}
@ -37,16 +37,16 @@ namespace sprout {
//
// push_front
//
template<typename Tuple, typename T>
inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::push_front<Tuple, T>::type push_front(
template<typename Tuple, typename... Args>
inline SPROUT_CONSTEXPR typename sprout::tuples::result_of::push_front<Tuple, Args...>::type push_front(
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,
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

View file

@ -4,8 +4,10 @@
#include <sprout/config.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/next_prior.hpp>
#include <boost/mpl/advance.hpp>
#include <sprout/type/iterator/next.hpp>
#include <sprout/type/iterator/prev.hpp>
#include <sprout/type/iterator/advance.hpp>
namespace sprout {
namespace types {
@ -23,6 +25,13 @@ namespace sprout {
struct prev<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 sprout

View file

@ -4,6 +4,7 @@
#include <sprout/config.hpp>
#include <sprout/type/iterator/next.hpp>
#include <sprout/type/iterator/prev.hpp>
#include <sprout/type/iterator/advance.hpp>
#include <sprout/type/iterator/deref.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 types {
template<typename Tuple, std::ptrdiff_t Index>
struct index_iterator;
namespace detail {
//
// index_iterator_impl
//
template<typename Tuple, std::ptrdiff_t Index, typename = void>
struct index_iterator_impl;
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 sprout::types::void_ type;
typedef sprout::types::void_ next;
typedef sprout::types::void_ prev;
};
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
>::type
> {
public:
typedef typename sprout::types::tuple_element<Index, Tuple>::type type;
typedef sprout::types::index_iterator<Tuple, Index + 1> next;
typedef sprout::types::void_ prev;
};
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 == sprout::types::tuple_size<Tuple>::value
>::type
> {
public:
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<
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;
};
} // namespace detail
// template<typename Tuple, std::ptrdiff_t Index>
// struct index_iterator;
//
// namespace detail {
// //
// // index_iterator_impl
// //
// template<typename Tuple, std::ptrdiff_t Index, typename = void>
// struct index_iterator_impl;
// 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 sprout::types::void_ type;
// typedef sprout::types::void_ next;
// typedef sprout::types::void_ prev;
// public:
// template<std::ptrdiff_t Disatnce>
// struct advance {
// public:
// 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
// >::type
// > {
// public:
// typedef typename sprout::types::tuple_element<Index, Tuple>::type type;
// typedef sprout::types::index_iterator<Tuple, Index + 1> next;
// typedef sprout::types::void_ prev;
// public:
// template<std::ptrdiff_t Disatnce>
// struct advance {
// public:
// 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 == sprout::types::tuple_size<Tuple>::value
// >::type
// > {
// public:
// typedef sprout::types::void_ type;
// typedef sprout::types::void_ next;
// typedef sprout::types::index_iterator<Tuple, sprout::types::tuple_size<Tuple>::value - 1> prev;
// public:
// template<std::ptrdiff_t Disatnce>
// struct advance {
// public:
// 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
//
// 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>
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:
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 sprout

View file

@ -13,6 +13,19 @@ namespace sprout {
public:
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 sprout

View file

@ -13,6 +13,19 @@ namespace sprout {
public:
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 sprout

View file

@ -6,5 +6,7 @@
#include <sprout/type/operation/append_front.hpp>
#include <sprout/type/operation/push_back.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

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

View file

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

View file

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

View file

@ -8,6 +8,7 @@
#include <sprout/type/tuple.hpp>
#include <sprout/type/iterator.hpp>
#include <sprout/type/iterator/index_iterator.hpp>
#include <sprout/type/rebind_types.hpp>
namespace sprout {
namespace types {
@ -21,6 +22,19 @@ namespace sprout {
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 {
template<std::size_t I, typename T>
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 {