12#ifndef SST_CORE_ELI_ELEMENTBUILDER_H
13#define SST_CORE_ELI_ELEMENTBUILDER_H
15#include "sst/core/eli/elibase.h"
25template <
class Base,
class... Args>
28 using createFxn = Base* (*)(Args...);
30 virtual Base* create(Args... ctorArgs) = 0;
32 template <
class NewBase>
33 using ChangeBase =
Builder<NewBase, Args...>;
38template <
class Base,
class... CtorArgs>
42 using BaseBuilder =
Builder<Base, CtorArgs...>;
44 explicit BuilderLibrary(
const std::string& name) :
48 BaseBuilder* getBuilder(
const std::string& name) {
return factories_[name]; }
50 const std::map<std::string, BaseBuilder*>& getMap()
const {
return factories_; }
52 void readdBuilder(
const std::string& name,
const std::string& alias, BaseBuilder* fact)
54 factories_[name] = fact;
55 if ( !alias.empty() ) factories_[alias] = fact;
58 bool addBuilder(
const std::string& elem,
const std::string& alias, BaseBuilder* fact)
60 readdBuilder(elem, alias, fact);
61 return addLoader(name_, elem, alias, fact);
64 bool addBuilder(
const std::string& elem, BaseBuilder* fact)
66 readdBuilder(elem,
"", fact);
67 return addLoader(name_, elem,
"", fact);
70 template <
class NewBase>
71 using ChangeBase = BuilderLibrary<NewBase, CtorArgs...>;
74 bool addLoader(
const std::string& elemlib,
const std::string& elem,
const std::string& alias, BaseBuilder* fact);
76 std::map<std::string, BaseBuilder*> factories_;
81template <
class Base,
class... CtorArgs>
86 using BaseFactory =
typename Library::BaseBuilder;
87 using Map = std::map<std::string, Library*>;
89 static Library* getLibrary(
const std::string& name)
92 auto& lib = libraries[name];
93 if ( !lib ) lib =
new Library(name);
97 template <
class NewBase>
101template <
class Base,
class Builder,
class... CtorArgs>
104 BuilderLoader(
const std::string& elemlib,
const std::string& elem,
const std::string& alias,
Builder* builder) :
113 BuilderLibraryDatabase<Base, CtorArgs...>::getLibrary(elemlib_)->readdBuilder(elem_, alias_, builder_);
116 BuilderLoader(
const BuilderLoader&) =
delete;
117 BuilderLoader& operator=(
const BuilderLoader&) =
delete;
120 std::string elemlib_;
126template <
class Base,
class... CtorArgs>
128BuilderLibrary<Base, CtorArgs...>::addLoader(
129 const std::string& elemlib,
const std::string& elem,
const std::string& alias, BaseBuilder* fact)
131 auto loader =
new BuilderLoader<Base, BaseBuilder, CtorArgs...>(elemlib, elem, alias, fact);
132 return ELI::LoadedLibraries::addLoader(elemlib, elem, alias, loader);
135template <
class Base,
class T>
138 static bool isLoaded() {
return loaded; }
140 static inline const bool loaded = Base::Ctor::template add<T>();
143template <
class Base,
class T,
class Enable =
void>
146 template <
class... Args>
147 T* operator()(Args&&... args)
149 return new T(std::forward<Args>(args)...);
153template <
class Base,
class T>
156 template <
class... Args>
157 Base* operator()(Args&&... ctorArgs)
159 static T* cached =
new T(std::forward<Args>(ctorArgs)...);
164template <
class T,
class Base,
class... Args>
167 Base* create(Args... ctorArgs)
override {
return Allocator<Base, T>()(std::forward<Args>(ctorArgs)...); }
170template <
class,
class>
171inline constexpr bool is_tuple_constructible_v =
false;
173template <
class T,
class... Args>
174inline constexpr bool is_tuple_constructible_v<T, std::tuple<Args...>> = std::is_constructible_v<T, Args...>;
178 template <
class T,
class... Args>
179 static BuilderLibrary<T, Args...>* getLibrary(
const std::string& name)
181 return BuilderLibraryDatabase<T, Args...>::getLibrary(name);
185template <
class Base,
class CtorTuple>
189template <
class Base,
class... Args>
192 static BuilderLibrary<Base, Args...>* getLibrary(
const std::string& name)
194 return BuilderLibraryDatabase<Base, Args...>::getLibrary(name);
198 static Builder<Base, Args...>* makeBuilder()
210template <
class NewCtor,
class OldCtor>
214 static constexpr bool is_constructible_v = NewCtor::template is_constructible_v<T>;
222 static std::enable_if_t<OldCtor::template is_constructible_v<T>,
bool>
add()
225 return NewCtor::template
add<T>() && OldCtor::template
add<T>();
229 static std::enable_if_t<!OldCtor::template is_constructible_v<T>,
bool>
add()
232 return NewCtor::template
add<T>();
235 template <
class __NewCtor>
236 using ExtendCtor = ExtendedCtor<__NewCtor, ExtendedCtor<NewCtor, OldCtor>>;
238 template <
class NewBase>
239 using ChangeBase =
typename NewCtor::template ChangeBase<NewBase>;
242template <
class Base,
class... Args>
246 static constexpr bool is_constructible_v = std::is_constructible_v<T, Args...>;
253 return Base::addBuilder(T::ELI_getLibrary(), T::ELI_getName(), SST::ELI::GetAlias<T>::get(), fact);
256 template <
class NewBase>
257 using ChangeBase =
SingleCtor<NewBase, Args...>;
259 template <
class NewCtor>
263template <
class Base,
class Ctor,
class... Ctors>
267 static constexpr bool is_constructible_v =
268 is_tuple_constructible_v<T, Ctor>
269 ||
CtorList<Base, Ctors...>::template is_constructible_v<T>;
271 template <
class T,
int NumVal
id = 0,
class U = T>
272 static std::enable_if_t<std::is_abstract_v<U> || is_tuple_constructible_v<U, Ctor>,
bool> add()
276 Base::addBuilder(T::ELI_getLibrary(), T::ELI_getName(), SST::ELI::GetAlias<T>::get(), fact);
277 return CtorList<Base, Ctors...>::template add<T, NumValid + 1>();
280 template <
class T,
int NumVal
id = 0,
class U = T>
281 static std::enable_if_t<!std::is_abstract_v<U> && !is_tuple_constructible_v<U, Ctor>,
bool> add()
283 return CtorList<Base, Ctors...>::template add<T, NumValid>();
286 template <
class NewBase>
287 using ChangeBase =
CtorList<NewBase, Ctor, Ctors...>;
290template <
int NumVal
id>
293 static constexpr bool atLeastOneValidCtor =
true;
304 static constexpr bool is_constructible_v =
false;
306 template <
class T,
int numVal
idCtors>
309 return NoValidConstructorsForDerivedType<numValidCtors>::atLeastOneValidCtor;
315#define ELI_CTOR(...) std::tuple<__VA_ARGS__>
316#define ELI_DEFAULT_CTOR() std::tuple<>
318#define SST_ELI_CTORS_COMMON(...) \
319 using Ctor = ::SST::ELI::CtorList<__LocalEliBase, __VA_ARGS__, void>; \
320 template <class __TT, class... __CtorArgs> \
321 using DerivedBuilder = ::SST::ELI::DerivedBuilder<__LocalEliBase, __TT, __CtorArgs...>; \
322 template <class... __InArgs> \
323 static SST::ELI::BuilderLibrary<__LocalEliBase, __InArgs...>* getBuilderLibraryTemplate(const std::string& name) \
325 return ::SST::ELI::BuilderDatabase::getLibrary<__LocalEliBase, __InArgs...>(name); \
327 template <class __TT> \
328 static bool addDerivedBuilder(const std::string& lib, const std::string& elem) \
330 return Ctor::template add<0, __TT>(lib, elem); \
333#define SST_ELI_DECLARE_CTORS(...) \
334 SST_ELI_CTORS_COMMON(ELI_FORWARD_AS_ONE(__VA_ARGS__)) \
335 template <class... Args> \
336 static bool addBuilder(const std::string& elemlib, const std::string& elem, const std::string& alias, \
337 SST::ELI::Builder<__LocalEliBase, Args...>* builder) \
339 return getBuilderLibraryTemplate<Args...>(elemlib)->addBuilder(elem, alias, builder); \
342#define SST_ELI_DECLARE_CTORS_EXTERN(...) SST_ELI_CTORS_COMMON(ELI_FORWARD_AS_ONE(__VA_ARGS__))
347#define SST_ELI_BUILDER_TYPEDEFS(...) \
348 using BaseBuilder = ::SST::ELI::Builder<__VA_ARGS__>; \
349 using BuilderLibrary = ::SST::ELI::BuilderLibrary<__VA_ARGS__>; \
350 using BuilderLibraryDatabase = ::SST::ELI::BuilderLibraryDatabase<__VA_ARGS__>; \
351 template <class __TT> \
352 using DerivedBuilder = ::SST::ELI::DerivedBuilder<__TT, __VA_ARGS__>;
354#define SST_ELI_BUILDER_FXNS() \
355 static BuilderLibrary* getBuilderLibrary(const std::string& name) \
357 return BuilderLibraryDatabase::getLibrary(name); \
359 static bool addBuilder( \
360 const std::string& elemlib, const std::string& elem, const std::string& alias, BaseBuilder* builder) \
362 return getBuilderLibrary(elemlib)->addBuilder(elem, alias, builder); \
366#define SST_ELI_DECLARE_CTOR(...) \
367 using Ctor = ::SST::ELI::SingleCtor<__LocalEliBase, __VA_ARGS__>; \
368 SST_ELI_BUILDER_TYPEDEFS(__LocalEliBase, __VA_ARGS__) \
369 SST_ELI_BUILDER_FXNS()
371#define SST_ELI_BUILDER_FXNS_EXTERN() \
372 static BuilderLibrary* getBuilderLibrary(const std::string& name); \
373 static bool addBuilder( \
374 const std::string& elemlib, const std::string& elem, const std::string& alias, BaseBuilder* builder);
376#define SST_ELI_DECLARE_CTOR_EXTERN(...) \
377 using Ctor = ::SST::ELI::SingleCtor<__LocalEliBase, __VA_ARGS__>; \
378 SST_ELI_BUILDER_TYPEDEFS(__LocalEliBase, __VA_ARGS__); \
379 SST_ELI_BUILDER_FXNS_EXTERN()
381#define SST_ELI_DEFINE_CTOR_EXTERN(base) \
382 bool base::addBuilder( \
383 const std::string& elemlib, const std::string& elem, const std::string& alias, BaseBuilder* builder) \
385 return getBuilderLibrary(elemlib)->addBuilder(elem, alias, builder); \
387 base::BuilderLibrary* base::getBuilderLibrary(const std::string& elemlib) \
389 return BuilderLibraryDatabase::getLibrary(elemlib); \
393#define SST_ELI_DECLARE_DEFAULT_CTOR() \
394 using Ctor = ::SST::ELI::SingleCtor<__LocalEliBase>; \
395 SST_ELI_BUILDER_TYPEDEFS(__LocalEliBase) \
396 SST_ELI_BUILDER_FXNS()
398#define SST_ELI_DECLARE_DEFAULT_CTOR_EXTERN() \
399 using Ctor = ::SST::ELI::SingleCtor<__LocalEliBase>; \
400 SST_ELI_BUILDER_TYPEDEFS(__LocalEliBase) \
401 SST_ELI_BUILDER_FXNS_EXTERN()
403#define SST_ELI_EXTEND_CTOR() using Ctor = ::SST::ELI::ExtendedCtor<LocalCtor, __ParentEliBase::Ctor>;
405#define SST_ELI_SAME_BASE_CTOR() \
406 using LocalCtor = __ParentEliBase::Ctor::ChangeBase<__LocalEliBase>; \
407 SST_ELI_EXTEND_CTOR() \
408 using BaseBuilder = typename __ParentEliBase::BaseBuilder::template ChangeBase<__LocalEliBase>; \
409 using BuilderLibrary = __ParentEliBase::BuilderLibrary::ChangeBase<__LocalEliBase>; \
410 using BuilderLibraryDatabase = __ParentEliBase::BuilderLibraryDatabase::ChangeBase<__LocalEliBase>; \
411 SST_ELI_BUILDER_FXNS()
413#define SST_ELI_NEW_BASE_CTOR(...) \
414 using LocalCtor = ::SST::ELI::SingleCtor<__LocalEliBase, __VA_ARGS__>; \
415 SST_ELI_EXTEND_CTOR() \
416 SST_ELI_BUILDER_TYPEDEFS(__LocalEliBase, __VA_ARGS__) \
417 SST_ELI_BUILDER_FXNS()
419#define SST_ELI_DEFAULT_BASE_CTOR() \
420 using LocalCtor = ::SST::ELI::SingleCtor<__LocalEliBase>; \
421 SST_ELI_EXTEND_CTOR() \
422 SST_ELI_BUILDER_TYPEDEFS(__LocalEliBase) \
423 SST_ELI_BUILDER_FXNS()
Definition elementbuilder.h:83
Definition elementbuilder.h:40
Definition elementbuilder.h:145
Definition elementbuilder.h:177
Definition elementbuilder.h:103
Definition elementbuilder.h:27
Definition elementbuilder.h:155
Definition elementbuilder.h:265
Definition elementbuilder.h:166
Definition elementbuilder.h:187
Implements a constructor for a derived base as usually happens with subcomponents,...
Definition elementbuilder.h:212
static std::enable_if_t< OldCtor::template is_constructible_v< T >, bool > add()
The derived Ctor can "block" the more abstract Ctor, meaning an object should only be instantiated as...
Definition elementbuilder.h:222
Definition elementbuilder.h:137
Definition elementbuilder.h:292
Definition elementbuilder.h:244