Mirror reflection library - Lagoon run-time layer 0.5.13
|
00001 00011 #ifndef LAGOON_POLYMORPH_FACTORY_1011291729_HPP 00012 #define LAGOON_POLYMORPH_FACTORY_1011291729_HPP 00013 00014 #include <lagoon/lagoon_fwd.hpp> 00015 #include <lagoon/utils.hpp> 00016 #include <lagoon/auxiliary/range_maker.hpp> 00017 #include <mirror/utils/polymorph_factory.hpp> 00018 00019 #if LAGOON_FACT_WITH_CREATE 00020 #include <boost/any.hpp> 00021 #endif 00022 00023 #include <vector> 00024 00025 LAGOON_NAMESPACE_BEGIN 00026 00037 // TODO: add a compile time switch between this and a real range 00038 // of meta-objects representing the context of the factory 00039 struct polymorph_factory_context 00040 { 00041 private: 00042 // the meta-object interface used by the context 00043 typedef meta_named_scoped_object mo_interface; 00044 // holder of the composite of meta-objects in the context 00045 struct item_list_holder 00046 { 00047 // the composite of context meta-object 00048 std::vector<shared<mo_interface> > item_list; 00049 00050 template <class Context> 00051 item_list_holder(Context) 00052 { 00053 mirror::mp::for_each<Context> 00054 (aux::range_maker<mo_interface>(item_list)); 00055 } 00056 } holder; 00057 public: 00058 template <class Context> 00059 polymorph_factory_context(Context context) 00060 : holder(context) 00061 { } 00062 00063 inline range<mo_interface> all(void) const 00064 { 00065 return range<mo_interface>( 00066 holder.item_list.begin(), 00067 holder.item_list.end() 00068 ); 00069 } 00070 }; 00071 00073 00079 struct polymorph_factory_manager 00080 { 00081 virtual ~polymorph_factory_manager(void) 00082 { } 00083 00084 virtual raw_ptr data(void) 00085 { 00086 return raw_ptr(); 00087 } 00088 00089 virtual raw_ptr add_constructor( 00090 raw_ptr data, 00091 const shared<meta_constructor>& constructor, 00092 const polymorph_factory_context& context, 00093 bool backward_iteration 00094 ) 00095 { 00096 return raw_ptr(); 00097 } 00098 00099 virtual void finish(raw_ptr data) 00100 { } 00101 00102 virtual int index(void) = 0; 00103 }; 00104 00106 00111 struct polymorph_factory_composite 00112 { 00113 virtual ~polymorph_factory_composite(void) 00114 { } 00115 00116 virtual raw_ptr data(void) 00117 { 00118 return raw_ptr(); 00119 } 00120 00121 virtual void finish(raw_ptr data) 00122 { } 00123 00124 virtual void on_create(void) 00125 { } 00126 }; 00127 00129 00134 struct polymorph_factory_arrayer 00135 { 00136 virtual ~polymorph_factory_arrayer(void) 00137 { } 00138 00139 virtual raw_ptr data(void) 00140 { 00141 return raw_ptr(); 00142 } 00143 00144 virtual void finish(raw_ptr data) 00145 { } 00146 00148 struct element_producer 00149 { 00150 virtual ~element_producer(void) 00151 { } 00152 00154 virtual void reset(void) = 0; 00155 00157 virtual void make_next(void) = 0; 00158 }; 00159 00161 virtual void assign_producer(element_producer& producer) 00162 { } 00163 00165 00168 virtual void create(element_producer& producer) = 0; 00169 }; 00170 00172 00179 template <typename Product> 00180 struct polymorph_factory_manufacturer 00181 { 00182 virtual ~polymorph_factory_manufacturer(void) 00183 { } 00184 00185 virtual void finish(raw_ptr parent_data) 00186 { } 00187 00188 virtual Product create(void) = 0; 00189 }; 00190 00192 00197 struct polymorph_factory_suppliers 00198 { 00199 virtual ~polymorph_factory_suppliers(void) 00200 { } 00201 00202 virtual void finish(raw_ptr parent_data) 00203 { } 00204 00206 00208 virtual raw_ptr get(void) = 0; 00209 }; 00210 00212 00219 struct polymorph_factory_enumerator 00220 { 00221 virtual ~polymorph_factory_enumerator(void) 00222 { } 00223 00224 virtual void finish(raw_ptr parent_data) 00225 { } 00226 00227 virtual int create(void) = 0; 00228 }; 00229 00230 // Builder's helper subinterface for instantiating manufacturers of a Product 00231 /* The individual builder units are composed together based on the 00232 * native types type range by the means of polymorph_factory_builder_units 00233 * 00234 * @ingroup lagoon_polymorphic_factories 00235 */ 00236 template <typename Product> 00237 class polymorph_factory_builder_unit 00238 { 00239 protected: 00240 virtual ~polymorph_factory_builder_unit(void) 00241 { } 00242 public: 00243 virtual std::shared_ptr<polymorph_factory_manufacturer<Product> > 00244 make_manufacturer( 00245 raw_ptr parent_data, 00246 const shared<meta_parameter>& ctr_param, 00247 const polymorph_factory_context& context 00248 ) = 0; 00249 }; 00250 00251 // Forward declaration of the builder unit composer 00252 template <template <class> class Unit, class Range> 00253 struct polymorph_factory_builder_units; 00254 00255 // Implementation of builder unit composer 00256 template <template <class> class Unit, typename ... P> 00257 class polymorph_factory_builder_units<Unit, mirror::mp::range<P...> > 00258 : virtual public Unit<P>... 00259 { 00260 private: 00261 template <class Product> 00262 Unit<Product>* this_unit(void) 00263 { 00264 return this; 00265 } 00266 public: 00267 template <typename Product> 00268 inline std::shared_ptr<polymorph_factory_manufacturer<Product> > 00269 make_manufacturer( 00270 raw_ptr parent_data, 00271 const shared<meta_parameter>& ctr_param, 00272 const polymorph_factory_context& context, 00273 mirror::mp::identity<Product> 00274 ) 00275 { 00276 return this_unit<Product>()->make_manufacturer( 00277 parent_data, 00278 ctr_param, 00279 context 00280 ); 00281 } 00282 }; 00283 00285 00297 struct polymorph_factory_builder 00298 : public polymorph_factory_builder_units< 00299 polymorph_factory_builder_unit, 00300 mirror::util_native_types 00301 > 00302 { 00303 virtual ~polymorph_factory_builder(void) 00304 { } 00305 00306 virtual std::shared_ptr<polymorph_factory_manager> 00307 make_manager( 00308 raw_ptr parent_data, 00309 const polymorph_factory_context& context 00310 ) = 0; 00311 00312 virtual std::shared_ptr<polymorph_factory_composite> 00313 make_composite( 00314 raw_ptr parent_data, 00315 const shared<meta_parameter>& func_param, 00316 const polymorph_factory_context& context 00317 ) = 0; 00318 00319 virtual std::shared_ptr<polymorph_factory_composite> 00320 make_composite( 00321 raw_ptr parent_data, 00322 const shared<meta_type>& product, 00323 const polymorph_factory_context& context 00324 ) = 0; 00325 00326 virtual std::shared_ptr<polymorph_factory_arrayer> 00327 make_arrayer( 00328 raw_ptr parent_data, 00329 const shared<meta_type>& element, 00330 const polymorph_factory_context& context 00331 ) = 0; 00332 00333 virtual std::shared_ptr<polymorph_factory_suppliers> 00334 make_suppliers( 00335 raw_ptr parent_data, 00336 const shared<meta_parameter>& ctr_param, 00337 const polymorph_factory_context& context 00338 ) = 0; 00339 00340 virtual std::shared_ptr<polymorph_factory_enumerator> 00341 make_enumerator( 00342 raw_ptr parent_data, 00343 const shared<meta_parameter>& ctr_param, 00344 const polymorph_factory_context& context 00345 ) = 0; 00346 }; 00347 00348 template < 00349 template <class> class ConcreteUnit, 00350 class Range 00351 > class concrete_polymorph_factory_bldr_hlpr; 00352 00353 template < 00354 template <class> class ConcreteUnit, 00355 typename T, 00356 typename ... P 00357 > class concrete_polymorph_factory_bldr_hlpr< 00358 ConcreteUnit, 00359 mirror::mp::range<T, P...> 00360 >: public ConcreteUnit<T> 00361 , public concrete_polymorph_factory_bldr_hlpr< 00362 ConcreteUnit, 00363 mirror::mp::range<P...> 00364 >{ }; 00365 00366 template < 00367 template <class> class ConcreteUnit 00368 > class concrete_polymorph_factory_bldr_hlpr< 00369 ConcreteUnit, 00370 mirror::mp::range<> 00371 >: public polymorph_factory_builder 00372 { }; 00373 00374 template <template <class> class BaseUnit> 00375 struct concrete_polymorph_factory_builder_unit 00376 { 00377 public: 00378 template <class Product> 00379 class impl 00380 : virtual public polymorph_factory_builder_unit<Product> 00381 , public BaseUnit<Product> 00382 { 00383 private: 00384 BaseUnit<Product>& base_unit(void) 00385 { 00386 return *this; 00387 } 00388 public: 00389 std::shared_ptr<polymorph_factory_manufacturer<Product> > 00390 make_manufacturer( 00391 raw_ptr parent_data, 00392 const shared<meta_parameter>& param, 00393 const polymorph_factory_context& context 00394 ) 00395 { 00396 return std::shared_ptr< 00397 polymorph_factory_manufacturer<Product> 00398 >(base_unit().make_manufacturer( 00399 parent_data, 00400 param, 00401 context 00402 )); 00403 } 00404 }; 00405 }; 00406 00407 template <class BaseBuilder, template <class> class BaseUnit> 00408 class concrete_polymorph_factory_builder 00409 : public BaseBuilder 00410 , public concrete_polymorph_factory_bldr_hlpr< 00411 concrete_polymorph_factory_builder_unit<BaseUnit>::template impl, 00412 mirror::util_native_types 00413 > 00414 { 00415 private: 00416 BaseBuilder& base_builder(void) 00417 { 00418 return *this; 00419 } 00420 public: 00421 std::shared_ptr<polymorph_factory_manager> 00422 make_manager( 00423 raw_ptr parent_data, 00424 const polymorph_factory_context& context 00425 ) 00426 { 00427 return std::shared_ptr<polymorph_factory_manager>( 00428 base_builder().make_manager(parent_data, context) 00429 ); 00430 } 00431 00432 std::shared_ptr<polymorph_factory_composite> 00433 make_composite( 00434 raw_ptr parent_data, 00435 const shared<meta_type>& product, 00436 const polymorph_factory_context& context 00437 ) 00438 { 00439 return std::shared_ptr<polymorph_factory_composite>( 00440 base_builder().make_composite( 00441 parent_data, 00442 product, 00443 context 00444 ) 00445 ); 00446 } 00447 00448 std::shared_ptr<polymorph_factory_composite> 00449 make_composite( 00450 raw_ptr parent_data, 00451 const shared<meta_parameter>& param, 00452 const polymorph_factory_context& context 00453 ) 00454 { 00455 return std::shared_ptr<polymorph_factory_composite>( 00456 base_builder().make_composite( 00457 parent_data, 00458 param, 00459 context 00460 ) 00461 ); 00462 } 00463 00464 std::shared_ptr<polymorph_factory_arrayer> 00465 make_arrayer( 00466 raw_ptr parent_data, 00467 const shared<meta_type>& element, 00468 const polymorph_factory_context& context 00469 ) 00470 { 00471 return std::shared_ptr<polymorph_factory_arrayer>( 00472 base_builder().make_arrayer( 00473 parent_data, 00474 element, 00475 context 00476 ) 00477 ); 00478 } 00479 00480 std::shared_ptr<polymorph_factory_suppliers> 00481 make_suppliers( 00482 raw_ptr parent_data, 00483 const shared<meta_parameter>& param, 00484 const polymorph_factory_context& context 00485 ) 00486 { 00487 return std::shared_ptr<polymorph_factory_suppliers>( 00488 base_builder().make_suppliers( 00489 parent_data, 00490 param, 00491 context 00492 ) 00493 ); 00494 } 00495 00496 std::shared_ptr<polymorph_factory_enumerator> 00497 make_enumerator( 00498 raw_ptr parent_data, 00499 const shared<meta_parameter>& param, 00500 const polymorph_factory_context& context 00501 ) 00502 { 00503 return std::shared_ptr<polymorph_factory_enumerator>( 00504 base_builder().make_enumerator( 00505 parent_data, 00506 param, 00507 context 00508 ) 00509 ); 00510 } 00511 00512 }; 00513 00515 00522 struct polymorph_factory 00523 { 00524 virtual ~polymorph_factory(void) 00525 { } 00526 00528 00532 virtual raw_ptr new_(void) = 0; 00533 00534 #if LAGOON_FACT_WITH_CREATE || \ 00535 MIRROR_DOCUMENTATION_ONLY 00536 00537 00544 virtual boost::any create(void) = 0; 00545 #endif 00546 }; 00547 00548 LAGOON_NAMESPACE_END 00549 00550 #endif // include guard 00551