registrar: add skeleton of plugin registry
This commit is contained in:
parent
520af37042
commit
0683f80903
@ -424,6 +424,8 @@ list (
|
|||||||
rational.hpp
|
rational.hpp
|
||||||
region.cpp
|
region.cpp
|
||||||
region.hpp
|
region.hpp
|
||||||
|
registrar.cpp
|
||||||
|
registrar.hpp
|
||||||
roots/bisection.hpp
|
roots/bisection.hpp
|
||||||
scoped.hpp
|
scoped.hpp
|
||||||
signal.cpp
|
signal.cpp
|
||||||
@ -624,6 +626,7 @@ if (TESTS)
|
|||||||
range
|
range
|
||||||
rational
|
rational
|
||||||
region
|
region
|
||||||
|
registrar
|
||||||
roots/bisection
|
roots/bisection
|
||||||
scoped
|
scoped
|
||||||
signal
|
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