-
Notifications
You must be signed in to change notification settings - Fork 92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use Meyers singletons #1222
base: devel
Are you sure you want to change the base?
Use Meyers singletons #1222
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -38,14 +38,7 @@ class BuilderLibrary | |
|
||
BuilderLibrary(const std::string& name) : name_(name) {} | ||
|
||
BaseBuilder* getBuilder(const std::string& name) | ||
{ | ||
auto iter = factories_.find(name); | ||
if ( iter == factories_.end() ) { return nullptr; } | ||
else { | ||
return iter->second; | ||
} | ||
} | ||
BaseBuilder* getBuilder(const std::string& name) { return factories_[name]; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since I do not see anywhere |
||
|
||
const std::map<std::string, BaseBuilder*>& getMap() const { return factories_; } | ||
|
||
|
@@ -88,29 +81,16 @@ class BuilderLibraryDatabase | |
|
||
static Library* getLibrary(const std::string& name) | ||
{ | ||
if ( !libraries ) { libraries = new std::map<std::string, Library*>; } | ||
auto iter = libraries->find(name); | ||
if ( iter == libraries->end() ) { | ||
auto* info = new Library(name); | ||
(*libraries)[name] = info; | ||
return info; | ||
} | ||
else { | ||
return iter->second; | ||
} | ||
static Map libraries; // Database | ||
auto& lib = libraries[name]; | ||
if ( !lib ) lib = new Library(name); | ||
return lib; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the Meyers singleton initializing the map on the first call to It also uses a reference to the map entry and checks if it's |
||
} | ||
|
||
template <class NewBase> | ||
using ChangeBase = BuilderLibraryDatabase<NewBase, CtorArgs...>; | ||
|
||
private: | ||
// Database - needs to be a pointer for static init order | ||
static Map* libraries; | ||
}; | ||
|
||
template <class Base, class... CtorArgs> | ||
typename BuilderLibraryDatabase<Base, CtorArgs...>::Map* BuilderLibraryDatabase<Base, CtorArgs...>::libraries = nullptr; | ||
|
||
template <class Base, class Builder, class... CtorArgs> | ||
struct BuilderLoader : public LibraryLoader | ||
{ | ||
|
@@ -147,12 +127,9 @@ struct InstantiateBuilder | |
{ | ||
static bool isLoaded() { return loaded; } | ||
|
||
static const bool loaded; | ||
static inline const bool loaded = Base::Ctor::template add<T>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
}; | ||
|
||
template <class Base, class T> | ||
const bool InstantiateBuilder<Base, T>::loaded = Base::Ctor::template add<T>(); | ||
|
||
template <class Base, class T, class Enable = void> | ||
struct Allocator | ||
{ | ||
|
@@ -169,14 +146,10 @@ struct CachedAllocator | |
template <class... Args> | ||
Base* operator()(Args&&... ctorArgs) | ||
{ | ||
if ( !cached_ ) { cached_ = new T(std::forward<Args>(ctorArgs)...); } | ||
return cached_; | ||
static T cached(std::forward<Args>(ctorArgs)...); | ||
return &cached; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another Meyers Singleton, in lieu of calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it needs to be a pointer which can be static T* cached = new T(std::forward<Args>(ctorArgs)...);
return cached; |
||
} | ||
|
||
static Base* cached_; | ||
}; | ||
template <class Base, class T> | ||
Base* CachedAllocator<Base, T>::cached_ = nullptr; | ||
|
||
template <class T, class Base, class... Args> | ||
struct DerivedBuilder : public Builder<Base, Args...> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,32 +59,24 @@ class DataBase | |
public: | ||
static T* get(const std::string& elemlib, const std::string& elem) | ||
{ | ||
if ( !infos_ ) return nullptr; | ||
|
||
auto libiter = infos_->find(elemlib); | ||
if ( libiter != infos_->end() ) { | ||
auto libiter = infos().find(elemlib); | ||
if ( libiter != infos().end() ) { | ||
auto& submap = libiter->second; | ||
auto elemiter = submap.find(elem); | ||
if ( elemiter != submap.end() ) { return elemiter->second; } | ||
} | ||
return nullptr; | ||
} | ||
|
||
static void add(const std::string& elemlib, const std::string& elem, T* info) | ||
{ | ||
if ( !infos_ ) { | ||
infos_ = std::unique_ptr<std::map<std::string, std::map<std::string, T*>>>( | ||
new std::map<std::string, std::map<std::string, T*>>); | ||
} | ||
|
||
(*infos_)[elemlib][elem] = info; | ||
} | ||
static void add(const std::string& elemlib, const std::string& elem, T* info) { infos()[elemlib][elem] = info; } | ||
|
||
private: | ||
static std::unique_ptr<std::map<std::string, std::map<std::string, T*>>> infos_; | ||
static auto& infos() | ||
{ | ||
static std::map<std::string, std::map<std::string, T*>> infos_; | ||
return infos_; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another Meyers singleton. |
||
}; | ||
template <class T> | ||
std::unique_ptr<std::map<std::string, std::map<std::string, T*>>> DataBase<T>::infos_; | ||
|
||
template <class Policy, class... Policies> | ||
class BuilderInfoImpl : public Policy, public BuilderInfoImpl<Policies...> | ||
|
@@ -166,7 +158,7 @@ class InfoLibrary | |
return count; | ||
} | ||
|
||
const std::map<std::string, BaseInfo*>& getMap() const { return infos_; } | ||
const auto& getMap() const { return infos_; } | ||
|
||
void readdInfo(const std::string& name, BaseInfo* info) | ||
{ | ||
|
@@ -208,36 +200,30 @@ class InfoLibraryDatabase | |
|
||
std::vector<std::string> ret; | ||
// First iterate over libraries | ||
for ( auto x : (*libraries) ) { | ||
for ( auto& y : x.second->getMap() ) { | ||
ret.push_back(x.first + "." + y.first); | ||
for ( auto& [name, lib] : libraries() ) { | ||
for ( auto& [elemlib, info] : lib->getMap() ) { | ||
ret.push_back(name + "." + elemlib); | ||
} | ||
} | ||
return ret; | ||
} | ||
|
||
static Library* getLibrary(const std::string& name) | ||
{ | ||
if ( !libraries ) { libraries = new Map; } | ||
auto iter = libraries->find(name); | ||
if ( iter == libraries->end() ) { | ||
auto* info = new Library(name); | ||
(*libraries)[name] = info; | ||
return info; | ||
} | ||
else { | ||
return iter->second; | ||
} | ||
auto& lib = libraries()[name]; | ||
if ( !lib ) lib = new Library(name); | ||
return lib; | ||
} | ||
|
||
private: | ||
// Database - needs to be a pointer for static init order | ||
static Map* libraries; | ||
// Database | ||
static Map& libraries() | ||
{ | ||
static Map libs; | ||
return libs; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again. |
||
}; | ||
|
||
template <class Base> | ||
typename InfoLibraryDatabase<Base>::Map* InfoLibraryDatabase<Base>::libraries = nullptr; | ||
|
||
template <class Base, class Info> | ||
struct InfoLoader : public LibraryLoader | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,32 +20,16 @@ namespace SST { | |
**************************************************************************/ | ||
namespace ELI { | ||
|
||
std::unique_ptr<LoadedLibraries::LibraryMap> LoadedLibraries::loaders_ {}; | ||
|
||
bool | ||
LoadedLibraries::addLoader( | ||
const std::string& lib, const std::string& name, const std::string& alias, LibraryLoader* loader) | ||
{ | ||
if ( !loaders_ ) { loaders_ = std::unique_ptr<LibraryMap>(new LibraryMap); } | ||
(*loaders_)[lib][name].push_back(loader); | ||
if ( !alias.empty() ) (*loaders_)[lib][alias].push_back(loader); | ||
return true; | ||
} | ||
std::shared_ptr<LibraryLoader> shared_loader(loader); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We create a |
||
|
||
const LoadedLibraries::LibraryMap& | ||
LoadedLibraries::getLoaders() | ||
{ | ||
if ( !loaders_ ) { loaders_ = std::unique_ptr<LibraryMap>(new LibraryMap); } | ||
return *loaders_; | ||
} | ||
|
||
bool | ||
LoadedLibraries::isLoaded(const std::string& name) | ||
{ | ||
if ( loaders_ ) { return loaders_->find(name) != loaders_->end(); } | ||
else { | ||
return false; // nothing loaded yet | ||
} | ||
auto& library = getLoaders()[lib]; | ||
if ( !alias.empty() && alias != name ) library[alias].push_back(shared_loader); | ||
library[name].push_back(std::move(shared_loader)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the last use of |
||
return true; | ||
} | ||
|
||
} // namespace ELI | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,11 +16,9 @@ | |
|
||
#include <algorithm> | ||
#include <cstring> | ||
#include <functional> | ||
#include <list> | ||
#include <deque> | ||
#include <map> | ||
#include <memory> | ||
#include <set> | ||
#include <string> | ||
#include <type_traits> | ||
#include <vector> | ||
|
@@ -124,28 +122,27 @@ combineEliInfo(std::vector<T>& base, const std::vector<T>& add) | |
|
||
struct LibraryLoader | ||
{ | ||
virtual void load() = 0; | ||
virtual ~LibraryLoader() {} | ||
virtual void load() = 0; | ||
virtual ~LibraryLoader() = default; | ||
}; | ||
|
||
class LoadedLibraries | ||
{ | ||
public: | ||
using InfoMap = std::map<std::string, std::list<LibraryLoader*>>; | ||
using InfoMap = std::map<std::string, std::deque<std::shared_ptr<LibraryLoader>>>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
using LibraryMap = std::map<std::string, InfoMap>; | ||
|
||
static bool isLoaded(const std::string& name); | ||
static bool isLoaded(const std::string& name) { return getLoaders().count(name) != 0; } | ||
|
||
/** | ||
@return A boolean indicated successfully added | ||
*/ | ||
// @return A boolean indicated successfully added | ||
static bool | ||
addLoader(const std::string& lib, const std::string& name, const std::string& alias, LibraryLoader* loader); | ||
|
||
static const LibraryMap& getLoaders(); | ||
|
||
private: | ||
static std::unique_ptr<LibraryMap> loaders_; | ||
static LibraryMap& getLoaders() | ||
{ | ||
static LibraryMap loaders; | ||
return loaders; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Meyers singleton. |
||
}; | ||
|
||
// Template used to get aliases. Needed because the ELI_getAlias() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This allows
loader
to be either a regular pointer or a smart pointer. The previous code only allowed regular pointers.