LCOV - code coverage report
Current view: top level - core - ActionRegister.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 7 7 100.0 %
Date: 2024-10-18 14:00:25 Functions: 1144 1164 98.3 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-2023 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #ifndef __PLUMED_core_ActionRegister_h
      23             : #define __PLUMED_core_ActionRegister_h
      24             : 
      25             : #include "RegisterBase.h"
      26             : 
      27             : #include "tools/Keywords.h"
      28             : 
      29             : namespace PLMD {
      30             : 
      31             : class Action;
      32             : class ActionOptions;
      33             : 
      34             : struct ActionRegisterPointers {
      35             : /// Pointer to a function which, given the options, create an Action
      36             :   typedef std::unique_ptr<Action>(*creator_pointer)(const ActionOptions&);
      37             : /// Pointer to a function which, returns the keywords allowed
      38             :   typedef void(*keywords_pointer)(Keywords&);
      39             :   creator_pointer create;
      40             :   keywords_pointer keys;
      41             : };
      42             : 
      43             : /// Register holding all the allowed keywords.
      44             : /// This is a register which holds a map between strings (directives) and function pointers.
      45             : /// The function pointers are pointing to functions which create an object of
      46             : /// the corresponding class given the corresponding options (ActionOptions).
      47             : /// There should be only one of there objects allocated.
      48             : /// Actions should be registered here at the beginning of execution
      49             : ///
      50        5316 : class ActionRegister:
      51             :   public RegisterBase<ActionRegisterPointers> {
      52             : 
      53             :   typedef ActionRegisterPointers::creator_pointer creator_pointer;
      54             :   typedef ActionRegisterPointers::keywords_pointer keywords_pointer;
      55             :   typedef ActionRegisterPointers Pointers;
      56             : 
      57             : public:
      58             :   ID add(std::string key,creator_pointer cp,keywords_pointer kp);
      59             : /// Create an Action of the type indicated in the options
      60             : /// \param ao object containing information for initialization, such as the full input line, a pointer to PlumedMain, etc
      61             :   std::unique_ptr<Action> create(const ActionOptions&ao);
      62             :   std::unique_ptr<Action> create(const std::vector<void*> & images,const ActionOptions&ao);
      63             : /// Print out the keywords for an action in html/vim ready for input into the manual
      64             :   bool printManual(const std::string& action, const bool& vimout, const bool& spellout);
      65             : /// Retrieve a keywords object for a particular action
      66             :   bool getKeywords( const std::string& action, Keywords& keys );
      67             :   void getKeywords(const std::vector<void*> & images, const std::string& action, Keywords& keys);
      68             : /// Print out a template command for an action
      69             :   bool printTemplate(const std::string& action, bool include_optional);
      70             :   std::vector<std::string> getActionNames() const;
      71             : };
      72             : 
      73             : /// Function returning a reference to the ActionRegister.
      74             : /// \relates ActionRegister
      75             : /// To avoid problems with order of initialization, this function contains
      76             : /// a static ActionRegister which is built the first time the function is called.
      77             : /// In this manner, it is always initialized before it's used
      78             : ActionRegister& actionRegister();
      79             : 
      80             : template<typename T>
      81             : inline constexpr bool isActionType = std::is_base_of<Action, T>::value;
      82             : //in C++20 you we'll make this a concept
      83             : //template<typename T>
      84             : //concept ActionType = std::is_base_of<::PLMD::Action, T>::value;
      85             : //so the template will be template<ActionType ActionType>class ActionRegistration{...}
      86             : //without the explicit need of the static assert
      87             : 
      88             : ///Each instance of this specialized class represents an action that can be called
      89             : ///with  the specified directive.
      90             : ///As soon it goes out of scope it will deregister the directive from the singleton ActionRegister
      91             : template<typename ActionClass>
      92             : class ActionRegistration {
      93             :   ActionRegister::ID id;
      94       51163 :   static std::unique_ptr<Action> create(const ActionOptions&ao) {
      95      101140 :     return std::make_unique<ActionClass>(ao);
      96             :   }
      97             : public:
      98             :   ///On construction register the ActionClass with the wanted directive
      99     2328408 :   ActionRegistration(std::string_view directive):
     100     2328408 :     id(actionRegister().add(directive.data(),create,ActionClass::registerKeywords))
     101             :   {
     102             :     static_assert(isActionType<ActionClass>,
     103             :                   "ActionRegistration accepts only class that inherit from Action");
     104     2328408 :   }
     105             :   ///On destruction deregister the ActionClass (useful when you unload a shared object)
     106     2328408 :   ~ActionRegistration() {actionRegister().remove(id);}
     107             : };
     108             : } //PLMD
     109             : 
     110             : #define PLUMED_CONCATENATE_DIRECT(s1, s2) s1##s2
     111             : #define PLUMED_CONCATENATE(s1, s2) PLUMED_CONCATENATE_DIRECT(s1, s2)
     112             : 
     113             : /// Shortcut for Action registration
     114             : /// \relates PLMD::ActionRegister
     115             : /// For easier registration, this file also provides a macro PLUMED_REGISTER_ACTION.
     116             : /// \param classname the name of the class to be registered
     117             : /// \param directive a string containing the corresponding directive
     118             : /// This macro should be used in the .cpp file of the corresponding class
     119             : #define PLUMED_REGISTER_ACTION(classname,directive) \
     120             :   namespace {::PLMD::ActionRegistration<classname> \
     121             :              PLUMED_CONCATENATE(classname##Registerer,__LINE__)(directive);}
     122             : #endif
     123             : 

Generated by: LCOV version 1.16