Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ makefile.dep
/config.*
/autom4*
/stamp-h
/build
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this can be a standalone commit?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed from this PR

/.vscode
36 changes: 27 additions & 9 deletions src/core/ActionRegister.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,34 @@ ActionRegister& actionRegister();

std::ostream & operator<<(std::ostream &log,const ActionRegister&ar);

}
template<typename T>
inline constexpr bool isActionType = std::is_base_of<Action, T>::value;
//in C++20 you we'll make this a concept
//template<typename T>
//concept ActionType = std::is_base_of<::PLMD::Action, T>::value;
//so the template will be template<ActionType ActionType>class ActionRegistration{...}
//without the explicit need of the static assert

///Each instance of this specialized class represents an action that can be called
///with the specified directive.
///As soon it goes out of scope it will deregister the directive from ActionRegister
template<typename ActionClass>
class ActionRegistration {
static std::unique_ptr<Action> create(const ActionOptions&ao) {
return std::make_unique<ActionClass>(ao);
}
public:
///On construction register the ActionClass with the wanted directive
ActionRegistration(std::string_view directive) {
static_assert(isActionType<ActionClass>,"ActionRegistration accepts only class that inherit from Action");
actionRegister().add(directive.data(),create,ActionClass::registerKeywords);
}
///On destruction deregister the ActionClass (useful when you unload a shared object)
~ActionRegistration() {actionRegister().remove(create);}
};

#define PLUMED_CONCATENATE_DIRECT(s1, s2) s1##s2
#define PLUMED_CONCATENATE(s1, s2) PLUMED_CONCATENATE_DIRECT(s1, s2)
#define PLUMED_UNIQUENAME(str) PLUMED_CONCATENATE(str, __LINE__)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You eliminated an indirection. I honestly do not remember anymore why it was there. Are you sure this is ok?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's correct. You are just using PLUMED_CONCATENATE below..


/// Shortcut for Action registration
/// \relates PLMD::ActionRegister
Expand All @@ -101,13 +124,8 @@ std::ostream & operator<<(std::ostream &log,const ActionRegister&ar);
/// \param directive a string containing the corresponding directive
/// This macro should be used in the .cpp file of the corresponding class
#define PLUMED_REGISTER_ACTION(classname,directive) \
namespace { class PLUMED_UNIQUENAME(classname##RegisterMe){ \
static std::unique_ptr<PLMD::Action> create(const PLMD::ActionOptions&ao){return std::make_unique<classname>(ao);} \
public: \
PLUMED_UNIQUENAME(classname##RegisterMe)(){PLMD::actionRegister().add(directive,create,classname::registerKeywords);} \
~PLUMED_UNIQUENAME(classname##RegisterMe)(){PLMD::actionRegister().remove(create);} \
} PLUMED_UNIQUENAME(classname##RegisterMe); }

namespace {::PLMD::ActionRegistration<classname> PLUMED_CONCATENATE(classname##Registerer,__LINE__)(directive);}

} //PLMD
#endif