LibraryLink Utilities  3.0.1
Modern C++ wrapper over LibraryLink and WSTP
ManagedExpression.hpp
Go to the documentation of this file.
1 
7 #ifndef LLU_MANAGEDEXPRESSION_HPP
8 #define LLU_MANAGEDEXPRESSION_HPP
9 
10 #include <memory>
11 #include <unordered_map>
12 #include <utility>
13 
14 #include "LLU/LibraryData.h"
15 #include "LLU/Utilities.hpp"
16 
21 #define DEFINE_MANAGED_STORE_AND_SPECIALIZATION(ClassName) \
22  LLU::ManagedExpressionStore<ClassName> ClassName##Store; \
23  \
24  template<> \
25  inline void LLU::manageInstanceCallback<ClassName>(WolframLibraryData, mbool mode, mint id) { \
26  ClassName##Store.manageInstance(mode, id); \
27  }
28 
29 namespace LLU {
30 
40  template<class T>
41  void manageInstanceCallback(WolframLibraryData /*libData*/, mbool /*mode*/, mint /*id*/) {
42  static_assert(dependent_false_v<T>, "Use of unspecialized ManageInstance function.");
43  }
44 
49  template<typename T>
51  public:
53  using iterator = typename std::unordered_map<mint, std::shared_ptr<T>>::iterator;
54 
56  using const_iterator = typename std::unordered_map<mint, std::shared_ptr<T>>::const_iterator;
57 
59  using size_type = typename std::unordered_map<mint, std::shared_ptr<T>>::size_type;
60  public:
69  void manageInstance(mbool mode, mint id) {
70  if (mode == False /* create new instance */) {
71  store[id] = nullptr;
72  } else {
73  store.erase(id);
74  }
75  }
76 
85  template<class DynamicType = T, typename... Args>
86  T& createInstance(mint id, Args&&... args) {
87  checkID(id); // at this point instance must already exist in store
88  store[id] = std::make_shared<DynamicType>(std::forward<Args>(args)...);
89  return *store[id];
90  }
91 
99  T& createInstance(mint id, std::shared_ptr<T> ptr) {
100  checkID(id);
101  store[id] = std::move(ptr);
102  return instanceAt(id);
103  }
104 
111  T& createInstance(mint id, std::unique_ptr<T> ptr) {
112  return createInstance(id, std::shared_ptr<T> {std::move(ptr)});
113  }
114 
123  int releaseInstance(mint id) {
124  return LibraryData::API()->releaseManagedLibraryExpression(expressionName.c_str(), id);
125  }
126 
132  [[nodiscard]] bool hasInstance(mint id) const {
133  return store.count(id) == 1;
134  }
135 
141  T& getInstance(mint id) {
142  checkID(id);
143  return instanceAt(id);
144  }
145 
151  std::shared_ptr<T> getInstancePointer(mint id) {
152  checkID(id);
153  return store[id];
154  }
155 
160  const std::string& getExpressionName() const noexcept {
161  return expressionName;
162  }
163 
168  size_type size() const noexcept {
169  return store.size();
170  }
171 
175  iterator begin() noexcept {
176  return store.begin();
177  }
178 
182  const_iterator begin() const noexcept {
183  return store.cbegin();
184  }
185 
189  const_iterator cbegin() const noexcept {
190  return store.cbegin();
191  }
192 
196  iterator end() noexcept {
197  return store.end();
198  }
199 
203  const_iterator end() const noexcept {
204  return store.end();
205  }
206 
210  const_iterator cend() const noexcept {
211  return store.cend();
212  }
213 
220  void registerType(std::string name, WolframLibraryData libData = LibraryData::API()) noexcept {
221  expressionName = std::move(name);
222  libData->registerLibraryExpressionManager(expressionName.c_str(), manageInstanceCallback<T>);
223  }
224 
230  void unregisterType(WolframLibraryData libData = LibraryData::API()) const noexcept {
231  libData->unregisterLibraryExpressionManager(expressionName.c_str());
232  }
233 
234  private:
239  void checkID(mint id) const {
240  if (!hasInstance(id)) {
242  }
243  }
244 
250  T& instanceAt(mint id) {
251  auto& instancePtr = store[id];
252  if (!instancePtr) {
254  }
255  return *instancePtr;
256  }
257 
258  private:
260  std::unordered_map<mint, std::shared_ptr<T>> store;
261 
263  std::string expressionName;
264  };
265 
266 } // namespace LLU
267 
268 #endif // LLU_MANAGEDEXPRESSION_HPP
LLU::ManagedExpressionStore::end
iterator end() noexcept
Get the iterator past the last element of the Store.
Definition: ManagedExpression.hpp:196
LLU::ErrorName::MLENullInstance
const std::string MLENullInstance
Missing managed object for a valid ID.
LLU
Main namespace of LibraryLink Utilities.
Definition: Queue.h:13
LLU::manageInstanceCallback
void manageInstanceCallback(WolframLibraryData, mbool, mint)
A template for library callback used by LibraryLink to manage instances of ManagedLibraryExpressions.
Definition: ManagedExpression.hpp:41
LLU::ManagedExpressionStore::releaseInstance
int releaseInstance(mint id)
Release an instance managed by this Store.
Definition: ManagedExpression.hpp:123
LLU::ManagedExpressionStore::createInstance
T & createInstance(mint id, Args &&... args)
Create new object of class T that will be managed from Wolfram Language and place it in the map of ma...
Definition: ManagedExpression.hpp:86
LibraryData.h
LLU::ManagedExpressionStore::getInstance
T & getInstance(mint id)
Get managed instance with given id.
Definition: ManagedExpression.hpp:141
LLU::LibraryData::API
static WolframLibraryData API()
Get currently owned WolframLibraryData, if any.
Definition: LibraryData.cpp:22
LLU::ManagedExpressionStore::manageInstance
void manageInstance(mbool mode, mint id)
Function that will actually be called by LibraryLink when an instance of Managed Expression is create...
Definition: ManagedExpression.hpp:69
LLU::ManagedExpressionStore::getExpressionName
const std::string & getExpressionName() const noexcept
Get symbol name that is used in the WL to represent Managed Expressions stored in this Store.
Definition: ManagedExpression.hpp:160
LLU::ManagedExpressionStore::getInstancePointer
std::shared_ptr< T > getInstancePointer(mint id)
Get a shared pointer to a managed instance with given id.
Definition: ManagedExpression.hpp:151
LLU::ManagedExpressionStore::size
size_type size() const noexcept
Get the number of currently managed expressions.
Definition: ManagedExpression.hpp:168
LLU::ManagedExpressionStore::cend
const_iterator cend() const noexcept
Get the const iterator past the last element of the Store.
Definition: ManagedExpression.hpp:210
LLU::ErrorManager::throwException
static void throwException(const std::string &errorName, T &&... args)
Throw exception with given name.
Definition: ErrorManager.h:199
LLU::ManagedExpressionStore::begin
const_iterator begin() const noexcept
Get the const iterator to the first element of the Store.
Definition: ManagedExpression.hpp:182
LLU::ManagedExpressionStore::begin
iterator begin() noexcept
Get the iterator to the first element of the Store.
Definition: ManagedExpression.hpp:175
LLU::ManagedExpressionStore::createInstance
T & createInstance(mint id, std::unique_ptr< T > ptr)
Create instance in the store from a unique pointer to the managed class object.
Definition: ManagedExpression.hpp:111
LLU::ErrorName::ManagedExprInvalidID
const std::string ManagedExprInvalidID
Given number is not an ID of any existing managed expression.
LLU::ManagedExpressionStore::createInstance
T & createInstance(mint id, std::shared_ptr< T > ptr)
Create instance in the store from a pointer to the managed class object.
Definition: ManagedExpression.hpp:99
LLU::ManagedExpressionStore::unregisterType
void unregisterType(WolframLibraryData libData=LibraryData::API()) const noexcept
Unregister class T as managed expression.
Definition: ManagedExpression.hpp:230
LLU::ManagedExpressionStore::registerType
void registerType(std::string name, WolframLibraryData libData=LibraryData::API()) noexcept
Register class T as managed expression under given name.
Definition: ManagedExpression.hpp:220
LLU::ManagedExpressionStore::iterator
typename std::unordered_map< mint, std::shared_ptr< T > >::iterator iterator
Iterator over ManagedExpressionStore - it iterates over the underlying hash map.
Definition: ManagedExpression.hpp:53
LLU::ManagedExpressionStore::cbegin
const_iterator cbegin() const noexcept
Get the const iterator to the first element of the Store.
Definition: ManagedExpression.hpp:189
LLU::ManagedExpressionStore::end
const_iterator end() const noexcept
Get the const iterator past the last element of the Store.
Definition: ManagedExpression.hpp:203
LLU::ManagedExpressionStore::hasInstance
bool hasInstance(mint id) const
Check if instance with given id is present in the store.
Definition: ManagedExpression.hpp:132
LLU::ManagedExpressionStore
ManagedExpressionStore will keep track of instances of managed class T and will provide safe access t...
Definition: ManagedExpression.hpp:50
Utilities.hpp
Short but generally useful functions.
LLU::ManagedExpressionStore::size_type
typename std::unordered_map< mint, std::shared_ptr< T > >::size_type size_type
Size type of the Store is the same as size_type of the underlying hash map.
Definition: ManagedExpression.hpp:59
LLU::ManagedExpressionStore::const_iterator
typename std::unordered_map< mint, std::shared_ptr< T > >::const_iterator const_iterator
Constant iterator over ManagedExpressionStore - it "const-iterates" over the underlying hash map.
Definition: ManagedExpression.hpp:56