1 #ifndef s11n_net_s11n_FACTORY_H_INCLUDED 2 #define s11n_net_s11n_FACTORY_H_INCLUDED 1 3 // Author: stephan beal <stephan@s11n.net> 4 // Various parts between 2003 and 2005. 5 // License: Public Domain 6 7 #include <string> 8 #include <map> 9 10 #include <functional> 11 12 #include <s11n.net/s11n/export.hpp> 13 #include <s11n.net/s11n/phoenix.hpp> // i don't like this dep, but i also don't like 14 // what happens in some cases when i don't use 15 // phoenix. :/ 16 17 namespace s11n { 18 19 namespace sharing { 20 /** 21 Internal marker type. 22 */ 23 struct factory_context {}; 24 } 25 26 /** 27 The s11n::fac namespace contains s11n's "private" object 28 factory manager. This code should not be considered to be 29 part of the public APIs: use the s11n::cl API for your 30 factory-related needs unless absolutely 31 necessary. Unfortunately, classloading can be intrusive 32 enough that this API might sometimes need to be leaked into 33 client- or non-core library code. The example which 34 immediately comes to mind is clients which want to get a 35 list of all registered factories: this can only be done by 36 querying the factory itself for them. 37 38 The factory manager layer acts as a registration point for 39 factories for near-arbitrary classes. Classes compatible 40 with this layer must currently meet the following requirements: 41 42 - DefaultConstructable. 43 44 - Must register with this layer. In s11n, this is done as 45 part of the normal s11n registration process. Clients 46 needing to manually register types should use the s11n::cl 47 class registering/loading API. 48 49 - Must be legal: delete instanceOfObject; This is really a 50 usage convention, and not a hard/fast rule of this type. 51 */ 52 namespace fac { 53 54 /** 55 create_hook is a helper object factory for the factory_mgr 56 API. It is used by that type to create instances of specific types. 57 It may be specialized to provide non-default object construction. 58 59 General conventions: 60 61 SubT must derive from (or be) T and must be Default 62 Constructuable on the heap. In short, the following must be 63 able to succeed: 64 65 <pre> 66 T * foo = new SubT; 67 </pre> 68 69 Clients may freely specialize this type to hook their 70 factories in, and the above 'new' requirement need 71 not be imposed by client-side specializations. For example, 72 specializations are used to provide no-op factories for 73 abstract types, where 'new T' cannot work. 74 */ 75 76 template < class T, class SubT > 77 struct S11N_EXPORT_API create_hook 78 { 79 /** 80 The type returned by create() and 81 operator(). 82 */ 83 typedef T * result_type; 84 85 /** 86 A typedef for the second template parameter for this 87 type. 88 */ 89 typedef SubT actual_type; 90 91 /** 92 This creates a new SubT, which is assumed to be a 93 subclass of T. It can be used as a factory for 94 factory & class_loader. 95 96 If T or SubT are abstract types, you must 97 specialize this type such that create() returns 0 98 for those. That is, we "simulate" creation of 99 abstract types by returning 0. 100 101 The caller owns the returned pointer, which 102 may be 0. 103 */ creates11n::fac::create_hook104 static result_type create() 105 { 106 return new actual_type; 107 } 108 109 /** 110 Same as create(). 111 */ operator ()s11n::fac::create_hook112 result_type operator()() const 113 { 114 return this->create(); 115 } 116 }; 117 118 119 /** 120 A helper class to alias one token to another. 121 122 AliasedType requires: 123 124 - Must be suitable for use as both key and value 125 types for a std::map, with all that that implies 126 (e.g., operator<() must be well-behaved). 127 128 */ 129 template <typename AliasedType> 130 class S11N_EXPORT_API aliaser 131 { 132 public: 133 typedef AliasedType key_type; 134 typedef AliasedType value_type; 135 /** 136 A map type for storing lookup key aliases. 137 */ 138 typedef std::map<key_type,value_type> alias_map_type; 139 140 /** 141 Aliases 'alias' as an equivalent of 'isthesameas'. 142 */ alias(const key_type & alias,const value_type & isthesameas)143 void alias( const key_type & alias, const value_type & isthesameas ) 144 { 145 this->aliases()[alias] = isthesameas; 146 } 147 148 /** 149 Returns the map of aliases. 150 */ aliases()151 alias_map_type & aliases() { return this->m_map; } 152 153 /** Const overload. */ aliases() const154 const alias_map_type & aliases() const { return this->m_map; } 155 156 typedef typename alias_map_type::iterator iterator; 157 typedef typename alias_map_type::const_iterator const_iterator; 158 159 /** Begin iterator for aliases(). */ begin()160 iterator begin() { return this->m_map.begin(); } 161 /** Begin const_iterator for aliases(). */ begin() const162 const_iterator begin() const { return this->m_map.begin(); } 163 164 /** End iterator for aliases(). */ end()165 iterator end() { return this->m_map.end(); } 166 /** End const_iterator for aliases(). */ end() const167 const_iterator end() const { return this->m_map.end(); } 168 169 /** 170 Expands the given alias recursively. If a circular 171 alias is detected, the last expansion is returned 172 (i.e., same as _alias). If no expansion is found 173 then _alias is returned. 174 */ expand(const key_type & _alias) const175 value_type expand( const key_type & _alias ) const 176 { 177 typename alias_map_type::const_iterator cit = this->m_map.find( _alias ), 178 cet = this->m_map.end(); 179 if( cet == cit ) 180 { 181 return _alias; 182 } 183 value_type exp = (*cit).second; 184 while( 1 ) 185 { 186 cit = this->m_map.find( exp ); 187 if( cet == cit ) 188 { 189 return exp; 190 } 191 exp = (*cit).second; 192 if( exp == _alias ) 193 { // circular aliasing 194 return exp; 195 } 196 } 197 return exp; 198 } 199 private: 200 alias_map_type m_map; 201 202 }; 203 204 /** 205 The factory_mgr class is essentially a static classloader, 206 capable of loading classes by using registered factories 207 for a given set of keys (e.g., class names). 208 209 Classloaders, at least in my experience, need to be able to 210 load all classes which derive from some given type. Without 211 a common base class, one can't safely attempt to cast from 212 an arbitrary pointer to the type we want to load. That's 213 where the InterfaceT parameter comes in. All objects 214 instantiated via this loader must inherit (be-a) from 215 InterfaceT, or must literally be InterfaceT. 216 217 KeyType is a type which specifies the type of key used to 218 look up classes, defaulting to std::string. 219 220 For this implementation, both InterfaceT and 221 KeyType must be Default Constructable, and 222 InterfaceT must be constructable on the heap (e.g., 223 via new InterfaceT()). 224 225 InterfaceT must be a "plain type", without any 226 pointer, reference or const qualifications. 227 228 Sample usage: 229 230 <pre> 231 factory_mgr<MyInterface> & fac = factory_mgr<MyInterface>::instance(); 232 fac.register_factory( "my_key", s11n::fac::create_hook<MyInterface,MyClass>::create ); 233 MyInterface *foo = fac.create( "some_key" ); // == NULL 234 foo = fac.create( "my_key" ); // == a new MyClass object 235 </pre> 236 237 Note that all instances of factory_mgr share the 238 same factories and aliases maps. This is a design 239 decision which is intended to simplify usage of the 240 type and ensure consistency of state across module 241 boundaries. In effect, the default implementation 242 is a Monostate type, which each instance sharing 243 the same data. 244 245 Trivia: above i mentioned "casting", but this 246 implementation requires no casting of any type, 247 neither in the library nor in client code (unless 248 the client explicitely needs to do so for their own 249 purposes). 250 */ 251 template < class InterfaceT, 252 class KeyType = std::string > 253 class S11N_EXPORT_API factory_mgr 254 { 255 private: 256 /** 257 Convenience typedef. 258 */ 259 typedef factory_mgr< InterfaceT, KeyType > ThisType; 260 public: 261 262 /** 263 A typedef for the KeyType used by this class. 264 */ 265 typedef KeyType key_type; 266 267 /** 268 A typedef for the InterfaceT used by this class. 269 For conformance with the Adaptable Unary Functor 270 model 271 */ 272 typedef InterfaceT value_type; 273 /** 274 Same as (InterfaceT *). 275 */ 276 typedef InterfaceT * result_type; 277 278 factory_mgr()279 factory_mgr() {} 280 ~factory_mgr()281 virtual ~factory_mgr() throw() {} 282 283 /** 284 A type used to map classname aliases for 285 this factory manager. 286 */ 287 typedef aliaser<key_type> aliaser_type; 288 /** 289 The type of factories used by this class: a 290 function taking void and returning (value_type 291 *). See factory_map(). 292 293 todo: implement proper functor support. 294 */ 295 typedef result_type ( *factory_function_type ) (); 296 297 /** 298 Internal container type used for mapping keys to 299 factories. 300 */ 301 typedef std::map < key_type, factory_function_type > factory_map_type; 302 303 304 /** 305 Returns the container of classname 306 aliases. In this implementation the aliases 307 are shared amongst all instances of 308 this type, because that aligns it with the 309 shared factory map. 310 */ aliases()311 aliaser_type & aliases() 312 { 313 return ::s11n::Detail::phoenix<aliaser_type, ThisType>::instance(); 314 } 315 316 /** 317 Const overload. 318 */ aliases() const319 const aliaser_type & aliases() const 320 { 321 return ::s11n::Detail::phoenix<aliaser_type, ThisType>::instance(); 322 } 323 324 325 /** 326 Tries to instantiate an instance of value_type 327 using the given key. Returns 0 if no object 328 could be loaded for the given key. 329 330 Subtypes are free to implement, e.g., DLL lookups. 331 332 This implementation calls aliases().expand(_key) to 333 expand any aliased class 334 names. Subclasses/specializations "should" do the 335 same, but are not strictly required to. 336 */ create(const key_type & _key)337 virtual result_type create( const key_type & _key ) 338 { 339 key_type key = this->aliases().expand( _key ); 340 typename factory_map_type::const_iterator it = factory_map().find( key ); 341 if ( it != factory_map().end() ) // found a factory? 342 { 343 return ( it->second ) (); // run our factory. 344 } 345 return 0; 346 } 347 348 349 /** 350 Returns create(key). 351 */ operator ()(const key_type & key)352 result_type operator()( const key_type & key ) 353 { 354 return this->create( key ); 355 } 356 357 /** 358 Simply calls delete obj. Subclasses are 359 free to do custom accounting, garbage 360 collection, or whatever, by overriding 361 this. 362 363 Note that it is NOT practical to expect all clients 364 to call this in order to destroy their objects, so 365 the utility of this function is HIGHLY arguable. 366 367 Also be aware that the simple delete 368 behaviour is not suitable if InterfaceT is 369 a populated container of dumb pointers, or 370 otherwise contains unowned pointers. 371 372 Subclasses are free to "suggest" a 373 must-destroy() policy if they wish, but 374 cannot expect anyone to actually follow 375 that wish. In pedantic terms, however, one 376 should destroy an object from the same code 377 module and thread which created it, to 378 avoid low-level problems involving crossing 379 module/thread boundaries. That's what 380 Sutter and Alexandrescu say, anyway, and 381 i'm not one to argue with them. 382 */ destroy(result_type obj)383 virtual void destroy( result_type obj ) 384 { 385 delete obj; 386 } 387 388 389 /** 390 Registers a factory using the given 391 key. Note that fp may not be declared as 392 returning a type other than (value_type *), 393 but the actual object it creates may be a 394 polymorphic subclass of value_type. See the 395 create_hook class for a factory which does 396 this subtype-to-base conversion. 397 398 For ABSTRACT interface types, you "should" 399 register a no-op factory which simply 400 returns 0. The difference between 401 registering a no-op factory and registering 402 NO factory is that when create() is called, 403 if NO factory is found, this type is free 404 to implement extra logic like DLL lookups 405 to try to find the type (which is futile 406 for an abstract type). However, if it has a 407 registered factory, it will not do this (it 408 doesn't care if the factory returns 0 or 409 not). 410 411 Subclasses are free to add behaviour, like 412 instrumentation, but should not forget to 413 actually carry through on the registration 414 part (e.g., by calling this 415 implementation). 416 */ register_factory(const key_type & key,factory_function_type fp)417 virtual void register_factory( const key_type & key, factory_function_type fp ) 418 { 419 // CERR << "register_factory("<<key<<",facfunc)\n"; 420 // ^^^ i keep that around for when i'm trying to figure out whether a DLL 421 // is actually registering itself. 422 factory_map().insert( typename factory_map_type::value_type( key, fp ) ); 423 } 424 425 /** 426 Returns the internal key-to-factory map. It is safe 427 for clients to modify this except in multi-threaded 428 environments, and then all guarantees go out the 429 window. That said, it should never be necessary for 430 clients to use this. 431 432 The default implementation returns the same map for 433 all instances of ThisType. The reasoning behind 434 using static factory maps is essentially this: we 435 can only have one definition of each type. We 436 normally want factories to always return an 437 instance constructed in the same way. If we allow 438 multiple factories per type we might introduce 439 hard-to-track inconsistencies in client code, where 440 different factories than intended are accidentally 441 used. OTOH, private factory maps would open up some 442 interesting possibilities. 443 444 TODO (well, to consider): use a hook or 445 Traits type to allow the user to replace 446 this object with his own, so that he can 447 control the scope of the map more 448 fully. Overkill. YAGNI. Christian 449 Prochnow's experience in the P::Classes 450 tree suggests that that would be Bad, 451 anyway, because clients linking from 452 different sources can end up with different 453 instances of the map. This has never been 454 witnessed using phoenix<> to share 455 instances, however. 456 */ factory_map()457 factory_map_type & factory_map() 458 { 459 return ::s11n::Detail::phoenix<factory_map_type, ThisType>::instance(); 460 } 461 462 /** Const overload. */ factory_map() const463 const factory_map_type & factory_map() const 464 { 465 return ::s11n::Detail::phoenix<factory_map_type, ThisType>::instance(); 466 } 467 468 /** 469 Returns true if the given key is registered 470 (alias expansions are considered). This is 471 sometimes useful for checking whether a 472 factory needs to be re-registered, which is 473 sometimes necessary post-main(), when the 474 internal map gets hosed before clients are 475 done using it. 476 477 The constness is arguable: 478 subclasses/specializations could arguably 479 do pre-lookups for DLLs (or similar) here, 480 and might need non-const behaviour. As a 481 consolation, we have made create() 482 non-const, so (provides()==false) can 483 symantically mean "we need to do a DLL 484 lookup". 485 */ provides(const key_type & key) const486 virtual bool provides( const key_type & key ) const 487 { 488 return factory_map().end() != factory_map().find( this->aliases().expand(key) ); 489 } 490 491 /** 492 Returns a shared reference to a factory. 493 494 The s11n core always calls this function to get factory 495 instances. 496 */ instance()497 static factory_mgr & instance() 498 { 499 // return ::s11n::fac::instance_hook<ThisType>::instance(); 500 // ^^^ Christian Prochnow reports that this approach can cause 501 // multiple objects to be created across DLLs, which is something 502 // we definately don't want to happen! 503 return ::s11n::Detail::phoenix<ThisType>::instance(); 504 } 505 506 }; // class factory_mgr 507 508 509 /** 510 Returns factory_mgr<InterfaceT, std::string>::instance(). 511 512 All s11n-internal factory_mgr operations operate on 513 one of these objects. 514 */ 515 template <typename InterfaceT> 516 inline factory_mgr<InterfaceT, std::string> & factory()517 factory() 518 { 519 return factory_mgr<InterfaceT, 520 std::string 521 >::instance(); 522 } 523 524 /** 525 Registers classname with InterfaceT using the given factory. 526 */ 527 template <typename InterfaceT> register_factory(const std::string & classname,InterfaceT * (* factory_function)())528 inline void register_factory( const std::string & classname, InterfaceT *(*factory_function)() ) 529 { 530 factory<InterfaceT>().register_factory( classname, factory_function ); 531 } 532 533 /** 534 Registers classname with InterfaceT using a default 535 factory: create_hook<InterfaceT,ImplT>::create(). 536 537 If ImplT is abstract then this function will fail 538 unless create_hook is specialized to not create an 539 object. 540 */ 541 template <typename InterfaceT> register_factory(const std::string & classname)542 inline void register_factory( const std::string & classname ) 543 { 544 factory<InterfaceT>().register_factory( classname, create_hook<InterfaceT,InterfaceT>::create ); 545 } 546 547 /** 548 Registers a factory creating ImplT objects with the 549 InterfaceT classloader using a default factory. 550 ImplT may not be abstract unless 551 create_hook<InterfaceT,ImplT> is specialized such 552 that it's create() function simply returns 0 (or 553 otherwise does not call: new ImplT). 554 */ 555 template <typename InterfaceT, typename ImplT> register_subtype(const std::string & classname)556 inline void register_subtype( const std::string & classname ) 557 { 558 factory<InterfaceT>().register_factory( classname, create_hook<InterfaceT,ImplT>::create ); 559 } 560 561 namespace Detail { 562 /** 563 Always returns 0. Intended for use as a 564 factory for abstract types. 565 */ 566 template <typename T> null_factory()567 inline T * null_factory() 568 { 569 return 0; 570 } 571 } 572 573 /** 574 Registers a no-op factory for the given name and 575 InterfaceT. The factory will always return 0. 576 */ 577 template <typename InterfaceT> register_abstract(const std::string & classname)578 void register_abstract( const std::string & classname ) 579 { 580 factory<InterfaceT>().register_factory( classname, Detail::null_factory<InterfaceT> ); 581 // ^^^ compiler bug? If i fully qualify ::s11n::Detail::null_factory<...> 582 // i get a parse error 583 } 584 585 586 /** 587 Returns the same as factory<InterfaceT>().create( classname ). 588 */ 589 template <typename InterfaceT> create(const std::string & classname)590 inline InterfaceT * create( const std::string & classname ) 591 { 592 return factory<InterfaceT>().create( classname ); 593 } 594 595 } // namespace fac 596 597 } // namespace s11n 598 599 #endif // s11n_net_s11n_FACTORY_H_INCLUDED 600