function_pack.hpp
Go to the documentation of this file.
00001 /* 00002 Copyright 2005-2007 Adobe Systems Incorporated 00003 Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt 00004 or a copy at http://opensource.adobe.com/licenses.html) 00005 */ 00006 00007 /******************************************************************************/ 00008 00009 #ifndef ADOBE_FUNCTION_PACK_HPP 00010 #define ADOBE_FUNCTION_PACK_HPP 00011 00012 #include <adobe/config.hpp> 00013 00014 #include <stdexcept> 00015 #include <sstream> 00016 00017 #include <boost/bind.hpp> 00018 #include <boost/static_assert.hpp> 00019 #include <boost/type_traits.hpp> 00020 #include <boost/utility/enable_if.hpp> 00021 00022 #include <adobe/any_regular.hpp> 00023 #include <adobe/array.hpp> 00024 #include <adobe/closed_hash.hpp> 00025 #include <adobe/dictionary.hpp> 00026 #include <adobe/empty.hpp> 00027 #include <adobe/function_traits.hpp> 00028 #include <adobe/string.hpp> 00029 #include <adobe/virtual_machine.hpp> 00030 00031 /******************************************************************************/ 00032 00033 namespace adobe { 00034 00035 /******************************************************************************/ 00036 #ifndef ADOBE_NO_DOCUMENTATION 00037 namespace implementation { 00038 00039 /******************************************************************************/ 00046 template <typename T> 00047 struct undecorate 00048 { typedef T type; }; 00049 00050 template <typename T> 00051 struct undecorate<const T> 00052 { typedef T type; }; 00053 00054 template <typename T> 00055 struct undecorate<T&> 00056 { typedef T type; }; 00057 00058 template <typename T> 00059 struct undecorate<const T&> 00060 { typedef T type; }; 00061 00062 /******************************************************************************/ 00063 00064 inline any_regular_t& find_arg(dictionary_t& named_argument_set, name_t arg_name) 00065 { 00066 dictionary_t::iterator arg(named_argument_set.find(arg_name)); 00067 00068 if (arg == named_argument_set.end()) 00069 throw std::runtime_error(make_string("No value for named argument '", arg_name.c_str(), "'")); 00070 00071 return arg->second; 00072 } 00073 00074 inline const any_regular_t& find_arg(const dictionary_t& named_argument_set, name_t arg_name) 00075 { 00076 return find_arg(const_cast<dictionary_t&>(named_argument_set), arg_name); 00077 } 00078 00079 inline any_regular_t& find_arg(array_t& argument_set, std::size_t index) 00080 { 00081 if (argument_set.size() < (index + 1)) 00082 { 00083 std::stringstream error; 00084 00085 error << "No value for unnamed argument " << (index + 1); 00086 00087 throw std::runtime_error(error.str()); 00088 } 00089 00090 return argument_set[index]; 00091 } 00092 00093 inline const any_regular_t& find_arg(const array_t& argument_set, std::size_t index) 00094 { 00095 return find_arg(const_cast<array_t&>(argument_set), index); 00096 } 00097 00098 /******************************************************************************/ 00099 00100 #define ADOBE_FUNCTION_UNNAMED_ARG(param_index) \ 00101 find_arg(argument_set, (param_index - 1)).cast<typename undecorate<typename traits_type::arg##param_index##_type>::type>() 00102 00103 #define ADOBE_FUNCTION_NAMED_ARG(param_index) \ 00104 find_arg(named_argument_set, name##param_index##_m).cast<typename undecorate<typename traits_type::arg##param_index##_type>::type>() 00105 00106 /******************************************************************************/ 00107 00108 template <typename T> 00109 struct novoid 00110 { typedef T type; }; 00111 00112 template <> 00113 struct novoid<void> 00114 { typedef adobe::empty_t type; }; 00115 00116 /******************************************************************************/ 00117 00118 template <typename F> 00119 inline typename boost::disable_if<boost::is_same<typename F::result_type, 00120 void>, 00121 typename F::result_type>::type 00122 invoke_novoid(const F& f) 00123 { 00124 return f(); 00125 } 00126 00127 template <typename F> 00128 inline typename boost::enable_if<boost::is_same<typename F::result_type, 00129 void>, 00130 adobe::empty_t>::type 00131 invoke_novoid(const F& f) 00132 { 00133 f(); 00134 00135 return adobe::empty_t(); 00136 } 00137 00138 /******************************************************************************/ 00139 00140 template <typename F, std::size_t Arity> 00141 struct function_pack_helper; 00142 00143 /******************************************************************************/ 00144 00145 template <typename F> 00146 struct function_pack_helper<F, 0> 00147 { 00148 typedef function_traits<F> traits_type; 00149 typedef typename traits_type::result_type traits_result_type; 00150 typedef typename novoid<traits_result_type>::type result_type; 00151 00152 explicit function_pack_helper(const F& f) : 00153 f_m(f) 00154 { } 00155 00156 template <typename T> 00157 result_type operator()(const T&) const 00158 { 00159 return invoke_novoid(boost::bind(f_m)); 00160 } 00161 00162 private: 00163 typename traits_type::function_type f_m; 00164 }; 00165 00166 /******************************************************************************/ 00167 00168 template <typename F> 00169 struct function_pack_helper<F, 1> 00170 { 00171 typedef function_traits<F> traits_type; 00172 typedef typename traits_type::result_type traits_result_type; 00173 typedef typename novoid<traits_result_type>::type result_type; 00174 00175 explicit function_pack_helper(const F& f, 00176 name_t arg1_name = name_t()) : 00177 f_m(f), 00178 name1_m(arg1_name) 00179 { } 00180 00181 result_type operator()(const array_t& argument_set) const 00182 { 00183 return invoke_novoid(boost::bind(f_m, ADOBE_FUNCTION_UNNAMED_ARG(1))); 00184 } 00185 00186 result_type operator()(const dictionary_t& named_argument_set) const 00187 { 00188 return invoke_novoid(boost::bind(f_m, ADOBE_FUNCTION_NAMED_ARG(1))); 00189 } 00190 00191 private: 00192 typename traits_type::function_type f_m; 00193 name_t name1_m; 00194 }; 00195 00196 /******************************************************************************/ 00197 00198 template <typename F> 00199 struct function_pack_helper<F, 2> 00200 { 00201 typedef function_traits<F> traits_type; 00202 typedef typename traits_type::result_type traits_result_type; 00203 typedef typename novoid<traits_result_type>::type result_type; 00204 00205 explicit function_pack_helper(const F& f, 00206 name_t arg1_name = name_t(), name_t arg2_name = name_t()) : 00207 f_m(f), 00208 name1_m(arg1_name), name2_m(arg2_name) 00209 { } 00210 00211 result_type operator()(const array_t& argument_set) const 00212 { 00213 return invoke_novoid(boost::bind(f_m, 00214 ADOBE_FUNCTION_UNNAMED_ARG(1), ADOBE_FUNCTION_UNNAMED_ARG(2))); 00215 } 00216 00217 result_type operator()(const dictionary_t& named_argument_set) const 00218 { 00219 return invoke_novoid(boost::bind(f_m, 00220 ADOBE_FUNCTION_NAMED_ARG(1), ADOBE_FUNCTION_NAMED_ARG(2))); 00221 } 00222 00223 private: 00224 typename traits_type::function_type f_m; 00225 name_t name1_m; 00226 name_t name2_m; 00227 }; 00228 00229 /******************************************************************************/ 00230 00231 template <typename F> 00232 struct function_pack_helper<F, 3> 00233 { 00234 typedef function_traits<F> traits_type; 00235 typedef typename traits_type::result_type traits_result_type; 00236 typedef typename novoid<traits_result_type>::type result_type; 00237 00238 explicit function_pack_helper(const F& f, 00239 name_t arg1_name = name_t(), name_t arg2_name = name_t(), 00240 name_t arg3_name = name_t()) : 00241 f_m(f), 00242 name1_m(arg1_name), name2_m(arg2_name), name3_m(arg3_name) 00243 { } 00244 00245 result_type operator()(const array_t& argument_set) const 00246 { 00247 return invoke_novoid(boost::bind(f_m, 00248 ADOBE_FUNCTION_UNNAMED_ARG(1), ADOBE_FUNCTION_UNNAMED_ARG(2), 00249 ADOBE_FUNCTION_UNNAMED_ARG(3))); 00250 } 00251 00252 result_type operator()(const dictionary_t& named_argument_set) const 00253 { 00254 return invoke_novoid(boost::bind(f_m, 00255 ADOBE_FUNCTION_NAMED_ARG(1), ADOBE_FUNCTION_NAMED_ARG(2), 00256 ADOBE_FUNCTION_NAMED_ARG(3))); 00257 } 00258 00259 private: 00260 typename traits_type::function_type f_m; 00261 name_t name1_m; 00262 name_t name2_m; 00263 name_t name3_m; 00264 }; 00265 00266 /******************************************************************************/ 00267 00268 template <typename F> 00269 struct function_pack_helper<F, 4> 00270 { 00271 typedef function_traits<F> traits_type; 00272 typedef typename traits_type::result_type traits_result_type; 00273 typedef typename novoid<traits_result_type>::type result_type; 00274 00275 explicit function_pack_helper(const F& f, 00276 name_t arg1_name = name_t(), name_t arg2_name = name_t(), 00277 name_t arg3_name = name_t(), name_t arg4_name = name_t()) : 00278 f_m(f), 00279 name1_m(arg1_name), name2_m(arg2_name), name3_m(arg3_name), name4_m(arg4_name) 00280 { } 00281 00282 result_type operator()(const array_t& argument_set) const 00283 { 00284 return invoke_novoid(boost::bind(f_m, 00285 ADOBE_FUNCTION_UNNAMED_ARG(1), ADOBE_FUNCTION_UNNAMED_ARG(2), 00286 ADOBE_FUNCTION_UNNAMED_ARG(3), ADOBE_FUNCTION_UNNAMED_ARG(4))); 00287 } 00288 00289 result_type operator()(const dictionary_t& named_argument_set) const 00290 { 00291 return invoke_novoid(boost::bind(f_m, 00292 ADOBE_FUNCTION_NAMED_ARG(1), ADOBE_FUNCTION_NAMED_ARG(2), 00293 ADOBE_FUNCTION_NAMED_ARG(3), ADOBE_FUNCTION_NAMED_ARG(4))); 00294 } 00295 00296 private: 00297 typename traits_type::function_type f_m; 00298 name_t name1_m; 00299 name_t name2_m; 00300 name_t name3_m; 00301 name_t name4_m; 00302 }; 00303 00304 /******************************************************************************/ 00305 00306 template <typename F> 00307 struct function_pack_helper<F, 5> 00308 { 00309 typedef function_traits<F> traits_type; 00310 typedef typename traits_type::result_type traits_result_type; 00311 typedef typename novoid<traits_result_type>::type result_type; 00312 00313 explicit function_pack_helper(const F& f, 00314 name_t arg1_name = name_t(), name_t arg2_name = name_t(), 00315 name_t arg3_name = name_t(), name_t arg4_name = name_t(), 00316 name_t arg5_name = name_t()) : 00317 f_m(f), 00318 name1_m(arg1_name), name2_m(arg2_name), name3_m(arg3_name), name4_m(arg4_name), 00319 name5_m(arg5_name) 00320 { } 00321 00322 result_type operator()(const array_t& argument_set) const 00323 { 00324 return invoke_novoid(boost::bind(f_m, 00325 ADOBE_FUNCTION_UNNAMED_ARG(1), ADOBE_FUNCTION_UNNAMED_ARG(2), 00326 ADOBE_FUNCTION_UNNAMED_ARG(3), ADOBE_FUNCTION_UNNAMED_ARG(4), 00327 ADOBE_FUNCTION_UNNAMED_ARG(5))); 00328 } 00329 00330 result_type operator()(const dictionary_t& named_argument_set) const 00331 { 00332 return invoke_novoid(boost::bind(f_m, 00333 ADOBE_FUNCTION_NAMED_ARG(1), ADOBE_FUNCTION_NAMED_ARG(2), 00334 ADOBE_FUNCTION_NAMED_ARG(3), ADOBE_FUNCTION_NAMED_ARG(4), 00335 ADOBE_FUNCTION_NAMED_ARG(5))); 00336 } 00337 00338 private: 00339 typename traits_type::function_type f_m; 00340 name_t name1_m; 00341 name_t name2_m; 00342 name_t name3_m; 00343 name_t name4_m; 00344 name_t name5_m; 00345 }; 00346 00347 /******************************************************************************/ 00348 00349 template <typename F> 00350 struct function_pack_helper<F, 6> 00351 { 00352 typedef function_traits<F> traits_type; 00353 typedef typename traits_type::result_type traits_result_type; 00354 typedef typename novoid<traits_result_type>::type result_type; 00355 00356 explicit function_pack_helper(const F& f, 00357 name_t arg1_name = name_t(), name_t arg2_name = name_t(), 00358 name_t arg3_name = name_t(), name_t arg4_name = name_t(), 00359 name_t arg5_name = name_t(), name_t arg6_name = name_t()) : 00360 f_m(f), 00361 name1_m(arg1_name), name2_m(arg2_name), name3_m(arg3_name), name4_m(arg4_name), 00362 name5_m(arg5_name), name6_m(arg6_name) 00363 { } 00364 00365 result_type operator()(const array_t& argument_set) const 00366 { 00367 return invoke_novoid(boost::bind(f_m, 00368 ADOBE_FUNCTION_UNNAMED_ARG(1), ADOBE_FUNCTION_UNNAMED_ARG(2), 00369 ADOBE_FUNCTION_UNNAMED_ARG(3), ADOBE_FUNCTION_UNNAMED_ARG(4), 00370 ADOBE_FUNCTION_UNNAMED_ARG(5), ADOBE_FUNCTION_UNNAMED_ARG(6))); 00371 } 00372 00373 result_type operator()(const dictionary_t& named_argument_set) const 00374 { 00375 return invoke_novoid(boost::bind(f_m, 00376 ADOBE_FUNCTION_NAMED_ARG(1), ADOBE_FUNCTION_NAMED_ARG(2), 00377 ADOBE_FUNCTION_NAMED_ARG(3), ADOBE_FUNCTION_NAMED_ARG(4), 00378 ADOBE_FUNCTION_NAMED_ARG(5), ADOBE_FUNCTION_NAMED_ARG(6))); 00379 } 00380 00381 private: 00382 typename traits_type::function_type f_m; 00383 name_t name1_m; 00384 name_t name2_m; 00385 name_t name3_m; 00386 name_t name4_m; 00387 name_t name5_m; 00388 name_t name6_m; 00389 }; 00390 00391 /******************************************************************************/ 00392 00393 template <typename F> 00394 struct function_pack_helper<F, 7> 00395 { 00396 typedef function_traits<F> traits_type; 00397 typedef typename traits_type::result_type traits_result_type; 00398 typedef typename novoid<traits_result_type>::type result_type; 00399 00400 explicit function_pack_helper(const F& f, 00401 name_t arg1_name = name_t(), name_t arg2_name = name_t(), 00402 name_t arg3_name = name_t(), name_t arg4_name = name_t(), 00403 name_t arg5_name = name_t(), name_t arg6_name = name_t(), 00404 name_t arg7_name = name_t()) : 00405 f_m(f), 00406 name1_m(arg1_name), name2_m(arg2_name), name3_m(arg3_name), name4_m(arg4_name), 00407 name5_m(arg5_name), name6_m(arg6_name), name7_m(arg7_name) 00408 { } 00409 00410 result_type operator()(const array_t& argument_set) const 00411 { 00412 return invoke_novoid(boost::bind(f_m, 00413 ADOBE_FUNCTION_UNNAMED_ARG(1), ADOBE_FUNCTION_UNNAMED_ARG(2), 00414 ADOBE_FUNCTION_UNNAMED_ARG(3), ADOBE_FUNCTION_UNNAMED_ARG(4), 00415 ADOBE_FUNCTION_UNNAMED_ARG(5), ADOBE_FUNCTION_UNNAMED_ARG(6), 00416 ADOBE_FUNCTION_UNNAMED_ARG(7))); 00417 } 00418 00419 result_type operator()(const dictionary_t& named_argument_set) const 00420 { 00421 return invoke_novoid(boost::bind(f_m, 00422 ADOBE_FUNCTION_NAMED_ARG(1), ADOBE_FUNCTION_NAMED_ARG(2), 00423 ADOBE_FUNCTION_NAMED_ARG(3), ADOBE_FUNCTION_NAMED_ARG(4), 00424 ADOBE_FUNCTION_NAMED_ARG(5), ADOBE_FUNCTION_NAMED_ARG(6), 00425 ADOBE_FUNCTION_NAMED_ARG(7))); 00426 } 00427 00428 private: 00429 typename traits_type::function_type f_m; 00430 name_t name1_m; 00431 name_t name2_m; 00432 name_t name3_m; 00433 name_t name4_m; 00434 name_t name5_m; 00435 name_t name6_m; 00436 name_t name7_m; 00437 }; 00438 00439 /******************************************************************************/ 00440 00441 #undef ADOBE_FUNCTION_UNNAMED_ARG 00442 #undef ADOBE_FUNCTION_NAMED_ARG 00443 00444 /******************************************************************************/ 00445 00446 template <typename T> 00447 any_regular_t wrap_regular(const T& x) 00448 { return any_regular_t(x); } 00449 00450 template <> 00451 inline any_regular_t wrap_regular<any_regular_t>(const any_regular_t& x) 00452 { return x; } 00453 00454 /******************************************************************************/ 00455 00456 } // namespace implementation 00457 // ADOBE_NO_DOCUMENTATION 00458 #endif 00459 /******************************************************************************/ 00460 00461 template <typename F> 00462 inline implementation::function_pack_helper<F, 0> 00463 named_bind(const F& f) 00464 { 00465 BOOST_STATIC_ASSERT((function_traits<F>::arity == 0)); 00466 00467 return implementation::function_pack_helper<F, 0>(f); 00468 } 00469 00470 template <typename F> 00471 inline implementation::function_pack_helper<F, 1> 00472 named_bind(const F& f, 00473 name_t arg1_name) 00474 { 00475 BOOST_STATIC_ASSERT((function_traits<F>::arity == 1)); 00476 00477 return implementation::function_pack_helper<F, 1>(f, 00478 arg1_name); 00479 } 00480 00481 template <typename F> 00482 inline implementation::function_pack_helper<F, 2> 00483 named_bind(const F& f, 00484 name_t arg1_name, name_t arg2_name) 00485 { 00486 BOOST_STATIC_ASSERT((function_traits<F>::arity == 2)); 00487 00488 return implementation::function_pack_helper<F, 2>(f, 00489 arg1_name, 00490 arg2_name); 00491 } 00492 00493 template <typename F> 00494 inline implementation::function_pack_helper<F, 3> 00495 named_bind(const F& f, 00496 name_t arg1_name, name_t arg2_name, name_t arg3_name) 00497 { 00498 BOOST_STATIC_ASSERT((function_traits<F>::arity == 3)); 00499 00500 return implementation::function_pack_helper<F, 3>(f, 00501 arg1_name, 00502 arg2_name, 00503 arg3_name); 00504 } 00505 00506 template <typename F> 00507 inline implementation::function_pack_helper<F, 4> 00508 named_bind(const F& f, 00509 name_t arg1_name, name_t arg2_name, name_t arg3_name, name_t arg4_name) 00510 { 00511 BOOST_STATIC_ASSERT((function_traits<F>::arity == 4)); 00512 00513 return implementation::function_pack_helper<F, 4>(f, 00514 arg1_name, 00515 arg2_name, 00516 arg3_name, 00517 arg4_name); 00518 } 00519 00520 template <typename F> 00521 inline implementation::function_pack_helper<F, 5> 00522 named_bind(const F& f, 00523 name_t arg1_name, name_t arg2_name, name_t arg3_name, name_t arg4_name, 00524 name_t arg5_name) 00525 { 00526 BOOST_STATIC_ASSERT((function_traits<F>::arity == 5)); 00527 00528 return implementation::function_pack_helper<F, 5>(f, 00529 arg1_name, 00530 arg2_name, 00531 arg3_name, 00532 arg4_name, 00533 arg5_name); 00534 } 00535 00536 template <typename F> 00537 inline implementation::function_pack_helper<F, 6> 00538 named_bind(const F& f, 00539 name_t arg1_name, name_t arg2_name, name_t arg3_name, name_t arg4_name, 00540 name_t arg5_name, name_t arg6_name) 00541 { 00542 BOOST_STATIC_ASSERT((function_traits<F>::arity == 6)); 00543 00544 return implementation::function_pack_helper<F, 6>(f, 00545 arg1_name, 00546 arg2_name, 00547 arg3_name, 00548 arg4_name, 00549 arg5_name, 00550 arg6_name); 00551 } 00552 00553 template <typename F> 00554 inline implementation::function_pack_helper<F, 7> 00555 named_bind(const F& f, 00556 name_t arg1_name, name_t arg2_name, name_t arg3_name, name_t arg4_name, 00557 name_t arg5_name, name_t arg6_name, name_t arg7_name) 00558 { 00559 BOOST_STATIC_ASSERT((function_traits<F>::arity == 7)); 00560 00561 return implementation::function_pack_helper<F, 7>(f, 00562 arg1_name, 00563 arg2_name, 00564 arg3_name, 00565 arg4_name, 00566 arg5_name, 00567 arg6_name, 00568 arg7_name); 00569 } 00570 00571 /******************************************************************************/ 00604 struct function_pack_t 00605 { 00606 #ifndef ADOBE_NO_DOCUMENTATION 00607 private: 00608 typedef boost::function<any_regular_t (const dictionary_t&)> dictionary_function_t; 00609 typedef boost::function<any_regular_t (const array_t&)> array_function_t; 00610 #endif 00611 00612 public: 00616 template <typename F> 00617 void register_function(name_t name, const F& f) 00618 { 00619 // We can't check arity here because unnamed argument functions 00620 // pass through this, which could be of any arity. 00621 00622 attach_unnamed(name, 00623 implementation::function_pack_helper<F, function_traits<F>::arity>(f)); 00624 } 00625 00629 template <typename F> 00630 void register_named0_function(name_t name, const F& f) 00631 { 00632 attach_named(name, named_bind(f)); 00633 } 00634 00641 template <typename F> 00642 void register_function(name_t name, const F& f, name_t arg1_name) 00643 { 00644 attach_named(name, 00645 named_bind(f, arg1_name)); 00646 } 00647 00654 template <typename F> 00655 void register_function(name_t name, const F& f, name_t arg1_name, name_t arg2_name) 00656 { 00657 attach_named(name, named_bind(f, 00658 arg1_name, arg2_name)); 00659 } 00660 00667 template <typename F> 00668 void register_function(name_t name, const F& f, name_t arg1_name, name_t arg2_name, name_t arg3_name) 00669 { 00670 attach_named(name, named_bind(f, 00671 arg1_name, arg2_name, arg3_name)); 00672 } 00673 00680 template <typename F> 00681 void register_function(name_t name, const F& f, 00682 name_t arg1_name, name_t arg2_name, name_t arg3_name, name_t arg4_name) 00683 { 00684 attach_named(name, named_bind(f, 00685 arg1_name, arg2_name, arg3_name, arg4_name)); 00686 } 00687 00694 template <typename F> 00695 void register_function(name_t name, const F& f, 00696 name_t arg1_name, name_t arg2_name, name_t arg3_name, name_t arg4_name, 00697 name_t arg5_name) 00698 { 00699 BOOST_STATIC_ASSERT((function_traits<F>::arity == 5)); 00700 00701 attach_named(name, named_bind(f, 00702 arg1_name, arg2_name, arg3_name, arg4_name, 00703 arg5_name)); 00704 } 00705 00712 template <typename F> 00713 void register_function(name_t name, const F& f, 00714 name_t arg1_name, name_t arg2_name, name_t arg3_name, name_t arg4_name, 00715 name_t arg5_name, name_t arg6_name) 00716 { 00717 attach_named(name, named_bind(f, 00718 arg1_name, arg2_name, arg3_name, arg4_name, 00719 arg5_name, arg6_name)); 00720 } 00721 00728 template <typename F> 00729 void register_function(name_t name, const F& f, 00730 name_t arg1_name, name_t arg2_name, name_t arg3_name, name_t arg4_name, 00731 name_t arg5_name, name_t arg6_name, name_t arg7_name) 00732 { 00733 attach_named(name, named_bind(f, 00734 arg1_name, arg2_name, arg3_name, arg4_name, 00735 arg5_name, arg6_name, arg7_name)); 00736 } 00737 00741 any_regular_t operator()(name_t function, const array_t& argument_set) const 00742 { 00743 return find_unnamed(function)->second(argument_set); 00744 } 00745 00749 any_regular_t operator()(name_t function, const dictionary_t& named_argument_set) const 00750 { 00751 return find_named(function)->second(named_argument_set); 00752 } 00753 00757 any_regular_t operator()(name_t function, array_t& argument_set) const 00758 { 00759 return find_unnamed(function)->second(argument_set); 00760 } 00761 00765 any_regular_t operator()(name_t function, dictionary_t& named_argument_set) const 00766 { 00767 return find_named(function)->second(named_argument_set); 00768 } 00769 00774 any_regular_t operator()(const array_t& argument_set) const 00775 { 00776 adobe::name_t function; 00777 00778 if (!argument_set.empty()) 00779 argument_set[0].cast<adobe::name_t>(function); 00780 00781 return (*this)(function, argument_set); 00782 } 00783 00788 any_regular_t operator()(const dictionary_t& named_argument_set) const 00789 { 00790 adobe::name_t function; 00791 00792 get_value(named_argument_set, adobe::static_name_t("command"), function); 00793 00794 return (*this)(function, named_argument_set); 00795 } 00796 00801 any_regular_t operator()(array_t& argument_set) const 00802 { 00803 adobe::name_t function; 00804 00805 if (!argument_set.empty()) 00806 argument_set[0].cast<adobe::name_t>(function); 00807 00808 return (*this)(function, argument_set); 00809 } 00810 00815 any_regular_t operator()(dictionary_t& named_argument_set) const 00816 { 00817 adobe::name_t function; 00818 00819 get_value(named_argument_set, adobe::static_name_t("command"), function); 00820 00821 return (*this)(function, named_argument_set); 00822 } 00823 00824 void register_unnamed(name_t name, const array_function_t& f) 00825 { 00826 array_function_map_m.insert(array_function_map_t::value_type(name, f)); 00827 } 00828 00829 void register_named(name_t name, const dictionary_function_t& f) 00830 { 00831 dictionary_function_map_m.insert(dictionary_function_map_t::value_type(name, f)); 00832 } 00833 00834 void clear() 00835 { 00836 dictionary_function_map_m.clear(); 00837 array_function_map_m.clear(); 00838 } 00839 00840 #ifndef ADOBE_NO_DOCUMENTATION 00841 private: 00842 typedef closed_hash_map<name_t, dictionary_function_t> dictionary_function_map_t; 00843 typedef closed_hash_map<name_t, array_function_t> array_function_map_t; 00844 00845 dictionary_function_map_t::const_iterator find_named(name_t function) const 00846 { 00847 if (function == name_t()) 00848 throw std::runtime_error("find_named: no function name specified"); 00849 00850 dictionary_function_map_t::const_iterator found(dictionary_function_map_m.find(function)); 00851 00852 if (found == dictionary_function_map_m.end()) 00853 throw std::runtime_error(make_string("find_named: function '", 00854 function.c_str(), 00855 "' not found")); 00856 00857 return found; 00858 } 00859 00860 array_function_map_t::const_iterator find_unnamed(name_t function) const 00861 { 00862 if (function == name_t()) 00863 throw std::runtime_error("find_named: no function name specified"); 00864 00865 array_function_map_t::const_iterator found(array_function_map_m.find(function)); 00866 00867 if (found == array_function_map_m.end()) 00868 throw std::runtime_error(make_string("find_unnamed: function '", 00869 function.c_str(), 00870 "' not found")); 00871 00872 return found; 00873 } 00874 00875 template <typename T> 00876 void attach_unnamed(name_t name, T helper) 00877 { 00878 typename T::result_type (T::*proc)(const array_t&) const = &T::operator(); 00879 00880 array_function_map_m.insert( 00881 array_function_map_t::value_type(name, 00882 boost::bind(&implementation::wrap_regular<typename T::result_type>, 00883 boost::bind(proc, helper, _1)))); 00884 } 00885 00886 template <typename T> 00887 void attach_named(name_t name, T helper) 00888 { 00889 typename T::result_type (T::*proc)(const dictionary_t&) const = &T::operator(); 00890 00891 dictionary_function_map_m.insert( 00892 dictionary_function_map_t::value_type(name, 00893 boost::bind(&implementation::wrap_regular<typename T::result_type>, 00894 boost::bind(proc, helper, _1)))); 00895 } 00896 00897 dictionary_function_map_t dictionary_function_map_m; 00898 array_function_map_t array_function_map_m; 00899 // ADOBE_NO_DOCUMENTATION 00900 #endif 00901 }; 00902 00903 /******************************************************************************/ 00914 inline void attach(virtual_machine_t& vm, const function_pack_t& pack) 00915 { 00916 vm.set_array_function_lookup(boost::cref(pack)); 00917 vm.set_dictionary_function_lookup(boost::cref(pack)); 00918 } 00919 00920 /******************************************************************************/ 00921 00922 } // namespace adobe 00923 00924 /******************************************************************************/ 00925 00926 #endif 00927 00928 /******************************************************************************/ |