CreatorMap.hpp 2.55 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#pragma once

// std c++ headers
#include <map>

// AMDiS includes
#include "CreatorInterface.hpp"

namespace AMDiS
{
  /** \ingroup Common
   * \brief
   * A CreatorMap is used to construct objects, which types depends on key words
   * determined at run time. For example the LinearSolverInterfaceMap can create the different
   * solver types depending on the solver parameter of the init file. The benefit
   * of such creator maps is, that you can extend them only by writing an creator
   * class for your own new class and give the creator together with a key word
   * to the map.
   */
  template <class BaseClass>
  class CreatorMap
  {
  public:
    using CreatorMapType = std::map<std::string, CreatorInterface<BaseClass>*>;

  public:
    /// Adds a new creator together with the given key to the map.
    static void addCreator(std::string key, CreatorInterface<BaseClass>* creator)
    {
      init();
      AMDIS_TEST_EXIT(creatorMap[key] == NULL,
        "There is already a creator for key " << key);
      creatorMap[key] = creator;
    }

    static void addCreator(std::string backend, 
                           std::string key, 
                           CreatorInterface<BaseClass>* creator)
    {
      addCreator(backend + "_" + key, creator);
    }

    /// Creates a object of the type corresponding to key.
    static CreatorInterface<BaseClass>* getCreator(std::string key, 
                                                   std::string initFileStr)
    {
      init();
      
      CreatorInterface<BaseClass>* creator = creatorMap[key];
      AMDIS_TEST_EXIT(creator,
        "No creator for key \"" << key << "\" defined in init file for parameter \"" << initFileStr << "\"");

      return creator;
    }

    static void clear()
    {
      for (auto entries : creatorMap)
        delete it->second;
    }

    static void addDefaultCreators();

  protected:
    /// Constructor is protected because derived maps should be singleton.
    static void init()
    {
      if (!initialized)
      {
        initialized = true;
        NullCreator<BaseClass>* nullCreator = new NullCreator<BaseClass>;
        addCreator("0", nullCreator);
        addDefaultCreators();
      }
    }

  protected:
    /// STL map containing the pairs of keys and creators.
    static CreatorMapType creatorMap;

    static bool initialized;
  };

  template <class BaseClass>
  typename CreatorMap<BaseClass>::CreatorMapType CreatorMap<BaseClass>::creatorMap;

  template <class BaseClass>
  bool CreatorMap<BaseClass>::initialized = false;

} // end namespace AMDiS

#include "CreatorMap.hh"