dune-istl  2.8.0
registry.hh
Go to the documentation of this file.
1 #ifndef DUNE_ISTL_COMMON_REGISTRY_HH
2 #define DUNE_ISTL_COMMON_REGISTRY_HH
3 
4 #include <cstddef>
5 #include <iostream>
6 #include <memory>
7 #include <string>
8 #include <utility>
9 
10 #include "counter.hh"
11 
12 #include <dune/common/typelist.hh>
13 #include <dune/common/hybridutilities.hh>
14 #include <dune/common/parameterizedobject.hh>
15 
16 #define DUNE_REGISTRY_PUT(Tag, id, ...) \
17  namespace { \
18  template<> \
19  struct Registry<Tag, DUNE_GET_COUNTER(Tag)> \
20  { \
21  static auto getCreator() \
22  { \
23  return __VA_ARGS__; \
24  } \
25  static std::string name() { return id; } \
26  }; \
27  } \
28  DUNE_INC_COUNTER(Tag)
29 
30 
31 namespace Dune {
32  namespace {
33  template<class Tag, std::size_t index>
34  struct Registry;
35  }
36 
37  namespace {
38  template<template<class> class Base, class V, class Tag, typename... Args>
39  auto registryGet(Tag , std::string name, Args... args)
40  {
41  constexpr auto count = DUNE_GET_COUNTER(Tag);
42  std::shared_ptr<Base<V> > result;
43  Dune::Hybrid::forEach(std::make_index_sequence<count>{},
44  [&](auto index) {
45  using Reg = Registry<Tag, index>;
46  if(!result && Reg::name() == name) {
47  result = Reg::getCreator()(Dune::MetaType<V>{}, args...);
48  }
49  });
50  return result;
51  }
52 
53  /*
54  Register all creators from the registry in the Parameterizedobjectfactory An
55  object of V is passed in the creator ans should be used to determine the
56  template arguments.
57  */
58  template<class V, class Type, class Tag, class... Args>
59  int addRegistryToFactory(Dune::ParameterizedObjectFactory<Type(Args...), std::string>& factory,
60  Tag){
61  constexpr auto count = DUNE_GET_COUNTER(Tag);
62  Dune::Hybrid::forEach(std::make_index_sequence<count>{},
63  [&](auto index) {
64  // we first get the generic lambda
65  // and later specialize it with given parameters.
66  // doing all at once lead to an ICE woth g++-6
67  using Reg = Registry<Tag, index>;
68  auto genericcreator = Reg::getCreator();
69  factory.define(Reg::name(), [genericcreator](Args... args){
70  return genericcreator(V{}, args...);
71  });
72  });
73  return count;
74  }
75  } // end anonymous namespace
76 } // end namespace Dune
77 
78 #endif // DUNE_ISTL_COMMON_REGISTRY_HH
#define DUNE_GET_COUNTER(Tag)
Definition: counter.hh:15
Definition: allocator.hh:9