Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
OperatorRegistry.hpp
Go to the documentation of this file.
1
6#pragma once
7
8#include <ext/functional>
9#include <ext/memory>
10#include <ext/vector>
11#include <ext/list>
12#include <ext/string>
13#include <ext/set>
14#include <ext/map>
15#include <ext/typeinfo>
16
18
21#include <common/Operators.hpp>
22
24#include "BaseRegistryEntry.hpp"
25
26namespace abstraction {
27
29public:
31 AlgorithmFullInfo m_entryInfo;
32
33 public:
34 explicit BinaryEntry ( AlgorithmFullInfo entryInfo ) : m_entryInfo ( std::move ( entryInfo ) ) {
35 }
36
37 const AlgorithmFullInfo & getEntryInfo ( ) const {
38 return m_entryInfo;
39 }
40 };
41
43 AlgorithmFullInfo m_entryInfo;
44
45 public:
46 explicit PrefixEntry ( AlgorithmFullInfo entryInfo ) : m_entryInfo ( std::move ( entryInfo ) ) {
47 }
48
49 const AlgorithmFullInfo & getEntryInfo ( ) const {
50 return m_entryInfo;
51 }
52 };
53
55 AlgorithmFullInfo m_entryInfo;
56
57 public:
58 explicit PostfixEntry ( AlgorithmFullInfo entryInfo ) : m_entryInfo ( std::move ( entryInfo ) ) {
59 }
60
61 const AlgorithmFullInfo & getEntryInfo ( ) const {
62 return m_entryInfo;
63 }
64 };
65
66private:
67 template < class Return, class FirstParam, class SecondParam >
68 class BinaryOperator : public BinaryEntry {
69 std::function < Return ( FirstParam, SecondParam ) > m_callback;
70
71 public:
72 explicit BinaryOperator ( std::function < Return ( FirstParam, SecondParam ) > callback ) : BinaryEntry ( AlgorithmFullInfo::operatorEntryInfo < Return, FirstParam, SecondParam > ( ) ), m_callback ( std::move ( callback ) ) {
73 }
74
75 std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override;
76 };
77
78 template < class Return, class Param >
79 class PrefixOperator : public PrefixEntry {
80 std::function < Return ( Param ) > m_callback;
81
82 public:
83 explicit PrefixOperator ( std::function < Return ( Param ) > callback ) : PrefixEntry ( AlgorithmFullInfo::operatorEntryInfo < Return, Param > ( ) ), m_callback ( std::move ( callback ) ) {
84 }
85
86 std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override;
87 };
88
89 template < class Return, class Param >
90 class PostfixOperator : public PostfixEntry {
91 std::function < Return ( Param ) > m_callback;
92
93 public:
94 explicit PostfixOperator ( std::function < Return ( Param ) > callback ) : PostfixEntry ( AlgorithmFullInfo::operatorEntryInfo < Return, Param > ( ) ), m_callback ( std::move ( callback ) ) {
95 }
96
97 std::shared_ptr < abstraction::OperationAbstraction > getAbstraction ( ) const override;
98 };
99
101
102 static bool isRegisteredBinary ( Operators::BinaryOperators type, const AlgorithmBaseInfo & entryInfo );
103
104 static void registerBinaryInternal ( Operators::BinaryOperators type, std::unique_ptr < BinaryEntry > value );
105
106 static void unregisterBinaryInternal ( Operators::BinaryOperators type, const AlgorithmBaseInfo & entryInfo );
107
108
109
111
112 static bool isRegisteredPrefix ( Operators::PrefixOperators type, const AlgorithmBaseInfo & entryInfo );
113
114 static void registerPrefixInternal ( Operators::PrefixOperators type, std::unique_ptr < PrefixEntry > value );
115
116 static void unregisterPrefixInternal ( Operators::PrefixOperators type, const AlgorithmBaseInfo & entryInfo );
117
118
119
121
122 static bool isRegisteredPostfix ( Operators::PostfixOperators type, const AlgorithmBaseInfo & entryInfo );
123
124 static void registerPostfixInternal ( Operators::PostfixOperators type, std::unique_ptr < PostfixEntry > value );
125
126 static void unregisterPostfixInternal ( Operators::PostfixOperators type, const AlgorithmBaseInfo & entryInfo );
127
128public:
129 template < class FirstParam, class SecondParam >
131 unregisterBinaryInternal ( type, AlgorithmBaseInfo::operatorEntryInfo < FirstParam, SecondParam > ( ) );
132 }
133
134 template < class Return, class FirstParam, class SecondParam >
135 static void registerBinary ( Operators::BinaryOperators type, std::function < Return ( FirstParam, SecondParam ) > func ) {
136 registerBinaryInternal ( type, std::make_unique < BinaryOperator < Return, FirstParam, SecondParam > > ( func ) );
137 }
138
139 template < Operators::BinaryOperators Type, class FirstParam, class SecondParam >
140 static void registerBinary ( ) {
142 std::function < decltype ( std::declval < FirstParam > ( ) && std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a && b; };
144 } else if constexpr ( Type == Operators::BinaryOperators::LOGICAL_OR ) {
145 std::function < decltype ( std::declval < FirstParam > ( ) || std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a || b; };
147 } else if constexpr ( Type == Operators::BinaryOperators::BINARY_AND ) {
148 std::function < decltype ( std::declval < FirstParam > ( ) & std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a & b; };
150 } else if constexpr ( Type == Operators::BinaryOperators::BINARY_OR ) {
151 std::function < decltype ( std::declval < FirstParam > ( ) | std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a | b; };
153 } else if constexpr ( Type == Operators::BinaryOperators::BINARY_XOR ) {
154 std::function < decltype ( std::declval < FirstParam > ( ) ^ std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a ^ b; };
156 } else if constexpr ( Type == Operators::BinaryOperators::ADD ) {
157 std::function < decltype ( std::declval < FirstParam > ( ) + std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a + b; };
159 } else if constexpr ( Type == Operators::BinaryOperators::SUB ) {
160 std::function < decltype ( std::declval < FirstParam > ( ) - std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a - b; };
162 } else if constexpr ( Type == Operators::BinaryOperators::MUL ) {
163 std::function < decltype ( std::declval < FirstParam > ( ) * std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a * b; };
165 } else if constexpr ( Type == Operators::BinaryOperators::MOD ) {
166 std::function < decltype ( std::declval < FirstParam > ( ) % std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a % b; };
168 } else if constexpr ( Type == Operators::BinaryOperators::DIV ) {
169 std::function < decltype ( std::declval < FirstParam > ( ) / std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a / b; };
171 } else if constexpr ( Type == Operators::BinaryOperators::EQUALS ) {
172 std::function < decltype ( std::declval < FirstParam > ( ) == std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a == b; };
174 } else if constexpr ( Type == Operators::BinaryOperators::NOT_EQUALS ) {
175 std::function < decltype ( std::declval < FirstParam > ( ) != std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a != b; };
177 } else if constexpr ( Type == Operators::BinaryOperators::LESS ) {
178 std::function < decltype ( std::declval < FirstParam > ( ) < std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a < b; };
180 } else if constexpr ( Type == Operators::BinaryOperators::LESS_OR_EQUAL ) {
181 std::function < decltype ( std::declval < FirstParam > ( ) <= std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a <= b; };
183 } else if constexpr ( Type == Operators::BinaryOperators::MORE ) {
184 std::function < decltype ( std::declval < FirstParam > ( ) > std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a > b; };
186 } else if constexpr ( Type == Operators::BinaryOperators::MORE_OR_EQUAL ) {
187 std::function < decltype ( std::declval < FirstParam > ( ) >= std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) { return a >= b; };
189 } else if constexpr ( Type == Operators::BinaryOperators::ASSIGN ) {
190 std::function < decltype ( std::declval < FirstParam > ( ) = std::declval < SecondParam > ( ) ) ( FirstParam, SecondParam ) > callback = [ ] ( FirstParam a, SecondParam b ) -> decltype ( auto ) { return a = b; };
192 } else {
193 static_assert ( "Unhandled binary operator." );
194 }
195 }
196
197 static std::shared_ptr < abstraction::OperationAbstraction > getBinaryAbstraction ( Operators::BinaryOperators type, const ext::vector < std::string > & paramTypes, const ext::vector < abstraction::TypeQualifiers::TypeQualifierSet > & typeQualifiers, AlgorithmCategories::AlgorithmCategory category );
198
200
201
202 template < class Param >
204 unregisterPrefixInternal ( type, AlgorithmBaseInfo::operatorEntryInfo < Param > ( ) );
205 }
206
207 template < class Return, class Param >
208 static void registerPrefix ( Operators::PrefixOperators type, std::function < Return ( Param ) > func ) {
209 registerPrefixInternal ( type, std::make_unique < PrefixOperator < Return, Param > > ( func ) );
210 }
211
212 template < Operators::PrefixOperators Type, class Param >
213 static void registerPrefix ( ) {
214 if constexpr ( Type == Operators::PrefixOperators::PLUS ) {
215 std::function < decltype ( + std::declval < Param > ( ) ) ( Param ) > callback = [ ] ( Param a ) { return + a; };
217 } else if constexpr ( Type == Operators::PrefixOperators::MINUS ) {
218 std::function < decltype ( - std::declval < Param > ( ) ) ( Param ) > callback = [ ] ( Param a ) -> decltype ( auto ) { return - a; };
220 } else if constexpr ( Type == Operators::PrefixOperators::LOGICAL_NOT ) {
221 std::function < decltype ( ! std::declval < Param > ( ) ) ( Param ) > callback = [ ] ( Param a ) -> decltype ( auto ) { return ! a; };
223 } else if constexpr ( Type == Operators::PrefixOperators::BINARY_NEG ) {
224 std::function < decltype ( ~ std::declval < Param > ( ) ) ( Param ) > callback = [ ] ( Param a ) -> decltype ( auto ) { return ~ a; };
226 } else if constexpr ( Type == Operators::PrefixOperators::INCREMENT ) {
227 std::function < decltype ( ++ std::declval < Param > ( ) ) ( Param ) > callback = [ ] ( Param a ) -> decltype ( auto ) { return ++ a; };
229 } else if constexpr ( Type == Operators::PrefixOperators::DECREMENT ) {
230 std::function < decltype ( -- std::declval < Param > ( ) ) ( Param ) > callback = [ ] ( Param a ) -> decltype ( auto ) { return -- a; };
232 } else {
233 static_assert ( "Unhandled prefix operator." );
234 }
235 }
236
237 static std::shared_ptr < abstraction::OperationAbstraction > getPrefixAbstraction ( Operators::PrefixOperators type, const ext::vector < std::string > & paramTypes, const ext::vector < abstraction::TypeQualifiers::TypeQualifierSet > & typeQualifiers, AlgorithmCategories::AlgorithmCategory category );
238
240
241
242 template < class Param >
244 unregisterPostfixInternal ( type, AlgorithmBaseInfo::operatorEntryInfo < Param > ( ) );
245 }
246
247 template < class Return, class Param >
248 static void registerPostfix ( Operators::PostfixOperators type, std::function < Return ( Param ) > func ) {
249 registerPostfixInternal ( type, std::make_unique < PostfixOperator < Return, Param > > ( func ) );
250 }
251
252 template < Operators::PostfixOperators Type, class Param >
253 static void registerPostfix ( ) {
254 if constexpr ( Type == Operators::PostfixOperators::INCREMENT ) {
255 std::function < decltype ( std::declval < Param > ( ) ++ ) ( Param ) > callback = [ ] ( Param a ) { std::decay_t < Param > tmp = a; a ++; return tmp; };
257 } else if constexpr ( Type == Operators::PostfixOperators::DECREMENT ) {
258 std::function < decltype ( std::declval < Param > ( ) -- ) ( Param ) > callback = [ ] ( Param a ) { std::decay_t < Param > tmp = a; a --; return tmp; };
260 } else {
261 static_assert ( "Unhandled postfix operator." );
262 }
263 }
264
265 static std::shared_ptr < abstraction::OperationAbstraction > getPostfixAbstraction ( Operators::PostfixOperators type, const ext::vector < std::string > & paramTypes, const ext::vector < abstraction::TypeQualifiers::TypeQualifierSet > & typeQualifiers, AlgorithmCategories::AlgorithmCategory category );
266
268
269};
270
271} /* namespace abstraction */
272
276
277namespace abstraction {
278
279template < class Return, class FirstParam, class SecondParam >
280std::shared_ptr < abstraction::OperationAbstraction > OperatorRegistry::BinaryOperator < Return, FirstParam, SecondParam >::getAbstraction ( ) const {
281 return std::make_shared < abstraction::AlgorithmAbstraction < Return, FirstParam, SecondParam > > ( m_callback );
282}
283
284template < class Return, class Param >
285std::shared_ptr < abstraction::OperationAbstraction > OperatorRegistry::PrefixOperator < Return, Param >::getAbstraction ( ) const {
286 return std::make_shared < abstraction::AlgorithmAbstraction < Return, Param > > ( m_callback );
287}
288
289template < class Return, class Param >
290std::shared_ptr < abstraction::OperationAbstraction > OperatorRegistry::PostfixOperator < Return, Param >::getAbstraction ( ) const {
291 return std::make_shared < abstraction::AlgorithmAbstraction < Return, Param > > ( m_callback );
292}
293
294} /* namespace abstraction */
295
AlgorithmCategory
Definition: AlgorithmCategories.hpp:14
Definition: AlgorithmRegistryInfo.hpp:89
Definition: BaseRegistryEntry.hpp:12
Definition: OperatorRegistry.hpp:30
const AlgorithmFullInfo & getEntryInfo() const
Definition: OperatorRegistry.hpp:37
BinaryEntry(AlgorithmFullInfo entryInfo)
Definition: OperatorRegistry.hpp:34
Definition: OperatorRegistry.hpp:54
PostfixEntry(AlgorithmFullInfo entryInfo)
Definition: OperatorRegistry.hpp:58
const AlgorithmFullInfo & getEntryInfo() const
Definition: OperatorRegistry.hpp:61
Definition: OperatorRegistry.hpp:42
PrefixEntry(AlgorithmFullInfo entryInfo)
Definition: OperatorRegistry.hpp:46
const AlgorithmFullInfo & getEntryInfo() const
Definition: OperatorRegistry.hpp:49
Definition: OperatorRegistry.hpp:28
static std::shared_ptr< abstraction::OperationAbstraction > getPostfixAbstraction(Operators::PostfixOperators type, const ext::vector< std::string > &paramTypes, const ext::vector< abstraction::TypeQualifiers::TypeQualifierSet > &typeQualifiers, AlgorithmCategories::AlgorithmCategory category)
Definition: OperatorRegistry.cpp:154
static void registerBinary()
Definition: OperatorRegistry.hpp:140
static ext::list< ext::pair< Operators::PrefixOperators, AlgorithmFullInfo > > listPrefixOverloads()
Definition: OperatorRegistry.cpp:109
static void registerPostfix()
Definition: OperatorRegistry.hpp:253
static ext::list< ext::pair< Operators::BinaryOperators, AlgorithmFullInfo > > listBinaryOverloads()
Definition: OperatorRegistry.cpp:58
static void unregisterPostfix(Operators::PostfixOperators type)
Definition: OperatorRegistry.hpp:243
static void registerPrefix(Operators::PrefixOperators type, std::function< Return(Param) > func)
Definition: OperatorRegistry.hpp:208
static std::shared_ptr< abstraction::OperationAbstraction > getBinaryAbstraction(Operators::BinaryOperators type, const ext::vector< std::string > &paramTypes, const ext::vector< abstraction::TypeQualifiers::TypeQualifierSet > &typeQualifiers, AlgorithmCategories::AlgorithmCategory category)
Definition: OperatorRegistry.cpp:52
static void registerPostfix(Operators::PostfixOperators type, std::function< Return(Param) > func)
Definition: OperatorRegistry.hpp:248
static void unregisterPrefix(Operators::PrefixOperators type)
Definition: OperatorRegistry.hpp:203
static void registerPrefix()
Definition: OperatorRegistry.hpp:213
static void unregisterBinary(Operators::BinaryOperators type)
Definition: OperatorRegistry.hpp:130
static void registerBinary(Operators::BinaryOperators type, std::function< Return(FirstParam, SecondParam) > func)
Definition: OperatorRegistry.hpp:135
static std::shared_ptr< abstraction::OperationAbstraction > getPrefixAbstraction(Operators::PrefixOperators type, const ext::vector< std::string > &paramTypes, const ext::vector< abstraction::TypeQualifiers::TypeQualifierSet > &typeQualifiers, AlgorithmCategories::AlgorithmCategory category)
Definition: OperatorRegistry.cpp:103
static ext::list< ext::pair< Operators::PostfixOperators, AlgorithmFullInfo > > listPostfixOverloads()
Definition: OperatorRegistry.cpp:160
PostfixOperators
Definition: Operators.hpp:43
PrefixOperators
Definition: Operators.hpp:34
BinaryOperators
Definition: Operators.hpp:14
Class extending the list class from the standard library. Original reason is to allow printing of the...
Definition: list.hpp:44
Class extending the map class from the standard library. Original reason is to allow printing of the ...
Definition: map.hpp:48
Class extending the vector class from the standard library. Original reason is to allow printing of t...
Definition: vector.hpp:45
Definition: AlgorithmAbstraction.hpp:11
int callback(struct dl_phdr_info *info, size_t, void *data)
Definition: simpleStacktrace.cpp:25
Type
Definition: MeasurementTypes.hpp:20
Definition: FordFulkerson.hpp:16