aqnwb 0.1.0
Loading...
Searching...
No Matches
RegisteredType.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <filesystem>
4#include <functional>
5#include <memory>
6#include <string>
7#include <unordered_map>
8#include <unordered_set>
9
10#include "Types.hpp"
11#include "Utils.hpp"
12#include "io/BaseIO.hpp"
13#include "io/ReadIO.hpp"
14
15namespace AQNWB
16{
17namespace NWB
18{
19
23constexpr auto AttributeField = AQNWB::Types::StorageObjectType::Attribute;
24
28constexpr auto DatasetField = AQNWB::Types::StorageObjectType::Dataset;
29
48{
49public:
59 RegisteredType(const std::string& path, std::shared_ptr<IO::BaseIO> io);
60
64 virtual ~RegisteredType();
65
70 inline std::string getPath() const { return m_path; }
71
79 inline std::string getName() const
80 {
81 return std::filesystem::path(m_path).filename().string();
82 }
83
88 inline std::shared_ptr<IO::BaseIO> getIO() const { return m_io; }
89
101 static std::unordered_set<std::string>& getRegistry();
102
114 static std::unordered_map<
115 std::string,
116 std::pair<std::function<std::unique_ptr<RegisteredType>(
117 const std::string&, std::shared_ptr<IO::BaseIO>)>,
118 std::pair<std::string, std::string>>>&
120
136 static std::shared_ptr<RegisteredType> create(
137 const std::string& fullClassName,
138 const std::string& path,
139 std::shared_ptr<IO::BaseIO> io,
140 bool fallbackToBase = false);
141
162 static std::shared_ptr<AQNWB::NWB::RegisteredType> create(
163 const std::string& path,
164 std::shared_ptr<IO::BaseIO> io,
165 bool fallbackToBase = false);
166
176 template<typename T>
177 static inline std::shared_ptr<T> create(const std::string& path,
178 std::shared_ptr<IO::BaseIO> io)
179 {
180 static_assert(std::is_base_of<RegisteredType, T>::value,
181 "T must be a derived class of RegisteredType");
182 return std::shared_ptr<T>(new T(path, io));
183 }
184
195 virtual std::string getTypeName() const;
196
208 virtual std::string getNamespace() const;
209
218 inline std::string getFullTypeName() const
219 {
220 return (getNamespace() + "::" + getTypeName());
221 }
222
243 template<StorageObjectType SOT,
244 typename VTYPE,
245 typename std::enable_if<Types::IsDataStorageObjectType<SOT>::value,
246 int>::type = 0>
247 inline std::unique_ptr<IO::ReadDataWrapper<SOT, VTYPE>> readField(
248 const std::string& fieldPath) const
249 {
250 return std::make_unique<IO::ReadDataWrapper<SOT, VTYPE>>(
251 m_io, AQNWB::mergePaths(m_path, fieldPath));
252 }
253
262 inline std::shared_ptr<AQNWB::NWB::RegisteredType> readField(
263 const std::string& fieldPath) const
264 {
265 return this->create(AQNWB::mergePaths(m_path, fieldPath), m_io);
266 }
267
286 virtual std::unordered_map<std::string, std::string> findOwnedTypes(
287 const std::unordered_set<std::string>& types = {},
288 const IO::SearchMode& search_mode = IO::SearchMode::STOP_ON_TYPE) const;
289
290protected:
293 static const std::string m_defaultUnregisteredGroupTypeClass;
294
298
308 static void registerSubclass(
309 const std::string& fullClassName,
310 std::function<std::unique_ptr<RegisteredType>(
311 const std::string&, std::shared_ptr<IO::BaseIO>)> factoryFunction,
312 const std::string& typeName,
313 const std::string& typeNamespace);
314
318 std::string m_path;
319
323 std::shared_ptr<IO::BaseIO> m_io;
324};
325
341#define REGISTER_SUBCLASS_WITH_TYPENAME(T, NAMESPACE, TYPENAME) \
342 static bool registerSubclass() \
343 { \
344 AQNWB::NWB::RegisteredType::registerSubclass( \
345 NAMESPACE "::" #T, \
346 [](const std::string& path, std::shared_ptr<IO::BaseIO> io) \
347 -> std::unique_ptr<AQNWB::NWB::RegisteredType> \
348 { return std::make_unique<T>(path, io); }, \
349 TYPENAME, \
350 NAMESPACE); \
351 return true; \
352 } \
353 static bool registered_; \
354 virtual std::string getTypeName() const override \
355 { \
356 return TYPENAME; \
357 } \
358 virtual std::string getNamespace() const override \
359 { \
360 return NAMESPACE; \
361 }
362
373#define REGISTER_SUBCLASS(T, NAMESPACE) \
374 REGISTER_SUBCLASS_WITH_TYPENAME(T, NAMESPACE, #T)
375
385#define REGISTER_SUBCLASS_IMPL(T) bool T::registered_ = T::registerSubclass();
386
407#define DEFINE_FIELD( \
408 name, storageObjectType, default_type, fieldPath, description) \
409 \
417 template<typename VTYPE = default_type> \
418 inline std::unique_ptr<IO::ReadDataWrapper<storageObjectType, VTYPE>> name() \
419 const \
420 { \
421 return std::make_unique<IO::ReadDataWrapper<storageObjectType, VTYPE>>( \
422 m_io, AQNWB::mergePaths(m_path, fieldPath)); \
423 }
424
439 * Doxygen but the version generated by its on PREDEFINED expansion.
440 *
441 * @param name The name of the function to generate.
442 * @param registeredType The specific subclass of registered type to use
443 * @param fieldPath The path to the field.
444 * @param description A detailed description of the field.
445 */
446#define DEFINE_REGISTERED_FIELD(name, registeredType, fieldPath, description) \
447
450 \
459 template<typename RTYPE = registeredType> \
460 inline std::shared_ptr<RTYPE> name() const \
461 { \
462 std::string objectPath = AQNWB::mergePaths(m_path, fieldPath); \
463 if (m_io->objectExists(objectPath)) { \
464 return RegisteredType::create<RTYPE>(objectPath, m_io); \
465 } \
466 return nullptr; \
467 }
468
490#define DEFINE_REFERENCED_REGISTERED_FIELD( \
491 name, registeredType, fieldPath, description) \
492 \
504 template<typename RTYPE = registeredType> \
505 inline std::shared_ptr<RTYPE> name() const \
506 { \
507 try { \
508 std::string attrPath = AQNWB::mergePaths(m_path, fieldPath); \
509 std::string objectPath = m_io->readReferenceAttribute(attrPath); \
510 if (m_io->objectExists(objectPath)) { \
511 return RegisteredType::create<RTYPE>(objectPath, m_io); \
512 } \
513 } catch (const std::exception& e) { \
514 return nullptr; \
515 } \
516 return nullptr; \
517 }
518
519} // namespace NWB
520} // namespace AQNWB
AQNWB::Types::StorageObjectType StorageObjectType
Definition BaseIO.hpp:21
std::shared_ptr< AQNWB::NWB::RegisteredType > readField(const std::string &fieldPath) const
Read a field that is itself a RegisteredType.
Definition RegisteredType.hpp:262
std::string getFullTypeName() const
Get the full name of the type, i.e., namespace::typename
Definition RegisteredType.hpp:218
virtual std::string getTypeName() const
Get the name of the class type.
Definition RegisteredType.cpp:60
std::string m_path
The path of the registered type.
Definition RegisteredType.hpp:318
static const std::string m_defaultUnregisteredDatasetTypeClass
Save the default RegisteredType to use for reading Dataset types that are not registered.
Definition RegisteredType.hpp:297
RegisteredType(const std::string &path, std::shared_ptr< IO::BaseIO > io)
Constructor.
Definition RegisteredType.cpp:15
virtual std::unordered_map< std::string, std::string > findOwnedTypes(const std::unordered_set< std::string > &types={}, const IO::SearchMode &search_mode=IO::SearchMode::STOP_ON_TYPE) const
Find all typed objects that are owned by this object, i.e., objects that have a neurodata_type and na...
Definition RegisteredType.cpp:132
std::shared_ptr< IO::BaseIO > m_io
A shared pointer to the IO object.
Definition RegisteredType.hpp:323
virtual std::string getNamespace() const
Get the schema namespace of the class type.
Definition RegisteredType.cpp:67
static std::shared_ptr< RegisteredType > create(const std::string &fullClassName, const std::string &path, std::shared_ptr< IO::BaseIO > io, bool fallbackToBase=false)
Create an instance of a registered subclass by name.
Definition RegisteredType.cpp:72
static std::unordered_map< std::string, std::pair< std::function< std::unique_ptr< RegisteredType >(const std::string &, std::shared_ptr< IO::BaseIO >)>, std::pair< std::string, std::string > > > & getFactoryMap()
Get the factory map for creating instances of subclasses.
Definition RegisteredType.cpp:35
std::string getName() const
Get the name of the object.
Definition RegisteredType.hpp:79
std::string getPath() const
Gets the path of the registered type.
Definition RegisteredType.hpp:70
static std::unordered_set< std::string > & getRegistry()
Get the registry of subclass names.
Definition RegisteredType.cpp:24
virtual ~RegisteredType()
Destructor.
Definition RegisteredType.cpp:22
static const std::string m_defaultUnregisteredGroupTypeClass
Save the default RegisteredType to use for reading Group types that are not registered.
Definition RegisteredType.hpp:293
static void registerSubclass(const std::string &fullClassName, std::function< std::unique_ptr< RegisteredType >(const std::string &, std::shared_ptr< IO::BaseIO >)> factoryFunction, const std::string &typeName, const std::string &typeNamespace)
Register a subclass name and its factory function in the registry.
Definition RegisteredType.cpp:46
std::unique_ptr< IO::ReadDataWrapper< SOT, VTYPE > > readField(const std::string &fieldPath) const
Support reading of arbitrary fields by their relative path.
Definition RegisteredType.hpp:247
static std::shared_ptr< T > create(const std::string &path, std::shared_ptr< IO::BaseIO > io)
Factory method to create an instance of a subclass of RegisteredType by type.
Definition RegisteredType.hpp:177
std::shared_ptr< IO::BaseIO > getIO() const
Get a shared pointer to the IO object.
Definition RegisteredType.hpp:88
SearchMode
Enum class for specifying the search mode for findTypes.
Definition BaseIO.hpp:152
@ STOP_ON_TYPE
Stop searching inside an object once a matching type is found.
Definition BaseIO.hpp:156
Namespace for all classes related to the NWB data standard.
Definition TimeSeries.hpp:12
constexpr auto AttributeField
Alias for AQNWB::Types::StorageObjectType::Attribute.
Definition RegisteredType.hpp:23
constexpr auto DatasetField
Alias for AQNWB::Types::StorageObjectType::Dataset.
Definition RegisteredType.hpp:28
The main namespace for AqNWB.
Definition Channel.hpp:11
static std::string mergePaths(const std::string &path1, const std::string &path2)
Merge two paths into a single path, handling extra trailing and starting "/".
Definition Utils.hpp:112