Mirror reflection library 0.5.13
|
00001 00011 #ifndef MIRROR_UTILS_POLYMORPH_FACTORY_1011291729_HPP 00012 #define MIRROR_UTILS_POLYMORPH_FACTORY_1011291729_HPP 00013 00014 #include <mirror/config.hpp> 00015 #include <mirror/factory.hpp> 00016 #include <mirror/meta_class.hpp> 00017 00018 #include <mirror/meta_prog/identity.hpp> 00019 #include <mirror/meta_prog/range.hpp> 00020 00021 #include <mirror/utils/native_types.hpp> 00022 #include <mirror/utils/polymorph_factory/fwd.hpp> 00023 #include <mirror/utils/polymorph_factory/data.hpp> 00024 #include <mirror/utils/polymorph_factory/manager_holder.hpp> 00025 #include <mirror/utils/polymorph_factory/manufacturer_holder.hpp> 00026 #include <mirror/utils/polymorph_factory/enumerator_holder.hpp> 00027 #include <mirror/utils/polymorph_factory/suppliers_holder.hpp> 00028 #include <mirror/utils/polymorph_factory/arrayer_holder.hpp> 00029 00030 #include <cassert> 00031 00032 MIRROR_NAMESPACE_BEGIN 00033 00034 template <typename FactoryTraits> 00035 struct polymorphic_factory_maker 00036 : public mirror::factory_maker< 00037 mirror::polymorph_factory_manufacturer_holder, 00038 mirror::polymorph_factory_suppliers_holder, 00039 mirror::polymorph_factory_enumerator_holder, 00040 FactoryTraits 00041 >{ }; 00042 00043 template <typename Product, class FactoryTraits> 00044 class polymorph_factory_base 00045 { 00046 private: 00047 typedef typename FactoryTraits::builder polymorph_builder; 00048 typedef typename FactoryTraits::data polymorph_data; 00049 typedef typename FactoryTraits::composite polymorph_composite; 00050 00051 typedef typename aux::reflect_type<Product>::type meta_product; 00052 00053 FactoryTraits traits; 00054 protected: 00055 polymorph_builder& builder; 00056 00057 polymorph_factory_data<FactoryTraits> root_data; 00058 00059 std::shared_ptr<polymorph_composite> composite; 00060 00061 polymorph_factory_data<FactoryTraits> data; 00062 00063 polymorph_factory_base( 00064 polymorph_builder& bldr, 00065 polymorph_data build_data 00066 ): builder(bldr) 00067 , root_data(&builder, build_data) 00068 , composite( 00069 builder.make_composite( 00070 build_data, 00071 traits.product_meta_data(meta_product()), 00072 traits.context_data(mp::empty_range()) 00073 ) 00074 ), data(root_data, composite->data()) 00075 { } 00076 public: 00077 typedef typename polymorphic_factory_maker< 00078 FactoryTraits 00079 >:: template factory<Product>::type factory_type; 00080 }; 00081 00082 template <typename Product, class FactoryTraits, class NoConstructors> 00083 class polymorph_factory_impl; 00084 00085 template <typename Product, class FactoryTraits> 00086 class polymorph_factory_impl<Product, FactoryTraits, std::false_type> 00087 : public polymorph_factory_base<Product, FactoryTraits> 00088 , public FactoryTraits::factory 00089 { 00090 private: 00091 typedef polymorph_factory_base<Product, FactoryTraits> base; 00092 typedef typename FactoryTraits::builder polymorph_builder; 00093 typedef typename FactoryTraits::data polymorph_data; 00094 typedef typename FactoryTraits::any_ptr any_ptr; 00095 typedef typename FactoryTraits::any_value any_value; 00096 00097 typename base::factory_type base_factory; 00098 public: 00099 polymorph_factory_impl( 00100 polymorph_builder& bldr, 00101 polymorph_data build_data 00102 ): base(bldr, build_data) 00103 , base_factory(this->data) 00104 { 00105 this->composite->finish(build_data); 00106 } 00107 00108 any_ptr new_(void) 00109 { 00110 this->composite->on_create(); 00111 return any_ptr(base_factory.new_()); 00112 } 00113 private: 00114 static any_value do_create(mp::identity<void>); 00115 00116 template <typename T> 00117 inline any_value do_create(mp::identity<T>) 00118 { 00119 this->composite->on_create(); 00120 return any_value(base_factory()); 00121 } 00122 public: 00123 any_value create(void) 00124 { 00125 return do_create(mp::identity<any_value>()); 00126 } 00127 }; 00128 00129 template <typename Product, class FactoryTraits> 00130 class polymorph_factory_impl<Product, FactoryTraits, std::true_type> 00131 : public FactoryTraits::factory 00132 { 00133 private: 00134 typedef typename FactoryTraits::builder polymorph_builder; 00135 typedef typename FactoryTraits::data polymorph_data; 00136 typedef typename FactoryTraits::any_ptr any_ptr; 00137 typedef typename FactoryTraits::any_value any_value; 00138 public: 00139 polymorph_factory_impl( 00140 polymorph_builder& bldr, 00141 polymorph_data build_data 00142 ){ } 00143 00144 any_ptr new_(void) 00145 { 00146 return any_ptr(); 00147 } 00148 00149 any_value create(void) 00150 { 00151 return any_value(); 00152 } 00153 }; 00154 00155 template <typename Product, class FactoryTraits> 00156 class polymorph_factory 00157 : public polymorph_factory_impl< 00158 Product, 00159 FactoryTraits, 00160 typename mirror::mp::empty< 00161 typename mirror::constructors< 00162 MIRRORED_TYPE(Product) 00163 >::type 00164 >::type 00165 > 00166 { 00167 private: 00168 typedef typename FactoryTraits::builder polymorph_builder; 00169 typedef typename FactoryTraits::data polymorph_data; 00170 typedef polymorph_factory_impl< 00171 Product, 00172 FactoryTraits, 00173 typename mirror::mp::empty< 00174 typename mirror::constructors< 00175 MIRRORED_TYPE(Product) 00176 >::type 00177 >::type 00178 > base_class; 00179 public: 00180 inline polymorph_factory( 00181 polymorph_builder& bldr, 00182 polymorph_data build_data 00183 ): base_class(bldr, build_data) 00184 { } 00185 }; 00186 00187 MIRROR_NAMESPACE_END 00188 00189 #endif // include guard 00190