Dune Core Modules (2.6.0)

parameterizedobject.hh
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 #ifndef DUNE_COMMON_PARAMETERIZEDOBJECT_HH
4 #define DUNE_COMMON_PARAMETERIZEDOBJECT_HH
5 
6 #include <functional>
7 #include <map>
8 
10 #include <dune/common/std/memory.hh>
12 
13 namespace Dune {
14 
32 template<typename Signature,
33  typename KeyT = std::string>
35 
36 template<typename TypeT,
37  typename KeyT,
38  typename... Args>
39 class ParameterizedObjectFactory<TypeT(Args...), KeyT>
40 {
41  public:
42 
44  typedef KeyT Key;
45 
47  using Type = TypeT;
48 
49  protected:
50 
51  using Creator = std::function<Type(Args...)>;
52 
53  template<class F>
54  static constexpr auto has_proper_signature(Dune::PriorityTag<1>)
55  -> decltype( std::declval<F>()(std::declval<Args>()...), std::true_type())
56  {
57  return {};
58  }
59 
60  template<class F>
61  static constexpr std::false_type has_proper_signature(Dune::PriorityTag<0>)
62  {
63  return {};
64  }
65 
66  public:
67 
75  Type create(Key const& key, Args ... args) {
76  typename Registry::const_iterator i = registry_.find(key);
77  if (i == registry_.end()) {
79  "ParametrizedObjectFactory: key ``" <<
80  key << "'' not registered");
81  }
82  else return i->second(args...);
83  }
84 
98  template<class Impl>
99  void define(Key const& key)
100  {
101  registry_[key] = DefaultCreator<Impl>();
102  }
103 
117  template<class F,
118  typename std::enable_if<has_proper_signature<F>(PriorityTag<42>()), int>::type = 0>
119  void define(Key const& key, F&& f)
120  {
121  registry_[key] = f;
122  }
123 
138  template<class Impl,
139  typename std::enable_if<
140  std::is_convertible<Impl, Type>::value
141  and not std::is_convertible<Impl, Creator>::value,
142  int>::type = 0>
143  void define(Key const& key, Impl&& t)
144  {
145  registry_[key] = [=](Args...) { return t;};
146  }
147 
148  private:
149 
150  template<class T>
151  struct Tag{};
152 
153  template<class Impl>
154  struct DefaultCreator
155  {
156  template<class... T>
157  Type operator()(T&&... args) const
158  {
159  return DefaultCreator::create(Tag<Type>(), PriorityTag<42>(), std::forward<T>(args)...);
160  }
161 
162  template<class Target, class... T>
163  static Type create(Tag<Target>, PriorityTag<1>, T&& ... args) {
164  return Impl(std::forward<T>(args)...);
165  }
166 
167  template<class Target, class... T>
168  static Type create(Tag<std::unique_ptr<Target>>, PriorityTag<2>, T&& ... args) {
169  return Dune::Std::make_unique<Impl>(std::forward<T>(args)...);
170  }
171 
172  template<class Target, class... T>
173  static Type create(Tag<std::shared_ptr<Target>>, PriorityTag<3>, T&& ... args) {
174  return std::make_shared<Impl>(std::forward<T>(args)...);
175  }
176 
177  };
178 
179  typedef std::map<Key, Creator> Registry;
180  Registry registry_;
181 };
182 
183 
184 
185 } // end namespace Dune
186 
187 #endif // DUNE_COMMON_PARAMETERIZEDOBJECT_HH
Default exception if a function was called while the object is not in a valid state for that function...
Definition: exceptions.hh:279
A factory class for parameterized objects.
Definition: parameterizedobject.hh:34
A few common exception classes.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
Dune namespace.
Definition: alignedallocator.hh:10
Helper class for tagging priorities.
Definition: typeutilities.hh:83
Helper class for tagging priorities.
Definition: typeutilities.hh:71
Utilities for type computations, constraining overloads, ...
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 5, 22:29, 2024)