dune-istl  2.9.0
registry.hh
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 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 
33 namespace 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 ans 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 lead to an ICE woth 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
#define DUNE_GET_COUNTER(Tag)
Definition: counter.hh:17
Definition: allocator.hh:11