summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorAlexey Gavrilov <rebovas@yahoo.com>2024-05-24 14:07:47 +0700
committerAlexey Gavrilov <rebovas@yahoo.com>2024-05-24 14:07:47 +0700
commit5fbf41e967ed8e413ecf1e6abb72e8d285169df4 (patch)
tree48e25b199ae3459e12c7202f7b18a37cd087bf9b /include
parent0a50b1758fd3da118408fd724825d0a50a9ecf17 (diff)
Pic + Tuple + refactor PrimaryInitialization class
Diffstat (limited to 'include')
-rw-r--r--include/ISingleton.h12
-rw-r--r--include/Templates.h127
-rw-r--r--include/containers/Tuple.h98
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