#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
c++-模板元编程TypeList定义及基本操作
最新推荐文章于 2023-11-03 13:26:42 发布