registrar: add skeleton of plugin registry
This commit is contained in:
parent
520af37042
commit
0683f80903
@ -424,6 +424,8 @@ list (
|
||||
rational.hpp
|
||||
region.cpp
|
||||
region.hpp
|
||||
registrar.cpp
|
||||
registrar.hpp
|
||||
roots/bisection.hpp
|
||||
scoped.hpp
|
||||
signal.cpp
|
||||
@ -624,6 +626,7 @@ if (TESTS)
|
||||
range
|
||||
rational
|
||||
region
|
||||
registrar
|
||||
roots/bisection
|
||||
scoped
|
||||
signal
|
||||
|
9
registrar.cpp
Normal file
9
registrar.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2019 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#include "registrar.hpp"
|
96
registrar.hpp
Normal file
96
registrar.hpp
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* Copyright 2019 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "log.hpp"
|
||||
#include "introspection.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace cruft {
|
||||
template <typename KeyT, typename FactoryT>
|
||||
class registry {
|
||||
public:
|
||||
struct cookie {
|
||||
explicit cookie (KeyT const &_key)
|
||||
: m_key (_key)
|
||||
{ ; }
|
||||
|
||||
explicit cookie (KeyT &&_key)
|
||||
: m_key (std::move (_key))
|
||||
{ ; }
|
||||
|
||||
cookie (cookie &&rhs) noexcept
|
||||
: m_key (std::move (rhs.key))
|
||||
{ ; }
|
||||
|
||||
cookie& operator= (cookie &&rhs) noexcept
|
||||
{
|
||||
std::swap (rhs.m_key, m_key);
|
||||
return *this;
|
||||
}
|
||||
|
||||
cookie (cookie const&) = delete;
|
||||
cookie& operator= (cookie const&) = delete;
|
||||
|
||||
~cookie ()
|
||||
{
|
||||
registry::remove (m_key);
|
||||
}
|
||||
|
||||
private:
|
||||
KeyT m_key;
|
||||
};
|
||||
|
||||
|
||||
static cookie
|
||||
add [[nodiscard]] (KeyT key, FactoryT &&factory)
|
||||
{
|
||||
auto const &[pos, success] = store ().insert (
|
||||
{ key, std::move (factory) }
|
||||
);
|
||||
|
||||
if (success) {
|
||||
LOG_INFO ("Registered %! for %!", key, cruft::type_name<FactoryT> ());
|
||||
return cookie { key };
|
||||
} {
|
||||
LOG_ERROR ("Unable to register %! for %!", key, cruft::type_name<FactoryT> ());
|
||||
throw std::runtime_error ("Unable to register type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static FactoryT remove (KeyT const &key)
|
||||
{
|
||||
auto &s_factory = store ();
|
||||
|
||||
auto pos = s_factory.find (key);
|
||||
if (pos == s_factory.cend ())
|
||||
throw std::invalid_argument ("Key not found");
|
||||
|
||||
auto val = s_factory.extract (pos);
|
||||
return std::move (val.mapped ());
|
||||
}
|
||||
|
||||
|
||||
static FactoryT& at (KeyT const &key)
|
||||
{
|
||||
return store ().at (key);
|
||||
}
|
||||
|
||||
private:
|
||||
static auto&
|
||||
store (void)
|
||||
{
|
||||
static std::map<KeyT,FactoryT> s_factory;
|
||||
return s_factory;
|
||||
}
|
||||
};
|
||||
}
|
26
test/registrar.cpp
Normal file
26
test/registrar.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include "registrar.hpp"
|
||||
|
||||
#include "tap.hpp"
|
||||
|
||||
|
||||
void foo () { }
|
||||
|
||||
int main ()
|
||||
{
|
||||
cruft::TAP::logger tap;
|
||||
|
||||
using void_fptr = void(*)();
|
||||
using registry_type = cruft::registry<char const*, void_fptr>;
|
||||
|
||||
{
|
||||
auto cookie = registry_type::add ("foo", foo);
|
||||
tap.expect_eq (registry_type::at ("foo"), foo, "queried value matches registered value");
|
||||
}
|
||||
|
||||
tap.expect_throw<std::out_of_range> (
|
||||
[] () { registry_type::at ("foo"); },
|
||||
"destruction of cookie removes value"
|
||||
);
|
||||
|
||||
return tap.status ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user