diff options
| author | Alexey Gavrilov <90127298+rebovas@users.noreply.github.com> | 2024-05-24 14:33:19 +0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-24 14:33:19 +0700 |
| commit | dc0b89fa63a181bd4add318bfd7a46344702f4e7 (patch) | |
| tree | 48e25b199ae3459e12c7202f7b18a37cd087bf9b /include | |
| parent | 0a50b1758fd3da118408fd724825d0a50a9ecf17 (diff) | |
| parent | 5fbf41e967ed8e413ecf1e6abb72e8d285169df4 (diff) | |
Pic + Tuple + refactor PrimaryInitialization class
Diffstat (limited to 'include')
| -rw-r--r-- | include/ISingleton.h | 12 | ||||
| -rw-r--r-- | include/Templates.h | 127 | ||||
| -rw-r--r-- | include/containers/Tuple.h | 98 |
3 files changed, 237 insertions, 0 deletions
diff --git a/include/ISingleton.h b/include/ISingleton.h new file mode 100644 index 0000000..1dcd0d1 --- /dev/null +++ b/include/ISingleton.h @@ -0,0 +1,12 @@ +#ifndef SINGLETON_H +#define SINGLETON_H + + +template <typename T> +class ISingleton +{ + public: + virtual T *getInstance() = 0; +}; + +#endif 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 diff --git a/include/containers/Tuple.h b/include/containers/Tuple.h new file mode 100644 index 0000000..cf870d1 --- /dev/null +++ b/include/containers/Tuple.h @@ -0,0 +1,98 @@ +#ifndef CONTAINERSTUPLE_H +#define CONTAINERSTUPLE_H + + +#include <Templates.h> + +template<typename Head = void, typename ... Tail> +class Tuple : public Tuple<Tail ...> +{ + private: + using valueType = Head; + valueType value; + public: + using baseType = Tuple<Tail ...>; + Tuple(Head val_, Tail ... args) : baseType(args ...), value(val_) {}; + + static constexpr unsigned int length() {return sizeof...(Tail) + 1;} + valueType getValue() {return value;}; + + template<uint16 indx> + auto get() + { + using returnType = cut<indx, Tuple>::process::result; + return static_cast<returnType>(*this); + }; + + /* + Create the class/struct before using the method + F is this class/struct to pass in method trought template argument. + F must contain a static method/s named "perform" + that will perform something action for every value in tuple object. + F must contain as many implementations + as there are different types in the template + F::perform() for the first argument accept tuple value, + next arguments optional + */ + template<typename F, uint16 If = length() - 1, uint16 ... I, + typename Mid = void, typename ... T> + void foreach(T ... arg) + { + if constexpr(If != NULL) + { + foreach<F, If - 1, If, I ...>(arg ...); + } + else + { + (F::perform(get<If>().getValue(), arg ...)); + (F::perform(get<I>().getValue(), arg ...), ...); + } + }; +}; + +template<> +class Tuple<> +{ + public: + static constexpr unsigned int length() {return 0;} +}; + +template<typename Head> +class Tuple<Head> +{ + private: + using valueType = Head; + valueType value; + public: + using baseType = Tuple<>; + Tuple(Head val_) : value(val_) {}; + Tuple() : value(valueType()) {}; + + static constexpr unsigned int length() {return 1;} + valueType getValue() {return value;}; + + template<uint16 indx> + auto get() + { + if constexpr (indx == NULL) return *this; + else static_assert(!indx, "Tuple::get<indx>: Out of bounds"); + }; + + /* + Create the class/struct before using the method + F is this class/struct to pass in method trought template argument. + F must contain a static method/s named "perform" + that will perform something action for every value in tuple object. + F must contain as many implementations + as there are different types in the template + F::perform() for the first argument accept tuple value, + next arguments optional + */ + template<typename F, typename ... T> + void foreach(T ... arg) + { + F::perform(value, arg ...); + }; +}; + +#endif |
