factory.hh

Go to the documentation of this file.
00001 // factory.hh: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2005, 2006 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 #ifndef VCSN_DESIGN_PATTERN_FACTORY_HH
00018 # define VCSN_DESIGN_PATTERN_FACTORY_HH
00019 
00020 # include <exception>
00021 # include <map>
00022 
00037 namespace vcsn
00038 {
00039 
00040   /*--------------.
00041   | Error control |
00042   `--------------*/
00043 
00044   template <class IdentifierType, class ProductType>
00045   class DefaultFactoryError
00046   {
00047   public:
00048     class Exception : public std::exception
00049     {
00050     public:
00051       Exception(const IdentifierType& unknown_id) : unknown_id_(unknown_id) {}
00052       ~Exception() throw() {};
00053       virtual const char*       what()
00054       {
00055         return "Unknown object type passed to Factory.";
00056       }
00057 
00058       const IdentifierType      GetId()
00059       {
00060         return unknown_id_;
00061       }
00062     private:
00063       IdentifierType            unknown_id_;
00064     };
00065 
00066   protected:
00067     ProductType*                OnUnknownType(const IdentifierType& id)
00068     {
00069       throw Exception(id);
00070     }
00071   };
00072 
00073 
00074   /*----------------.
00075   | Generic Factory |
00076   `----------------*/
00077 
00078   template <
00079     class AbstractProduct,
00080     class IdentifierType,
00081     class ProductCreator = AbstractProduct* (*)(),
00082     template <typename, class> class FactoryErrorPolicy = DefaultFactoryError
00083   >
00084   class Factory : public FactoryErrorPolicy<IdentifierType, AbstractProduct>
00085   {
00086   public:
00087     bool                        reg(const IdentifierType& id,
00088                                     ProductCreator creator)
00089     {
00090       typedef typename assoc_map_t::value_type value_type;
00091 
00092       return associations_.insert(value_type(id, creator)).second;
00093     }
00094 
00095 
00096     bool                        unreg(const IdentifierType& id)
00097     {
00098       return associations_.erase(id) == 1;
00099     }
00100 
00101 
00102     AbstractProduct*            create_object(const IdentifierType& id)
00103     {
00104       typename assoc_map_t::const_iterator i = associations_.find(id);
00105 
00106       if (i != associations_.end())
00107         return (i->second)();
00108       return OnUnknownType(id);
00109     }
00110 
00111   private:
00112     typedef std::map<IdentifierType, ProductCreator> assoc_map_t;
00113     assoc_map_t associations_;
00114   };
00115 
00116 } // !vcsn
00117 
00118 
00119 #define factory_reg(factory, typeId, creationFunction) \
00120         factory.reg(typeId, creationFunction)
00121 
00122 #define factory_create(factory, typeId) \
00123         factory.create_object(typeId)
00124 
00125 
00126 #endif // ! VCSN_DESIGN_PATTERN_FACTORY_HH

Generated on Wed Jun 13 17:00:21 2007 for Vaucanson by  doxygen 1.5.1