Listing 2: The prototype factory class using traits

template<typename Proto>
class prototype_traits
{
public:
  typedef Proto* stored_type;
  typedef Proto* cloning_result_type;
  
  enum{ destroy_prototypes = true, };

  static cloning_result_type Clone(stored_type p)
  { return p->Clone(); }

  static void Destroy(stored_type p)
  { delete p; }

};

template<typename Proto, typename Id>
class ProtoTypeFactory
{
public:
  void RegisterProtoType(
    const prototype_traits<Proto>::stored_type& protoType,
    Id id
  )
  { protoTypeCollection[id] = protoType; }
  
  prototype_traits<Proto>::cloning_result_type
  GetClone(Id id)
  { 
    return prototype_traits<Proto>::Clone(
      protoTypeCollection[id]
      ); 
  }

  ~ProtoTypeFactory()
  { 
    if( prototype_traits<Proto>::destroy_prototypes )
    {
      std::for_each(
        protoTypeCollection.begin(),
        protoTypeCollection.end(),
        DestroyPrototype()
        );
    }
   }

protected:
  std::map<Id, prototype_traits<Proto>::stored_type>
    protoTypeCollection;

private:
  class DestroyPrototype
  {
  public:
    operator()(std::pair<Id, prototype_traits<Proto>::stored_type> elem)
    { prototype_traits<Proto>::Destroy(elem.second); }
  };
};
— End of Listing —