Listing 5: A prototype factory with multiple policies

// Default policies defined in Listing 6
//
template
<
  typename Proto, 
  typename Id,
  typename ProtoTypingPolicy = PFPlainOwnedPointers<Proto>,
  typename ThreadingPolicy = PFSingleThreaded
>
class ProtoTypeFactory : public ThreadingPolicy
{

  typedef std::map<Id, ProtoTypingPolicy::stored_type> 
    PrototypeMap;

public:
  bool RegisterProtoType(
    const ProtoTypingPolicy::stored_type& protoType,
    Id id
  )
  { 
    Lock lock(this);
    return protoTypeCollection.insert(
      std::make_pair(id, protoType)
      ).second;
  }
  
  ProtoTypingPolicy::cloning_result_type GetClone(Id id)
  { 
    PrototypeMap::iterator itProto, itEnd;
    {
      Lock lock(this);
      itEnd = protoTypeCollection.end();
      itProto = protoTypeCollection.find(id);
    }    
    
    // Can do this outside of lock scope:
    // map insertions do not invalidate iterators.
    //
    if( itEnd == itProto )
      return NULL;
    else
      return ProtoTypingPolicy::Clone(itProto->second); 
  }

  ~ProtoTypeFactory()
  { 
    ProtoTypingPolicy::DestroyProtoTypes(
      protoTypeCollection.begin(),
      protoTypeCollection.end()
      );
  }

private:
  PrototypeMap protoTypeCollection;

};
— End of Listing —