Mirror reflection library 0.5.13

mirror/utils/polymorph_factory.hpp

Go to the documentation of this file.
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 

Copyright © 2006-2011 Matus Chochlik, University of Zilina, Zilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Fri Dec 16 2011 by Doxygen (version 1.7.3).
Important note: Although the 'boostified' version of Mirror uses the Boost C++ libraries Coding Guidelines and is implemented inside of the boost namespace, it IS NOT an officially reviewed and accepted Boost library. Mirror is being developed with the intention to be submitted for review for inclusion to the Boost C++ libraries.