Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add keys to ModuleManager #326

Merged
merged 14 commits into from
Dec 8, 2023
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
sphinx
sphinx_rtd_theme
sphinx_rtd_theme==1.3.0
sphinxcontrib-bibtex
sphinx_tabs
13 changes: 12 additions & 1 deletion include/pluginplay/module_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,15 @@ class ModuleManager {
/// Type of a map holding usable modules
using module_map = utilities::CaseInsensitiveMap<std::shared_ptr<Module>>;

// The type of the runtime
/// The type of the runtime
using runtime_type = parallelzone::runtime::RuntimeView;

/// A pointer to a runtime
using runtime_ptr = std::shared_ptr<runtime_type>;

/// Type of module key container
using key_container_type = std::vector<type::key>;

///@{
/** @name Ctors and assignment operators
*
Expand Down Expand Up @@ -231,6 +234,14 @@ class ModuleManager {
*/
runtime_type& get_runtime() const noexcept;

/** @brief Returns the keys of all the modules in the module manager.
*
* @return A vector of keys for all the modules in the module manager.
*
* @throw std::bad_alloc if an allocation error arises.
*/
key_container_type keys() const noexcept;
keceli marked this conversation as resolved.
Show resolved Hide resolved

private:
/// Bridges the gap between the set_default and the PIMPL
void set_default_(const std::type_info& type, type::input_map inps,
Expand Down
7 changes: 7 additions & 0 deletions src/pluginplay/detail_/module_manager_pimpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,13 @@ struct ModuleManagerPIMPL {
void set_runtime(runtime_ptr runtime) noexcept { m_runtime_ = runtime; }

runtime_type& get_runtime() const { return *m_runtime_.get(); }

ModuleManager::key_container_type keys() const noexcept {
keceli marked this conversation as resolved.
Show resolved Hide resolved
ModuleManager::key_container_type keys;
keys.reserve(m_modules.size());
for(const auto& [k, v] : m_modules) keys.push_back(k);
return keys;
}
///@}

///@{
Expand Down
3 changes: 3 additions & 0 deletions src/pluginplay/module_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,7 @@ ModuleManager::runtime_type& ModuleManager::get_runtime() const noexcept {
return pimpl_->get_runtime();
};

ModuleManager::key_container_type ModuleManager::keys() const noexcept {
keceli marked this conversation as resolved.
Show resolved Hide resolved
return pimpl_->keys();
}
} // namespace pluginplay
10 changes: 6 additions & 4 deletions src/python/export_module_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <pluginplay/any/any.hpp>
#include <pluginplay/module_manager.hpp>
#include <pluginplay/python/python_wrapper.hpp>
#include <pybind11/stl.h>

namespace pluginplay {

Expand Down Expand Up @@ -53,10 +54,11 @@ void export_module_manager(py_module_reference m) {
.def("run_as",
[](py_obj self, py_obj pt, py_obj key, pybind11::args args) {
return self.attr("at")(key).attr("run_as")(pt, *args);
});
//.def("set_runtime", &ModuleManager::set_runtime)
//.def("get_runtime", &ModuleManager::get_runtime)

})
.def("keys", &ModuleManager::keys)
.def("__getitem__", [](ModuleManager& self, const type::key& key) {
return self.at(key);
});
m.def("defaulted_mm", []() { return ModuleManager(nullptr); });
}

Expand Down
19 changes: 19 additions & 0 deletions tests/cxx/unit_tests/pluginplay/detail_/module_manager_pimpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,22 @@ TEST_CASE("ModuleManagerPIMPL : at") {
}
}
}

TEST_CASE("ModuleManagerPIMPL : keys") {
ModuleManagerPIMPL pimpl1;
SECTION("Empty") {
REQUIRE(pimpl1.keys().size() == 0);
REQUIRE(pimpl1.keys().empty());
}
SECTION("With module") {
auto ptr1 = std::make_shared<Rectangle>();
pimpl1.add_module("rectangle", ptr1);
REQUIRE(pimpl1.keys().size() == 1);
REQUIRE(pimpl1.keys().at(0) == "rectangle");
auto ptr2 = std::make_shared<Prism>();
pimpl1.add_module("prism", ptr2);
REQUIRE(pimpl1.keys().size() == 2);
REQUIRE(pimpl1.keys().at(0) == "prism");
REQUIRE(pimpl1.keys().at(1) == "rectangle");
}
}
25 changes: 25 additions & 0 deletions tests/cxx/unit_tests/pluginplay/module_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,29 @@ TEST_CASE("ModuleManager") {
auto corr = testing::make_module<mod_t>();
REQUIRE(mm.at("a mod") == *corr);
}

SECTION("iterator") {
using mod_t = testing::NoPTModule; // Type of the Module we're adding

mm.add_module("a key", std::make_shared<mod_t>());
mm.add_module("b key", std::make_shared<testing::ReadyModule>());
auto count = 0;
for(auto& [key, mod] : mm) {
count += 1;
REQUIRE("key" == key.substr(key.size() - 3));
REQUIRE_FALSE(mod->has_description());
}
REQUIRE(count == mm.size());
}

SECTION("keys") {
using mod_t = testing::NoPTModule; // Type of the Module we're adding

mm.add_module("a key", std::make_shared<mod_t>());
mm.add_module("b key", std::make_shared<testing::ReadyModule>());
auto keys = mm.keys();
REQUIRE(keys.size() == mm.size());
REQUIRE(keys[0] == "a key");
REQUIRE(keys[1] == "b key");
}
}
12 changes: 12 additions & 0 deletions tests/python/unit_tests/test_module_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,18 @@ def test_pluginplay_309(self):
self.assertEqual(rv, 1)


def test_get_item(self):
module_with_description = self.has_mods['C++ with description']
self.assertTrue(module_with_description.has_description())
self.assertNotEqual(self.has_mods['C++ no PT'], None)


def test_keys(self):
self.assertEqual(len(self.defaulted.keys()), self.defaulted.size())
self.assertEqual(len(self.has_mods.keys()), self.has_mods.size())
self.assertTrue('C++ Null PT' in self.has_mods.keys())


def setUp(self):
self.defaulted = pp.defaulted_mm()
self.has_mods = test_pp.get_mm()
Expand Down