5-1
//5-1
template<class Seq,int N>
struct double_first_half_imp{
typedef typename mpl::at<Seq,int_<0>>::type element;
typedef typename double_first_half_imp<typename mpl::pop_front<Seq>::type,N-1>::type oritype;
typedef typename mpl::push_front<oritype,typename multiplies<element,int_<2> >::type>::type type;
};
template<class Seq>
struct double_first_half_imp<Seq,1>{
typedef typename mpl::push_front<typename mpl::pop_front<Seq>::type,typename multiplies<typename mpl::at<Seq,int_<0>>::type,int_<2> >::type>::type type;
};
template<class Seq>
struct double_first_half{
static const int size = mpl::size<Seq>::type::value;
typedef typename double_first_half_imp<Seq,size/2>::type type;
};
//5-1
5-2
//5-2
namespace boost{namespace mpl{
template<>
struct push_front_impl<SeqTag>
{
template<class Seq,class T>
struct apply : Sequence<T,typename Seq::T0,typename Seq::T1>{
static const int Ssize= Seq_size<typename Seq::T0,typename Seq::T1,typename Seq::T2>::type::value;
BOOST_STATIC_ASSERT((Ssize<3));
};
};
};}; //5-2
5-3
//5-3
template<typename Seq,typename T,int N=2>
struct Seq_insert;
template<typename Seq,typename T>
struct Seq_insert<Seq,T,0>:Sequence<T,typename Seq::T0,typename Seq::T1>{};
template<typename Seq,typename T>
struct Seq_insert<Seq,T,1>:Sequence<typename Seq::T0,T,typename Seq::T1>{};
template<typename Seq,typename T>
struct Seq_insert<Seq,T,2>:Sequence<typename Seq::T0,typename Seq::T1,T>{};
//5-3
//5-3
namespace boost{namespace mpl{
template<>
struct push_back_impl<SeqTag>
{
template<class Seq,class T>
struct apply{
static const int Ssize = Seq_size<typename Seq::T0,typename Seq::T1,typename Seq::T2>::type::value;
BOOST_STATIC_ASSERT((Ssize<3));
typedef typename Seq_insert<Seq,T,Seq_size<typename Seq::T0,typename Seq::T1,typename Seq::T2>::type::value>::type type;
};
};
template<typename tag>
struct insert_imp;
template<>
struct insert_imp<SeqTag>
{
template<class Seq,class T,class pos>
struct apply:Seq_insert<Seq,T,pos::value>{};
};
template<typename Seq,typename T,typename pos>
struct insert:insert_imp<typename Seq::tag>::template apply<Seq,T,pos>{};
};}; //5-3
//5-5
template<typename Seq,int N>struct Seq_pop_back;
template<typename Seq>
struct Seq_pop_back<Seq,0>:Sequence<>{};
template<typename Seq>
struct Seq_pop_back<Seq,1>:Sequence<>{};
template<typename Seq>
struct Seq_pop_back<Seq,2>:Sequence<typename Seq::T0>{};
template<typename Seq>
struct Seq_pop_back<Seq,3>:Sequence<typename Seq::T0,typename Seq::T1>{};
template<typename Seq,int N>struct Seq_pop_front;
template<typename Seq>
struct Seq_pop_front<Seq,0>:Sequence<>{};
template<typename Seq>
struct Seq_pop_front<Seq,1>:Sequence<>{};
template<typename Seq>
struct Seq_pop_front<Seq,2>:Sequence<typename Seq::T1>{};
template<typename Seq>
struct Seq_pop_front<Seq,3>:Sequence<typename Seq::T1,typename Seq::T2>{};
//5-5
//5-5
namespace boost{namespace mpl{
template<>
struct pop_back_impl<SeqTag>{
template<class Seq>
struct apply:Seq_pop_back<Seq,Seq_size<typename Seq::T0,typename Seq::T1,typename Seq::T2>::type::value>{};
};
template<>
struct pop_front_impl<SeqTag>{
template<class Seq>
struct apply:Seq_pop_front<Seq,Seq_size<typename Seq::T0,typename Seq::T1,typename Seq::T2>::type::value>{};
};
};}; //5-5
//5-6在下面
//5-10
struct nothing{};
template<typename T0,typename T1=nothing,typename T2=nothing>
struct tree
{
typedef T0 root;
typedef T1 lson;
typedef T2 rson;
};
template<typename vec,typename T>//T是个普通类型
struct inorder_view_imp:mpl::push_back<vec,T>{};
template<typename vec>
struct inorder_view_imp<vec,nothing>{//nothing
typedef vec type;
};
template<typename vec,typename T0,typename T1,typename T2>//T是树
struct inorder_view_imp<vec,tree<T0,T1,T2> >
{
typedef typename mpl::push_back<vec,T0>::type tmpvec;
typedef typename inorder_view_imp<typename inorder_view_imp<tmpvec,T1>::type,T2>::type type;
};
template<class T>
struct inorder_view:inorder_view_imp<mpl::vector<>,T>::type{};
//5-10
//5-6
struct dimensions_tag;
template<class T>
struct dimensions_imp{
static const int num = 0;
};
template<class T,int N>
struct dimensions_imp<T[N]>{
static const int value = N;
static const int num = 1+dimensions_imp<T>::num;
typedef dimensions_imp<T> next;
};
template<class T>
struct dimensions
{
typedef dimensions_tag tag;
typedef T type;
};
template<class T,int num>struct at_c_imp;
template<class T,int N,int num>
struct at_c_imp<T[N],num>:at_c_imp<T,num-1>{};
template<class T,int N>
struct at_c_imp<T[N],1>{
typedef mpl::int_<N> type;
};
namespace boost{namespace mpl{
template<>
struct size_impl<dimensions_tag>{
template<class Seq>
struct apply
{
typedef int_<dimensions_imp<typename Seq::type>::num> type;
};
};
};};
template<class T,int N>
struct at_c:at_c_imp<typename T::type,mpl::size<T>::type::value-N>{};
//5-6
//5-7把tiny打过一遍后觉得这些操作都是比较相似的,的确很多时候只有加一个外覆器就能解决大部分问题。
//5-8
struct f_s_tag;
template<int N>
struct fibonacci_series_value{
typedef typename mpl::plus<typename fibonacci_series_value<N-1>::type,typename fibonacci_series_value<N-2>::type>::type type;
};
template<>
struct fibonacci_series_value<0>{
typedef mpl::int_<0> type;
};
template<>
struct fibonacci_series_value<1>{
typedef mpl::int_<1> type;
};
struct fibonacci_series
{
typedef f_s_tag tag;
};
namespace boost{namespace mpl{
template<class pos>
struct iterator<fibonacci_series,pos>{};
template<>
struct begin<fibonacci_series>{
typedef iterator<fibonacci_series,int_<0> > type;
};
template<class pos>
struct next<iterator<fibonacci_series,pos> >
{
typedef iterator<fibonacci_series,typename next<pos>::type > type;
};
template<class pos>
struct deref<iterator<fibonacci_series,pos> >:fibonacci_series_value<pos::value>{
};
template<class pos,int N>
struct advance_c<iterator<fibonacci_series,pos>,N>{
typedef iterator<fibonacci_series,typename plus<pos,int_<N> >::type> type;
};
};};