diff --git a/include/class_loader/class_loader.hpp b/include/class_loader/class_loader.hpp
index 5a5e077..5b52148 100644
--- a/include/class_loader/class_loader.hpp
+++ b/include/class_loader/class_loader.hpp
@@ -124,8 +124,8 @@ class ClassLoader
* by InterfaceTraits of the Base class)
* @return A std::shared_ptr to newly created plugin object
*/
- template, bool> = true>
+ template
+ requires InterfaceConstructible
[[nodiscard]] std::shared_ptr createInstance(
const std::string & derived_class_name, Args &&... args)
{
@@ -150,8 +150,8 @@ class ClassLoader
* by InterfaceTraits of the Base class)
* @return A std::unique_ptr to newly created plugin object.
*/
- template, bool> = true>
+ template
+ requires InterfaceConstructible
[[nodiscard]] UniquePtr createUniqueInstance(
const std::string & derived_class_name, Args &&... args)
{
@@ -177,8 +177,8 @@ class ClassLoader
* by InterfaceTraits of the Base class)
* @return An unmanaged (i.e. not a shared_ptr) Base* to newly created plugin object.
*/
- template, bool> = true>
+ template
+ requires InterfaceConstructible
[[nodiscard]] Base * createUnmanagedInstance(
const std::string & derived_class_name, Args &&... args)
{
@@ -196,8 +196,7 @@ class ClassLoader
[[nodiscard]] bool isClassAvailable(const std::string & class_name) const
{
std::vector available_classes = getAvailableClasses();
- return std::find(
- available_classes.begin(), available_classes.end(), class_name) != available_classes.end();
+ return std::ranges::find(available_classes, class_name) != available_classes.end();
}
/**
@@ -314,8 +313,8 @@ class ClassLoader
* by InterfaceTraits of the Base class)
* @return A Base* to newly created plugin object.
*/
- template, bool> = true>
+ template
+ requires InterfaceConstructible
Base * createRawInstance(const std::string & derived_class_name, bool managed, Args &&... args)
{
if (!managed) {
diff --git a/include/class_loader/class_loader_core.hpp b/include/class_loader/class_loader_core.hpp
index 917d9f4..418418b 100644
--- a/include/class_loader/class_loader_core.hpp
+++ b/include/class_loader/class_loader_core.hpp
@@ -32,6 +32,7 @@
#ifndef CLASS_LOADER__CLASS_LOADER_CORE_HPP_
#define CLASS_LOADER__CLASS_LOADER_CORE_HPP_
+#include
#include
#include
#include
@@ -277,25 +278,16 @@ registerPlugin(const std::string & class_name, const std::string & base_class_na
[](AbstractMetaObjectBase * p) {
getPluginBaseToFactoryMapMapMutex().lock();
MetaObjectGraveyardVector & graveyard = getMetaObjectGraveyard();
- for (auto iter = graveyard.begin(); iter != graveyard.end(); ++iter) {
- if (*iter == p) {
- graveyard.erase(iter);
- break;
- }
+ if (auto iter = std::ranges::find(graveyard, p); iter != graveyard.end()) {
+ graveyard.erase(iter);
}
BaseToFactoryMapMap & factory_map_map = getGlobalPluginBaseToFactoryMapMap();
- bool erase_flag = false;
- for (auto & factory_map_item : factory_map_map) {
- FactoryMap & factory_map = factory_map_item.second;
- for (auto iter = factory_map.begin(); iter != factory_map.end(); ++iter) {
- if (iter->second == p) {
- factory_map.erase(iter);
- erase_flag = true;
- break;
- }
- }
- if (erase_flag) {
+ for (auto & [base_class_name, factory_map] : factory_map_map) {
+ if (auto iter = std::ranges::find(factory_map, p, &FactoryMap::value_type::second);
+ iter != factory_map.end())
+ {
+ factory_map.erase(iter);
break;
}
}
@@ -318,7 +310,7 @@ registerPlugin(const std::string & class_name, const std::string & base_class_na
// Add it to global factory map map
getPluginBaseToFactoryMapMapMutex().lock();
FactoryMap & factoryMap = getFactoryMapForBaseClass();
- if (factoryMap.find(class_name) != factoryMap.end()) {
+ if (factoryMap.contains(class_name)) {
CONSOLE_BRIDGE_logWarn(
"class_loader.impl: SEVERE WARNING!!! "
"A namespace collision has occurred with plugin factory for class %s. "
@@ -349,16 +341,16 @@ registerPlugin(const std::string & class_name, const std::string & base_class_na
* by InterfaceTraits of the Base class)
* @return A pointer to newly created plugin, note caller is responsible for object destruction
*/
-template, bool> = true>
+template
+requires InterfaceConstructible
Base * createInstance(const std::string & derived_class_name, ClassLoader * loader, Args &&... args)
{
AbstractMetaObject * factory = nullptr;
getPluginBaseToFactoryMapMapMutex().lock();
FactoryMap & factoryMap = getFactoryMapForBaseClass();
- if (factoryMap.find(derived_class_name) != factoryMap.end()) {
- factory = dynamic_cast *>(factoryMap[derived_class_name]);
+ if (auto it = factoryMap.find(derived_class_name); it != factoryMap.end()) {
+ factory = dynamic_cast *>(it->second);
} else {
CONSOLE_BRIDGE_logError(
"class_loader.impl: No metaobject exists for class type %s.", derived_class_name.c_str());
diff --git a/include/class_loader/interface_traits.hpp b/include/class_loader/interface_traits.hpp
index f7285be..2c0b668 100644
--- a/include/class_loader/interface_traits.hpp
+++ b/include/class_loader/interface_traits.hpp
@@ -103,15 +103,17 @@ struct InterfaceTraits
namespace impl
{
-template
+template
struct interface_constructor_parameters_impl
{
using type = ConstructorParameters<>;
};
+// Constrained partial specialization replaces the std::void_t detection idiom:
+// it is selected when InterfaceTraits defines a `constructor_parameters` member.
template
-struct interface_constructor_parameters_impl::constructor_parameters>>
+requires requires {typename InterfaceTraits::constructor_parameters;}
+struct interface_constructor_parameters_impl
{
using type = typename InterfaceTraits::constructor_parameters;
};
@@ -190,6 +192,17 @@ template
constexpr bool is_interface_constructible_v =
is_interface_constructible::value;
+/**
+ * @brief Concept satisfied when a plugin deriving from @p Base can be constructed
+ * from @p Args, as declared by its InterfaceTraits.
+ *
+ * Used in place of std::enable_if to constrain the create*Instance() factories,
+ * yielding clearer diagnostics ("constraint not satisfied") on a mismatch.
+ * @see is_interface_constructible
+ */
+template
+concept InterfaceConstructible = is_interface_constructible_v;
+
} // namespace class_loader
#endif // CLASS_LOADER__INTERFACE_TRAITS_HPP_
diff --git a/include/class_loader/multi_library_class_loader.hpp b/include/class_loader/multi_library_class_loader.hpp
index 4b70fd8..a8ea70e 100644
--- a/include/class_loader/multi_library_class_loader.hpp
+++ b/include/class_loader/multi_library_class_loader.hpp
@@ -32,6 +32,7 @@
#ifndef CLASS_LOADER__MULTI_LIBRARY_CLASS_LOADER_HPP_
#define CLASS_LOADER__MULTI_LIBRARY_CLASS_LOADER_HPP_
+#include
#include
#include