Line | Branch | Exec | Source |
---|---|---|---|
1 | // Copyright Contributors to the OpenVDB Project | ||
2 | // SPDX-License-Identifier: MPL-2.0 | ||
3 | |||
4 | /// @file codegen/FunctionRegistry.h | ||
5 | /// | ||
6 | /// @authors Nick Avramoussis | ||
7 | /// | ||
8 | /// @brief Contains the global function registration definition which | ||
9 | /// described all available user front end functions | ||
10 | /// | ||
11 | |||
12 | #ifndef OPENVDB_AX_CODEGEN_FUNCTION_REGISTRY_HAS_BEEN_INCLUDED | ||
13 | #define OPENVDB_AX_CODEGEN_FUNCTION_REGISTRY_HAS_BEEN_INCLUDED | ||
14 | |||
15 | #include "FunctionTypes.h" | ||
16 | |||
17 | #include "openvdb_ax/compiler/CompilerOptions.h" | ||
18 | |||
19 | #include <openvdb/version.h> | ||
20 | |||
21 | #include <unordered_map> | ||
22 | |||
23 | namespace openvdb { | ||
24 | OPENVDB_USE_VERSION_NAMESPACE | ||
25 | namespace OPENVDB_VERSION_NAME { | ||
26 | |||
27 | namespace ax { | ||
28 | namespace codegen { | ||
29 | |||
30 | /// @brief The function registry which is used for function code generation. | ||
31 | /// Each time a function is visited within the AST, its identifier is used as | ||
32 | /// a key into this registry for the corresponding function retrieval and | ||
33 | /// execution. Functions can be inserted into the registry using insert() with | ||
34 | /// a given identifier and pointer. | ||
35 | 1488 | class OPENVDB_AX_API FunctionRegistry | |
36 | { | ||
37 | public: | ||
38 | using ConstructorT = FunctionGroup::UniquePtr(*)(const FunctionOptions&); | ||
39 | using Ptr = std::shared_ptr<FunctionRegistry>; | ||
40 | using UniquePtr = std::unique_ptr<FunctionRegistry>; | ||
41 | |||
42 | /// @brief An object to represent a registered function, storing its | ||
43 | /// constructor, a pointer to the function definition and whether it | ||
44 | /// should only be available internally (i.e. to a developer, not a user) | ||
45 | /// | ||
46 | struct RegisteredFunction | ||
47 | { | ||
48 | /// @brief Constructor | ||
49 | /// @param creator The function definition used to create this function | ||
50 | /// @param internal Whether the function should be only internally accessible | ||
51 | RegisteredFunction(const ConstructorT& creator, const bool internal = false) | ||
52 | 157537 | : mConstructor(creator), mFunction(), mInternal(internal) {} | |
53 | |||
54 | /// @brief Create a function object using this creator of this function | ||
55 | /// @param op The current function options | ||
56 | 11418 | inline void create(const FunctionOptions& op) { mFunction = mConstructor(op); } | |
57 | |||
58 | /// @brief Return a pointer to this function definition | ||
59 | inline const FunctionGroup* function() const { return mFunction.get(); } | ||
60 | |||
61 | /// @brief Check whether this function should be only internally accesible | ||
62 |
4/4✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 5266 times.
✓ Branch 3 taken 5 times.
|
5279 | inline bool isInternal() const { return mInternal; } |
63 | |||
64 | private: | ||
65 | ConstructorT mConstructor; | ||
66 | FunctionGroup::Ptr mFunction; | ||
67 | bool mInternal; | ||
68 | }; | ||
69 | |||
70 | using RegistryMap = std::unordered_map<std::string, RegisteredFunction>; | ||
71 | |||
72 | /// @brief Insert and register a function object to a function identifier. | ||
73 | /// @note Throws if the identifier is already registered | ||
74 | /// | ||
75 | /// @param identifier The function identifier to register | ||
76 | /// @param creator The function to link to the provided identifier | ||
77 | /// @param internal Whether to mark the function as only internally accessible | ||
78 | void insert(const std::string& identifier, | ||
79 | const ConstructorT creator, | ||
80 | const bool internal = false); | ||
81 | |||
82 | /// @brief Insert and register a function object to a function identifier. | ||
83 | /// @note Throws if the identifier is already registered | ||
84 | /// | ||
85 | /// @param identifier The function identifier to register | ||
86 | /// @param creator The function to link to the provided identifier | ||
87 | /// @param op FunctionOptions to pass the function constructor | ||
88 | /// @param internal Whether to mark the function as only internally accessible | ||
89 | void insertAndCreate(const std::string& identifier, | ||
90 | const ConstructorT creator, | ||
91 | const FunctionOptions& op, | ||
92 | const bool internal = false); | ||
93 | |||
94 | /// @brief Return the corresponding function from a provided function identifier | ||
95 | /// @note Returns a nullptr if no such function identifier has been | ||
96 | /// registered or if the function is marked as internal | ||
97 | /// | ||
98 | /// @param identifier The function identifier | ||
99 | /// @param op FunctionOptions to pass the function constructor | ||
100 | /// @param allowInternalAccess Whether to look in the 'internal' functions | ||
101 | const FunctionGroup* getOrInsert(const std::string& identifier, | ||
102 | const FunctionOptions& op, | ||
103 | const bool allowInternalAccess); | ||
104 | |||
105 | /// @brief Return the corresponding function from a provided function identifier | ||
106 | /// @note Returns a nullptr if no such function identifier has been | ||
107 | /// registered or if the function is marked as internal | ||
108 | /// | ||
109 | /// @param identifier The function identifier | ||
110 | /// @param allowInternalAccess Whether to look in the 'internal' functions | ||
111 | const FunctionGroup* get(const std::string& identifier, | ||
112 | const bool allowInternalAccess) const; | ||
113 | |||
114 | /// @brief Force the (re)creations of all function objects for all | ||
115 | /// registered functions | ||
116 | /// @param op The current function options | ||
117 | /// @param verify Checks functions are created and have valid identifiers/symbols | ||
118 | void createAll(const FunctionOptions& op, const bool verify = false); | ||
119 | |||
120 | /// @brief Return a const reference to the current registry map | ||
121 | inline const RegistryMap& map() const { return mMap; } | ||
122 | |||
123 | /// @brief Return whether or not the registry is empty | ||
124 | inline bool empty() const { return mMap.empty(); } | ||
125 | |||
126 | /// @brief Clear the underlying function registry | ||
127 | inline void clear() { mMap.clear(); } | ||
128 | |||
129 | private: | ||
130 | RegistryMap mMap; | ||
131 | }; | ||
132 | |||
133 | } // namespace codegen | ||
134 | } // namespace ax | ||
135 | } // namespace OPENVDB_VERSION_NAME | ||
136 | } // namespace openvdb | ||
137 | |||
138 | #endif // OPENVDB_AX_CODEGEN_FUNCTION_REGISTRY_HAS_BEEN_INCLUDED | ||
139 | |||
140 |