From c9e80bb5682bb2c5b1c52b72cbb16ca0b4598147 Mon Sep 17 00:00:00 2001
From: Benedikt Hegner <benedikt.hegner@cern.ch>
Date: Mon, 16 Oct 2017 14:58:01 +0000
Subject: [PATCH] Merge branch 'modernize-genconf' into 'master'

Modernize genconf

See merge request !437
---
 GaudiKernel/src/Util/genconf.cpp              | 312 ++++++++++--------
 .../Gaudi/Details/PluginServiceDetails.h      |   8 +-
 GaudiPluginService/src/PluginService.cpp      |  10 +-
 GaudiPluginService/src/listcomponents.cpp     |  12 +-
 4 files changed, 177 insertions(+), 165 deletions(-)

diff --git a/GaudiKernel/src/Util/genconf.cpp b/GaudiKernel/src/Util/genconf.cpp
index d338fd6123..168b132eb3 100644
--- a/GaudiKernel/src/Util/genconf.cpp
+++ b/GaudiKernel/src/Util/genconf.cpp
@@ -64,6 +64,7 @@
 #include <iostream>
 #include <set>
 #include <sstream>
+#include <type_traits>
 #include <vector>
 
 #include "DsoUtils.h"
@@ -92,6 +93,51 @@ namespace
   /// Regular expression to validate the property names.
   /// @see http://docs.python.org/reference/lexical_analysis.html#identifiers
   const boost::regex pythonIdentifier( "^[a-zA-Z_][a-zA-Z0-9_]*$" );
+
+  //-----------------------------------------------------------------------------
+  enum class component_t {
+    Module,
+    DefaultName,
+    Algorithm,
+    AlgTool,
+    Auditor,
+    Service,
+    ApplicationMgr,
+    IInterface,
+    Converter,
+    DataObject,
+    Unknown
+  };
+
+  const std::string& toString( component_t type )
+  {
+    static const std::array<std::string, 11> names = {"Module",    "DefaultName", "Algorithm",      "AlgTool",
+                                                      "Auditor",   "Service",     "ApplicationMgr", "IInterface",
+                                                      "Converter", "DataObject",  "Unknown"};
+    return names.at( static_cast<std::underlying_type_t<component_t>>( type ) );
+  }
+  std::ostream& operator<<( std::ostream& os, component_t type ) { return os << toString( type ); }
+
+  //-----------------------------------------------------------------------------
+  /// Translate a valid C++ typename into a valid python one
+  std::string pythonizeName( const std::string& name )
+  {
+    static const string in( "<>&*,: ()." );
+    static const string out( "__rp__s___" );
+    auto r = boost::algorithm::replace_all_copy( name, ", ", "," );
+    for ( auto& c : r ) {
+      auto rep                     = in.find( c );
+      if ( rep != string::npos ) c = out[rep];
+    }
+    return r;
+  }
+  //-----------------------------------------------------------------------------
+  template <typename T>
+  std::type_index typeIndex()
+  {
+    return std::type_index{typeid( T )};
+  }
+  //-----------------------------------------------------------------------------
 }
 
 class configGenerator
@@ -108,9 +154,8 @@ class configGenerator
 
   /// switch to decide if the generated configurables need
   /// to import GaudiHandles (ie: if one of the components has a XyzHandle<T>)
-  bool m_importGaudiHandles;
-
-  bool m_importDataObjectHandles;
+  bool m_importGaudiHandles      = false;
+  bool m_importDataObjectHandles = false;
 
   /// buffer of generated configurables informations for the "Db" file
   /// The "Db" file is holding informations about the generated configurables
@@ -123,17 +168,11 @@ class configGenerator
   ///  - Name of the configurable base class for the Algorithm component
   ///  - Name of the configurable base class for the AlgTool component
   ///  - Name of the configurable base class for the Service component
-  GaudiUtils::HashMap<std::string, std::string> m_configurable;
+  std::unordered_map<component_t, std::string> m_configurable;
 
 public:
   configGenerator( const string& pkgName, const string& outputDirName )
-      : m_pkgName( pkgName )
-      , m_outputDirName( outputDirName )
-      , m_pyBuf()
-      , m_importGaudiHandles( false )
-      , m_importDataObjectHandles( false )
-      , m_dbBuf()
-      , m_configurable()
+      : m_pkgName( pkgName ), m_outputDirName( outputDirName )
   {
   }
 
@@ -144,30 +183,36 @@ public:
   int genConfig( const Strings_t& modules, const string& userModule );
 
   /// customize the Module name where configurable base classes are defined
