Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
19 changes: 9 additions & 10 deletions include/class_loader/class_loader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ class ClassLoader
* by InterfaceTraits of the Base class)
* @return A std::shared_ptr<Base> to newly created plugin object
*/
template<class Base, class ... Args,
std::enable_if_t<is_interface_constructible_v<Base, Args...>, bool> = true>
template<class Base, class ... Args>
requires InterfaceConstructible<Base, Args...>
[[nodiscard]] std::shared_ptr<Base> createInstance(
const std::string & derived_class_name, Args &&... args)
{
Expand All @@ -150,8 +150,8 @@ class ClassLoader
* by InterfaceTraits of the Base class)
* @return A std::unique_ptr<Base> to newly created plugin object.
*/
template<class Base, class ... Args,
std::enable_if_t<is_interface_constructible_v<Base, Args...>, bool> = true>
template<class Base, class ... Args>
requires InterfaceConstructible<Base, Args...>
[[nodiscard]] UniquePtr<Base> createUniqueInstance(
const std::string & derived_class_name, Args &&... args)
{
Expand All @@ -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<class Base, class ... Args,
std::enable_if_t<is_interface_constructible_v<Base, Args...>, bool> = true>
template<class Base, class ... Args>
requires InterfaceConstructible<Base, Args...>
[[nodiscard]] Base * createUnmanagedInstance(
const std::string & derived_class_name, Args &&... args)
{
Expand All @@ -196,8 +196,7 @@ class ClassLoader
[[nodiscard]] bool isClassAvailable(const std::string & class_name) const
{
std::vector<std::string> available_classes = getAvailableClasses<Base>();
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();
}

/**
Expand Down Expand Up @@ -314,8 +313,8 @@ class ClassLoader
* by InterfaceTraits of the Base class)
* @return A Base* to newly created plugin object.
*/
template<class Base, class ... Args,
std::enable_if_t<is_interface_constructible_v<Base, Args...>, bool> = true>
template<class Base, class ... Args>
requires InterfaceConstructible<Base, Args...>
Base * createRawInstance(const std::string & derived_class_name, bool managed, Args &&... args)
{
if (!managed) {
Expand Down
34 changes: 13 additions & 21 deletions include/class_loader/class_loader_core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#ifndef CLASS_LOADER__CLASS_LOADER_CORE_HPP_
#define CLASS_LOADER__CLASS_LOADER_CORE_HPP_

#include <algorithm>
#include <cstddef>
#include <cstdio>
#include <functional>
Expand Down Expand Up @@ -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;
}
}
Expand All @@ -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<Base>();
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. "
Expand Down Expand Up @@ -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<typename Base, class ... Args,
std::enable_if_t<is_interface_constructible_v<Base, Args...>, bool> = true>
template<typename Base, class ... Args>
requires InterfaceConstructible<Base, Args...>
Base * createInstance(const std::string & derived_class_name, ClassLoader * loader, Args &&... args)
{
AbstractMetaObject<Base> * factory = nullptr;

getPluginBaseToFactoryMapMapMutex().lock();
FactoryMap & factoryMap = getFactoryMapForBaseClass<Base>();
if (factoryMap.find(derived_class_name) != factoryMap.end()) {
factory = dynamic_cast<impl::AbstractMetaObject<Base> *>(factoryMap[derived_class_name]);
if (auto it = factoryMap.find(derived_class_name); it != factoryMap.end()) {
factory = dynamic_cast<impl::AbstractMetaObject<Base> *>(it->second);
} else {
CONSOLE_BRIDGE_logError(
"class_loader.impl: No metaobject exists for class type %s.", derived_class_name.c_str());
Expand Down
19 changes: 16 additions & 3 deletions include/class_loader/interface_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,17 @@ struct InterfaceTraits
namespace impl
{

template<class T, class = void>
template<class T>
struct interface_constructor_parameters_impl
{
using type = ConstructorParameters<>;
};

// Constrained partial specialization replaces the std::void_t detection idiom:
// it is selected when InterfaceTraits<T> defines a `constructor_parameters` member.
template<class T>
struct interface_constructor_parameters_impl<T,
std::void_t<typename InterfaceTraits<T>::constructor_parameters>>
requires requires {typename InterfaceTraits<T>::constructor_parameters;}
struct interface_constructor_parameters_impl<T>
{
using type = typename InterfaceTraits<T>::constructor_parameters;
};
Expand Down Expand Up @@ -190,6 +192,17 @@ template<class Base, class ... Args>
constexpr bool is_interface_constructible_v =
is_interface_constructible<Base, Args...>::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<class Base, class ... Args>
concept InterfaceConstructible = is_interface_constructible_v<Base, Args...>;

} // namespace class_loader

#endif // CLASS_LOADER__INTERFACE_TRAITS_HPP_
28 changes: 14 additions & 14 deletions include/class_loader/multi_library_class_loader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#ifndef CLASS_LOADER__MULTI_LIBRARY_CLASS_LOADER_HPP_
#define CLASS_LOADER__MULTI_LIBRARY_CLASS_LOADER_HPP_

#include <algorithm>
#include <cstddef>
#include <map>
#include <memory>
Expand Down Expand Up @@ -92,8 +93,8 @@ class CLASS_LOADER_PUBLIC MultiLibraryClassLoader
* by InterfaceTraits of the Base class)
* @return A std::shared_ptr<Base> to newly created plugin
*/
template<class Base, class ... Args,
std::enable_if_t<is_interface_constructible_v<Base, Args...>, bool> = true>
template<class Base, class ... Args>
requires InterfaceConstructible<Base, Args...>
[[nodiscard]] std::shared_ptr<Base> createInstance(
const std::string & class_name, Args &&... args)
{
Expand Down Expand Up @@ -124,8 +125,8 @@ class CLASS_LOADER_PUBLIC MultiLibraryClassLoader
* by InterfaceTraits of the Base class)
* @return A std::shared_ptr<Base> to newly created plugin
*/
template<class Base, class ... Args,
std::enable_if_t<is_interface_constructible_v<Base, Args...>, bool> = true>
template<class Base, class ... Args>
requires InterfaceConstructible<Base, Args...>
[[nodiscard]] std::shared_ptr<Base> createInstance(
const std::string & class_name, const std::string & library_path, Args &&... args)
{
Expand All @@ -150,8 +151,8 @@ class CLASS_LOADER_PUBLIC MultiLibraryClassLoader
* by InterfaceTraits of the Base class)
* @return A unique pointer to newly created plugin
*/
template<class Base, class ... Args,
std::enable_if_t<is_interface_constructible_v<Base, Args...>, bool> = true>
template<class Base, class ... Args>
requires InterfaceConstructible<Base, Args...>
[[nodiscard]] ClassLoader::UniquePtr<Base> createUniqueInstance(
const std::string & class_name, Args &&... args)
{
Expand Down Expand Up @@ -180,8 +181,8 @@ class CLASS_LOADER_PUBLIC MultiLibraryClassLoader
* by InterfaceTraits of the Base class)
* @return A unique pointer to newly created plugin
*/
template<class Base, class ... Args,
std::enable_if_t<is_interface_constructible_v<Base, Args...>, bool> = true>
template<class Base, class ... Args>
requires InterfaceConstructible<Base, Args...>
[[nodiscard]] ClassLoader::UniquePtr<Base>
createUniqueInstance(
const std::string & class_name, const std::string & library_path,
Expand Down Expand Up @@ -209,8 +210,8 @@ class CLASS_LOADER_PUBLIC MultiLibraryClassLoader
* by InterfaceTraits of the Base class)
* @return An unmanaged Base* to newly created plugin
*/
template<class Base, class ... Args,
std::enable_if_t<is_interface_constructible_v<Base, Args...>, bool> = true>
template<class Base, class ... Args>
requires InterfaceConstructible<Base, Args...>
[[nodiscard]] Base * createUnmanagedInstance(const std::string & class_name, Args &&... args)
{
ClassLoader * loader = getClassLoaderForClass<Base>(class_name);
Expand All @@ -232,8 +233,8 @@ class CLASS_LOADER_PUBLIC MultiLibraryClassLoader
* @param args - arguments for the constructor of the derived class (types defined
* by InterfaceTraits of the Base class)
*/
template<class Base, class ... Args,
std::enable_if_t<is_interface_constructible_v<Base, Args...>, bool> = true>
template<class Base, class ... Args>
requires InterfaceConstructible<Base, Args...>
[[nodiscard]] Base * createUnmanagedInstance(
const std::string & class_name, const std::string & library_path,
Args &&... args)
Expand All @@ -259,8 +260,7 @@ class CLASS_LOADER_PUBLIC MultiLibraryClassLoader
[[nodiscard]] bool isClassAvailable(const std::string & class_name) const
{
std::vector<std::string> available_classes = getAvailableClasses<Base>();
return available_classes.end() != std::find(
available_classes.begin(), available_classes.end(), class_name);
return std::ranges::find(available_classes, class_name) != available_classes.end();
}

/**
Expand Down
Loading