c++-模板元编程TypeList定义及基本操作

#ifndef TYPELIST_DEF_H
#define TYPELIST_DEF_H

#include <iostream>
#include <boost/type_index.hpp>

using namespace std;

/*
 TypeList 及 Typelist 的基本操作
1. typelist
2. front
3. popfront
4. pushront
5. pushback
6. reverse
7. popback
8. size
9. nth_element
10. IsEmpty;
*/

template<typename ...Types>
struct TypeList{};

// 辅助类
template<typename T>
struct Identity {
    using type = T;
};

// ************************* IsEmpty
template<typename List>
struct IsEmpty_ {
    constexpr static auto value = false;
};

template<typename List>
constexpr auto IsEmpty_v = IsEmpty_<List>::value;

template<>
struct IsEmpty_<TypeList<>> {
    constexpr static auto value = true;
};

// ************************* Front
template<typename List, bool = IsEmpty_v<List>>
struct Front_;

template<typename Head, typename ...Rest>
struct Front_<TypeList<Head, Rest...>, false> {
    using type = Head;
};

template<typename List>
struct Front_<List, true> {
    static_assert(IsEmpty_v<List>, "empty List, no front type");
};

template<typename List>
using Front_t = typename Front_<List>::type;


// ************************* PopFront;

template<typename List, bool = IsEmpty_v<List>>
struct PopFront_;

template<typename List>
using PopFront_t = typename PopFront_<List>::type;

template<typename Head, typename ...Rest>
struct PopFront_<TypeList<Head, Rest...>, false> {
    using type = TypeList<Rest...>;
};

template<typename List>
struct PopFront_<List, true> {
    using type = List;
};

// ************************* PushFront;

template<typename List, typename Elem>
struct PushFront_;

template<typename List, typename Elem>
using PushFront_t = typename PushFront_<List, Elem>::type;

template<typename ...Types, typename Elem>
struct PushFront_<TypeList<Types...>, Elem> {
    using type = TypeList<Elem, Types...>;
};

// ************************* PushBack
template<typename List, typename Elem>
struct PushBack_;

template<typename List, typename Elem>
using PushBack_t = typename PushBack_<List, Elem>::type;

template<typename ...Types, typename Elem>
struct PushBack_<TypeList<Types...>, Elem> {
    using type = TypeList<Types..., Elem>;
};

// ************************* Reverse

// 类比下面代码
//void reserseStack(stack<int>& st) {
//    // 递归边界
//    if (st.empty()) {
//        return;
//    }
//    // 得到头
//    int front = st.top(); st.pop();
//    // 递归
//    reserseStack(st);
//    // 操作
//    st.push(front);
//}

// 实现方法一
//template<typename List>
//struct Reverse_ {
// private:
//    using Front = FrontT<List>;
//    using Tail =  typename Reverse_<PopFrontT<List>>::type;
// public:
//    using type = PushFrontT<Tail, Front>;
//
//};

// 实现方法二v
template<typename List, bool = IsEmpty_v<List>>
struct Reverse_ : public PushBack_<typename Reverse_<PopFront_t<List>>::type, Front_t<List>> {
};

template<typename List>
using Reverse_t = typename Reverse_<List>::type;

template<typename List>
struct Reverse_<List, true> {
    using type = List;
};

// ************************* PopBack
//template<typename List>
//struct PopBack_ {
//    using type = Reverse_<PopFrontT<ReverseT<List>>>;
//};

template<typename List>
struct PopBack_ : public Reverse_<PopFront_t<Reverse_t<List>>> {};

template<typename List>
using PopBack_t = typename PopBack_<List>::type;

template<>
struct PopBack_<TypeList<>> {
    using type = TypeList<>;
};

// ************************* Size

template<typename List>
struct ListSize_;

template<typename List>
constexpr auto ListSize_v = ListSize_<List>::value;

template<typename ...Types>
struct ListSize_<TypeList<Types...>> {
    constexpr static auto value = sizeof...(Types);
};

// ************************* NthElem

template<typename List, size_t N, bool = (ListSize_v<List> >= N + 1)>
struct NthElem_;

template<typename List, size_t N>
using NthElem_t = typename NthElem_<List, N>::type;


template<typename List, size_t N>
struct NthElem_<List, N, true> : public NthElem_<PopFront_t<List>, N - 1> {};

template<typename Head, typename ...Rest>
struct NthElem_<TypeList<Head, Rest...>, 0, true> {
    using type = Head;
};

template<typename List, size_t N>
struct NthElem_<List, N, false> {
    static_assert(ListSize_v<List> <= N + 1, "NthElem index out of range");
};

//#define DEF
//#ifdef DEF
int main() {
    using SL = TypeList<int, long>;
    Reverse_t<SL> ss;
    cout << boost::typeindex::type_id_with_cvr<decltype(ss)>().pretty_name() << endl;
    NthElem_t<SL, 0> t;
    cout << boost::typeindex::type_id_with_cvr<decltype(t)>().pretty_name() << endl;
}
//#endif

#endif //TYPELIST_DEF_H

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值