rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
func_chain.h
Go to the documentation of this file.
1/**
2 * @author Matthew Kennedy, (c) 2019
3 *
4 * This lets us compose multiple functions in to a single function. If we have
5 * conversion functions F(x), G(x), and H(x), we can define a new function
6 * FuncChain<F, G, H> that will compute H(G(F(X))). F first, then G, then H.
7 */
8
9#pragma once
10
12
13#include <type_traits>
14#include <utility>
15
16namespace priv {
17template <class... _Types>
19
20template <>
21class FuncChain<> {
22protected:
23 SensorResult convert(float input) const {
24 // Base case is the identity function
25 return input;
26 }
27
28 void showInfo(float testInputValue) const {
29 // base case does nothing
30 (void)testInputValue;
31 }
32};
33
34template <typename TFirst, typename... TRest>
35class FuncChain<TFirst, TRest...> : private FuncChain<TRest...> {
36 static_assert(std::is_base_of_v<SensorConverter, TFirst>, "Template parameters must inherit from SensorConverter");
37
38private:
39 using TBase = FuncChain<TRest...>;
40
41public:
42 SensorResult convert(float input) const {
43 // Convert the current step
44 SensorResult currentStep = m_f.convert(input);
45
46 // if it was valid, pass this result to the chain of (n-1) functions that remain
47 if (currentStep.Valid) {
48 return TBase::convert(currentStep.Value);
49 } else {
50 return SensorResult(currentStep.Code);
51 }
52 }
53
54 // Get the element in the current level
55 template <class TGet>
56 std::enable_if_t<std::is_same_v<TGet, TFirst>, TGet &> get() {
57 return m_f;
58 }
59
60 template <class TGet>
61 std::enable_if_t<std::is_same_v<TGet, TFirst>, TGet *> getPtr() {
62 return &m_f;
63 }
64
65 // We don't have it - check level (n - 1)
66 template <class TGet>
67 std::enable_if_t<!std::is_same_v<TGet, TFirst>, TGet &> get() {
68 return TBase::template get<TGet>();
69 }
70
71 // We don't have it - check level (n - 1)
72 template <class TGet>
73 std::enable_if_t<!std::is_same_v<TGet, TFirst>, TGet *> getPtr() {
74 return TBase::template getPtr<TGet>();
75 }
76
77 void showInfo(float testInputValue) const {
78 // Print info about this level
79 m_f.showInfo(testInputValue);
80
81 // If valid, recurse down
82 auto res = m_f.convert(testInputValue);
83 if (res.Valid) {
84 TBase::showInfo(res.Value);
85 }
86 }
87
88private:
89 TFirst m_f;
90};
91} // namespace priv
92
93template <typename... TFuncs>
94class FuncChain : public SensorConverter {
95public:
96 // Perform chained conversion of all functions in TFuncs
97 SensorResult convert(float input) const override {
98 return m_fs.convert(input);
99 }
100
101 // Access the sub-function of type TGet
102 template <typename TGet>
103 TGet &get() {
104 return m_fs.template get<TGet>();
105 }
106
107 // references would be sometimes implicitly deleted, right? adding parallel pointer API which would stay?
108 template <typename TGet>
109 TGet *getPtr() {
110 return m_fs.template getPtr<TGet>();
111 }
112
113 void showInfo(float testInputValue) const override {
114 m_fs.showInfo(testInputValue);
115 }
116
117private:
119};
TGet * getPtr()
Definition func_chain.h:109
priv::FuncChain< TFuncs... > m_fs
Definition func_chain.h:118
TGet & get()
Definition func_chain.h:103
SensorResult convert(float input) const override
Definition func_chain.h:97
void showInfo(float testInputValue) const override
Definition func_chain.h:113
SensorResult convert(float input) const
Definition func_chain.h:42
std::enable_if_t< std::is_same_v< TGet, TFirst >, TGet * > getPtr()
Definition func_chain.h:61
void showInfo(float testInputValue) const
Definition func_chain.h:77
std::enable_if_t<!std::is_same_v< TGet, TFirst >, TGet & > get()
Definition func_chain.h:67
std::enable_if_t<!std::is_same_v< TGet, TFirst >, TGet * > getPtr()
Definition func_chain.h:73
std::enable_if_t< std::is_same_v< TGet, TFirst >, TGet & > get()
Definition func_chain.h:56
SensorResult convert(float input) const
Definition func_chain.h:23
void showInfo(float testInputValue) const
Definition func_chain.h:28
expected< float > SensorResult
Definition sensor.h:46