1 //////////////////////////////////////////////////////////////////////////////// 2 // The Loki Library 3 // Copyright (c) 2001 by Andrei Alexandrescu 4 // Copyright (c) 2005 by Peter Kuemmel 5 // This code DOES NOT accompany the book: 6 // Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 7 // Patterns Applied". Copyright (c) 2001. Addison-Wesley. 8 // 9 // Code covered by the MIT License 10 // The authors make no representations about the suitability of this software 11 // for any purpose. It is provided "as is" without express or implied warranty. 12 //////////////////////////////////////////////////////////////////////////////// 13 #ifndef LOKI_FACTORYPARM_INC_ 14 #define LOKI_FACTORYPARM_INC_ 15 16 // $Id: Factory.h 788 2006-11-24 22:30:54Z clitte_bbt $ 17 18 19 #include "LokiTypeInfo.h" 20 #include "Functor.h" 21 #include "AssocVector.h" 22 #include "SmallObj.h" 23 #include "Sequence.h" 24 25 #ifdef _MSC_VER 26 #pragma warning(push) 27 #pragma warning(disable: 4702) 28 //unreachable code if OnUnknownType throws an exception 29 #endif 30 31 /** 32 * \defgroup FactoriesGroup Factories 33 * \defgroup FactoryGroup Factory 34 * \ingroup FactoriesGroup 35 * \brief Implements a generic object factory. 36 * 37 * <i>The Factory Method pattern is an object-oriented design pattern. 38 * Like other creational patterns, it deals with the problem of creating objects 39 * (products) without specifying the exact class of object that will be created. 40 * Factory Method, one of the patterns from the Design Patterns book, handles 41 * this problem by defining a separate method for creating the objects, which 42 * subclasses can then override to specify the derived type of product that will 43 * be created. 44 * <br> 45 * More generally, the term Factory Method is often used to refer to any method 46 * whose main purpose is creation of objects.</i> 47 * <div ALIGN="RIGHT"><a href="http://en.wikipedia.org/wiki/Factory_method_pattern"> 48 * Wikipedia</a></div> 49 * 50 * Loki proposes a generic version of the Factory. Here is a typical use.<br> 51 * <code><br> 52 * 1. Factory< AbstractProduct, int > aFactory;<br> 53 * 2. aFactory.Register( 1, createProductNull );<br> 54 * 3. aFactory.CreateObject( 1 ); <br> 55 * </code><br> 56 * <br> 57 * - 1. The declaration<br> 58 * You want a Factory that produces AbstractProduct.<br> 59 * The client will refer to a creation method through an int.<br> 60 * - 2.The registration<br> 61 * The code that will contribute to the Factory will now need to declare its 62 * ProductCreator by registering them into the Factory.<br> 63 * A ProductCreator is a just a function that will return the right object. ie <br> 64 * <code> 65 * Product* createProductNull()<br> 66 * {<br> 67 * return new Product<br> 68 * }<br> 69 * </code><br> 70 * - 3. The use<br> 71 * Now the client can create object by calling the Factory's CreateObject method 72 * with the right identifier. If the ProductCreator were to have arguments 73 * (<i>ie :Product* createProductParm( int a, int b )</i>) 74 */ 75 76 namespace Loki 77 { 78 79 /** 80 * \defgroup FactoryErrorPoliciesGroup Factory Error Policies 81 * \ingroup FactoryGroup 82 * \brief Manages the "Unknown Type" error in an object factory 83 * 84 * \class DefaultFactoryError 85 * \ingroup FactoryErrorPoliciesGroup 86 * \brief Default policy that throws an exception 87 * 88 */ 89 90 template <typename IdentifierType, class AbstractProduct> 91 struct DefaultFactoryError 92 { 93 struct Exception : public std::exception 94 { whatDefaultFactoryError::Exception95 const char* what() const throw() { return "Unknown Type"; } 96 }; 97 OnUnknownTypeDefaultFactoryError98 static AbstractProduct* OnUnknownType(IdentifierType) 99 { 100 throw Exception(); 101 } 102 }; 103 104 105 #define LOKI_ENABLE_NEW_FACTORY_CODE 106 #ifdef LOKI_ENABLE_NEW_FACTORY_CODE 107 108 109 //////////////////////////////////////////////////////////////////////////////// 110 // class template FunctorImpl 111 //////////////////////////////////////////////////////////////////////////////// 112 113 struct FactoryImplBase 114 { 115 typedef EmptyType Parm1; 116 typedef EmptyType Parm2; 117 typedef EmptyType Parm3; 118 typedef EmptyType Parm4; 119 typedef EmptyType Parm5; 120 typedef EmptyType Parm6; 121 typedef EmptyType Parm7; 122 typedef EmptyType Parm8; 123 typedef EmptyType Parm9; 124 typedef EmptyType Parm10; 125 typedef EmptyType Parm11; 126 typedef EmptyType Parm12; 127 typedef EmptyType Parm13; 128 typedef EmptyType Parm14; 129 typedef EmptyType Parm15; 130 }; 131 132 template <typename AP, typename Id, typename TList > 133 struct FactoryImpl; 134 135 template<typename AP, typename Id> 136 struct FactoryImpl<AP, Id, NullType> 137 : public FactoryImplBase 138 { 139 virtual ~FactoryImpl() {} 140 virtual AP* CreateObject(const Id & id ) = 0; 141 }; 142 template <typename AP, typename Id, typename P1 > 143 struct FactoryImpl<AP,Id, Seq<P1> > 144 : public FactoryImplBase 145 { 146 typedef typename TypeTraits<P1>::ParameterType Parm1; 147 virtual ~FactoryImpl() {} 148 virtual AP* CreateObject(const Id& id,Parm1 ) = 0; 149 }; 150 151 template<typename AP, typename Id, typename P1,typename P2 > 152 struct FactoryImpl<AP, Id, Seq<P1, P2> > 153 : public FactoryImplBase 154 { 155 typedef typename TypeTraits<P1>::ParameterType Parm1; 156 typedef typename TypeTraits<P2>::ParameterType Parm2; 157 virtual ~FactoryImpl() {} 158 virtual AP* CreateObject(const Id& id,Parm1, Parm2 ) = 0; 159 }; 160 161 template<typename AP, typename Id, typename P1,typename P2,typename P3 > 162 struct FactoryImpl<AP, Id, Seq<P1, P2, P3> > 163 : public FactoryImplBase 164 { 165 typedef typename TypeTraits<P1>::ParameterType Parm1; 166 typedef typename TypeTraits<P2>::ParameterType Parm2; 167 typedef typename TypeTraits<P3>::ParameterType Parm3; 168 virtual ~FactoryImpl() {} 169 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3 ) = 0; 170 }; 171 172 template<typename AP, typename Id, typename P1,typename P2,typename P3,typename P4 > 173 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4> > 174 : public FactoryImplBase 175 { 176 typedef typename TypeTraits<P1>::ParameterType Parm1; 177 typedef typename TypeTraits<P2>::ParameterType Parm2; 178 typedef typename TypeTraits<P3>::ParameterType Parm3; 179 typedef typename TypeTraits<P4>::ParameterType Parm4; 180 virtual ~FactoryImpl() {} 181 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4 ) = 0; 182 }; 183 184 template<typename AP, typename Id, 185 typename P1,typename P2,typename P3,typename P4,typename P5 > 186 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5> > 187 : public FactoryImplBase 188 { 189 typedef typename TypeTraits<P1>::ParameterType Parm1; 190 typedef typename TypeTraits<P2>::ParameterType Parm2; 191 typedef typename TypeTraits<P3>::ParameterType Parm3; 192 typedef typename TypeTraits<P4>::ParameterType Parm4; 193 typedef typename TypeTraits<P5>::ParameterType Parm5; 194 virtual ~FactoryImpl() {} 195 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5 ) = 0; 196 }; 197 198 template<typename AP, typename Id, 199 typename P1,typename P2,typename P3,typename P4,typename P5, 200 typename P6> 201 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6> > 202 : public FactoryImplBase 203 { 204 typedef typename TypeTraits<P1>::ParameterType Parm1; 205 typedef typename TypeTraits<P2>::ParameterType Parm2; 206 typedef typename TypeTraits<P3>::ParameterType Parm3; 207 typedef typename TypeTraits<P4>::ParameterType Parm4; 208 typedef typename TypeTraits<P5>::ParameterType Parm5; 209 typedef typename TypeTraits<P6>::ParameterType Parm6; 210 virtual ~FactoryImpl() {} 211 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 212 Parm6 ) 213 = 0; 214 }; 215 216 template<typename AP, typename Id, 217 typename P1,typename P2,typename P3,typename P4,typename P5, 218 typename P6,typename P7> 219 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7> > 220 : public FactoryImplBase 221 { 222 typedef typename TypeTraits<P1>::ParameterType Parm1; 223 typedef typename TypeTraits<P2>::ParameterType Parm2; 224 typedef typename TypeTraits<P3>::ParameterType Parm3; 225 typedef typename TypeTraits<P4>::ParameterType Parm4; 226 typedef typename TypeTraits<P5>::ParameterType Parm5; 227 typedef typename TypeTraits<P6>::ParameterType Parm6; 228 typedef typename TypeTraits<P7>::ParameterType Parm7; 229 virtual ~FactoryImpl() {} 230 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 231 Parm6, Parm7 ) 232 = 0; 233 }; 234 235 template<typename AP, typename Id, 236 typename P1,typename P2,typename P3,typename P4,typename P5, 237 typename P6,typename P7,typename P8> 238 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8> > 239 : public FactoryImplBase 240 { 241 typedef typename TypeTraits<P1>::ParameterType Parm1; 242 typedef typename TypeTraits<P2>::ParameterType Parm2; 243 typedef typename TypeTraits<P3>::ParameterType Parm3; 244 typedef typename TypeTraits<P4>::ParameterType Parm4; 245 typedef typename TypeTraits<P5>::ParameterType Parm5; 246 typedef typename TypeTraits<P6>::ParameterType Parm6; 247 typedef typename TypeTraits<P7>::ParameterType Parm7; 248 typedef typename TypeTraits<P8>::ParameterType Parm8; 249 virtual ~FactoryImpl() {} 250 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 251 Parm6, Parm7, Parm8) 252 = 0; 253 }; 254 255 template<typename AP, typename Id, 256 typename P1,typename P2,typename P3,typename P4,typename P5, 257 typename P6,typename P7,typename P8,typename P9> 258 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9> > 259 : public FactoryImplBase 260 { 261 typedef typename TypeTraits<P1>::ParameterType Parm1; 262 typedef typename TypeTraits<P2>::ParameterType Parm2; 263 typedef typename TypeTraits<P3>::ParameterType Parm3; 264 typedef typename TypeTraits<P4>::ParameterType Parm4; 265 typedef typename TypeTraits<P5>::ParameterType Parm5; 266 typedef typename TypeTraits<P6>::ParameterType Parm6; 267 typedef typename TypeTraits<P7>::ParameterType Parm7; 268 typedef typename TypeTraits<P8>::ParameterType Parm8; 269 typedef typename TypeTraits<P9>::ParameterType Parm9; 270 virtual ~FactoryImpl() {} 271 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 272 Parm6, Parm7, Parm8, Parm9) 273 = 0; 274 }; 275 276 template<typename AP, typename Id, 277 typename P1,typename P2,typename P3,typename P4,typename P5, 278 typename P6,typename P7,typename P8,typename P9,typename P10> 279 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> > 280 : public FactoryImplBase 281 { 282 typedef typename TypeTraits<P1>::ParameterType Parm1; 283 typedef typename TypeTraits<P2>::ParameterType Parm2; 284 typedef typename TypeTraits<P3>::ParameterType Parm3; 285 typedef typename TypeTraits<P4>::ParameterType Parm4; 286 typedef typename TypeTraits<P5>::ParameterType Parm5; 287 typedef typename TypeTraits<P6>::ParameterType Parm6; 288 typedef typename TypeTraits<P7>::ParameterType Parm7; 289 typedef typename TypeTraits<P8>::ParameterType Parm8; 290 typedef typename TypeTraits<P9>::ParameterType Parm9; 291 typedef typename TypeTraits<P10>::ParameterType Parm10; 292 virtual ~FactoryImpl() {} 293 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 294 Parm6, Parm7, Parm8, Parm9,Parm10) 295 = 0; 296 }; 297 298 template<typename AP, typename Id, 299 typename P1,typename P2,typename P3,typename P4,typename P5, 300 typename P6,typename P7,typename P8,typename P9,typename P10, 301 typename P11> 302 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> > 303 : public FactoryImplBase 304 { 305 typedef typename TypeTraits<P1>::ParameterType Parm1; 306 typedef typename TypeTraits<P2>::ParameterType Parm2; 307 typedef typename TypeTraits<P3>::ParameterType Parm3; 308 typedef typename TypeTraits<P4>::ParameterType Parm4; 309 typedef typename TypeTraits<P5>::ParameterType Parm5; 310 typedef typename TypeTraits<P6>::ParameterType Parm6; 311 typedef typename TypeTraits<P7>::ParameterType Parm7; 312 typedef typename TypeTraits<P8>::ParameterType Parm8; 313 typedef typename TypeTraits<P9>::ParameterType Parm9; 314 typedef typename TypeTraits<P10>::ParameterType Parm10; 315 typedef typename TypeTraits<P11>::ParameterType Parm11; 316 virtual ~FactoryImpl() {} 317 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 318 Parm6, Parm7, Parm8, Parm9,Parm10, 319 Parm11) 320 = 0; 321 }; 322 323 template<typename AP, typename Id, 324 typename P1,typename P2,typename P3,typename P4,typename P5, 325 typename P6,typename P7,typename P8,typename P9,typename P10, 326 typename P11,typename P12> 327 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12> > 328 : public FactoryImplBase 329 { 330 typedef typename TypeTraits<P1>::ParameterType Parm1; 331 typedef typename TypeTraits<P2>::ParameterType Parm2; 332 typedef typename TypeTraits<P3>::ParameterType Parm3; 333 typedef typename TypeTraits<P4>::ParameterType Parm4; 334 typedef typename TypeTraits<P5>::ParameterType Parm5; 335 typedef typename TypeTraits<P6>::ParameterType Parm6; 336 typedef typename TypeTraits<P7>::ParameterType Parm7; 337 typedef typename TypeTraits<P8>::ParameterType Parm8; 338 typedef typename TypeTraits<P9>::ParameterType Parm9; 339 typedef typename TypeTraits<P10>::ParameterType Parm10; 340 typedef typename TypeTraits<P11>::ParameterType Parm11; 341 typedef typename TypeTraits<P12>::ParameterType Parm12; 342 virtual ~FactoryImpl() {} 343 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 344 Parm6, Parm7, Parm8, Parm9,Parm10, 345 Parm11,Parm12) 346 = 0; 347 }; 348 349 template<typename AP, typename Id, 350 typename P1,typename P2,typename P3,typename P4,typename P5, 351 typename P6,typename P7,typename P8,typename P9,typename P10, 352 typename P11,typename P12,typename P13> 353 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13> > 354 : public FactoryImplBase 355 { 356 typedef typename TypeTraits<P1>::ParameterType Parm1; 357 typedef typename TypeTraits<P2>::ParameterType Parm2; 358 typedef typename TypeTraits<P3>::ParameterType Parm3; 359 typedef typename TypeTraits<P4>::ParameterType Parm4; 360 typedef typename TypeTraits<P5>::ParameterType Parm5; 361 typedef typename TypeTraits<P6>::ParameterType Parm6; 362 typedef typename TypeTraits<P7>::ParameterType Parm7; 363 typedef typename TypeTraits<P8>::ParameterType Parm8; 364 typedef typename TypeTraits<P9>::ParameterType Parm9; 365 typedef typename TypeTraits<P10>::ParameterType Parm10; 366 typedef typename TypeTraits<P11>::ParameterType Parm11; 367 typedef typename TypeTraits<P12>::ParameterType Parm12; 368 typedef typename TypeTraits<P13>::ParameterType Parm13; 369 virtual ~FactoryImpl() {} 370 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 371 Parm6, Parm7, Parm8, Parm9,Parm10, 372 Parm11,Parm12,Parm13) 373 = 0; 374 }; 375 376 template<typename AP, typename Id, 377 typename P1,typename P2,typename P3,typename P4,typename P5, 378 typename P6,typename P7,typename P8,typename P9,typename P10, 379 typename P11,typename P12,typename P13,typename P14> 380 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14> > 381 : public FactoryImplBase 382 { 383 typedef typename TypeTraits<P1>::ParameterType Parm1; 384 typedef typename TypeTraits<P2>::ParameterType Parm2; 385 typedef typename TypeTraits<P3>::ParameterType Parm3; 386 typedef typename TypeTraits<P4>::ParameterType Parm4; 387 typedef typename TypeTraits<P5>::ParameterType Parm5; 388 typedef typename TypeTraits<P6>::ParameterType Parm6; 389 typedef typename TypeTraits<P7>::ParameterType Parm7; 390 typedef typename TypeTraits<P8>::ParameterType Parm8; 391 typedef typename TypeTraits<P9>::ParameterType Parm9; 392 typedef typename TypeTraits<P10>::ParameterType Parm10; 393 typedef typename TypeTraits<P11>::ParameterType Parm11; 394 typedef typename TypeTraits<P12>::ParameterType Parm12; 395 typedef typename TypeTraits<P13>::ParameterType Parm13; 396 typedef typename TypeTraits<P14>::ParameterType Parm14; 397 virtual ~FactoryImpl() {} 398 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 399 Parm6, Parm7, Parm8, Parm8,Parm10, 400 Parm11,Parm12,Parm13,Parm14) 401 = 0; 402 }; 403 404 template<typename AP, typename Id, 405 typename P1,typename P2,typename P3,typename P4,typename P5, 406 typename P6,typename P7,typename P8,typename P9,typename P10, 407 typename P11,typename P12,typename P13,typename P14,typename P15 > 408 struct FactoryImpl<AP, Id, Seq<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15> > 409 : public FactoryImplBase 410 { 411 typedef typename TypeTraits<P1>::ParameterType Parm1; 412 typedef typename TypeTraits<P2>::ParameterType Parm2; 413 typedef typename TypeTraits<P3>::ParameterType Parm3; 414 typedef typename TypeTraits<P4>::ParameterType Parm4; 415 typedef typename TypeTraits<P5>::ParameterType Parm5; 416 typedef typename TypeTraits<P6>::ParameterType Parm6; 417 typedef typename TypeTraits<P7>::ParameterType Parm7; 418 typedef typename TypeTraits<P8>::ParameterType Parm8; 419 typedef typename TypeTraits<P9>::ParameterType Parm9; 420 typedef typename TypeTraits<P10>::ParameterType Parm10; 421 typedef typename TypeTraits<P11>::ParameterType Parm11; 422 typedef typename TypeTraits<P12>::ParameterType Parm12; 423 typedef typename TypeTraits<P13>::ParameterType Parm13; 424 typedef typename TypeTraits<P14>::ParameterType Parm14; 425 typedef typename TypeTraits<P15>::ParameterType Parm15; 426 virtual ~FactoryImpl() {} 427 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 428 Parm6, Parm7, Parm8, Parm9,Parm10, 429 Parm11,Parm12,Parm13,Parm14,Parm15 ) 430 = 0; 431 }; 432 433 #ifndef LOKI_DISABLE_TYPELIST_MACROS 434 435 template <typename AP, typename Id, typename P1 > 436 struct FactoryImpl<AP,Id, LOKI_TYPELIST_1( P1 )> 437 : public FactoryImplBase 438 { 439 typedef typename TypeTraits<P1>::ParameterType Parm1; 440 virtual ~FactoryImpl() {} 441 virtual AP* CreateObject(const Id& id,Parm1 ) = 0; 442 }; 443 444 template<typename AP, typename Id, typename P1,typename P2 > 445 struct FactoryImpl<AP, Id, LOKI_TYPELIST_2( P1, P2 )> 446 : public FactoryImplBase 447 { 448 typedef typename TypeTraits<P1>::ParameterType Parm1; 449 typedef typename TypeTraits<P2>::ParameterType Parm2; 450 virtual ~FactoryImpl() {} 451 virtual AP* CreateObject(const Id& id,Parm1, Parm2 ) = 0; 452 }; 453 454 template<typename AP, typename Id, typename P1,typename P2,typename P3 > 455 struct FactoryImpl<AP, Id, LOKI_TYPELIST_3( P1, P2, P3 )> 456 : public FactoryImplBase 457 { 458 typedef typename TypeTraits<P1>::ParameterType Parm1; 459 typedef typename TypeTraits<P2>::ParameterType Parm2; 460 typedef typename TypeTraits<P3>::ParameterType Parm3; 461 virtual ~FactoryImpl() {} 462 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3 ) = 0; 463 }; 464 465 template<typename AP, typename Id, typename P1,typename P2,typename P3,typename P4 > 466 struct FactoryImpl<AP, Id, LOKI_TYPELIST_4( P1, P2, P3, P4 )> 467 : public FactoryImplBase 468 { 469 typedef typename TypeTraits<P1>::ParameterType Parm1; 470 typedef typename TypeTraits<P2>::ParameterType Parm2; 471 typedef typename TypeTraits<P3>::ParameterType Parm3; 472 typedef typename TypeTraits<P4>::ParameterType Parm4; 473 virtual ~FactoryImpl() {} 474 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4 ) = 0; 475 }; 476 477 template<typename AP, typename Id, 478 typename P1,typename P2,typename P3,typename P4,typename P5 > 479 struct FactoryImpl<AP, Id, LOKI_TYPELIST_5( P1, P2, P3, P4, P5 )> 480 : public FactoryImplBase 481 { 482 typedef typename TypeTraits<P1>::ParameterType Parm1; 483 typedef typename TypeTraits<P2>::ParameterType Parm2; 484 typedef typename TypeTraits<P3>::ParameterType Parm3; 485 typedef typename TypeTraits<P4>::ParameterType Parm4; 486 typedef typename TypeTraits<P5>::ParameterType Parm5; 487 virtual ~FactoryImpl() {} 488 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5 ) = 0; 489 }; 490 491 template<typename AP, typename Id, 492 typename P1,typename P2,typename P3,typename P4,typename P5, 493 typename P6> 494 struct FactoryImpl<AP, Id, LOKI_TYPELIST_6( P1, P2, P3, P4, P5, P6 )> 495 : public FactoryImplBase 496 { 497 typedef typename TypeTraits<P1>::ParameterType Parm1; 498 typedef typename TypeTraits<P2>::ParameterType Parm2; 499 typedef typename TypeTraits<P3>::ParameterType Parm3; 500 typedef typename TypeTraits<P4>::ParameterType Parm4; 501 typedef typename TypeTraits<P5>::ParameterType Parm5; 502 typedef typename TypeTraits<P6>::ParameterType Parm6; 503 virtual ~FactoryImpl() {} 504 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 505 Parm6 ) 506 = 0; 507 }; 508 509 template<typename AP, typename Id, 510 typename P1,typename P2,typename P3,typename P4,typename P5, 511 typename P6,typename P7> 512 struct FactoryImpl<AP, Id, LOKI_TYPELIST_7( P1, P2, P3, P4, P5, P6, P7 )> 513 : public FactoryImplBase 514 { 515 typedef typename TypeTraits<P1>::ParameterType Parm1; 516 typedef typename TypeTraits<P2>::ParameterType Parm2; 517 typedef typename TypeTraits<P3>::ParameterType Parm3; 518 typedef typename TypeTraits<P4>::ParameterType Parm4; 519 typedef typename TypeTraits<P5>::ParameterType Parm5; 520 typedef typename TypeTraits<P6>::ParameterType Parm6; 521 typedef typename TypeTraits<P7>::ParameterType Parm7; 522 virtual ~FactoryImpl() {} 523 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 524 Parm6, Parm7 ) 525 = 0; 526 }; 527 528 template<typename AP, typename Id, 529 typename P1,typename P2,typename P3,typename P4,typename P5, 530 typename P6,typename P7,typename P8> 531 struct FactoryImpl<AP, Id, LOKI_TYPELIST_8( P1, P2, P3, P4, P5, P6, P7, P8 )> 532 : public FactoryImplBase 533 { 534 typedef typename TypeTraits<P1>::ParameterType Parm1; 535 typedef typename TypeTraits<P2>::ParameterType Parm2; 536 typedef typename TypeTraits<P3>::ParameterType Parm3; 537 typedef typename TypeTraits<P4>::ParameterType Parm4; 538 typedef typename TypeTraits<P5>::ParameterType Parm5; 539 typedef typename TypeTraits<P6>::ParameterType Parm6; 540 typedef typename TypeTraits<P7>::ParameterType Parm7; 541 typedef typename TypeTraits<P8>::ParameterType Parm8; 542 virtual ~FactoryImpl() {} 543 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 544 Parm6, Parm7, Parm8) 545 = 0; 546 }; 547 548 template<typename AP, typename Id, 549 typename P1,typename P2,typename P3,typename P4,typename P5, 550 typename P6,typename P7,typename P8,typename P9> 551 struct FactoryImpl<AP, Id, LOKI_TYPELIST_9( P1, P2, P3, P4, P5, P6, P7, P8, P9 )> 552 : public FactoryImplBase 553 { 554 typedef typename TypeTraits<P1>::ParameterType Parm1; 555 typedef typename TypeTraits<P2>::ParameterType Parm2; 556 typedef typename TypeTraits<P3>::ParameterType Parm3; 557 typedef typename TypeTraits<P4>::ParameterType Parm4; 558 typedef typename TypeTraits<P5>::ParameterType Parm5; 559 typedef typename TypeTraits<P6>::ParameterType Parm6; 560 typedef typename TypeTraits<P7>::ParameterType Parm7; 561 typedef typename TypeTraits<P8>::ParameterType Parm8; 562 typedef typename TypeTraits<P9>::ParameterType Parm9; 563 virtual ~FactoryImpl() {} 564 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 565 Parm6, Parm7, Parm8, Parm9) 566 = 0; 567 }; 568 569 template<typename AP, typename Id, 570 typename P1,typename P2,typename P3,typename P4,typename P5, 571 typename P6,typename P7,typename P8,typename P9,typename P10> 572 struct FactoryImpl<AP, Id, LOKI_TYPELIST_10( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10 )> 573 : public FactoryImplBase 574 { 575 typedef typename TypeTraits<P1>::ParameterType Parm1; 576 typedef typename TypeTraits<P2>::ParameterType Parm2; 577 typedef typename TypeTraits<P3>::ParameterType Parm3; 578 typedef typename TypeTraits<P4>::ParameterType Parm4; 579 typedef typename TypeTraits<P5>::ParameterType Parm5; 580 typedef typename TypeTraits<P6>::ParameterType Parm6; 581 typedef typename TypeTraits<P7>::ParameterType Parm7; 582 typedef typename TypeTraits<P8>::ParameterType Parm8; 583 typedef typename TypeTraits<P9>::ParameterType Parm9; 584 typedef typename TypeTraits<P10>::ParameterType Parm10; 585 virtual ~FactoryImpl() {} 586 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 587 Parm6, Parm7, Parm8, Parm9,Parm10) 588 = 0; 589 }; 590 591 template<typename AP, typename Id, 592 typename P1,typename P2,typename P3,typename P4,typename P5, 593 typename P6,typename P7,typename P8,typename P9,typename P10, 594 typename P11> 595 struct FactoryImpl<AP, Id, LOKI_TYPELIST_11( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11 )> 596 : public FactoryImplBase 597 { 598 typedef typename TypeTraits<P1>::ParameterType Parm1; 599 typedef typename TypeTraits<P2>::ParameterType Parm2; 600 typedef typename TypeTraits<P3>::ParameterType Parm3; 601 typedef typename TypeTraits<P4>::ParameterType Parm4; 602 typedef typename TypeTraits<P5>::ParameterType Parm5; 603 typedef typename TypeTraits<P6>::ParameterType Parm6; 604 typedef typename TypeTraits<P7>::ParameterType Parm7; 605 typedef typename TypeTraits<P8>::ParameterType Parm8; 606 typedef typename TypeTraits<P9>::ParameterType Parm9; 607 typedef typename TypeTraits<P10>::ParameterType Parm10; 608 typedef typename TypeTraits<P11>::ParameterType Parm11; 609 virtual ~FactoryImpl() {} 610 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 611 Parm6, Parm7, Parm8, Parm9,Parm10, 612 Parm11) 613 = 0; 614 }; 615 616 template<typename AP, typename Id, 617 typename P1,typename P2,typename P3,typename P4,typename P5, 618 typename P6,typename P7,typename P8,typename P9,typename P10, 619 typename P11,typename P12> 620 struct FactoryImpl<AP, Id, LOKI_TYPELIST_12( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12 )> 621 : public FactoryImplBase 622 { 623 typedef typename TypeTraits<P1>::ParameterType Parm1; 624 typedef typename TypeTraits<P2>::ParameterType Parm2; 625 typedef typename TypeTraits<P3>::ParameterType Parm3; 626 typedef typename TypeTraits<P4>::ParameterType Parm4; 627 typedef typename TypeTraits<P5>::ParameterType Parm5; 628 typedef typename TypeTraits<P6>::ParameterType Parm6; 629 typedef typename TypeTraits<P7>::ParameterType Parm7; 630 typedef typename TypeTraits<P8>::ParameterType Parm8; 631 typedef typename TypeTraits<P9>::ParameterType Parm9; 632 typedef typename TypeTraits<P10>::ParameterType Parm10; 633 typedef typename TypeTraits<P11>::ParameterType Parm11; 634 typedef typename TypeTraits<P12>::ParameterType Parm12; 635 virtual ~FactoryImpl() {} 636 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 637 Parm6, Parm7, Parm8, Parm9,Parm10, 638 Parm11,Parm12) 639 = 0; 640 }; 641 642 template<typename AP, typename Id, 643 typename P1,typename P2,typename P3,typename P4,typename P5, 644 typename P6,typename P7,typename P8,typename P9,typename P10, 645 typename P11,typename P12,typename P13> 646 struct FactoryImpl<AP, Id, LOKI_TYPELIST_13( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13 )> 647 : public FactoryImplBase 648 { 649 typedef typename TypeTraits<P1>::ParameterType Parm1; 650 typedef typename TypeTraits<P2>::ParameterType Parm2; 651 typedef typename TypeTraits<P3>::ParameterType Parm3; 652 typedef typename TypeTraits<P4>::ParameterType Parm4; 653 typedef typename TypeTraits<P5>::ParameterType Parm5; 654 typedef typename TypeTraits<P6>::ParameterType Parm6; 655 typedef typename TypeTraits<P7>::ParameterType Parm7; 656 typedef typename TypeTraits<P8>::ParameterType Parm8; 657 typedef typename TypeTraits<P9>::ParameterType Parm9; 658 typedef typename TypeTraits<P10>::ParameterType Parm10; 659 typedef typename TypeTraits<P11>::ParameterType Parm11; 660 typedef typename TypeTraits<P12>::ParameterType Parm12; 661 typedef typename TypeTraits<P13>::ParameterType Parm13; 662 virtual ~FactoryImpl() {} 663 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 664 Parm6, Parm7, Parm8, Parm9,Parm10, 665 Parm11,Parm12,Parm13) 666 = 0; 667 }; 668 669 template<typename AP, typename Id, 670 typename P1,typename P2,typename P3,typename P4,typename P5, 671 typename P6,typename P7,typename P8,typename P9,typename P10, 672 typename P11,typename P12,typename P13,typename P14> 673 struct FactoryImpl<AP, Id, LOKI_TYPELIST_14( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14 )> 674 : public FactoryImplBase 675 { 676 typedef typename TypeTraits<P1>::ParameterType Parm1; 677 typedef typename TypeTraits<P2>::ParameterType Parm2; 678 typedef typename TypeTraits<P3>::ParameterType Parm3; 679 typedef typename TypeTraits<P4>::ParameterType Parm4; 680 typedef typename TypeTraits<P5>::ParameterType Parm5; 681 typedef typename TypeTraits<P6>::ParameterType Parm6; 682 typedef typename TypeTraits<P7>::ParameterType Parm7; 683 typedef typename TypeTraits<P8>::ParameterType Parm8; 684 typedef typename TypeTraits<P9>::ParameterType Parm9; 685 typedef typename TypeTraits<P10>::ParameterType Parm10; 686 typedef typename TypeTraits<P11>::ParameterType Parm11; 687 typedef typename TypeTraits<P12>::ParameterType Parm12; 688 typedef typename TypeTraits<P13>::ParameterType Parm13; 689 typedef typename TypeTraits<P14>::ParameterType Parm14; 690 virtual ~FactoryImpl() {} 691 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 692 Parm6, Parm7, Parm8, Parm8,Parm10, 693 Parm11,Parm12,Parm13,Parm14) 694 = 0; 695 }; 696 697 template<typename AP, typename Id, 698 typename P1,typename P2,typename P3,typename P4,typename P5, 699 typename P6,typename P7,typename P8,typename P9,typename P10, 700 typename P11,typename P12,typename P13,typename P14,typename P15 > 701 struct FactoryImpl<AP, Id, LOKI_TYPELIST_15( P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15 )> 702 : public FactoryImplBase 703 { 704 typedef typename TypeTraits<P1>::ParameterType Parm1; 705 typedef typename TypeTraits<P2>::ParameterType Parm2; 706 typedef typename TypeTraits<P3>::ParameterType Parm3; 707 typedef typename TypeTraits<P4>::ParameterType Parm4; 708 typedef typename TypeTraits<P5>::ParameterType Parm5; 709 typedef typename TypeTraits<P6>::ParameterType Parm6; 710 typedef typename TypeTraits<P7>::ParameterType Parm7; 711 typedef typename TypeTraits<P8>::ParameterType Parm8; 712 typedef typename TypeTraits<P9>::ParameterType Parm9; 713 typedef typename TypeTraits<P10>::ParameterType Parm10; 714 typedef typename TypeTraits<P11>::ParameterType Parm11; 715 typedef typename TypeTraits<P12>::ParameterType Parm12; 716 typedef typename TypeTraits<P13>::ParameterType Parm13; 717 typedef typename TypeTraits<P14>::ParameterType Parm14; 718 typedef typename TypeTraits<P15>::ParameterType Parm15; 719 virtual ~FactoryImpl() {} 720 virtual AP* CreateObject(const Id& id,Parm1, Parm2, Parm3, Parm4, Parm5, 721 Parm6, Parm7, Parm8, Parm9,Parm10, 722 Parm11,Parm12,Parm13,Parm14,Parm15 ) 723 = 0; 724 }; 725 726 #endif //LOKI_DISABLE_TYPELIST_MACROS 727 728 729 //////////////////////////////////////////////////////////////////////////////// 730 /// \class Factory 731 /// 732 /// \ingroup FactoryGroup 733 /// Implements a generic object factory. 734 /// 735 /// Create functions can have up to 15 parameters. 736 /// 737 /// \par Singleton lifetime when used with Loki::SingletonHolder 738 /// Because Factory uses internally Functors which inherits from 739 /// SmallObject you must use the singleton lifetime 740 /// \code Loki::LongevityLifetime::DieAsSmallObjectChild \endcode 741 /// Alternatively you could suppress for Functor the inheritance 742 /// from SmallObject by defining the macro: 743 /// \code LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT \endcode 744 //////////////////////////////////////////////////////////////////////////////// 745 template 746 < 747 class AbstractProduct, 748 typename IdentifierType, 749 typename CreatorParmTList = NullType, 750 template<typename, class> class FactoryErrorPolicy = DefaultFactoryError 751 > 752 class Factory : public FactoryErrorPolicy<IdentifierType, AbstractProduct> 753 { 754 typedef FactoryImpl< AbstractProduct, IdentifierType, CreatorParmTList > Impl; 755 756 typedef typename Impl::Parm1 Parm1; 757 typedef typename Impl::Parm2 Parm2; 758 typedef typename Impl::Parm3 Parm3; 759 typedef typename Impl::Parm4 Parm4; 760 typedef typename Impl::Parm5 Parm5; 761 typedef typename Impl::Parm6 Parm6; 762 typedef typename Impl::Parm7 Parm7; 763 typedef typename Impl::Parm8 Parm8; 764 typedef typename Impl::Parm9 Parm9; 765 typedef typename Impl::Parm10 Parm10; 766 typedef typename Impl::Parm11 Parm11; 767 typedef typename Impl::Parm12 Parm12; 768 typedef typename Impl::Parm13 Parm13; 769 typedef typename Impl::Parm14 Parm14; 770 typedef typename Impl::Parm15 Parm15; 771 772 typedef Functor<AbstractProduct*, CreatorParmTList> ProductCreator; 773 774 typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap; 775 776 IdToProductMap associations_; 777 778 public: 779 780 Factory() 781 : associations_() 782 { 783 } 784 785 ~Factory() 786 { 787 associations_.erase(associations_.begin(), associations_.end()); 788 } 789 790 bool Register(const IdentifierType& id, ProductCreator creator) 791 { 792 return associations_.insert( 793 typename IdToProductMap::value_type(id, creator)).second != 0; 794 } 795 796 template <class PtrObj, typename CreaFn> 797 bool Register(const IdentifierType& id, const PtrObj& p, CreaFn fn) 798 { 799 ProductCreator creator( p, fn ); 800 return associations_.insert( 801 typename IdToProductMap::value_type(id, creator)).second != 0; 802 } 803 804 bool Unregister(const IdentifierType& id) 805 { 806 return associations_.erase(id) != 0; 807 } 808 809 std::vector<IdentifierType> RegisteredIds() 810 { 811 std::vector<IdentifierType> ids; 812 for(typename IdToProductMap::iterator it = associations_.begin(); 813 it != associations_.end(); ++it) 814 { 815 ids.push_back(it->first); 816 } 817 return ids; 818 } 819 820 AbstractProduct* CreateObject(const IdentifierType& id) 821 { 822 typename IdToProductMap::iterator i = associations_.find(id); 823 if (i != associations_.end()) 824 return (i->second)( ); 825 return this->OnUnknownType(id); 826 } 827 828 AbstractProduct* CreateObject(const IdentifierType& id, 829 Parm1 p1) 830 { 831 typename IdToProductMap::iterator i = associations_.find(id); 832 if (i != associations_.end()) 833 return (i->second)( p1 ); 834 return this->OnUnknownType(id); 835 } 836 837 AbstractProduct* CreateObject(const IdentifierType& id, 838 Parm1 p1, Parm2 p2) 839 { 840 typename IdToProductMap::iterator i = associations_.find(id); 841 if (i != associations_.end()) 842 return (i->second)( p1,p2 ); 843 return this->OnUnknownType(id); 844 } 845 846 AbstractProduct* CreateObject(const IdentifierType& id, 847 Parm1 p1, Parm2 p2, Parm3 p3) 848 { 849 typename IdToProductMap::iterator i = associations_.find(id); 850 if (i != associations_.end()) 851 return (i->second)( p1,p2,p3 ); 852 return this->OnUnknownType(id); 853 } 854 855 AbstractProduct* CreateObject(const IdentifierType& id, 856 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4) 857 { 858 typename IdToProductMap::iterator i = associations_.find(id); 859 if (i != associations_.end()) 860 return (i->second)( p1,p2,p3,p4 ); 861 return this->OnUnknownType(id); 862 } 863 864 AbstractProduct* CreateObject(const IdentifierType& id, 865 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5) 866 { 867 typename IdToProductMap::iterator i = associations_.find(id); 868 if (i != associations_.end()) 869 return (i->second)( p1,p2,p3,p4,p5 ); 870 return this->OnUnknownType(id); 871 } 872 873 AbstractProduct* CreateObject(const IdentifierType& id, 874 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, 875 Parm6 p6) 876 { 877 typename IdToProductMap::iterator i = associations_.find(id); 878 if (i != associations_.end()) 879 return (i->second)( p1,p2,p3,p4,p5,p6 ); 880 return this->OnUnknownType(id); 881 } 882 883 AbstractProduct* CreateObject(const IdentifierType& id, 884 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, 885 Parm6 p6, Parm7 p7 ) 886 { 887 typename IdToProductMap::iterator i = associations_.find(id); 888 if (i != associations_.end()) 889 return (i->second)( p1,p2,p3,p4,p5,p6,p7 ); 890 return this->OnUnknownType(id); 891 } 892 893 AbstractProduct* CreateObject(const IdentifierType& id, 894 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, 895 Parm6 p6, Parm7 p7, Parm8 p8) 896 { 897 typename IdToProductMap::iterator i = associations_.find(id); 898 if (i != associations_.end()) 899 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8 ); 900 return this->OnUnknownType(id); 901 } 902 903 AbstractProduct* CreateObject(const IdentifierType& id, 904 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, 905 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9) 906 { 907 typename IdToProductMap::iterator i = associations_.find(id); 908 if (i != associations_.end()) 909 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9 ); 910 return this->OnUnknownType(id); 911 } 912 AbstractProduct* CreateObject(const IdentifierType& id, 913 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, 914 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9,Parm10 p10) 915 { 916 typename IdToProductMap::iterator i = associations_.find(id); 917 if (i != associations_.end()) 918 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10 ); 919 return this->OnUnknownType(id); 920 } 921 922 AbstractProduct* CreateObject(const IdentifierType& id, 923 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, 924 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, 925 Parm11 p11) 926 { 927 typename IdToProductMap::iterator i = associations_.find(id); 928 if (i != associations_.end()) 929 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11 ); 930 return this->OnUnknownType(id); 931 } 932 933 AbstractProduct* CreateObject(const IdentifierType& id, 934 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, 935 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, 936 Parm11 p11, Parm12 p12) 937 { 938 typename IdToProductMap::iterator i = associations_.find(id); 939 if (i != associations_.end()) 940 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12 ); 941 return this->OnUnknownType(id); 942 } 943 944 AbstractProduct* CreateObject(const IdentifierType& id, 945 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, 946 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, 947 Parm11 p11, Parm12 p12, Parm13 p13) 948 { 949 typename IdToProductMap::iterator i = associations_.find(id); 950 if (i != associations_.end()) 951 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13 ); 952 return this->OnUnknownType(id); 953 } 954 955 AbstractProduct* CreateObject(const IdentifierType& id, 956 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, 957 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, 958 Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14) 959 { 960 typename IdToProductMap::iterator i = associations_.find(id); 961 if (i != associations_.end()) 962 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14 ); 963 return this->OnUnknownType(id); 964 } 965 966 AbstractProduct* CreateObject(const IdentifierType& id, 967 Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, 968 Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9, Parm10 p10, 969 Parm11 p11, Parm12 p12, Parm13 p13, Parm14 p14, Parm15 p15) 970 { 971 typename IdToProductMap::iterator i = associations_.find(id); 972 if (i != associations_.end()) 973 return (i->second)( p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15 ); 974 return this->OnUnknownType(id); 975 } 976 977 }; 978 979 #else 980 981 template 982 < 983 class AbstractProduct, 984 typename IdentifierType, 985 typename ProductCreator = AbstractProduct* (*)(), 986 template<typename, class> 987 class FactoryErrorPolicy = DefaultFactoryError 988 > 989 class Factory 990 : public FactoryErrorPolicy<IdentifierType, AbstractProduct> 991 { 992 public: 993 bool Register(const IdentifierType& id, ProductCreator creator) 994 { 995 return associations_.insert( 996 typename IdToProductMap::value_type(id, creator)).second != 0; 997 } 998 999 bool Unregister(const IdentifierType& id) 1000 { 1001 return associations_.erase(id) != 0; 1002 } 1003 1004 AbstractProduct* CreateObject(const IdentifierType& id) 1005 { 1006 typename IdToProductMap::iterator i = associations_.find(id); 1007 if (i != associations_.end()) 1008 { 1009 return (i->second)(); 1010 } 1011 return this->OnUnknownType(id); 1012 } 1013 1014 private: 1015 typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap; 1016 IdToProductMap associations_; 1017 }; 1018 1019 #endif //#define ENABLE_NEW_FACTORY_CODE 1020 1021 /** 1022 * \defgroup CloneFactoryGroup Clone Factory 1023 * \ingroup FactoriesGroup 1024 * \brief Creates a copy from a polymorphic object. 1025 * 1026 * \class CloneFactory 1027 * \ingroup CloneFactoryGroup 1028 * \brief Creates a copy from a polymorphic object. 1029 */ 1030 1031 template 1032 < 1033 class AbstractProduct, 1034 class ProductCreator = 1035 AbstractProduct* (*)(const AbstractProduct*), 1036 template<typename, class> 1037 class FactoryErrorPolicy = DefaultFactoryError 1038 > 1039 class CloneFactory 1040 : public FactoryErrorPolicy<TypeInfo, AbstractProduct> 1041 { 1042 public: 1043 bool Register(const TypeInfo& ti, ProductCreator creator) 1044 { 1045 return associations_.insert( 1046 typename IdToProductMap::value_type(ti, creator)).second != 0; 1047 } 1048 1049 bool Unregister(const TypeInfo& id) 1050 { 1051 return associations_.erase(id) != 0; 1052 } 1053 1054 AbstractProduct* CreateObject(const AbstractProduct* model) 1055 { 1056 if (model == NULL) 1057 { 1058 return NULL; 1059 } 1060 1061 typename IdToProductMap::iterator i = 1062 associations_.find(typeid(*model)); 1063 1064 if (i != associations_.end()) 1065 { 1066 return (i->second)(model); 1067 } 1068 return this->OnUnknownType(typeid(*model)); 1069 } 1070 1071 private: 1072 typedef AssocVector<TypeInfo, ProductCreator> IdToProductMap; 1073 IdToProductMap associations_; 1074 }; 1075 1076 } // namespace Loki 1077 1078 1079 #ifdef _MSC_VER 1080 #pragma warning( pop ) 1081 #endif 1082 1083 #endif // end file guardian 1084 1085