stlab.adobe.com Adobe Systems Incorporated

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 /******************************************************************************/

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google