Core/TypeList: Add Apply, Empty and Size operations

This commit is contained in:
Jérôme Leclercq 2021-07-06 11:00:53 +02:00
parent 1a1e16e9df
commit 7cd772a254
2 changed files with 136 additions and 91 deletions

View File

@ -18,6 +18,9 @@ namespace Nz
template<typename, typename> template<typename, typename>
struct ListAppend; struct ListAppend;
template<typename, template<typename> typename>
struct ListApply;
template<typename, std::size_t> template<typename, std::size_t>
struct ListAt; struct ListAt;
@ -33,6 +36,9 @@ namespace Nz
template<typename, typename> template<typename, typename>
struct ListPrepend; struct ListPrepend;
template<typename>
struct ListSize;
template<typename, typename> template<typename, typename>
struct ListUnique; struct ListUnique;
} }
@ -40,12 +46,18 @@ namespace Nz
template<typename List, typename NewType> template<typename List, typename NewType>
using TypeListAppend = typename Detail::ListAppend<List, NewType>::Result; using TypeListAppend = typename Detail::ListAppend<List, NewType>::Result;
template<typename List, template<typename> typename Functor, typename... Args>
void TypeListApply(Args&&... args);
template<typename List, std::size_t Index> template<typename List, std::size_t Index>
using TypeListAt = typename Detail::ListAt<List, Index>::Type; using TypeListAt = typename Detail::ListAt<List, Index>::Type;
template<typename FirstList, typename SecondList> template<typename FirstList, typename SecondList>
using TypeListConcat = typename Detail::ListConcat<FirstList, SecondList>::Result; using TypeListConcat = typename Detail::ListConcat<FirstList, SecondList>::Result;
template<typename List>
constexpr bool TypeListEmpty = Detail::ListSize<List>::Size == 0;
template<typename List, typename Type> template<typename List, typename Type>
constexpr bool TypeListFind = Detail::ListFind<List, Type>::Find(); constexpr bool TypeListFind = Detail::ListFind<List, Type>::Find();
@ -55,6 +67,9 @@ namespace Nz
template<typename List, typename NewType> template<typename List, typename NewType>
using TypeListPrepend = typename Detail::ListPrepend<List, NewType>::Result; using TypeListPrepend = typename Detail::ListPrepend<List, NewType>::Result;
template<typename List>
constexpr std::size_t TypeListSize = Detail::ListSize<List>::Size;
template<typename List> template<typename List>
using TypeListUnique = typename Detail::ListUnique<TypeList<>, List>::Result; using TypeListUnique = typename Detail::ListUnique<TypeList<>, List>::Result;
} }

View File

@ -4,9 +4,12 @@
#include <Nazara/Core/TypeList.hpp> #include <Nazara/Core/TypeList.hpp>
#include <type_traits> #include <type_traits>
#include <utility>
#include <Nazara/Core/Debug.hpp> #include <Nazara/Core/Debug.hpp>
namespace Nz::Detail namespace Nz
{
namespace Detail
{ {
template<typename NewType, typename... ListTypes> template<typename NewType, typename... ListTypes>
struct ListAppend<TypeList<ListTypes...>, NewType> struct ListAppend<TypeList<ListTypes...>, NewType>
@ -15,6 +18,18 @@ namespace Nz::Detail
}; };
template<template<typename> typename Functor, typename T, typename... ListTypes>
struct ListApply<TypeList<T, ListTypes...>, Functor>
{
template<typename... Args>
static void Apply(Args&&... args)
{
Functor<T>()(std::forward<Args>(args)...);
if constexpr (sizeof...(ListTypes) > 0)
ListApply<TypeList<ListTypes...>, Functor>::Apply(std::forward<Args>(args)...);
}
};
template<typename T, typename... ListTypes> template<typename T, typename... ListTypes>
struct ListAt<TypeList<T, ListTypes...>, 0> struct ListAt<TypeList<T, ListTypes...>, 0>
{ {
@ -95,6 +110,13 @@ namespace Nz::Detail
}; };
template<typename... ListTypes>
struct ListSize<TypeList<ListTypes...>>
{
static constexpr std::size_t Size = sizeof...(ListTypes);
};
template<typename... Types, typename T1> template<typename... Types, typename T1>
struct ListUnique<TypeList<Types...>, TypeList<T1>> struct ListUnique<TypeList<Types...>, TypeList<T1>>
{ {
@ -109,4 +131,12 @@ namespace Nz::Detail
}; };
} }
template<typename List, template<typename> typename Functor, typename... Args>
void TypeListApply(Args&&... args)
{
if constexpr (!TypeListEmpty<List>)
Detail::ListApply<List, Functor>::Apply(std::forward<Args>(args)...);
}
}
#include <Nazara/Core/DebugOff.hpp> #include <Nazara/Core/DebugOff.hpp>