-  void setConfigurableModule( const std::string& moduleName ) { m_configurable["Module"] = moduleName; }
+  void setConfigurableModule( const std::string& moduleName ) { m_configurable[component_t::Module] = moduleName; }
 
   /// customize the default name for configurable instances
-  void setConfigurableDefaultName( const std::string& defaultName ) { m_configurable["DefaultName"] = defaultName; }
+  void setConfigurableDefaultName( const std::string& defaultName )
+  {
+    m_configurable[component_t::DefaultName] = defaultName;
+  }
 
   /// customize the configurable base class for Algorithm component
-  void setConfigurableAlgorithm( const std::string& cfgAlgorithm ) { m_configurable["Algorithm"] = cfgAlgorithm; }
+  void setConfigurableAlgorithm( const std::string& cfgAlgorithm )
+  {
+    m_configurable[component_t::Algorithm] = cfgAlgorithm;
+  }
 
   /// customize the configurable base class for AlgTool component
-  void setConfigurableAlgTool( const std::string& cfgAlgTool ) { m_configurable["AlgTool"] = cfgAlgTool; }
+  void setConfigurableAlgTool( const std::string& cfgAlgTool ) { m_configurable[component_t::AlgTool] = cfgAlgTool; }
 
   /// customize the configurable base class for AlgTool component
-  void setConfigurableAuditor( const std::string& cfgAuditor ) { m_configurable["Auditor"] = cfgAuditor; }
+  void setConfigurableAuditor( const std::string& cfgAuditor ) { m_configurable[component_t::Auditor] = cfgAuditor; }
 
   /// customize the configurable base class for Service component
   void setConfigurableService( const std::string& cfgService )
   {
-    m_configurable["Service"]        = cfgService;
-    m_configurable["ApplicationMgr"] = cfgService;
+    m_configurable[component_t::Service]        = cfgService;
+    m_configurable[component_t::ApplicationMgr] = cfgService;
   }
 
 private:
-  int genComponent( const std::string& libName, const std::string& componentName, const std::string& componentType,
-                    const vector<PropertyBase*>& properties );
+  bool genComponent( const std::string& libName, const std::string& componentName, component_t componentType,
+                     const vector<PropertyBase*>& properties );
   void genImport( std::ostream& s, const boost::format& frmt, std::string indent );
   void genHeader( std::ostream& pyOut, std::ostream& dbOut );
   void genBody( std::ostream& pyOut, std::ostream& dbOut )
@@ -179,9 +224,6 @@ private:
 
   /// handle the "marshalling" of Properties
   void pythonizeValue( const PropertyBase* prop, string& pvalue, string& ptype );
-
-  /// Translates a valid C++ typename into a valid python one
-  void pythonizeName( string& name );
 };
 
 int createAppMgr();
@@ -297,16 +339,16 @@ int main( int argc, char** argv )
     //  - split into tokens.
     Strings_t inputLibs;
     {
-      string tmp = vm["input-libraries"].as<string>();
+      std::string tmp = vm["input-libraries"].as<std::string>();
       boost::trim( tmp );
       boost::split( inputLibs, tmp, boost::is_any_of( " " ), boost::token_compress_on );
     }
 
     //
     libs.reserve( inputLibs.size() );
