Mirror reflection library 0.5.13
|
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