Mirror reflection library 0.5.13

/home/chochlik/devel/mirror-lib/src/mirror/example/factories/input_ui.hpp

Go to the documentation of this file.
00001 
00012 #ifndef MIRROR_EXAMPLE_FACTORIES_INPUT_UI_1011291729_HPP
00013 #define MIRROR_EXAMPLE_FACTORIES_INPUT_UI_1011291729_HPP
00014 
00015 #include <iostream>
00016 #include <sstream>
00017 
00018 #include <mirror/factory.hpp>
00019 #include <mirror/meta_class.hpp>
00020 #include <mirror/meta_enum.hpp>
00021 #include <mirror/pre_registered/type/native.hpp>
00022 #include <mirror/meta_prog.hpp>
00023 #include <mirror/utils/default_suppliers.hpp>
00024 #include <mirror/utils/enum_val_by_name.hpp>
00025 
00026 namespace test {
00027 
00032 template <class Product, typename IsEnum>
00033 struct console_input_ui
00034 {
00035     Product x;
00036 
00037     struct constr_param_name_printer
00038     {
00039         template <class IterInfo>
00040         inline void operator()(IterInfo) const
00041         {
00042             if(!IterInfo::is_first::value)
00043                 std::cout << ", ";
00044             std::cout << IterInfo::type::base_name();
00045         }
00046     };
00047 
00048     struct constr_context_printer
00049     {
00050         template <class IterInfo>
00051         inline void operator()(IterInfo) const
00052         {
00053             if(!IterInfo::is_first::value)
00054                 std::cout << "::";
00055             std::cout << IterInfo::type::base_name();
00056         }
00057     };
00058 
00059     template <typename X>
00060     static bool parse_input(const std::string& input, std::true_type, X& x)
00061     {
00062         auto opt_val = mirror::enum_value_by_name<X>::get_opt(input);
00063         if(opt_val.first)
00064         {
00065             x = opt_val.second;
00066             return true;
00067         }
00068         return false;
00069     }
00070 
00071     template <typename X>
00072     static bool parse_input(const std::string& input, std::false_type, X& x)
00073     {
00074         std::stringstream tmp(input);
00075         tmp >> x;
00076         return tmp.good();
00077     }
00078 
00079     template <class ConstructionInfo>
00080     console_input_ui(
00081         int tabs,
00082         ConstructionInfo construction_info,
00083         const Product& _x
00084     ): x(_x)
00085     {
00086         using namespace mirror;
00087         // get the meta-function
00088         //
00089         std::cout <<
00090             std::string(tabs, '\t') <<
00091             "Enter " <<
00092             MIRRORED_TYPE(Product)::full_name() <<
00093             " " <<
00094             ConstructionInfo::parameter::base_name() <<
00095             " for " <<
00096             ConstructionInfo::function::full_name() <<
00097             "(";
00098         //
00099         mp::for_each_ii<typename ConstructionInfo::parameters>(
00100             constr_param_name_printer()
00101         );
00102         std::cout << ") in context (";
00103         mp::for_each_ii<typename ConstructionInfo::context>(
00104             constr_context_printer()
00105         );
00106         std::cout <<
00107             ") [" <<
00108             x <<
00109             "]" <<
00110             " = " <<
00111             ::std::flush;
00112         //
00113         while(1)
00114         {
00115             std::string input;
00116             std::getline(std::cin, input);
00117             if(!input.empty())
00118                 if(parse_input(input, IsEnum(), x))
00119                     break;
00120         }
00121     }
00122 
00123     void finish(int){ }
00124 
00125     inline Product operator()(void)
00126     {
00127         return x;
00128     }
00129 };
00130 
00131 template <class Product, class Unused>
00132 struct input_ui_enum : console_input_ui<Product, std::true_type>
00133 {
00134     template <class ConstructionInfo>
00135     inline input_ui_enum(int tabs, ConstructionInfo construction_info)
00136      : console_input_ui<Product, std::true_type>(
00137         tabs,
00138         construction_info,
00139         Product()
00140     ){ }
00141 };
00142 
00143 /*  The general implementation of the input user interface template.
00144  *  Upon construction prints-out a banner and uses a factory
00145  *  configured to use the same input user interface to construct
00146  *  the Product.
00147  */
00148 template <class Product, class Unused>
00149 struct input_ui
00150 {
00151     struct banner
00152     {
00153         template <class ConstructionInfo>
00154         banner(int tabs, ConstructionInfo)
00155         {
00156             using namespace mirror;
00157             typedef typename ConstructionInfo::parameter param;
00158             //
00159             // print some prompt
00160             std::cout <<
00161                 std::string(tabs, '\t') <<
00162                 "Get " <<
00163                 MIRRORED_TYPE(Product)::full_name() <<
00164                 " " <<
00165                 param::base_name() <<
00166                 ::std::endl;
00167         }
00168     } b;
00169 
00170     typedef typename mirror::factory_maker<
00171         ::test::input_ui,
00172         mirror::default_fact_suppliers,
00173         ::test::input_ui_enum,
00174         Unused
00175     > maker;
00176     typename maker::template factory< Product >::type f;
00177 
00178     template <class ConstructionInfo>
00179     inline input_ui(int tabs, ConstructionInfo construction_info)
00180      : b(tabs, construction_info)
00181      , f(tabs, construction_info)
00182     { }
00183 
00184     void finish(int){ }
00185 
00186     inline Product operator()(void)
00187     {
00188         return f();
00189     }
00190 };
00191 
00192 #define MIRROR_EXAMPLES_SPECIALIZE_CONSOLE_INPUT_UI(TYPE, DEFAULT) \
00193 template <class Unused>  \
00194 struct input_ui< TYPE, Unused> : console_input_ui< TYPE, std::false_type > \
00195 { \
00196     template <class ConstructionInfo> \
00197     inline input_ui(int tabs, ConstructionInfo construction_info) \
00198      : console_input_ui<TYPE, std::false_type>(\
00199         tabs, \
00200         construction_info, \
00201         DEFAULT \
00202     ){ } \
00203 };
00204 
00205 MIRROR_EXAMPLES_SPECIALIZE_CONSOLE_INPUT_UI(double, 0.0)
00206 MIRROR_EXAMPLES_SPECIALIZE_CONSOLE_INPUT_UI(std::string, std::string())
00207 
00213 template <class Unused>
00214 struct input_ui<void, Unused>
00215 {
00216     template <typename Context>
00217     input_ui(int _tabs, Context)
00218     { }
00219 
00220     void finish(int){ }
00221 
00222     template <class ConstructionInfo>
00223     inline int add_constructor(
00224         int tabs,
00225         ConstructionInfo
00226     ) const
00227     {
00228         return tabs + 1;
00229     }
00230 
00231     inline int index(void)
00232     {
00233         return 0;
00234     }
00235 };
00236 
00237 typedef mirror::factory_maker<
00238     input_ui,
00239     mirror::default_fact_suppliers,
00240     input_ui_enum,
00241     void
00242 > input_ui_factory_maker;
00243 
00244 typedef mirror::invoker_maker<
00245     input_ui,
00246     mirror::default_fact_suppliers,
00247     input_ui_enum,
00248     void
00249 > input_ui_invoker_maker;
00250 
00251 } // namespace test
00252 
00253 #endif
00254 

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.