00001
00002
00003
00004
00005
00006
00007
00008 #include <utility>
00009 #include <set>
00010 #include <string>
00011 #include <cctype>
00012 #include <typeinfo>
00013
00014 #include <boost/type_traits/is_same.hpp>
00015 #include <boost/type_traits/is_polymorphic.hpp>
00016 #include <boost/type_traits/is_base_of.hpp>
00017 #include <boost/type_traits/is_convertible.hpp>
00018 #include <boost/static_assert.hpp>
00019
00020 #include "execution_context.hpp"
00021
00022
00023
00024
00025 class EVAL_EXECUTION_CONTEXT_NAME : public eval::execution_context
00026 {
00027 public:
00028 EVAL_EXECUTION_CONTEXT_NAME()
00029 : eval::execution_context()
00030 {
00031 }
00032
00033
00034 virtual ~EVAL_EXECUTION_CONTEXT_NAME()
00035 {
00036 }
00037
00038 protected:
00039
00040 virtual void register_functions();
00041
00042 virtual void register_methods_and_ctors();
00043
00044 virtual void register_types();
00045
00046 virtual void register_conversions();
00047
00048 private:
00049
00051 EVAL_EXECUTION_CONTEXT_NAME(const EVAL_EXECUTION_CONTEXT_NAME& e);
00053 EVAL_EXECUTION_CONTEXT_NAME& operator=(const EVAL_EXECUTION_CONTEXT_NAME& rhs);
00054 };
00055
00056
00057
00058 #define EVAL_NOTHING
00059 #define EVAL_BRACKET_OPEN (
00060 #define EVAL_BRACKET_CLOSE )
00061
00062
00063
00064
00065
00066
00067 #include "detail/reset_execution_context_macros.hpp"
00068
00069
00070
00071
00072 #ifndef EVAL_EXECUTION_CONTEXT_DEFINITION_H
00073 #define EVAL_EXECUTION_CONTEXT_DEFINITION_H
00074
00075 # define EVAL_REGISTER_TYPE(T) \
00076 EVAL_REGISTER_TYPE_RENAME(T, T)
00077
00078 # define EVAL_REGISTER_FUNCTION(f) \
00079 EVAL_REGISTER_FUNCTION_RENAME(f, f)
00080
00081 # define EVAL_REGISTER_FUNCTION_RENAME(f, name) \
00082 EVAL_REGISTER_FUNCTION_IMPL(EVAL_NOTHING, f, EVAL_NOTHING, name)
00083
00084 # define EVAL_REGISTER_FUNCTION_OVERLOADED(RvT, ArgT, f) \
00085 EVAL_REGISTER_FUNCTION_OVERLOADED_RENAME(RvT, ArgT, f, f)
00086
00087 # define EVAL_REGISTER_FUNCTION_OVERLOADED_RENAME(RvT, ArgT, f, name) \
00088 EVAL_REGISTER_FUNCTION_IMPL(static_cast<RvT (*) ArgT > EVAL_BRACKET_OPEN, \
00089 f, EVAL_BRACKET_CLOSE, name)
00090
00091 # define EVAL_REGISTER_METHOD(m) \
00092 EVAL_REGISTER_METHOD_RENAME(m, m)
00093
00094 # define EVAL_REGISTER_METHOD_OVERLOADED(RvT, ArgT, m) \
00095 EVAL_REGISTER_METHOD_OVERLOADED_RENAME(RvT, ArgT, m, m)
00096
00097 # define EVAL_REGISTER_STATIC_METHOD(m) \
00098 EVAL_REGISTER_STATIC_METHOD_RENAME(m, m)
00099
00100 # define EVAL_REGISTER_STATIC_METHOD_RENAME(m, name) \
00101 EVAL_REGISTER_STATIC_METHOD_IMPL(EVAL_NOTHING, m, EVAL_NOTHING, name)
00102
00103 # define EVAL_REGISTER_STATIC_METHOD_OVERLOADED(RvT, ArgT, m) \
00104 EVAL_REGISTER_STATIC_METHOD_OVERLOADED_RENAME(RvT, ArgT, m, m)
00105
00106 # define EVAL_REGISTER_STATIC_METHOD_OVERLOADED_RENAME(RvT, ArgT, m, name) \
00107 EVAL_REGISTER_STATIC_METHOD_IMPL(static_cast<RvT (*) ArgT > EVAL_BRACKET_OPEN, \
00108 m, EVAL_BRACKET_CLOSE, name)
00109
00110
00111
00112 namespace eval
00113 {
00114 namespace detail
00115 {
00116 std::string remove_spaces(const char *str)
00117 {
00118 std::string rv;
00119 for( ; *str; str++)
00120 {
00121 if(!std::isspace(*str))
00122 {
00123 rv += *str;
00124 }
00125 }
00126 return rv;
00127 }
00128 }
00129 }
00130
00131
00132
00133 #endif // include guard
00134
00135 void inline EVAL_EXECUTION_CONTEXT_NAME::register_functions()
00136 {
00137 #undef EVAL_REGISTER_FUNCTION_IMPL
00138 #define EVAL_REGISTER_FUNCTION_IMPL(begin_cast, f, end_cast, name) \
00139 _functions.insert(std::pair<std::string, eval::fwrap>(eval::detail::remove_spaces(#name), \
00140 eval::fwrap( begin_cast &f end_cast )));
00141
00142 # include "detail/include_eval_include_files.hpp"
00143
00144 # include "detail/reset_execution_context_macros.hpp"
00145
00146 }
00147
00148
00149
00150
00151 namespace eval
00152 {
00153 namespace detail
00154 {
00155 namespace EVAL_EXECUTION_CONTEXT_NAME
00156 {
00157 template<typename BaseT, typename SuperT>
00158 class methods_and_ctors_for_type
00159 {
00160 BOOST_STATIC_ASSERT(sizeof(BaseT) == 0);
00161 };
00162
00163 #undef EVAL_REGISTER_TYPE_RENAME
00164 #define EVAL_REGISTER_TYPE_RENAME(T, name) \
00165 template<typename SuperT> \
00166 class methods_and_ctors_for_type<T, SuperT> \
00167 { \
00168 public: \
00169 typedef T BaseT; \
00170 \
00171 \
00172 static void add_to(std::string type_name, object_method_store *methods, \
00173 std::multimap<std::string, fwrap> *ctor_store, \
00174 std::multimap<std::string, fwrap> *static_store2) \
00175 { \
00176 std::set<std::string> methods_added; \
00177 std::pair<std::set<std::string>::iterator, bool> set_rv;
00178
00179
00180
00181 #undef EVAL_INHERIT_FROM
00182 #define EVAL_INHERIT_FROM(T) \
00183 methods_and_ctors_for_type<T, SuperT>::add_to(type_name, methods, 0, \
00184 static_store2);
00185
00186 #undef EVAL_REGISTER_CONSTRUCTOR
00187 #define EVAL_REGISTER_CONSTRUCTOR(ArgT) \
00188 if(ctor_store) \
00189 { \
00190 ctor_store->insert(std::pair<std::string, eval::fwrap>( \
00191 type_name, \
00192 eval::fwrap::wrap_ctor<BaseT, void (*) ArgT>()));\
00193 }
00194
00195 #undef EVAL_REGISTER_CONSTRUCTOR_RENAME
00196 #define EVAL_REGISTER_CONSTRUCTOR_RENAME(ArgT, name) \
00197 if(ctor_store) \
00198 { \
00199 ctor_store->insert(std::pair<std::string, eval::fwrap>( \
00200 eval::detail::remove_spaces(#name), \
00201 eval::fwrap::wrap_ctor<BaseT, void (*) ArgT>()));\
00202 }
00203
00204 #undef EVAL_REGISTER_METHOD_RENAME
00205 #define EVAL_REGISTER_METHOD_RENAME(m, name) \
00206 set_rv = methods_added.insert(eval::detail::remove_spaces(#name)); \
00207 if(set_rv.second == true) \
00208 { \
00209 \
00210 \
00211 \
00212 methods->delete_methods(eval::detail::remove_spaces(#name)); \
00213 } \
00214 methods->add_method(eval::detail::remove_spaces(#name), \
00215 fwrap(&SuperT::m));
00216
00217 #undef EVAL_REGISTER_METHOD_OVERLOADED_RENAME
00218 #define EVAL_REGISTER_METHOD_OVERLOADED_RENAME(RvT, ArgT, m, name) \
00219 set_rv = methods_added.insert(eval::detail::remove_spaces(#name)); \
00220 if(set_rv.second == true) \
00221 { \
00222 \
00223 \
00224 \
00225 methods->delete_methods(eval::detail::remove_spaces(#name)); \
00226 } \
00227 methods->add_method(eval::detail::remove_spaces(#name), \
00228 fwrap(static_cast<RvT (SuperT::*) ArgT>(&SuperT::m)));
00229
00230
00231 #undef EVAL_REGISTER_STATIC_METHOD_IMPL
00232 #define EVAL_REGISTER_STATIC_METHOD_IMPL(begin_cast, m, end_cast, name) \
00233 set_rv = methods_added.insert(eval::detail::remove_spaces(#name)); \
00234 if(set_rv.second == true) \
00235 { \
00236 \
00237 \
00238 \
00239 methods->delete_methods(eval::detail::remove_spaces(#name)); \
00240 std::pair<std::multimap<std::string, eval::fwrap>::iterator, \
00241 std::multimap<std::string, eval::fwrap>::iterator \
00242 > static_remove_range; \
00243 static_remove_range = static_store2->equal_range(type_name + "::" \
00244 + eval::detail::remove_spaces(#name)); \
00245 static_store2->erase(static_remove_range.first, \
00246 static_remove_range.second); \
00247 } \
00248 methods->add_static_method(eval::detail::remove_spaces(#name), \
00249 fwrap(begin_cast &SuperT::m end_cast)); \
00250 static_store2->insert(std::pair<std::string, eval::fwrap>( \
00251 type_name + "::" + eval::detail::remove_spaces(#name), \
00252 fwrap(begin_cast &SuperT::m end_cast)));
00253
00254
00255 #undef EVAL_END_TYPE
00256 #define EVAL_END_TYPE \
00257 } \
00258 };
00259
00260 # include "detail/include_eval_include_files.hpp"
00261
00262 # include "detail/reset_execution_context_macros.hpp"
00263
00264
00265 }
00266 }
00267 }
00268
00269
00270 void inline EVAL_EXECUTION_CONTEXT_NAME::register_methods_and_ctors()
00271 {
00272 #undef EVAL_REGISTER_TYPE_RENAME
00273 #define EVAL_REGISTER_TYPE_RENAME(T, name) \
00274 { \
00275 eval::detail::object_method_store *m; \
00276 m = new eval::detail::object_method_store(eval::detail::remove_spaces(#name)); \
00277 _objects.insert(std::pair<const std::type_info *, \
00278 eval::detail::object_method_store *>(&typeid(T), m)); \
00279 eval::detail::EVAL_EXECUTION_CONTEXT_NAME::methods_and_ctors_for_type<T, T> \
00280 ::add_to(eval::detail::remove_spaces(#name), m, \
00281 &_functions, &_functions); \
00282 }
00283
00284 # include "detail/include_eval_include_files.hpp"
00285
00286 # include "detail/reset_execution_context_macros.hpp"
00287 }
00288
00289
00290 void inline EVAL_EXECUTION_CONTEXT_NAME::register_types()
00291 {
00292 #undef EVAL_REGISTER_TYPE_RENAME
00293 #define EVAL_REGISTER_TYPE_RENAME(T, name) \
00294 _types.insert(std::pair<std::string, const std::type_info *>( \
00295 eval::detail::remove_spaces(#name), &typeid(T)));
00296
00297 # include "detail/include_eval_include_files.hpp"
00298
00299 # include "detail/reset_execution_context_macros.hpp"
00300 }
00301
00302
00303 namespace eval
00304 {
00305 namespace detail
00306 {
00307 namespace EVAL_EXECUTION_CONTEXT_NAME
00308 {
00309 template<typename CurrentT, typename DesiredT>
00310 inline val ptr_convert(val& v)
00311 {
00312
00313
00314 if(v.is_const())
00315 {
00316 const CurrentT *curr = val_cast_ptr<const CurrentT>(v);
00317 const DesiredT *converted = curr;
00318 return val(converted, UNMANAGED_PTR);
00319 }
00320 else
00321 {
00322 CurrentT *curr = val_cast_ptr<CurrentT>(v);
00323 DesiredT *converted = curr;
00324 return val(converted, UNMANAGED_PTR);
00325 }
00326 }
00327
00328 template<typename CurrentT, typename DesiredT>
00329 inline val dynamic_ptr_convert(val& v)
00330 {
00331 if(v.is_const())
00332 {
00333 const CurrentT *curr = val_cast_ptr<const CurrentT>(v);
00334 return val(dynamic_cast<const DesiredT *>(curr), UNMANAGED_PTR);
00335 }
00336 else
00337 {
00338 CurrentT *curr = val_cast_ptr<CurrentT>(v);
00339 return val(dynamic_cast<DesiredT *>(curr), UNMANAGED_PTR);
00340 }
00341 }
00342
00343 template<typename CurrentT, typename DesiredT>
00344 inline val value_convert(val& v)
00345 {
00346 BOOST_STATIC_ASSERT((boost::is_convertible<CurrentT, DesiredT>::value));
00347
00348 const CurrentT& curr = *val_cast_ptr<const CurrentT>(v);
00349
00350
00351
00352
00353
00354
00355
00356 DesiredT *new_ptr = new DesiredT(curr);
00357 return val(new_ptr, TRANSFER_OWNERSHIP);
00358 }
00359
00369 template<typename CurrentT, typename DesiredT>
00370 inline val ptr_value_convert(val& v)
00371 {
00372 const CurrentT *curr = val_cast_ptr<const CurrentT>(v);
00373 DesiredT *new_ptr = new DesiredT(curr);
00374 return val(new_ptr, TRANSFER_OWNERSHIP);
00375 }
00376
00377
00378 template<typename CurrentT, typename DesiredT>
00379 inline execution_context::val_convert_t get_ptr_convert_fn(const boost::true_type&)
00380 {
00381 return &ptr_convert<CurrentT, DesiredT>;
00382 }
00383
00384 template<typename CurrentT, typename DesiredT>
00385 inline execution_context::val_convert_t get_ptr_convert_fn(const boost::false_type&)
00386 {
00387 return 0;
00388 }
00389
00390 template<typename CurrentT, typename DesiredT>
00391 inline execution_context::val_convert_t
00392 get_dynamic_ptr_convert_fn(const boost::true_type&)
00393 {
00394 return &dynamic_ptr_convert<CurrentT, DesiredT>;
00395 }
00396
00397 template<typename CurrentT, typename DesiredT>
00398 inline execution_context::val_convert_t
00399 get_dynamic_ptr_convert_fn(const boost::false_type&)
00400 {
00401 return 0;
00402 }
00403
00404 template<typename CurrentT, typename DesiredT>
00405 inline execution_context::val_convert_t
00406 get_value_convert_fn(const boost::true_type&)
00407 {
00408 return &value_convert<CurrentT, DesiredT>;
00409 }
00410
00411 template<typename CurrentT, typename DesiredT>
00412 inline execution_context::val_convert_t
00413 get_value_convert_fn(const boost::false_type&)
00414 {
00415 return 0;
00416 }
00417
00418 template<typename CurrentT, typename DesiredT>
00419 inline execution_context::val_convert_t
00420 get_ptr_value_convert_fn(const boost::true_type&)
00421 {
00422 return &ptr_value_convert<CurrentT, DesiredT>;
00423 }
00424
00425 template<typename CurrentT, typename DesiredT>
00426 inline execution_context::val_convert_t
00427 get_ptr_value_convert_fn(const boost::false_type&)
00428 {
00429 return 0;
00430 }
00431
00432
00433
00434
00435
00436
00437 template<typename CurrentT, typename DesiredT>
00438 inline execution_context::val_convert_t
00439 get_value_convert_fn_if_not_same(const boost::true_type&)
00440 {
00441 return 0;
00442 }
00443
00444 template<typename CurrentT, typename DesiredT>
00445 inline execution_context::val_convert_t
00446 get_value_convert_fn_if_not_same(const boost::false_type&)
00447 {
00448 execution_context::val_convert_t rv;
00449 rv = get_value_convert_fn<CurrentT, DesiredT>(
00450 boost::is_convertible<const CurrentT&,
00451 DesiredT>());
00452 if(!rv)
00453 {
00454 rv = get_ptr_value_convert_fn<CurrentT, DesiredT>(
00455 boost::is_convertible<const CurrentT *, DesiredT>());
00456 }
00457 return rv;
00458 }
00459
00460
00461 template<typename DesiredT>
00462 inline void add_val_convert_for_type(
00463 std::map<type_info_conversion_store, execution_context::val_convert_t>& ptr_conv,
00464 std::map<type_info_conversion_store, execution_context::val_convert_t>& value_conv)
00465 {
00466 execution_context::val_convert_t conv_p;
00467
00468 #undef EVAL_REGISTER_TYPE_RENAME
00469 #define EVAL_REGISTER_TYPE_RENAME(T, name) \
00470 conv_p = get_ptr_convert_fn<T, DesiredT>( \
00471 boost::is_convertible<T *, DesiredT *>()); \
00472 if(!conv_p) \
00473 { \
00474 conv_p = get_dynamic_ptr_convert_fn<T, DesiredT>( \
00475 boost::integral_constant \
00476 <bool, boost::is_base_of<T, DesiredT>::value \
00477 && boost::is_polymorphic<T>::value \
00478 >()); \
00479 } \
00480 \
00481 if(conv_p) \
00482 { \
00483 ptr_conv.insert(std::make_pair( \
00484 type_info_conversion_store(&typeid(T), &typeid(DesiredT)), \
00485 conv_p)); \
00486 } \
00487 \
00488 conv_p = get_value_convert_fn_if_not_same<T, DesiredT>( \
00489 boost::is_same<T, DesiredT>()); \
00490 if(conv_p) \
00491 { \
00492 value_conv.insert(std::make_pair( \
00493 type_info_conversion_store(&typeid(T), &typeid(DesiredT)), \
00494 conv_p)); \
00495 }
00496
00497
00498 # include "detail/include_eval_include_files.hpp"
00499
00500 # include "detail/reset_execution_context_macros.hpp"
00501 }
00502
00503
00504 }
00505 }
00506 }
00507
00508 void inline EVAL_EXECUTION_CONTEXT_NAME::register_conversions()
00509 {
00510 #undef EVAL_REGISTER_TYPE_RENAME
00511 #define EVAL_REGISTER_TYPE_RENAME(T, name) \
00512 eval::detail::EVAL_EXECUTION_CONTEXT_NAME::add_val_convert_for_type<T> \
00513 (_ptr_conversions, _value_conversions);
00514
00515 # include "detail/include_eval_include_files.hpp"
00516
00517 # include "detail/reset_execution_context_macros.hpp"
00518
00519 }
00520
00521
00522 #undef EVAL_NOTHING
00523 #undef EVAL_BRACKET_OPEN
00524 #undef EVAL_BRACKET_CLOSE
00525
00526