Dune Core Modules (unstable)

registry.hh
1// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3#ifndef DUNE_ISTL_COMMON_REGISTRY_HH
4#define DUNE_ISTL_COMMON_REGISTRY_HH
5
6#include <cstddef>
7#include <iostream>
8#include <memory>
9#include <string>
10#include <utility>
11
12#include "counter.hh"
13
14#include <dune/common/typelist.hh>
15#include <dune/common/hybridutilities.hh>
16#include <dune/common/parameterizedobject.hh>
17
18#define DUNE_REGISTRY_PUT(Tag, id, ...) \
19 namespace { \
20 template<> \
21 struct Registry<Tag, DUNE_GET_COUNTER(Tag)> \
22 { \
23 static auto getCreator() \
24 { \
25 return __VA_ARGS__; \
26 } \
27 static std::string name() { return id; } \
28 }; \
29 } \
30 DUNE_INC_COUNTER(Tag)
31
32
33namespace Dune {
34 namespace {
35 template<class Tag, std::size_t index>
36 struct Registry;
37 }
38
39 namespace {
40 template<template<class> class Base, class V, class Tag, typename... Args>
41 auto registryGet(Tag , std::string name, Args... args)
42 {
43 constexpr auto count = DUNE_GET_COUNTER(Tag);
44 std::shared_ptr<Base<V> > result;
45 Dune::Hybrid::forEach(std::make_index_sequence<count>{},
46 [&](auto index) {
47 using Reg = Registry<Tag, index>;
48 if(!result && Reg::name() == name) {
49 result = Reg::getCreator()(Dune::MetaType<V>{}, args...);
50 }
51 });
52 return result;
53 }
54
55 /*
56 Register all creators from the registry in the Parameterizedobjectfactory. An
57 object of V is passed in the creator and should be used to determine the
58 template arguments.
59 */
60 template<class V, class Type, class Tag, class... Args>
61 int addRegistryToFactory(Dune::ParameterizedObjectFactory<Type(Args...), std::string>& factory,
62 Tag){
63 constexpr auto count = DUNE_GET_COUNTER(Tag);
64 Dune::Hybrid::forEach(std::make_index_sequence<count>{},
65 [&](auto index) {
66 // we first get the generic lambda
67 // and later specialize it with given parameters.
68 // doing all at once leads to an ICE with g++-6
69 using Reg = Registry<Tag, index>;
70 auto genericcreator = Reg::getCreator();
71 factory.define(Reg::name(), [genericcreator](Args... args){
72 return genericcreator(V{}, args...);
73 });
74 });
75 return count;
76 }
77 } // end anonymous namespace
78} // end namespace Dune
79
80#endif // DUNE_ISTL_COMMON_REGISTRY_HH
A factory class for parameterized objects.
Definition: parameterizedobject.hh:36
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
Dune namespace.
Definition: alignedallocator.hh:13
A type that refers to another type.
Definition: typelist.hh:33
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)