diff --git a/include/Nazara/Core/TypeList.hpp b/include/Nazara/Core/TypeList.hpp index eff4158e7..90958804c 100644 --- a/include/Nazara/Core/TypeList.hpp +++ b/include/Nazara/Core/TypeList.hpp @@ -18,6 +18,9 @@ namespace Nz template struct ListAppend; + template typename> + struct ListApply; + template struct ListAt; @@ -33,6 +36,9 @@ namespace Nz template struct ListPrepend; + template + struct ListSize; + template struct ListUnique; } @@ -40,12 +46,18 @@ namespace Nz template using TypeListAppend = typename Detail::ListAppend::Result; + template typename Functor, typename... Args> + void TypeListApply(Args&&... args); + template using TypeListAt = typename Detail::ListAt::Type; template using TypeListConcat = typename Detail::ListConcat::Result; + template + constexpr bool TypeListEmpty = Detail::ListSize::Size == 0; + template constexpr bool TypeListFind = Detail::ListFind::Find(); @@ -55,6 +67,9 @@ namespace Nz template using TypeListPrepend = typename Detail::ListPrepend::Result; + template + constexpr std::size_t TypeListSize = Detail::ListSize::Size; + template using TypeListUnique = typename Detail::ListUnique, List>::Result; } diff --git a/include/Nazara/Core/TypeList.inl b/include/Nazara/Core/TypeList.inl index 62adec870..05e11c3ad 100644 --- a/include/Nazara/Core/TypeList.inl +++ b/include/Nazara/Core/TypeList.inl @@ -4,109 +4,139 @@ #include #include +#include #include -namespace Nz::Detail +namespace Nz { - template - struct ListAppend, NewType> + namespace Detail { - using Result = TypeList; - }; - - - template - struct ListAt, 0> - { - using Type = T; - }; - - template - struct ListAt, Index> - { - static_assert(Index <= sizeof...(ListTypes), "Index out of range"); - - using Type = typename ListAt, Index - 1>::Type; - }; - - - template - struct ListConcat, TypeList<>> - { - using Result = TypeList; - }; - - template - struct ListConcat, TypeList> - { - using Result = TypeList; - }; - - template - struct ListConcat, TypeList> - { - using Result = TypeList; - }; - - template - struct ListConcat, TypeList> - { - using Result = typename ListConcat, TypeList>::Result; - }; - - - struct ListFindHelper - { - template static constexpr bool Find() + template + struct ListAppend, NewType> { - if constexpr (std::is_same_v) - return true; - else - return Find(); - } + using Result = TypeList; + }; - template static constexpr bool Find() + + template typename Functor, typename T, typename... ListTypes> + struct ListApply, Functor> { - return false; - } - }; + template + static void Apply(Args&&... args) + { + Functor()(std::forward(args)...); + if constexpr (sizeof...(ListTypes) > 0) + ListApply, Functor>::Apply(std::forward(args)...); + } + }; - template - struct ListFind, TypeToFind> - { - static constexpr bool Find() + template + struct ListAt, 0> { - return ListFindHelper::Find(); - } - }; + using Type = T; + }; + + template + struct ListAt, Index> + { + static_assert(Index <= sizeof...(ListTypes), "Index out of range"); + + using Type = typename ListAt, Index - 1>::Type; + }; - template typename Class, typename... ListTypes> - struct ListInstantiate, Class> + template + struct ListConcat, TypeList<>> + { + using Result = TypeList; + }; + + template + struct ListConcat, TypeList> + { + using Result = TypeList; + }; + + template + struct ListConcat, TypeList> + { + using Result = TypeList; + }; + + template + struct ListConcat, TypeList> + { + using Result = typename ListConcat, TypeList>::Result; + }; + + + struct ListFindHelper + { + template static constexpr bool Find() + { + if constexpr (std::is_same_v) + return true; + else + return Find(); + } + + template static constexpr bool Find() + { + return false; + } + }; + + template + struct ListFind, TypeToFind> + { + static constexpr bool Find() + { + return ListFindHelper::Find(); + } + }; + + + template typename Class, typename... ListTypes> + struct ListInstantiate, Class> + { + using Result = Class; + }; + + + template + struct ListPrepend, NewType> + { + using Result = TypeList; + }; + + + template + struct ListSize> + { + static constexpr std::size_t Size = sizeof...(ListTypes); + }; + + + template + struct ListUnique, TypeList> + { + static constexpr bool IsTypePresent = ListFind, T1>::Find(); + using Result = std::conditional_t, TypeList>; + }; + + template + struct ListUnique, TypeList> + { + using Result = typename ListUnique, TypeList>::Result, TypeList>::Result; + }; + } + + template typename Functor, typename... Args> + void TypeListApply(Args&&... args) { - using Result = Class; - }; - - - template - struct ListPrepend, NewType> - { - using Result = TypeList; - }; - - - template - struct ListUnique, TypeList> - { - static constexpr bool IsTypePresent = ListFind, T1>::Find(); - using Result = std::conditional_t, TypeList>; - }; - - template - struct ListUnique, TypeList> - { - using Result = typename ListUnique, TypeList>::Result, TypeList>::Result; - }; + if constexpr (!TypeListEmpty) + Detail::ListApply::Apply(std::forward(args)...); + } } #include