Listing 2: Providing a user-definable policy via a map of function pointers

//
//---- begin file library.h ----
//

#include <string>
#include <map>
#include <iostream>

typedef void(*policyFunction)();
typedef std::map<std::string, policyFunction> policyMap_t;

// singleton class to manage policies
class Policies {
public:
   void registerPolicy(const std::string id,
                       const policyFunction func);
   void policy(const std::string id) const;

   static Policies& policyMap();
private:
   Policies() {}
   policyMap_t typeMap_;
};

// member function definitions
void
Policies::registerPolicy(const std::string id,
                         const policyFunction func)
{
   if (id != "" && func !=0) {
      typeMap_[id] = func;
   }
}

void Policies::policy(const std::string id) const
{
   policyMap_t::const_iterator iter = typeMap_.find(id);
   if (iter != typeMap_.end()) {
      (*iter).second();
   }
   else {
       std::cout << "Performing Default Policy." 
                 << std::endl << std::endl;
   }
}
    
Policies& Policies::policyMap() 
{
   static Policies typeMap;
   return typeMap;
}    

// namespace scope function for convenience
Policies& policyMap()
{
   return Policies::policyMap();
}

//
//---- begin file container.h ----
//

#include "library.h"
#include <string>
#include <iostream>

template <class ElementType>
class MyContainer {
public:
    MyContainer(const std::string iName) : instanceName(iName) 
   {}
   // class implementation
   // ...
   
   // forwards the policy request
   void doPolicy();
   // a service that uses the policy
   void performService() { doPolicy(); }
   
   const std::string instanceName;
};

// elements for example's sake
template<class T>
struct Element1 {
// ...
};

template<class T>
struct Element2 {
// ...
};


template <class ElementType>
void MyContainer<ElementType>::doPolicy() 
{ 
    policyMap().policy("MyContainer");
}

//
//---- begin file user.cpp ----
//

#include "container.h"

void MyPolicy()
{
    std::cout << "Performing My Policy." 
              << std::endl << std::endl;
}
           
           
int main() {

   MyContainer<Element1<int> > c("test object");
   c.doPolicy();
   policyMap().registerPolicy("MyContainer", MyPolicy);
   c.doPolicy();

   return 0;
}
— End of Listing —