factory.hpp

Go to the documentation of this file.
00001 #ifndef s11n_net_s11n_FACTORY_H_INCLUDED
00002 #define s11n_net_s11n_FACTORY_H_INCLUDED 1
00003 // Author: stephan beal <stephan@s11n.net>
00004 // Various parts between 2003 and 2005.
00005 // License: Public Domain
00006 
00007 #include <string>
00008 #include <map>
00009 
00010 #include <functional>
00011 
00012 #include <s11n.net/s11n/export.hpp>
00013 #include <s11n.net/s11n/phoenix.hpp> // i don't like this dep, but i also don't like
00014                            // what happens in some cases when i don't use
00015                            // phoenix. :/
00016 namespace s11n {
00017 
00018     /**
00019        The s11n::fac namespace contains s11n's "private" object
00020        factory manager.  This code should not be considered to be
00021        part of the public APIs: use the s11n::cl API for your
00022        factory-related needs unless absolutely
00023        necessary. Unfortunately, classloading can be intrusive
00024        enough that this API might sometimes need to be leaked into
00025        client- or non-core library code. The example which
00026        immediately comes to mind is clients which want to get a
00027        list of all registered factories: this can only be done by
00028        querying the factory itself for them.
00029 
00030        The factory manager layer acts as a registration point for
00031        factories for near-arbitrary classes. Classes compatible
00032        with this layer must currently meet the following requirements:
00033 
00034        - DefaultConstructable.
00035 
00036        - Must register with this layer. In s11n, this is done as
00037        part of the normal s11n registration process. Clients
00038        needing to manually register types should use the s11n::cl
00039        class registering/loading API.
00040 
00041        - Must be legal: delete instanceOfObject; This is really a
00042        usage convention, and not a hard/fast rule of this type.
00043     */
00044     namespace fac {
00045 
00046         /**
00047            create_hook is a helper object factory for the factory_mgr
00048            API. It is used by that type to create instances of specific types.
00049            It may be specialized to provide non-default object construction.
00050 
00051            General conventions:
00052 
00053            SubT must derive from (or be) T and must be Default
00054            Constructuable on the heap. In short, the following must be
00055            able to succeed:
00056        
00057            <pre>
00058            T * foo = new SubT;
00059            </pre>
00060 
00061            Clients may freely specialize this type to hook their
00062            factories in, and the above 'new' requirement need
00063            not be imposed by client-side specializations. For example,
00064            specializations are used to provide no-op factories for
00065            abstract types, where 'new T' cannot work.
00066         */
00067 
00068         template < class T, class SubT >
00069         struct S11N_EXPORT_API create_hook
00070         {
00071             /**
00072                The type returned by create() and
00073                operator().
00074             */
00075             typedef T * result_type;
00076 
00077             /**
00078                A typedef for the second template parameter for this
00079                type.
00080             */
00081             typedef SubT actual_type;
00082             
00083             /**
00084                This creates a new SubT, which is assumed to be a
00085                subclass of T.  It can be used as a factory for
00086                factory & class_loader.
00087                
00088                If T or SubT are abstract types, you must
00089                specialize this type such that create() returns 0
00090                for those.  That is, we "simulate" creation of
00091                abstract types by returning 0.
00092 
00093                The caller owns the returned pointer, which
00094                may be 0.
00095             */
00096             static result_type create()
00097             {
00098                 return new actual_type;
00099             }
00100 
00101             /**
00102                Same as create().
00103             */
00104             result_type operator()() const
00105             {
00106                 return this->create();
00107             }
00108         };
00109 
00110 
00111         /**
00112            A helper class to alias one token to another.
00113 
00114            AliasedType requires:
00115 
00116            - Must be suitable for use as both key and value
00117            types for a std::map, with all that that implies
00118            (e.g., operator<() must be well-behaved).
00119 
00120         */
00121         template <typename AliasedType>
00122         class S11N_EXPORT_API aliaser
00123         {
00124         public:
00125             typedef AliasedType key_type;
00126             typedef AliasedType value_type;
00127             /**
00128                A map type for storing lookup key aliases.
00129             */
00130             typedef std::map<key_type,value_type> alias_map_type;
00131 
00132             /**
00133                Aliases 'alias' as an equivalent of 'isthesameas'.
00134             */
00135             void alias( const key_type & alias, const value_type & isthesameas )
00136             {
00137                 this->aliases()[alias] = isthesameas;
00138             }
00139 
00140             /**
00141                Returns the map of aliases.
00142             */
00143             alias_map_type & aliases() { return this->m_map; }
00144 
00145             /** Const overload. */
00146             const alias_map_type & aliases() const { return this->m_map; }
00147 
00148             typedef typename alias_map_type::iterator iterator;
00149             typedef typename alias_map_type::const_iterator const_iterator;
00150 
00151             /** Begin iterator for aliases(). */
00152             iterator begin() { return this->m_map.begin(); }
00153             /** Begin const_iterator for aliases(). */
00154             const_iterator begin() const { return this->m_map.begin(); }
00155 
00156             /** End iterator for aliases(). */
00157             iterator end() { return this->m_map.end(); }
00158             /** End const_iterator for aliases(). */
00159             const_iterator end() const { return this->m_map.end(); }
00160 
00161             /**
00162                Expands the given alias recursively. If a circular
00163                alias is detected, the last expansion is returned
00164                (i.e., same as _alias). If no expansion is found
00165                then _alias is returned.
00166             */
00167             value_type expand( const key_type & _alias ) const
00168             {
00169                 typename alias_map_type::const_iterator cit = this->m_map.find( _alias ),
00170                     cet = this->m_map.end();
00171                 if( cet == cit )
00172                 {
00173                     return _alias;
00174                 }
00175                 value_type exp = (*cit).second;
00176                 while( 1 )
00177                 {
00178                     cit = this->m_map.find( exp );
00179                     if( cet == cit )
00180                     {
00181                         return exp;
00182                     }
00183                     exp = (*cit).second;
00184                     if( exp == _alias )
00185                     { // circular aliasing
00186                         return exp;
00187                     }
00188                 }
00189                 return exp;
00190             }
00191         private:
00192             alias_map_type m_map;
00193 
00194         };
00195 
00196         /**
00197            The factory_mgr class is essentially a static classloader,
00198            capable of loading classes by using registered factories
00199            for a given set of keys (e.g., class names).
00200 
00201            Classloaders, at least in my experience, need to be able to
00202            load all classes which derive from some given type. Without
00203            a common base class, one can't safely attempt to cast from
00204            an arbitrary pointer to the type we want to load. That's
00205            where the InterfaceT parameter comes in. All objects
00206            instantiated via this loader must inherit (be-a) from
00207            InterfaceT, or must literally be InterfaceT.
00208 
00209            KeyType is a type which specifies the type of key used to
00210            look up classes, defaulting to std::string.
00211 
00212            For this implementation, both InterfaceT and
00213            KeyType must be Default Constructable, and
00214            InterfaceT must be constructable on the heap (e.g.,
00215            via new InterfaceT()).
00216 
00217            InterfaceT must be a "plain type", without any
00218            pointer, reference or const qualifications.
00219 
00220            Sample usage:
00221 
00222            <pre>
00223            factory_mgr<MyInterface> & fac = factory_mgr<MyInterface>::instance();
00224            fac.register_factory( "my_key", s11n::fac::create_hook<MyInterface,MyClass>::create );
00225            MyInterface *foo = fac.create( "some_key" ); // == NULL
00226            foo = fac.create( "my_key" ); // == a new MyClass object
00227            </pre>
00228 
00229            Note that all instances of factory_mgr share the
00230            same factories and aliases maps. This is a design
00231            decision which is intended to simplify usage of the
00232            type and ensure consistency of state across module
00233            boundaries. In effect, the default implementation
00234            is a Monostate type, which each instance sharing
00235            the same data.
00236 
00237            Trivia: above i mentioned "casting", but this
00238            implementation requires no casting of any type,
00239            neither in the library nor in client code (unless
00240            the client explicitely needs to do so for their own
00241            purposes).
00242         */
00243         template < class InterfaceT,
00244                class KeyType = std::string >
00245         class S11N_EXPORT_API factory_mgr
00246         {
00247         public:
00248 
00249             /**
00250                A typedef for the KeyType used by this class.
00251             */
00252             typedef KeyType key_type;
00253 
00254             /**
00255                A typedef for the InterfaceT used by this class.
00256                For conformance with the Adaptable Unary Functor
00257                model
00258             */
00259             typedef InterfaceT value_type;
00260             /**
00261                Same as (InterfaceT *).
00262             */
00263             typedef InterfaceT * result_type;
00264 
00265 
00266             /**
00267                The type of factories used by this class: a
00268                function taking void and returning (value_type
00269                *). See factory_map().
00270 
00271                todo: implement proper functor support.
00272             */
00273             typedef result_type ( *factory_function_type ) ();
00274 
00275             /**
00276                Internal container type used for mapping keys to
00277                factories.
00278             */
00279             typedef std::map < key_type, factory_function_type > factory_map_type;
00280 
00281             /**
00282                A type used to map classname aliases for
00283                this factory manager.
00284             */
00285             typedef aliaser<key_type> aliaser_type;
00286 
00287         private:
00288             /** Internal marker type. */
00289             struct context { };
00290         protected:
00291 
00292             /**
00293                Returns the internal key-to-factory map. It is safe
00294                for clients to modify this except in multi-threaded
00295                environments, and then all guarantees go out the
00296                window. That said, it should never be necessary for
00297                clients to use this.
00298 
00299                The default implementation returns the same map for
00300                all instances of factory_mgr.  The reasoning behind
00301                using static factory maps is essentially this: we
00302                can only have one definition of each type. We
00303                normally want factories to always return an
00304                instance constructed in the same way. If we allow
00305                multiple factories per type we might introduce
00306                hard-to-track inconsistencies in client code, where
00307                different factories than intended are accidentally
00308                used. OTOH, private factory maps would open up some
00309                interesting possibilities.
00310 
00311                TODO (well, to consider): use a hook or
00312                Traits type to allow the user to replace
00313                this object with his own, so that he can
00314                control the scope of the map more
00315                fully. Overkill. YAGNI. Christian
00316                Prochnow's experience in the P::Classes
00317                tree suggests that that would be Bad,
00318                anyway, because clients linking from
00319                different sources can end up with different
00320                instances of the map. This has never been
00321                witnessed using phoenix<> to share
00322                instances, however.
00323             */
00324             factory_map_type & factory_map()
00325             {
00326                 return ::s11n::Detail::phoenix<factory_map_type, factory_mgr>::instance();
00327             }
00328 
00329             /** Const overload. */
00330             const factory_map_type & factory_map() const
00331             {
00332                 return ::s11n::Detail::phoenix<factory_map_type, factory_mgr>::instance();
00333             }
00334 
00335             /**
00336                Returns the container of classname
00337                aliases. In this implementation the aliases
00338                are shared amongst all instances of
00339                this type, because that aligns it with the
00340                shared factory map.
00341 
00342                Access to this object is not locked,
00343                so clients using multiple threads and
00344                factories should not call this if they're
00345                worried about the alias list changing while
00346                they're using it.
00347             */
00348             aliaser_type & aliases()
00349             {
00350                 return ::s11n::Detail::phoenix<aliaser_type,factory_mgr>::instance();
00351             }
00352 
00353         public:
00354 
00355 
00356             factory_mgr() {}
00357 
00358             virtual ~factory_mgr() throw() {}
00359 
00360 
00361             /**
00362                Tries to instantiate an instance of value_type
00363                using the given key. Returns 0 if no object
00364                could be loaded for the given key.
00365 
00366                Subtypes are free to implement, e.g., DLL lookups.
00367 
00368                This implementation calls aliases().expand(_key) to
00369                expand any aliased class
00370                names. Subclasses/specializations "should" do the
00371                same, but are not strictly required to.
00372             */
00373             virtual result_type create( const key_type & _key )
00374             {
00375                 factory_function_type func = 0;
00376                 key_type key = this->aliases().expand( _key );
00377                 typename factory_map_type::const_iterator it = factory_map().find( key );
00378                 if ( it != factory_map().end() )    // found a factory?
00379                 {
00380                     func = it->second;
00381                 }
00382                 return (0 == func)
00383                     ? 0
00384                     : func();
00385             }
00386 
00387 
00388             /**
00389                Returns create(key).
00390             */
00391             result_type operator()( const key_type & key )
00392             {
00393                 return this->create( key );
00394             }
00395 
00396             /**
00397                Simply calls delete obj. Subclasses are
00398                free to do custom accounting, garbage
00399                collection, or whatever, by overriding
00400                this.
00401 
00402                Note that it is NOT practical to expect all clients
00403                to call this in order to destroy their objects, so
00404                the utility of this function is HIGHLY arguable.
00405 
00406                Also be aware that the simple delete
00407                behaviour is not suitable if InterfaceT is
00408                a populated container of dumb pointers, or
00409                otherwise contains unowned pointers.
00410 
00411                Subclasses are free to "suggest" a
00412                must-destroy() policy if they wish, but
00413                cannot expect anyone to actually follow
00414                that wish. In pedantic terms, however, one
00415                should destroy an object from the same code
00416                module and thread which created it, to
00417                avoid low-level problems involving crossing
00418                module/thread boundaries. That's what
00419                Sutter and Alexandrescu say, anyway, and
00420                i'm not one to argue with them.
00421             */
00422             virtual void destroy( result_type obj )
00423             {
00424                 delete obj;
00425             }
00426 
00427 
00428             /**
00429                Registers a factory using the given
00430                key. Note that fp may not be declared as
00431                returning a type other than (value_type *),
00432                but the actual object it creates may be a
00433                polymorphic subclass of value_type. See the
00434                create_hook class for a factory which does
00435                this subtype-to-base conversion.
00436 
00437                For ABSTRACT interface types, you "should"
00438                register a no-op factory which simply
00439                returns 0.  The difference between
00440                registering a no-op factory and registering
00441                NO factory is that when create() is called,
00442                if NO factory is found, this type is free
00443                to implement extra logic like DLL lookups
00444                to try to find the type (which is futile
00445                for an abstract type). However, if it has a
00446                registered factory, such lookups will not
00447                be done (this code doesn't care if the
00448                factory returns 0 or not).
00449 
00450                Subclasses are free to add behaviour, like
00451                instrumentation, but should not forget to
00452                actually carry through on the registration
00453                part (e.g., by calling this
00454                implementation).
00455             */
00456             virtual void register_factory( const key_type & key, factory_function_type fp )
00457             {
00458                 // CERR << "register_factory("<<key<<",facfunc)\n";
00459                 // ^^^ i keep that around for when i'm trying to figure out whether a DLL
00460                 // is actually registering itself.
00461                 factory_map().insert( typename factory_map_type::value_type( key, fp ) );
00462             }
00463 
00464 
00465             /**
00466                Returns true if the given key is registered
00467                (alias expansions are considered). This is
00468                sometimes useful for checking whether a
00469                factory needs to be re-registered, which is
00470                sometimes necessary post-main(), when the
00471                internal map gets hosed before clients are
00472                done using it.
00473 
00474                The constness is arguable:
00475                subclasses/specializations could arguably
00476                do pre-lookups for DLLs (or similar) here,
00477                and might need non-const behaviour. As a
00478                consolation, we have made create()
00479                non-const, so (provides()==false) can
00480                symantically mean "we need to do a DLL
00481                lookup".
00482             */
00483             virtual bool provides( const key_type & key ) const
00484             {
00485                 return factory_map().end() != factory_map().find( this->aliases().expand(key) );
00486             }
00487 
00488             /**
00489                Returns a shared reference to a factory.
00490 
00491                The s11n core always calls this function to get factory
00492                instances.
00493             */
00494             static factory_mgr & instance()
00495             {
00496                 // return ::s11n::fac::instance_hook<factory_mgr>::instance();
00497                 // ^^^ Christian Prochnow reports that this approach can cause
00498                 // multiple objects to be created across DLLs, which is something
00499                 // we definately don't want to happen!
00500                 return ::s11n::Detail::phoenix<factory_mgr>::instance();
00501             }
00502 
00503             /**
00504                Const overload. See the non-const variant for
00505                information about threading.
00506 
00507                The ONLY reason that this function is in
00508                the public API is so that
00509                s11n::io::serializer_list() can fetch the
00510                list of alias names. Don't rely on this
00511                function remaining public!
00512             */
00513             const aliaser_type & aliases() const
00514             {
00515                 return ::s11n::Detail::phoenix<aliaser_type,factory_mgr>::instance();
00516             }
00517 
00518             /**
00519                Aliases Alias to be the same as Real, such that create(Alias)
00520                and create(Real) are functionally identical.
00521 
00522                A tip for remembering the order of the arguments:
00523                it follows the same order as when assigning an alias
00524                via a Unix shell: alias thealias="the original string"
00525             */
00526             void alias( std::string const & Alias, std::string const & Real )
00527             {
00528                 this->aliases().alias( Alias, Real );
00529             }
00530 
00531         }; // class factory_mgr
00532 
00533         /**
00534            Returns factory_mgr<InterfaceT, std::string>::instance().
00535 
00536            All s11n-internal factory_mgr operations operate on
00537            one of these objects.
00538         */
00539         template <typename InterfaceT>
00540         inline factory_mgr<InterfaceT, std::string> &
00541         factory()
00542         {
00543             return factory_mgr<InterfaceT,
00544                 std::string
00545                 >::instance();
00546         }
00547 
00548         /**
00549            Registers classname with InterfaceT using the given factory.
00550         */
00551         template <typename InterfaceT>
00552         inline void register_factory( const std::string & classname, InterfaceT *(*factory_function)() )
00553         {
00554             factory<InterfaceT>().register_factory( classname, factory_function );
00555         }
00556 
00557         /**
00558            Registers classname with InterfaceT using a default
00559            factory: create_hook<InterfaceT,ImplT>::create().
00560 
00561            If ImplT is abstract then this function will fail
00562            unless create_hook is specialized to not create an
00563            object.
00564         */
00565         template <typename InterfaceT>
00566         inline void register_factory( const std::string & classname )
00567         {
00568             factory<InterfaceT>().register_factory( classname, create_hook<InterfaceT,InterfaceT>::create );
00569         }
00570 
00571         /**
00572            Registers a factory creating ImplT objects with the
00573            InterfaceT classloader using a default factory.
00574            ImplT may not be abstract unless
00575            create_hook<InterfaceT,ImplT> is specialized such
00576            that its create() function simply returns 0 (or
00577            otherwise does not call: new ImplT).
00578         */
00579         template <typename InterfaceT, typename ImplT>
00580         inline void register_subtype( const std::string & classname )
00581         {
00582             factory<InterfaceT>().register_factory( classname, create_hook<InterfaceT,ImplT>::create );
00583         }
00584 
00585         namespace Detail {
00586             /**
00587                Always returns 0. Intended for use as a
00588                factory for abstract types.
00589             */
00590             template <typename T>
00591             inline T * null_factory()
00592             {
00593                 return 0;
00594             }
00595         }
00596 
00597         /**
00598            Registers a no-op factory for the given name and
00599            InterfaceT. The factory will always return 0.
00600         */
00601         template <typename InterfaceT>
00602         void register_abstract( const std::string & classname )
00603         {
00604             factory<InterfaceT>().register_factory( classname, Detail::null_factory<InterfaceT> );
00605             // ^^^ compiler bug? If i fully qualify ::s11n::Detail::null_factory<...>
00606             // i get a parse error
00607         }
00608 
00609     
00610         /**
00611            Returns the same as factory<InterfaceT>().create( classname ).
00612         */
00613         template <typename InterfaceT>
00614         inline InterfaceT * create( const std::string & classname )
00615         {
00616             return factory<InterfaceT>().create( classname );
00617         }
00618 
00619         /**
00620            Same as factory<InterfaceT>().alias(Alias,Real).
00621         */
00622         template <typename InterfaceT>
00623         inline void alias( std::string const & Alias, const std::string & Real )
00624         {
00625             return factory<InterfaceT>().alias( Alias, Real );
00626         }
00627 
00628     } // namespace fac
00629 
00630 } // namespace s11n
00631 
00632 #endif // s11n_net_s11n_FACTORY_H_INCLUDED

Generated on Wed Jun 4 21:44:19 2008 for libs11n by  doxygen 1.5.3