LibraryLink Utilities  3.0.1
Modern C++ wrapper over LibraryLink and WSTP
Generic/DataStore.hpp
Go to the documentation of this file.
1 
6 #ifndef LLU_CONTAINERS_GENERIC_DATASTORE_HPP
7 #define LLU_CONTAINERS_GENERIC_DATASTORE_HPP
8 
11 #include "LLU/MArgument.h"
12 #include "LLU/TypedMArgument.h"
13 
14 namespace LLU {
15 
18 
22  template<>
23  class MContainer<MArgumentType::DataStore> : public MContainerBase<MArgumentType::DataStore> {
24 
25  template<typename T>
26  using EnableIfArgumentType = std::enable_if_t<Argument::PrimitiveQ<remove_cv_ref<T>> || Argument::WrapperQ<remove_cv_ref<T>>, int>;
27 
28  template<MArgumentType T>
29  using EnableIfUnambiguousWrapperType = std::enable_if_t<!Argument::PrimitiveQ<Argument::WrapperType<T>>, int>;
30 
31  public:
34 
37 
40 
44  MContainer() : MContainer(LibraryData::DataStoreAPI()->createDataStore(), Ownership::Library) {}
45 
52  MContainer(Container c, Ownership owner);
53 
59  MContainer clone() const {
60  return MContainer {cloneContainer(), Ownership::Library};
61  }
62 
67  mint length() const {
68  return LibraryData::DataStoreAPI()->DataStore_getLength(this->getContainer());
69  }
70 
75  DataStoreNode front() const {
76  return LibraryData::DataStoreAPI()->DataStore_getFirstNode(this->getContainer());
77  };
78 
83  DataStoreNode back() const {
84  return LibraryData::DataStoreAPI()->DataStore_getLastNode(this->getContainer());
85  };
86 
88  iterator begin() const {
89  return iterator {front()};
90  }
91 
93  // NOLINTNEXTLINE(readability-convert-member-functions-to-static): although in theory end() could be static, it would be uncommon and confusing
94  iterator end() const {
95  return iterator {nullptr};
96  }
97 
100  return begin();
101  }
102 
105  return end();
106  }
107 
115  template<typename T, EnableIfArgumentType<T> = 0>
116  void push_back(T nodeValue);
117 
126  template<typename T, EnableIfArgumentType<T> = 0>
127  void push_back(std::string_view name, T nodeValue);
128 
134  template<MArgumentType Type, EnableIfUnambiguousWrapperType<Type> = 0>
136  PrimitiveWrapper<Type>::addDataStoreNode(getContainer(), Argument::toPrimitiveType<Type>(nodeValue));
137  }
138 
145  template<MArgumentType Type, EnableIfUnambiguousWrapperType<Type> = 0>
146  void push_back(std::string_view name, Argument::WrapperType<Type> nodeValue) {
147  PrimitiveWrapper<Type>::addDataStoreNode(getContainer(), name, Argument::toPrimitiveType<Type>(nodeValue));
148  }
149 
155  template<MArgumentType Type>
157  PrimitiveWrapper<Type>::addDataStoreNode(getContainer(), nodeValue);
158  }
159 
166  template<MArgumentType Type>
167  void push_back(std::string_view name, Argument::CType<Type> nodeValue) {
168  PrimitiveWrapper<Type>::addDataStoreNode(getContainer(), name, nodeValue);
169  }
170 
175  void push_back(const Argument::Typed::Any& node);
176 
182  void push_back(std::string_view name, const Argument::Typed::Any& node);
183 
184  private:
186  Container cloneImpl() const override {
187  return LibraryData::DataStoreAPI()->copyDataStore(this->getContainer());
188  }
189 
194  mint shareCountImpl() const noexcept override {
195  return 0;
196  }
197 
202  void passImpl(MArgument& res) const noexcept override {
203  //NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast): c-style cast used in a macro in WolframIOLibraryFunctions.h
204  MArgument_setDataStore(res, this->getContainer());
205  }
206  };
207 
208  template<typename T, GenericDataList::EnableIfArgumentType<T>>
209  void GenericDataList::push_back(T nodeValue) {
210  static_assert(!std::is_same_v<T, MTensor>, "Do not use push_back templated on the argument type with MTensor or MNumericArray.");
211  if constexpr (Argument::PrimitiveQ<T>) {
212  constexpr MArgumentType Type = Argument::PrimitiveIndex<T>;
213  PrimitiveWrapper<Type>::addDataStoreNode(getContainer(), nodeValue);
214  } else if constexpr (Argument::WrapperQ<T>) {
215  constexpr MArgumentType Type = Argument::WrapperIndex<T>;
216  PrimitiveWrapper<Type>::addDataStoreNode(getContainer(), Argument::toPrimitiveType<Type>(nodeValue));
217  }
218  }
219 
220  template<typename T, GenericDataList::EnableIfArgumentType<T>>
221  void GenericDataList::push_back(std::string_view name, T nodeValue) {
222  static_assert(!std::is_same_v<T, MTensor>, "Do not use push_back templated on the argument type with MTensor or MNumericArray.");
223  if constexpr (Argument::PrimitiveQ<T>) {
224  constexpr MArgumentType Type = Argument::PrimitiveIndex<T>;
225  PrimitiveWrapper<Type>::addDataStoreNode(getContainer(), name, nodeValue);
226  } else if constexpr (Argument::WrapperQ<T>) {
227  constexpr MArgumentType Type = Argument::WrapperIndex<T>;
228  PrimitiveWrapper<Type>::addDataStoreNode(getContainer(), name, Argument::toPrimitiveType<Type>(nodeValue));
229  }
230  }
231 
232  template<typename T>
234  auto v = value();
235  auto* ptr = std::get_if<T>(std::addressof(v));
236  if (!ptr) {
238  }
239  return std::move(*ptr);
240  }
241 } // namespace LLU
242 
243 #endif // LLU_CONTAINERS_GENERIC_DATASTORE_HPP
LLU::MContainerBase
Template of the base class for all generic containers.
Definition: Base.hpp:35
LLU::MContainer< MArgumentType::DataStore >::cend
const_iterator cend() const
Proxy iterator past the last element of the DataStore.
Definition: Generic/DataStore.hpp:104
LLU::MContainer< MArgumentType::DataStore >::push_back
void push_back(Argument::CType< Type > nodeValue)
Add new nameless node at the end of the underlying DataStore.
Definition: Generic/DataStore.hpp:156
LLU::ErrorName::DLInvalidNodeType
const std::string DLInvalidNodeType
DataStoreNode passed to Node wrapper carries data of invalid type.
LLU::Argument::CType
std::conditional_t< T==MArgumentType::MArgument, MArgument, std::variant_alternative_t< static_cast< size_t >(T), PrimitiveAny > > CType
Type alias that binds given MArgumentType (enumerated value) to the corresponding type of MArgument.
Definition: MArgument.h:53
LLU::MContainer< MArgumentType::DataStore >
MContainer specialization for DataStore, provides basic list interface for the underlying raw DataSto...
Definition: Generic/DataStore.hpp:23
LLU
Main namespace of LibraryLink Utilities.
Definition: Queue.h:13
LLU::MContainer
MContainer is an abstract class template for generic containers. Only specializations shall be used.
Definition: Base.hpp:245
TypedMArgument.h
LLU::MContainer< MArgumentType::DataStore >::push_back
void push_back(T nodeValue)
Add new nameless node at the end of the underlying DataStore.
Definition: Generic/DataStore.hpp:209
LLU::MContainer< MArgumentType::DataStore >::MContainer
MContainer()
Default constructor, creates empty DataStore owned by the Library.
Definition: Generic/DataStore.hpp:44
LLU::DataStoreIterator
Proxy input iterator over DataStoreNodes, when dereferenced yields GenericDataNode proxy objects.
Definition: Iterators/DataStore.hpp:75
LLU::Argument::Typed::Any
TypedArgument Any
Any is a union of all supported types. Typed::Any can be used as a template parameter for DataList to...
Definition: TypedMArgument.h:70
LLU::GenericDataNode::as
T as() const
Get node value if it is of type T, otherwise throw an exception.
Definition: Generic/DataStore.hpp:233
LLU::Ownership::Library
@ Library
The library (LLU) is responsible for managing the container's memory. Used for Manual passing and con...
LLU::PrimitiveWrapper::addDataStoreNode
static void addDataStoreNode(DataStore ds, std::string_view name, value_type val)
Add val to the DataStore ds inside a node named name This is a static method because there is no MArg...
LLU::MContainer< MArgumentType::DataStore >::end
iterator end() const
Proxy iterator past the last element of the DataStore.
Definition: Generic/DataStore.hpp:94
LLU::Argument::Typed::DataStore
MContainer< MArgumentType::DataStore > DataStore
DataStore stands for a GenericDataList - type agnostic wrapper over DataStore.
Definition: TypedMArgument.h:62
LLU::Argument::WrapperType
std::conditional_t< T==MArgumentType::MArgument, TypedArgument, std::variant_alternative_t< static_cast< size_t >(T), TypedArgument > > WrapperType
Get wrapper type corresponding to primitive LibraryLink argument type T.
Definition: TypedMArgument.h:92
LLU::MContainer< MArgumentType::DataStore >::length
mint length() const
Get the length of the DataStore.
Definition: Generic/DataStore.hpp:67
LLU::MContainer< MArgumentType::DataStore >::back
DataStoreNode back() const
Get the last node of the DataStore.
Definition: Generic/DataStore.hpp:83
LLU::MContainer< MArgumentType::DataStore >::clone
MContainer clone() const
Clone this MContainer, performs a deep copy of the underlying DataStore.
Definition: Generic/DataStore.hpp:59
LLU::ErrorManager::throwException
static void throwException(const std::string &errorName, T &&... args)
Throw exception with given name.
Definition: ErrorManager.h:199
Base.hpp
Definitions of MContainerBase and MContainer class templates.
LLU::MContainer< MArgumentType::DataStore >::push_back
void push_back(std::string_view name, Argument::WrapperType< Type > nodeValue)
Add new named node at the end of the underlying DataStore.
Definition: Generic/DataStore.hpp:146
LLU::MContainer< MArgumentType::DataStore >::push_back
void push_back(std::string_view name, Argument::CType< Type > nodeValue)
Add new named node at the end of the underlying DataStore.
Definition: Generic/DataStore.hpp:167
LLU::MArgumentType
MArgumentType
Strongly type enum with possible types of data stored in MArgument.
Definition: MArgument.h:22
LLU::MContainer< MArgumentType::DataStore >::cbegin
const_iterator cbegin() const
Proxy iterator to the first element of the DataStore.
Definition: Generic/DataStore.hpp:99
LLU::MContainer< MArgumentType::DataStore >::begin
iterator begin() const
Proxy iterator to the first element of the DataStore.
Definition: Generic/DataStore.hpp:88
LLU::MContainer< MArgumentType::DataStore >::front
DataStoreNode front() const
Get the first node of the DataStore.
Definition: Generic/DataStore.hpp:75
LLU::LibraryData::DataStoreAPI
static const st_WolframIOLibrary_Functions * DataStoreAPI()
Get a pointer to structure with function pointers to DataStore API.
Definition: LibraryData.cpp:45
MArgument.h
Template class and utilities to work with MArgument in type-safe manner.
DataStore.hpp
LLU::GenericDataNode::value
Argument::TypedArgument value() const
Get value of the node as the variant type.
Definition: DataStore.cpp:26
LLU::Ownership
Ownership
An enum listing possible owners of a LibraryLink container.
Definition: Base.hpp:22
LLU::MContainer< MArgumentType::DataStore >::push_back
void push_back(Argument::WrapperType< Type > nodeValue)
Add new nameless node at the end of the underlying DataStore.
Definition: Generic/DataStore.hpp:135
LLU::LibraryData
This structure offers a static copy of WolframLibData accessible throughout the whole life of the DLL...
Definition: LibraryData.h:48