00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 #ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_CLONE_FACTORY_H
00122 #define LASS_GUARDIAN_OF_INCLUSION_UTIL_CLONE_FACTORY_H
00123
00124 #include "util_common.h"
00125 #include "shared_ptr.h"
00126
00127 namespace lass
00128 {
00129 namespace util
00130 {
00131
00132 template
00133 <
00134 class AbstractProduct,
00135 class IdentifierType,
00136 class ProductCloner = AbstractProduct*(*)(const AbstractProduct&)
00137 >
00138 class CloneFactory
00139 {
00140 public:
00141
00142 typedef AbstractProduct TAbstractProduct;
00143 typedef IdentifierType TIdentifier;
00144 typedef ProductCloner TProductCloner;
00145
00146
00147
00148 CloneFactory(typename CallTraits<ProductCloner>::TParam iCloner):
00149 cloner_(iCloner)
00150 {
00151 }
00152
00153
00154
00155
00156 bool subscribe(typename CallTraits<IdentifierType>::TParam iIdentifier,
00157 std::auto_ptr<AbstractProduct> iPrototype)
00158 {
00159 return prototypes_.insert(typename TPrototypes::value_type(iIdentifier, iPrototype)).second;
00160 }
00161
00162
00163
00164 bool unsubscribe(typename CallTraits<IdentifierType>::TParam iIdentifier)
00165 {
00166 return prototypes_.erase(iIdentifier) == 1;
00167 }
00168
00169
00170
00171
00172 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier) const
00173 {
00174 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00175 if (i == prototypes_.end())
00176 {
00177 LASS_THROW("Unknown Product identifier '" << iIdentifier
00178 << "' passed to CloneFactory.");
00179 }
00180 return cloner_(*i->second);
00181 }
00182
00183
00184
00185
00186 template <typename P1>
00187 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00188 P1& iP1) const
00189 {
00190 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00191 if (i == prototypes_.end())
00192 {
00193 LASS_THROW("Unknown Product identifier '" << iIdentifier
00194 << "' passed to CloneFactory.");
00195 }
00196 return cloner_(*i->second, iP1);
00197 }
00198
00199
00200
00201
00202 template <typename P1, typename P2>
00203 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00204 P1& iP1, P2& iP2) const
00205 {
00206 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00207 if (i == prototypes_.end())
00208 {
00209 LASS_THROW("Unknown Product identifier '" << iIdentifier
00210 << "' passed to CloneFactory.");
00211 }
00212 return cloner_(*i->second, iP1, iP2);
00213 }
00214
00215
00216
00217
00218 template <typename P1, typename P2, typename P3>
00219 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00220 P1& iP1, P2& iP2, P3& iP3) const
00221 {
00222 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00223 if (i == prototypes_.end())
00224 {
00225 LASS_THROW("Unknown Product identifier '" << iIdentifier
00226 << "' passed to CloneFactory.");
00227 }
00228 return cloner_(*i->second, iP1, iP2, iP3);
00229 }
00230
00231
00232
00233
00234 template <typename P1, typename P2, typename P3, typename P4>
00235 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00236 P1& iP1, P2& iP2, P3& iP3, P4& iP4) const
00237 {
00238 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00239 if (i == prototypes_.end())
00240 {
00241 LASS_THROW("Unknown Product identifier '" << iIdentifier
00242 << "' passed to CloneFactory.");
00243 }
00244 return cloner_(*i->second, iP1, iP2, iP3, iP4);
00245 }
00246
00247
00248
00249
00250 template <typename P1, typename P2, typename P3, typename P4, typename P5>
00251 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00252 P1& iP1, P2& iP2, P3& iP3, P4& iP4, P5& iP5) const
00253 {
00254 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00255 if (i == prototypes_.end())
00256 {
00257 LASS_THROW("Unknown Product identifier '" << iIdentifier
00258 << "' passed to CloneFactory.");
00259 }
00260 return cloner_(*i->second, iP1, iP2, iP3, iP4, iP5);
00261 }
00262
00263
00264
00265
00266 template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
00267 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00268 P1& iP1, P2& iP2, P3& iP3, P4& iP4, P5& iP5, P6& iP6) const
00269 {
00270 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00271 if (i == prototypes_.end())
00272 {
00273 LASS_THROW("Unknown Product identifier '" << iIdentifier
00274 << "' passed to CloneFactory.");
00275 }
00276 return cloner_(*i->second, iP1, iP2, iP3, iP4, iP5, iP6);
00277 }
00278
00279
00280
00281
00282 template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
00283 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00284 P1& iP1, P2& iP2, P3& iP3, P4& iP4, P5& iP5, P6& iP6, P7& iP7) const
00285 {
00286 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00287 if (i == prototypes_.end())
00288 {
00289 LASS_THROW("Unknown Product identifier '" << iIdentifier
00290 << "' passed to CloneFactory.");
00291 }
00292 return cloner_(*i->second, iP1, iP2, iP3, iP4, iP5, iP6, iP7);
00293 }
00294
00295
00296
00297
00298 template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
00299 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00300 P1& iP1, P2& iP2, P3& iP3, P4& iP4, P5& iP5, P6& iP6, P7& iP7, P8& iP8) const
00301 {
00302 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00303 if (i == prototypes_.end())
00304 {
00305 LASS_THROW("Unknown Product identifier '" << iIdentifier
00306 << "' passed to CloneFactory.");
00307 }
00308 return cloner_(*i->second, iP1, iP2, iP3, iP4, iP5, iP6, iP7, iP8);
00309 }
00310
00311
00312
00313
00314 template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9>
00315 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00316 P1& iP1, P2& iP2, P3& iP3, P4& iP4, P5& iP5, P6& iP6, P7& iP7, P8& iP8, P9& iP9) const
00317 {
00318 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00319 if (i == prototypes_.end())
00320 {
00321 LASS_THROW("Unknown Product identifier '" << iIdentifier
00322 << "' passed to CloneFactory.");
00323 }
00324 return cloner_(*i->second, iP1, iP2, iP3, iP4, iP5, iP6, iP7, iP8, iP9);
00325 }
00326
00327
00328
00329
00330 template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10>
00331 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00332 P1& iP1, P2& iP2, P3& iP3, P4& iP4, P5& iP5, P6& iP6, P7& iP7, P8& iP8, P9& iP9, P10& iP10) const
00333 {
00334 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00335 if (i == prototypes_.end())
00336 {
00337 LASS_THROW("Unknown Product identifier '" << iIdentifier
00338 << "' passed to CloneFactory.");
00339 }
00340 return cloner_(*i->second, iP1, iP2, iP3, iP4, iP5, iP6, iP7, iP8, iP9, iP10);
00341 }
00342
00343
00344
00345
00346 template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11>
00347 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00348 P1& iP1, P2& iP2, P3& iP3, P4& iP4, P5& iP5, P6& iP6, P7& iP7, P8& iP8, P9& iP9, P10& iP10, P11& iP11) const
00349 {
00350 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00351 if (i == prototypes_.end())
00352 {
00353 LASS_THROW("Unknown Product identifier '" << iIdentifier
00354 << "' passed to CloneFactory.");
00355 }
00356 return cloner_(*i->second, iP1, iP2, iP3, iP4, iP5, iP6, iP7, iP8, iP9, iP10, iP11);
00357 }
00358
00359
00360
00361
00362 template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12>
00363 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00364 P1& iP1, P2& iP2, P3& iP3, P4& iP4, P5& iP5, P6& iP6, P7& iP7, P8& iP8, P9& iP9, P10& iP10, P11& iP11, P12& iP12) const
00365 {
00366 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00367 if (i == prototypes_.end())
00368 {
00369 LASS_THROW("Unknown Product identifier '" << iIdentifier
00370 << "' passed to CloneFactory.");
00371 }
00372 return cloner_(*i->second, iP1, iP2, iP3, iP4, iP5, iP6, iP7, iP8, iP9, iP10, iP11, iP12);
00373 }
00374
00375
00376
00377
00378 template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12, typename P13>
00379 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00380 P1& iP1, P2& iP2, P3& iP3, P4& iP4, P5& iP5, P6& iP6, P7& iP7, P8& iP8, P9& iP9, P10& iP10, P11& iP11, P12& iP12, P13& iP13) const
00381 {
00382 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00383 if (i == prototypes_.end())
00384 {
00385 LASS_THROW("Unknown Product identifier '" << iIdentifier
00386 << "' passed to CloneFactory.");
00387 }
00388 return cloner_(*i->second, iP1, iP2, iP3, iP4, iP5, iP6, iP7, iP8, iP9, iP10, iP11, iP12, iP13);
00389 }
00390
00391
00392
00393
00394 template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12, typename P13, typename P14>
00395 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00396 P1& iP1, P2& iP2, P3& iP3, P4& iP4, P5& iP5, P6& iP6, P7& iP7, P8& iP8, P9& iP9, P10& iP10, P11& iP11, P12& iP12, P13& iP13, P14& iP14) const
00397 {
00398 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00399 if (i == prototypes_.end())
00400 {
00401 LASS_THROW("Unknown Product identifier '" << iIdentifier
00402 << "' passed to CloneFactory.");
00403 }
00404 return cloner_(*i->second, iP1, iP2, iP3, iP4, iP5, iP6, iP7, iP8, iP9, iP10, iP11, iP12, iP13, iP14);
00405 }
00406
00407
00408
00409
00410 template <typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8, typename P9, typename P10, typename P11, typename P12, typename P13, typename P14, typename P15>
00411 AbstractProduct* make(typename CallTraits<IdentifierType>::TParam iIdentifier,
00412 P1& iP1, P2& iP2, P3& iP3, P4& iP4, P5& iP5, P6& iP6, P7& iP7, P8& iP8, P9& iP9, P10& iP10, P11& iP11, P12& iP12, P13& iP13, P14& iP14, P15& iP15) const
00413 {
00414 typename TPrototypes::const_iterator i = prototypes_.find(iIdentifier);
00415 if (i == prototypes_.end())
00416 {
00417 LASS_THROW("Unknown Product identifier '" << iIdentifier
00418 << "' passed to CloneFactory.");
00419 }
00420 return cloner_(*i->second, iP1, iP2, iP3, iP4, iP5, iP6, iP7, iP8, iP9, iP10, iP11, iP12, iP13, iP14, iP15);
00421 }
00422
00423
00424 private:
00425
00426 typedef SharedPtr<AbstractProduct> TPrototypePtr;
00427 typedef std::map<IdentifierType, TPrototypePtr> TPrototypes;
00428
00429 TPrototypes prototypes_;
00430 TProductCloner cloner_;
00431 };
00432
00433
00434
00435 }
00436
00437 }
00438
00439 #endif
00440
00441