#ifndef s11n_cl_S11N_CLASSLOAD_HPP_INCLUDED #define s11n_cl_S11N_CLASSLOAD_HPP_INCLUDED 1 #include // S11N_TRACE() #include namespace s11n { /** The s11n::cl namespace encapsulates the public classloader-related API for libs11n. Note that the registration functions in this namespace register with the s11n::fac family of classes. Clients wishing to use their own factories should: - register with their appropriate classloader. - specialize the object_factory class template so that it forwards calls to their classloader. This layer is used for classloading anything which s11n needs to dynamically load, including: - Serializables - Serializers - FlexLexers It supports loading types via DLLs if the optional s11n::plugin layer is enabled. Changes from 1.0.x to 1.1.x: - Now internally uses s11n::factory_mgr and s11n::plugin instead of the cllite API. Changed in 1.2.2: - operator() implementation code was moved to classload.tpp. */ namespace cl { /** A default object factory functor for use with the s11n::s11n_traits type. Clients may specialize this to return objects from their own factories. By default it uses s11n::fac's mini-framework, and thus can load any type registered with that API. */ template struct S11N_EXPORT_API object_factory { /** Same as InterfaceBase. */ typedef InterfaceBase base_type; /** The default implementation returns ::s11n::fac::factory().create(key). The caller owns the returned pointer, which may be 0. If the underlying factory does not have the requested class and s11n is built with the s11n::plugin layer, then s11n::plugin::open(classname) is used to search for a DLL. Under the s11n classloader model, opening a plugin will register classes defined in the plugin back with the factory. This function propagates exceptions if the underlying factory's create() feature throws. a) s11n_exceptions are passed on as-is. b) std::exceptions are translated to s11n::factory_exceptions, keeping the what() text. c) Unknown exceptions (...) are translated to s11n::factory_exceptions with an unspecified non-empty what() text. */ base_type * operator()( const std::string & key ) const; }; /** Returns object_factory(key). */ template InterfaceBase * classload( const std::string key ); /** Registers a factory with InterfaceBase's classloader. Trivia: 'register' is a reserved word in C++, inherited from C, so this function has an unduly long name. register() was the first choice. */ template void classloader_register( const std::string & classname, InterfaceBase * (*factory_func)() ); /** Registers a default factory which returns a SubType object. SubType must be a public subtype of InterfaceBase, or must be InterfaceBase, and must not be abstract. */ template inline void classloader_register_subtype( const std::string & classname ) { classloader_register( classname, ::s11n::fac::create_hook::create ); } /** Registers InterfaceBase with its own classloader using a default factory. InterfaceBase must be creatable with 'new', or the default factory implementation must be specialized to accomodate the abstract class. */ template inline void classloader_register_base( const std::string & classname ) { classloader_register_subtype( classname ); } namespace Detail { /** Internal no-op factory. Always returns 0. */ template inline T * noop_factory() { return 0; } } /** Registers InterfaceBase as an abstract type. That is, it assigns it a factory which always returns 0. If types you register with classloader_register() (and friends) have an abstract InterfaceBase then that InterfaceBase should be registered via this function (or equivalent). Note that this is also suitable for registering abstract subtypes of an abstract type, but InterfaceBase MUST be the type passed here (not the subtype's type), or the registrations will go to the subtype's classloader, which normally isn't what you want to do. */ template inline void classloader_register_abstract( const std::string & classname ) { classloader_register( classname, Detail::noop_factory ); } /** Aliases the given classname with the underlying factory layer, such that classload(_alias) will return the same as classload(classname). A tip for remembering the order of the arguments: it follows the same order as when assigning an alias via a Unix shell: alias thealias="the original string" Added in 1.1.0. Maintenance reminder: this function relies directly on the s11n::fac API, which isn't "really" public. This functionality is commonly useful when hand-registering types, thus we have a public-API wrapper around this fac-layer-specific feature. */ template inline void classloader_alias( const std::string & _alias, const std::string & classname) { ::s11n::fac::factory().aliases().alias( _alias, classname ); } } // namespace cl } // namespace s11n #include // implementations #endif // s11n_cl_S11N_CLASSLOAD_HPP_INCLUDED