Skip to content
Snippets Groups Projects
CreatorMap.h 3.55 KiB
// ============================================================================
// ==                                                                        ==
// == AMDiS - Adaptive multidimensional simulations                          ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
// ==  crystal growth group                                                  ==
// ==                                                                        ==
// ==  Stiftung caesar                                                       ==
// ==  Ludwig-Erhard-Allee 2                                                 ==
// ==  53175 Bonn                                                            ==
// ==  germany                                                               ==
// ==                                                                        ==
// ============================================================================
// ==                                                                        ==
// ==  http://www.caesar.de/cg/AMDiS                                         ==
// ==                                                                        ==
// ============================================================================

/** \file CreatorMap.h */

#ifndef AMDIS_CREATORMAP_H
#define AMDIS_CREATORMAP_H

#include <map>
#include "Global.h"
#include "CreatorInterface.h"

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 OEMSolverMap 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<typename BaseClass>
  class CreatorMap
  {
  public:
    /// Adds a new creator together with the given key to the map.
    static void addCreator(std::string key, CreatorInterface<BaseClass>* creator) 
    {
      FUNCNAME("CreatorMap::addCreator()");
      init();
      TEST_EXIT(creatorMap[key] == NULL)
	("there is already a creator for key %s\n",key.c_str());
      creatorMap[key] = creator;
    }

    /// Creates a object of the type corresponding to key.
    static CreatorInterface<BaseClass>* getCreator(std::string key) 
    {
      FUNCNAME("CreatorMap::getCreator()");
      init();
      CreatorInterface<BaseClass> *creator = creatorMap[key];
      TEST_EXIT(creator)("no creator for key %s\n", key.c_str());
      return creator;
    }

    static void clear();

    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 std::map< std::string, CreatorInterface<BaseClass>* > creatorMap;

    static bool initialized;
  };

  template<typename BaseClass>
  std::map< std::string, CreatorInterface<BaseClass>* > CreatorMap<BaseClass>::creatorMap;

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

}

#include "CreatorMap.hh"

#endif