diff options
| author | Alexey Gavrilov <rebovas@yahoo.com> | 2024-05-24 14:07:47 +0700 |
|---|---|---|
| committer | Alexey Gavrilov <rebovas@yahoo.com> | 2024-05-24 14:07:47 +0700 |
| commit | 5fbf41e967ed8e413ecf1e6abb72e8d285169df4 (patch) | |
| tree | 48e25b199ae3459e12c7202f7b18a37cd087bf9b /include/Templates.h | |
| parent | 0a50b1758fd3da118408fd724825d0a50a9ecf17 (diff) | |
Pic + Tuple + refactor PrimaryInitialization class
Diffstat (limited to 'include/Templates.h')
| -rw-r--r-- | include/Templates.h | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/include/Templates.h b/include/Templates.h new file mode 100644 index 0000000..8a1bd95 --- /dev/null +++ b/include/Templates.h @@ -0,0 +1,127 @@ +#ifndef TEMPLATES_H +#define TEMPLATES_H + + +#include <types.h> + +template<typename T, T val> +struct constant +{ + static constexpr T value = val; + T& operator()() {return value;} +}; + +template<typename T, typename U> +struct isSame +{ + using cnst = constant<bool, false>; + bool static inline constexpr val(){return cnst::value;}; + constexpr operator bool() const {return cnst::value;} + bool constexpr operator()() {return cnst::value;} +}; + +template<typename T> +struct isSame<T, T> +{ + using cnst = constant<bool, true>; + constexpr operator bool() const {return cnst::value;} + bool static inline constexpr val(){return cnst::value;}; + bool constexpr operator()() {return cnst::value;} +}; + +template <typename ... params> +struct parametersOperations +{ + template<typename Head, typename ... Tail> + using first = Head; + + template<typename Head, typename ... Tail> + using tail = parametersOperations<Tail ...>; + + // Append operation + template<typename Head, typename ... Tail> + struct append + { + using result = parametersOperations<params ..., Head>::template append<Tail ...>::result; + }; + + template<template <typename ... NestedList> typename NestedType, typename ... NestedList, typename ... OuterList> + requires(isSame<NestedType<>, parametersOperations<>>::val()) + struct append<NestedType<NestedList ...>, OuterList ...> + { + using result = parametersOperations<params..., NestedList ...>::template append<OuterList ...>::result; + }; + + template<template <typename ... NestedList> typename NestedType, typename ... NestedList> + requires(isSame<NestedType<>, parametersOperations<>>::val()) + struct append<NestedType<NestedList ...>> + { + using result = parametersOperations<params..., NestedList ...>; + }; + + template<typename One> + struct append<One> {using result = parametersOperations<params ..., One>;}; +}; + +template< unsigned I, typename T> +struct cut +{ + using process = cut<I - 1, typename T::baseType>::process; +}; + +template<typename T> +struct cut<0, T> +{ + using process = cut<0, T>; + using result = T; +}; + +template<uint16 N, typename Head, typename ... Args> +struct reper +{ + using toList = typename reper<N-1, Head, Head, Args ...>::toList; +}; + +template<uint16 N, typename Type> +struct repeat +{ + using toList = typename reper<N-1, Type>::toList; +}; + +template<typename Type> +struct repeat<0, Type> {}; + +template<typename Head, typename ... Args> +struct reper<0, Head, Args ...> +{ + using toList = parametersOperations<Head, Args ...>; +}; + +template<typename Root, typename toType> +struct switchRoot {using result = toType;}; + +template<template <typename ... RootList> typename RootType, template <typename ... toTypeListArgs> typename toType, typename ... RootList, typename ... toTypeListArgs> +struct switchRoot<RootType<RootList ...>, toType<toTypeListArgs ...>>{using result = toType<RootList ...>;}; + +template<typename arg, template<typename ... toTypeListArgs> typename toType, typename ... toTypeListArgs> +struct switchRoot<arg, toType<toTypeListArgs ...>>{using result = toType<arg>;}; + +template<typename arg, typename ... args> +struct parameters +{ + public: + using baseType = parameters<args ...>; + using types = parametersOperations<>::template append<arg, typename baseType::types>::result; + template<template <typename ... > typename T> + using submitTo = switchRoot<types, T<>>::result; +}; + +template<typename arg> +struct parameters<arg> +{ + public: + using types = arg; + template<template <typename ... > typename T> + using submitTo = switchRoot<types, T<>>::result; +}; +#endif |
