//
// Created by 倪超 on 2021/10/26.
//
#ifndef TYPELIST_DEF_H
#define TYPELIST_DEF_H
#include
#include
using namespace std;
template
struct TypeList{};
// 辅助类
template
struct Identity {
using type = T;
};
// ************************* IsEmpty
template
struct IsEmpty_ {
constexpr static auto value = false;
};
template
constexpr auto IsEmpty_v = IsEmpty_::value;
template<>
struct IsEmpty_> {
constexpr static auto value = true;
};
// ************************* Front
template>
struct Front_;
template
struct Front_, false> {
using type = Head;
};
template
struct Front_ {
static_assert(IsEmpty_v, "empty List, no front type");
};
template
using Front_t = typename Front_::type;
// ************************* PopFront;
template>
struct PopFront_;
template
using PopFront_t = typename PopFront_::type;
template
struct PopFront_, false> {
using type = TypeList;
};
template
struct PopFront_ {
using type = List;
};
// ************************* PushFront;
template
struct PushFront_;
template
using PushFront_t = typename PushFront_::type;
template
struct PushFront_, Elem> {
using type = TypeList;
};
// ************************* PushBack
template
struct PushBack_;
template
using PushBack_t = typename PushBack_::type;
template
struct PushBack_, Elem> {
using type = TypeList;
};
// ************************* Reverse
// 类比下面代码
//void reserseStack(stack& st) {
// // 递归边界
// if (st.empty()) {
// return;
// }
// // 得到头
// int front = st.top(); st.pop();
// // 递归
// reserseStack(st);
// // 操作
// st.push(front);
//}
// 实现方法一
//template
//struct Reverse_ {
// private:
// using Front = FrontT;
// using Tail = typename Reverse_>::type;
// public:
// using type = PushFrontT;
//
//};
// 实现方法二v
template>
struct Reverse_ : public PushBack_>::type, Front_t> {
};
template
using Reverse_t = typename Reverse_::type;
template
struct Reverse_ {
using type = List;
};
// ************************* PopBack
//template
//struct PopBack_ {
// using type = Reverse_>>;
//};
template
struct PopBack_ : public Reverse_>> {};
template
using PopBack_t = typename PopBack_::type;
template<>
struct PopBack_> {
using type = TypeList<>;
};
// ************************* Size
template
struct ListSize_;
template
constexpr auto ListSize_v = ListSize_::value;
template
struct ListSize_> {
constexpr static auto value = sizeof...(Types);
};
// ************************* NthElem
template >= N + 1)>
struct NthElem_;
template >= N + 1)>
using NthElem_t = typename NthElem_::type;
template
struct NthElem_ : public NthElem_, N - 1> {};
template
struct NthElem_, 0, true> {
using type = Head;
};
template
struct NthElem_ {
static_assert(ListSize_v >= N + 1, "NthElem index out of range");
};
//#define DEF
#ifdef DEF
int main() {
using SL = TypeList;
Reverse_t ss;
cout << boost::typeindex::type_id_with_cvr().pretty_name() << endl;
NthElem_t t;
cout << boost::typeindex::type_id_with_cvr().pretty_name() << endl;
}
#endif
#endif //TYPELIST_DEF_H