-    for ( Strings_t::const_iterator iLib = inputLibs.begin(); iLib != inputLibs.end(); ++iLib ) {
-      std::string lib = fs::path( *iLib ).stem().string();
-      if ( 0 == lib.find( "lib" ) ) {
+    for ( const auto& iLib : inputLibs ) {
+      std::string lib = fs::path( iLib ).stem().string();
+      if ( lib.compare( 0, 3, "lib" ) == 0 ) {
         lib = lib.substr( 3 ); // For *NIX remove "lib"
       }
       // remove duplicates
@@ -334,14 +376,11 @@ int main( int argc, char** argv )
   }
 
   if ( vm.count( "load-library" ) ) {
-    Strings_t lLib_list = vm["load-library"].as<Strings_t>();
-    for ( Strings_t::const_iterator lLib = lLib_list.begin(); lLib != lLib_list.end(); ++lLib ) {
+    for ( const auto& lLib : vm["load-library"].as<Strings_t>() ) {
       // load done through Gaudi helper class
       System::ImageHandle tmp; // we ignore the library handle
-      unsigned long err = System::loadDynamicLib( *lLib, &tmp );
-      if ( err != 1 ) {
-        LOG_WARNING << "failed to load: " << *lLib;
-      }
+      unsigned long err = System::loadDynamicLib( lLib, &tmp );
+      if ( err != 1 ) LOG_WARNING << "failed to load: " << lLib;
     }
   }
 
@@ -357,7 +396,7 @@ int main( int argc, char** argv )
   {
     std::ostringstream msg;
     msg << ":::::: libraries : [ ";
-    copy( libs.begin(), libs.end(), ostream_iterator<string>( msg, " " ) );
+    std::copy( libs.begin(), libs.end(), std::ostream_iterator<std::string>( msg, " " ) );
     msg << "] ::::::";
     LOG_INFO << msg.str();
   }
@@ -381,14 +420,14 @@ int main( int argc, char** argv )
 
   if ( EXIT_SUCCESS == sc && !vm.count( "no-init" ) ) {
     // create an empty __init__.py file in the output dir
-    fstream initPy( ( out / fs::path( "__init__.py" ) ).string(), std::ios_base::out | std::ios_base::trunc );
+    std::fstream initPy( ( out / fs::path( "__init__.py" ) ).string(), std::ios_base::out | std::ios_base::trunc );
     initPy << "## Hook for " << pkgName << " genConf module\n" << flush;
   }
 
   {
     std::ostringstream msg;
     msg << ":::::: libraries : [ ";
-    copy( libs.begin(), libs.end(), ostream_iterator<string>( msg, " " ) );
+    std::copy( libs.begin(), libs.end(), std::ostream_iterator<std::string>( msg, " " ) );
     msg << "] :::::: [DONE]";
     LOG_INFO << msg.str();
   }
@@ -402,10 +441,10 @@ int configGenerator::genConfig( const Strings_t& libs, const string& userModule
   //--- Disable checking StatusCode -------------------------------------------
   StatusCode::disableChecking();
 
-  const Strings_t::const_iterator endLib = libs.end();
+  const auto endLib = libs.end();
 
-  const std::string gaudiSvc = "GaudiCoreSvc";
-  const bool isGaudiSvc      = ( std::find( libs.begin(), endLib, gaudiSvc ) != endLib );
+  static const std::string gaudiSvc = "GaudiCoreSvc";
+  const bool isGaudiSvc             = ( std::find( libs.begin(), endLib, gaudiSvc ) != endLib );
 
   //--- Instantiate ApplicationMgr --------------------------------------------
   if ( !isGaudiSvc && createAppMgr() ) {
@@ -417,7 +456,7 @@ int configGenerator::genConfig( const Strings_t& libs, const string& userModule
   using Gaudi::PluginService::Details::Registry;
   Registry& registry = Registry::instance();
 
-  std::set<std::string> bkgNames = registry.loadedFactories();
+  auto bkgNames = registry.loadedFactoryNames();
 
   ISvcLocator* svcLoc  = Gaudi::svcLocator();
   IInterface* dummySvc = new Service( "DummySvc", svcLoc );
@@ -426,9 +465,9 @@ int configGenerator::genConfig( const Strings_t& libs, const string& userModule
   bool allGood = true;
 
   // iterate over all the requested libraries
-  for ( Strings_t::const_iterator iLib = libs.begin(); iLib != endLib; ++iLib ) {
+  for ( const auto& iLib : libs ) {
 
-    LOG_INFO << ":::: processing library: " << *iLib << "...";
+    LOG_INFO << ":::: processing library: " << iLib << "...";
 
     // reset state
     m_importGaudiHandles      = false;
@@ -438,26 +477,23 @@ int configGenerator::genConfig( const Strings_t& libs, const string& userModule
 
     //--- Load component library ----------------------------------------------
     System::ImageHandle handle;
-    unsigned long err = System::loadDynamicLib( *iLib, &handle );
+    unsigned long err = System::loadDynamicLib( iLib, &handle );
     if ( err != 1 ) {
       LOG_ERROR << System::getLastErrorString();
       allGood = false;
       continue;
     }
 
-    std::set<std::string> factories = registry.loadedFactories();
-
-    for ( std::set<std::string>::iterator it = factories.begin(); it != factories.end(); ++it ) {
-      const string ident = *it;
-      if ( bkgNames.find( ident ) != bkgNames.end() ) {
+    for ( const auto& factoryName : registry.loadedFactoryNames() ) {
+      if ( bkgNames.find( factoryName ) != bkgNames.end() ) {
         if ( Gaudi::PluginService::Details::logger().level() <= 1 ) {
-          LOG_INFO << "\t==> skipping [" << ident << "]...";
+          LOG_INFO << "\t==> skipping [" << factoryName << "]...";
         }
         continue;
       }
 
-      const Registry::FactoryInfo info = registry.getInfo( *it );
-      const string rtype               = info.rtype;
+      const Registry::FactoryInfo info = registry.getInfo( factoryName );
+      const std::string& rtype         = info.rtype;
 
       // do not generate configurables for the Reflex-compatible aliases
       if ( info.properties.find( "ReflexName" ) != info.properties.end() ) continue;
@@ -466,50 +502,46 @@ int configGenerator::genConfig( const Strings_t& libs, const string& userModule
       // Skip the generation of configurables if the component does not come
       // from the same library we are processing (i.e. we found a symbol that
       // is coming from a library loaded by the linker).
-      if ( !DsoUtils::inDso( info.ptr, DsoUtils::libNativeName( *iLib ) ) ) {
-        LOG_WARNING << "library [" << *iLib << "] exposes factory [" << ident << "] which is declared in ["
+      if ( !DsoUtils::inDso( info.ptr, DsoUtils::libNativeName( iLib ) ) ) {
+        LOG_WARNING << "library [" << iLib << "] exposes factory [" << factoryName << "] which is declared in ["
                     << DsoUtils::dsoName( info.ptr ) << "] !!";
         continue;
       }
 
-      string type;
-      bool known = true;
-      if ( ident == "ApplicationMgr" )
-        type = "ApplicationMgr";
+      component_t type = component_t::Unknown;
+      if ( factoryName == "ApplicationMgr" )
+        type = component_t::ApplicationMgr;
       else if ( rtype == typeid( IInterface* ).name() )
-        type = "IInterface";
+        type = component_t::IInterface;
       else if ( rtype == typeid( IAlgorithm* ).name() )
-        type = "Algorithm";
+        type = component_t::Algorithm;
       else if ( rtype == typeid( IService* ).name() )
-        type = "Service";
+        type = component_t::Service;
       else if ( rtype == typeid( IAlgTool* ).name() )
-        type = "AlgTool";
+        type = component_t::AlgTool;
       else if ( rtype == typeid( IAuditor* ).name() )
-        type = "Auditor";
+        type = component_t::Auditor;
       else if ( rtype == typeid( IConverter* ).name() )
-        type = "Converter";
+        type = component_t::Converter;
       else if ( rtype == typeid( DataObject* ).name() )
-        type = "DataObject";
-      else
-        type = "Unknown", known = false;
-      string name = ident;
+        type = component_t::DataObject;
       // handle possible problems with templated components
-      boost::trim( name );
+      std::string name = boost::trim_copy( factoryName );
 
-      if ( type == "IInterface" ) {
+      if ( type == component_t::IInterface ) {
         /// not enough information...
         /// skip it
         continue;
       }
 
-      if ( type == "Converter" || type == "DataObject" ) {
+      if ( type == component_t::Converter || type == component_t::DataObject ) {
         /// no Properties, so don't bother create Configurables...
         continue;
       }
 
-      if ( !known ) {
+      if ( type == component_t::Unknown ) {
         LOG_WARNING << "Unknown (return) type [" << System::typeinfoName( rtype.c_str() ) << "] !!"
-                    << " Component [" << ident << "] is skipped !";
+                    << " Component [" << factoryName << "] is skipped !";
         continue;
       }
 
@@ -519,33 +551,39 @@ int configGenerator::genConfig( const Strings_t& libs, const string& userModule
       string cname = "DefaultName";
       SmartIF<IProperty> prop;
       try {
-        if ( type == "Algorithm" ) {
-          prop = SmartIF<IAlgorithm>( Algorithm::Factory::create( ident, cname, svcLoc ) );
-        } else if ( type == "Service" ) {
-          prop = SmartIF<IService>( Service::Factory::create( ident, cname, svcLoc ) );
-        } else if ( type == "AlgTool" ) {
-          prop = SmartIF<IAlgTool>( AlgTool::Factory::create( ident, cname, type, dummySvc ) );
+        switch ( type ) {
+        case component_t::Algorithm:
+          prop = SmartIF<IAlgorithm>( Algorithm::Factory::create( factoryName, cname, svcLoc ) );
+          break;
+        case component_t::Service:
+          prop = SmartIF<IService>( Service::Factory::create( factoryName, cname, svcLoc ) );
+          break;
+        case component_t::AlgTool:
+          prop = SmartIF<IAlgTool>( AlgTool::Factory::create( factoryName, cname, toString( type ), dummySvc ) );
           // FIXME: AlgTool base class increase artificially by 1 the refcount.
           prop->release();
-        } else if ( type == "Auditor" ) {
-          prop = SmartIF<IAuditor>( Auditor::Factory::create( ident, cname, svcLoc ) );
-        } else if ( type == "ApplicationMgr" ) {
+          break;
+        case component_t::Auditor:
+          prop = SmartIF<IAuditor>( Auditor::Factory::create( factoryName, cname, svcLoc ) );
+          break;
+        case component_t::ApplicationMgr:
           prop = SmartIF<ISvcLocator>( svcLoc );
-        } else {
+          break;
+        default:
           continue; // unknown
         }
       } catch ( exception& e ) {
-        LOG_ERROR << "Error instantiating " << name << " from " << *iLib;
+        LOG_ERROR << "Error instantiating " << name << " from " << iLib;
         LOG_ERROR << "Got exception: " << e.what();
         allGood = false;
         continue;
       } catch ( ... ) {
-        LOG_ERROR << "Error instantiating " << name << " from " << *iLib;
+        LOG_ERROR << "Error instantiating " << name << " from " << iLib;
         allGood = false;
         continue;
       }
       if ( prop ) {
-        if ( genComponent( *iLib, name, type, prop->getProperties() ) ) {
+        if ( !genComponent( iLib, name, type, prop->getProperties() ) ) {
           allGood = false;
         }
         prop.reset();
@@ -560,8 +598,8 @@ int configGenerator::genConfig( const Strings_t& libs, const string& userModule
     ///
     /// write-out files for this library
     ///
-    const std::string pyName = ( fs::path( m_outputDirName ) / fs::path( *iLib + "Conf.py" ) ).string();
-    const std::string dbName = ( fs::path( m_outputDirName ) / fs::path( *iLib + ".confdb" ) ).string();
+    const std::string pyName = ( fs::path( m_outputDirName ) / fs::path( iLib + "Conf.py" ) ).string();
+    const std::string dbName = ( fs::path( m_outputDirName ) / fs::path( iLib + ".confdb" ) ).string();
 
     std::fstream py( pyName, std::ios_base::out | std::ios_base::trunc );
     std::fstream db( dbName, std::ios_base::out | std::ios_base::trunc );
@@ -587,10 +625,10 @@ void configGenerator::genImport( std::ostream& s, const boost::format& frmt, std
 
   while ( std::string::npos != pos ) {
     // find end of module name
-    nxtpos = m_configurable["Module"].find_first_of( ',', pos );
+    nxtpos = m_configurable[component_t::Module].find_first_of( ',', pos );
 
     // Prepare import string
-    mod = m_configurable["Module"].substr( pos, nxtpos - pos );
+    mod = m_configurable[component_t::Module].substr( pos, nxtpos - pos );
     std::ostringstream import;
     import << boost::format( frmt ) % mod;
 
@@ -623,7 +661,7 @@ void configGenerator::genHeader( std::ostream& py, std::ostream& db )
   }
 
   if ( m_importDataObjectHandles ) {
-    py << "from GaudiKernel.DataObjectHandleBase import *\n";
+    py << "from GaudiKernel.DataObjectHandleBase import DataObjectHandleBase\n";
   }
 
   genImport( py, boost::format( "from %1%.Configurable import *" ) );
@@ -642,23 +680,19 @@ void configGenerator::genTrailer( std::ostream& /*py*/, std::ostream& db )
 }
 
 //-----------------------------------------------------------------------------
-int configGenerator::genComponent( const std::string& libName, const std::string& componentName,
-                                   const std::string& componentType, const vector<PropertyBase*>& properties )
+bool configGenerator::genComponent( const std::string& libName, const std::string& componentName,
+                                    component_t componentType, const vector<PropertyBase*>& properties )
 //-----------------------------------------------------------------------------
 {
-  string cname = componentName;
-  pythonizeName( cname );
+  auto cname = pythonizeName( componentName );
 
-  typedef GaudiUtils::HashMap<std::string, std::string> PropertyDoc_t;
-  PropertyDoc_t propDoc;
+  std::vector<std::pair<std::string, std::string>> propDoc;
+  propDoc.reserve( properties.size() );
 
-  m_pyBuf << "\n";
-  m_pyBuf << "class " << cname << "( " << m_configurable[componentType] << " ) :"
-          << "\n";
+  m_pyBuf << "\nclass " << cname << "( " << m_configurable[componentType] << " ) :\n";
   m_pyBuf << "  __slots__ = { \n";
-  for ( vector<PropertyBase*>::const_iterator it = properties.begin(); it != properties.end(); ++it ) {
-
-    const string pname = ( *it )->name();
+  for ( const auto& prop : properties ) {
+    const string& pname = prop->name();
     // Validate property name (it must be a valid Python identifier)
     if ( !boost::regex_match( pname, pythonIdentifier ) ) {
       std::cout << "ERROR: invalid property name \"" << pname << "\" in component " << cname
@@ -666,26 +700,26 @@ int configGenerator::genComponent( const std::string& libName, const std::string
       // try to make the buffer at least more or less valid python code.
       m_pyBuf << " #ERROR-invalid identifier '" << pname << "'\n"
               << "  }\n";
-      return 1;
+      return false;
     }
 
     string pvalue, ptype;
-    pythonizeValue( ( *it ), pvalue, ptype );
+    pythonizeValue( prop, pvalue, ptype );
     m_pyBuf << "    '" << pname << "' : " << pvalue << ", # " << ptype << "\n";
 
-    if ( ( *it )->documentation() != "none" ) {
-      propDoc[pname] = ( *it )->documentation() + " [" + ( *it )->ownerTypeName() + "]";
+    if ( prop->documentation() != "none" ) {
+      propDoc.emplace_back( pname, prop->documentation() + " [" + prop->ownerTypeName() + "]" );
     }
   }
   m_pyBuf << "  }\n";
   m_pyBuf << "  _propertyDocDct = { \n";
-  for ( PropertyDoc_t::const_iterator iProp = propDoc.begin(); iProp != propDoc.end(); ++iProp ) {
-    m_pyBuf << std::setw( 5 ) << "'" << iProp->first << "' : "
-            << "\"\"\" " << iProp->second << " \"\"\",\n";
+  for ( const auto& prop : propDoc ) {
+    m_pyBuf << std::setw( 5 ) << "'" << prop.first << "' : "
+            << "\"\"\" " << prop.second << " \"\"\",\n";
   }
   m_pyBuf << "  }\n";
 
-  m_pyBuf << "  def __init__(self, name = " << m_configurable["DefaultName"] << ", **kwargs):\n"
+  m_pyBuf << "  def __init__(self, name = " << m_configurable[component_t::DefaultName] << ", **kwargs):\n"
           << "      super(" << cname << ", self).__init__(name)\n"
           << "      for n,v in kwargs.items():\n"
           << "         setattr(self, n, v)\n"
@@ -703,18 +737,7 @@ int configGenerator::genComponent( const std::string& libName, const std::string
   // now the db part
   m_dbBuf << m_pkgName << "." << modName << " " << libName << " " << cname << "\n" << flush;
 
-  return 0;
-}
-//-----------------------------------------------------------------------------
-void configGenerator::pythonizeName( string& name )
-//-----------------------------------------------------------------------------
-{
-  static string in( "<>&*,: ()." );
-  static string out( "__rp__s___" );
-  boost::algorithm::replace_all( name, ", ", "," );
-  for ( string::iterator i = name.begin(); i != name.end(); ++i ) {
-    if ( in.find( *i ) != string::npos ) *i = out[in.find( *i )];
-  }
+  return true;
 }
 
 //-----------------------------------------------------------------------------
@@ -722,19 +745,19 @@ void configGenerator::pythonizeValue( const PropertyBase* p, string& pvalue, str
 //-----------------------------------------------------------------------------
 {
   const std::string cvalue = p->toString();
-  const type_info& ti      = *p->type_info();
-  if ( ti == typeid( bool ) ) {
+  const std::type_index ti = std::type_index( *p->type_info() );
+  if ( ti == typeIndex<bool>() ) {
     pvalue = ( cvalue == "0" || cvalue == "False" || cvalue == "false" ) ? "False" : "True";
     ptype  = "bool";
-  } else if ( ti == typeid( char ) || ti == typeid( signed char ) || ti == typeid( unsigned char ) ||
-              ti == typeid( short ) || ti == typeid( unsigned short ) || ti == typeid( int ) ||
-              ti == typeid( unsigned int ) || ti == typeid( long ) || ti == typeid( unsigned long ) ) {
+  } else if ( ti == typeIndex<char>() || ti == typeIndex<signed char>() || ti == typeIndex<unsigned char>() ||
+              ti == typeIndex<short>() || ti == typeIndex<unsigned short>() || ti == typeIndex<int>() ||
+              ti == typeIndex<unsigned int>() || ti == typeIndex<long>() || ti == typeIndex<unsigned long>() ) {
     pvalue = cvalue;
     ptype  = "int";
-  } else if ( ti == typeid( long long ) || ti == typeid( unsigned long long ) ) {
+  } else if ( ti == typeIndex<long long>() || ti == typeIndex<unsigned long long>() ) {
     pvalue = cvalue + "L";
     ptype  = "long";
-  } else if ( ti == typeid( float ) || ti == typeid( double ) ) {
+  } else if ( ti == typeIndex<float>() || ti == typeIndex<double>() ) {
     // forces python to handle this as a float: put a dot in there...
     pvalue = boost::to_lower_copy( cvalue );
     if ( pvalue == "nan" ) {
@@ -744,31 +767,30 @@ void configGenerator::pythonizeValue( const PropertyBase* p, string& pvalue, str
       pvalue = cvalue + ".0";
     }
     ptype = "float";
-  } else if ( ti == typeid( string ) ) {
-
+  } else if ( ti == typeIndex<string>() ) {
     pvalue = "'" + cvalue + "'";
     ptype  = "str";
-  } else if ( ti == typeid( GaudiHandleBase ) ) {
-    m_importGaudiHandles           = true;
+  } else if ( ti == typeIndex<GaudiHandleBase>() ) {
     const GaudiHandleProperty& hdl = dynamic_cast<const GaudiHandleProperty&>( *p );
     const GaudiHandleBase& base    = hdl.value();
 
-    pvalue = base.pythonRepr();
-    ptype  = "GaudiHandle";
-  } else if ( ti == typeid( GaudiHandleArrayBase ) ) {
-    m_importGaudiHandles                = true;
+    pvalue               = base.pythonRepr();
+    ptype                = "GaudiHandle";
+    m_importGaudiHandles = true;
+  } else if ( ti == typeIndex<GaudiHandleArrayBase>() ) {
     const GaudiHandleArrayProperty& hdl = dynamic_cast<const GaudiHandleArrayProperty&>( *p );
     const GaudiHandleArrayBase& base    = hdl.value();
 
-    pvalue = base.pythonRepr();
-    ptype  = "GaudiHandleArray";
-  } else if ( ti == typeid( DataObjectHandleBase ) ) {
-    m_importDataObjectHandles           = true;
+    pvalue               = base.pythonRepr();
+    ptype                = "GaudiHandleArray";
+    m_importGaudiHandles = true;
+  } else if ( ti == typeIndex<DataObjectHandleBase>() ) {
     const DataObjectHandleProperty& hdl = dynamic_cast<const DataObjectHandleProperty&>( *p );
     const DataObjectHandleBase& base    = hdl.value();
 
-    pvalue = base.pythonRepr();
-    ptype  = "DataObjectHandleBase";
+    pvalue                    = base.pythonRepr();
+    ptype                     = "DataObjectHandleBase";
+    m_importDataObjectHandles = true;
   } else {
     std::ostringstream v_str;
     v_str.setf( std::ios::showpoint ); // to correctly display floats
@@ -785,13 +807,13 @@ int createAppMgr()
   IInterface* iface = Gaudi::createApplicationMgr();
   SmartIF<IAppMgrUI> appUI( iface );
   auto propMgr = appUI.as<IProperty>();
-
   if ( !propMgr || !appUI ) return EXIT_FAILURE;
+
   propMgr->setProperty( "JobOptionsType", "NONE" ); // No job options
   propMgr->setProperty( "AppName", "" );            // No initial printout message
   propMgr->setProperty( "OutputLevel", "7" );       // No other printout messages
   appUI->configure();
-  SmartIF<IProperty> msgSvc{SmartIF<IMessageSvc>{iface}};
+  auto msgSvc = SmartIF<IMessageSvc>{iface}.as<IProperty>();
   msgSvc->setProperty( "setWarning", "['DefaultName', 'PropertyHolder']" );
   msgSvc->setProperty( "Format", "%T %0W%M" );
   return EXIT_SUCCESS;
diff --git a/GaudiPluginService/Gaudi/Details/PluginServiceDetails.h b/GaudiPluginService/Gaudi/Details/PluginServiceDetails.h
index 4550e76b7b..ad5bd214a6 100644
--- a/GaudiPluginService/Gaudi/Details/PluginServiceDetails.h
+++ b/GaudiPluginService/Gaudi/Details/PluginServiceDetails.h
@@ -20,9 +20,7 @@
 #include <typeinfo>
 #include <utility>
 
-#if defined( __GXX_EXPERIMENTAL_CXX0X__ ) || __cplusplus >= 201103L
 #include <mutex>
-#endif
 
 #if __GNUC__ >= 4
 #define GAUDIPS_HASCLASSVISIBILITY
@@ -118,7 +116,7 @@ namespace Gaudi
         typedef std::map<KeyType, std::string> Properties;
 
         struct FactoryInfo {
-          FactoryInfo( std::string lib, void* p = 0, std::string t = "", std::string rt = "", std::string cn = "",
+          FactoryInfo( std::string lib, void* p = nullptr, std::string t = "", std::string rt = "", std::string cn = "",
                        Properties props = Properties() )
               : library( std::move( lib ) )
               , ptr( p )
@@ -174,7 +172,7 @@ namespace Gaudi
         Registry& addProperty( const std::string& id, const std::string& k, const std::string& v );
 
         /// Return a list of all the known and loaded factories
-        std::set<KeyType> loadedFactories() const;
+        std::set<KeyType> loadedFactoryNames() const;
 
         /// Return the known factories (loading the list if not yet done).
         inline const FactoryMap& factories() const
@@ -214,10 +212,8 @@ namespace Gaudi
         /// Internal storage for factories.
         FactoryMap m_factories;
 
-#if defined( __GXX_EXPERIMENTAL_CXX0X__ ) || __cplusplus >= 201103L
         /// Mutex used to control concurrent access to the internal data.
         mutable std::recursive_mutex m_mutex;
-#endif
       };
 
       /// Simple logging class, just to provide a default implementation.
diff --git a/GaudiPluginService/src/PluginService.cpp b/GaudiPluginService/src/PluginService.cpp
index 5adb87c195..8f4dac6a19 100644
--- a/GaudiPluginService/src/PluginService.cpp
+++ b/GaudiPluginService/src/PluginService.cpp
@@ -25,7 +25,6 @@
 #include <cxxabi.h>
 #include <sys/stat.h>
 
-#if defined( __GXX_EXPERIMENTAL_CXX0X__ ) || __cplusplus >= 201103L
 #define REG_SCOPE_LOCK std::lock_guard<std::recursive_mutex> _guard( m_mutex );
 
 namespace
@@ -33,10 +32,6 @@ namespace
   std::mutex registrySingletonMutex;
 }
 #define SINGLETON_LOCK std::lock_guard<std::mutex> _guard(::registrySingletonMutex );
-#else
-#define REG_SCOPE_LOCK
-#define SINGLETON_LOCK
-#endif
 
 #include <algorithm>
 
@@ -322,12 +317,11 @@ namespace Gaudi
         return *this;
       }
 
-      std::set<Registry::KeyType> Registry::loadedFactories() const
+      std::set<Registry::KeyType> Registry::loadedFactoryNames() const
       {
         REG_SCOPE_LOCK
-        const FactoryMap& facts = factories();
         std::set<KeyType> l;
-        for ( const auto& f : facts ) {
+        for ( const auto& f : factories() ) {
           if ( f.second.ptr ) l.insert( f.first );
         }
         return l;
diff --git a/GaudiPluginService/src/listcomponents.cpp b/GaudiPluginService/src/listcomponents.cpp
index c542d9d93b..2227003597 100644
--- a/GaudiPluginService/src/listcomponents.cpp
+++ b/GaudiPluginService/src/listcomponents.cpp
@@ -52,7 +52,7 @@ int main( int argc, char* argv[] )
   // cache to keep track of the loaded factories
   std::map<key_type, std::string> loaded;
   // initialize the local cache
-  for ( const auto& elem : reg.loadedFactories() ) loaded.emplace( elem, "<preloaded>" );
+  for ( const auto& name : reg.loadedFactoryNames() ) loaded.emplace( name, "<preloaded>" );
 
   // Parse command line
   std::list<char*> libs;
@@ -99,13 +99,13 @@ int main( int argc, char* argv[] )
   // loop over the list of libraries passed on the command line
   for ( char* lib : libs ) {
     if ( dlopen( lib, RTLD_LAZY | RTLD_LOCAL ) ) {
-      for ( const auto& factory : reg.loadedFactories() ) {
-        auto f = loaded.find( factory );
+      for ( const auto& factoryName : reg.loadedFactoryNames() ) {
+        auto f = loaded.find( factoryName );
         if ( f == loaded.end() ) {
-          output << lib << ":" << factory << std::endl;
-          loaded.emplace( factory, lib );
+          output << lib << ":" << factoryName << std::endl;
+          loaded.emplace( factoryName, lib );
         } else
-          std::cerr << "WARNING: factory '" << factory << "' already found in " << f->second << std::endl;
+          std::cerr << "WARNING: factory '" << factoryName << "' already found in " << f->second << std::endl;
       }
     } else {
       std::cerr << "ERROR: failed to load " << lib << ": " << dlerror() << std::endl;
-- 
GitLab