Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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

Generated on Sun Dec 25 20:26:11 2005 for libs11n-1.2.3 by  doxygen 1.4.4