00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00035
00036 #ifndef GROOVX_TCL_MAKECMD_H_UTC20050628162421_DEFINED
00037 #define GROOVX_TCL_MAKECMD_H_UTC20050628162421_DEFINED
00038
00039 #include "nub/ref.h"
00040
00041 #include "tcl/argspec.h"
00042 #include "tcl/conversions.h"
00043 #include "tcl/command.h"
00044 #include "tcl/commandgroup.h"
00045 #include "tcl/vecdispatch.h"
00046
00047 #include "rutz/functors.h"
00048 #include "rutz/shared_ptr.h"
00049
00050 namespace rutz
00051 {
00052 struct file_pos;
00053
00055 template <class MF>
00056 struct func_traits<mem_functor<MF> > : public func_traits<MF>
00057 {
00058 typedef nub::soft_ref<typename mem_functor<MF>::C> arg1_t;
00059 };
00060 }
00061
00062 namespace tcl
00063 {
00065
00067 template <class T>
00068 inline nub::ref<T> aux_convert_to(Tcl_Obj* obj, nub::ref<T>*)
00069 {
00070 nub::uid uid = tcl::convert_to<nub::uid>(obj);
00071 return nub::ref<T>(uid);
00072 }
00073
00075
00077 template <class T>
00078 inline tcl::obj aux_convert_from(nub::ref<T> obj)
00079 {
00080 return convert_from<nub::uid>(obj.id());
00081 }
00082
00084
00086 template <class T>
00087 inline nub::soft_ref<T> aux_convert_to(Tcl_Obj* obj, nub::soft_ref<T>*)
00088 {
00089 nub::uid uid = tcl::convert_to<nub::uid>(obj);
00090 return nub::soft_ref<T>(uid);
00091 }
00092
00094
00096 template <class T>
00097 inline tcl::obj aux_convert_from(nub::soft_ref<T> obj)
00098 {
00099 return convert_from<nub::uid>(obj.id());
00100 }
00101
00102
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00115
00116 #ifdef EXTRACT_PARAM
00117 # error EXTRACT_PARAM macro already defined
00118 #endif
00119
00120 #define EXTRACT_PARAM(N) \
00121 typename rutz::func_traits<Func>::arg##N##_t p##N = \
00122 ctx.template get_arg<typename rutz::func_traits<Func>::arg##N##_t>(N);
00123
00125 template <unsigned int N, class R, class Func>
00126 class func_wrapper
00127 {};
00128 }
00129
00130 namespace rutz
00131 {
00133 template <unsigned int N, class F, class Func>
00134 struct func_traits<tcl::func_wrapper<N, F, Func> >
00135 {
00136 typedef typename rutz::func_traits<Func>::retn_t retn_t;
00137 };
00138 }
00139
00140 namespace tcl
00141 {
00142
00143
00144
00146
00147 template <class R, class Func>
00148 struct func_wrapper<0, R, Func>
00149 {
00150 private:
00151 Func m_held_func;
00152
00153 public:
00154 func_wrapper<0, R, Func>(Func f) : m_held_func(f) {}
00155
00156 ~func_wrapper() throw() {}
00157
00158 R operator()(tcl::call_context& )
00159 {
00160 return m_held_func();
00161 }
00162 };
00163
00164
00165
00167
00168 template <class R, class Func>
00169 struct func_wrapper<1, R, Func>
00170 {
00171 private:
00172 Func m_held_func;
00173
00174 public:
00175 func_wrapper<1, R, Func>(Func f) : m_held_func(f) {}
00176
00177 ~func_wrapper() throw() {}
00178
00179 R operator()(tcl::call_context& ctx)
00180 {
00181 EXTRACT_PARAM(1);
00182 return m_held_func(p1);
00183 }
00184 };
00185
00186
00187
00189
00190 template <class R, class Func>
00191 struct func_wrapper<2, R, Func>
00192 {
00193 private:
00194 Func m_held_func;
00195
00196 public:
00197 func_wrapper<2, R, Func>(Func f) : m_held_func(f) {}
00198
00199 ~func_wrapper() throw() {}
00200
00201 R operator()(tcl::call_context& ctx)
00202 {
00203 EXTRACT_PARAM(1); EXTRACT_PARAM(2);
00204 return m_held_func(p1, p2);
00205 }
00206 };
00207
00208
00209
00211
00212 template <class R, class Func>
00213 struct func_wrapper<3, R, Func>
00214 {
00215 private:
00216 Func m_held_func;
00217
00218 public:
00219 func_wrapper<3, R, Func>(Func f) : m_held_func(f) {}
00220
00221 ~func_wrapper() throw() {}
00222
00223 R operator()(tcl::call_context& ctx)
00224 {
00225 EXTRACT_PARAM(1); EXTRACT_PARAM(2); EXTRACT_PARAM(3);
00226 return m_held_func(p1, p2, p3);
00227 }
00228 };
00229
00230
00231
00233
00234 template <class R, class Func>
00235 struct func_wrapper<4, R, Func>
00236 {
00237 private:
00238 Func m_held_func;
00239
00240 public:
00241 func_wrapper<4, R, Func>(Func f) : m_held_func(f) {}
00242
00243 ~func_wrapper() throw() {}
00244
00245 R operator()(tcl::call_context& ctx)
00246 {
00247 EXTRACT_PARAM(1); EXTRACT_PARAM(2); EXTRACT_PARAM(3);
00248 EXTRACT_PARAM(4);
00249 return m_held_func(p1, p2, p3, p4);
00250 }
00251 };
00252
00253
00254
00256
00257 template <class R, class Func>
00258 struct func_wrapper<5, R, Func>
00259 {
00260 private:
00261 Func m_held_func;
00262
00263 public:
00264 func_wrapper<5, R, Func>(Func f) : m_held_func(f) {}
00265
00266 ~func_wrapper() throw() {}
00267
00268 R operator()(tcl::call_context& ctx)
00269 {
00270 EXTRACT_PARAM(1); EXTRACT_PARAM(2); EXTRACT_PARAM(3);
00271 EXTRACT_PARAM(4); EXTRACT_PARAM(5);
00272 return m_held_func(p1, p2, p3, p4, p5);
00273 }
00274 };
00275
00276
00277
00279
00280 template <class R, class Func>
00281 struct func_wrapper<6, R, Func>
00282 {
00283 private:
00284 Func m_held_func;
00285
00286 public:
00287 func_wrapper<6, R, Func>(Func f) : m_held_func(f) {}
00288
00289 ~func_wrapper() throw() {}
00290
00291 R operator()(tcl::call_context& ctx)
00292 {
00293 EXTRACT_PARAM(1); EXTRACT_PARAM(2); EXTRACT_PARAM(3);
00294 EXTRACT_PARAM(4); EXTRACT_PARAM(5); EXTRACT_PARAM(6);
00295 return m_held_func(p1, p2, p3, p4, p5, p6);
00296 }
00297 };
00298
00299
00301
00302 template <class R, class Func>
00303 struct func_wrapper<7, R, Func>
00304 {
00305 private:
00306 Func m_held_func;
00307
00308 public:
00309 func_wrapper<7, R, Func>(Func f) : m_held_func(f) {}
00310
00311 ~func_wrapper() throw() {}
00312
00313 R operator()(tcl::call_context& ctx)
00314 {
00315 EXTRACT_PARAM(1); EXTRACT_PARAM(2); EXTRACT_PARAM(3);
00316 EXTRACT_PARAM(4); EXTRACT_PARAM(5); EXTRACT_PARAM(6);
00317 EXTRACT_PARAM(7);
00318 return m_held_func(p1, p2, p3, p4, p5, p6, p7);
00319 }
00320 };
00321
00322
00324
00325 template <class R, class Func>
00326 struct func_wrapper<8, R, Func>
00327 {
00328 private:
00329 Func m_held_func;
00330
00331 public:
00332 func_wrapper<8, R, Func>(Func f) : m_held_func(f) {}
00333
00334 ~func_wrapper() throw() {}
00335
00336 R operator()(tcl::call_context& ctx)
00337 {
00338 EXTRACT_PARAM(1); EXTRACT_PARAM(2); EXTRACT_PARAM(3);
00339 EXTRACT_PARAM(4); EXTRACT_PARAM(5); EXTRACT_PARAM(6);
00340 EXTRACT_PARAM(7); EXTRACT_PARAM(8);
00341 return m_held_func(p1, p2, p3, p4, p5, p6, p7, p8);
00342 }
00343 };
00344
00345 #undef EXTRACT_PARAM
00346
00347
00349
00350 template <class Fptr>
00351 inline func_wrapper<rutz::func_traits<Fptr>::num_args,
00352 typename rutz::func_traits<Fptr>::retn_t,
00353 typename rutz::functor_of<Fptr>::type>
00354 build_func_wrapper(Fptr f)
00355 {
00356 return rutz::build_functor(f);
00357 }
00358
00359
00360
00362
00363 template <class R, class func_wrapper>
00364 class generic_function : public tcl::function
00365 {
00366 protected:
00367 generic_function<R, func_wrapper>(func_wrapper f) : m_held_func(f) {}
00368
00369 public:
00370 static rutz::shared_ptr<tcl::function> make(func_wrapper f)
00371 {
00372 return rutz::shared_ptr<tcl::function>(new generic_function(f));
00373 }
00374
00375 virtual ~generic_function() throw() {}
00376
00377 protected:
00378 virtual void invoke(tcl::call_context& ctx)
00379 {
00380 R res(m_held_func(ctx)); ctx.set_result(res);
00381 }
00382
00383 private:
00384 func_wrapper m_held_func;
00385 };
00386
00387
00389
00390 template <class func_wrapper>
00391 class generic_function<void, func_wrapper> : public tcl::function
00392 {
00393 protected:
00394 generic_function<void, func_wrapper>(func_wrapper f) : m_held_func(f) {}
00395
00396 public:
00397 static rutz::shared_ptr<tcl::function> make(func_wrapper f)
00398 {
00399 return rutz::shared_ptr<tcl::function>(new generic_function(f));
00400 }
00401
00402 virtual ~generic_function() throw() {}
00403
00404 protected:
00405 virtual void invoke(tcl::call_context& ctx)
00406 {
00407 m_held_func(ctx);
00408 }
00409
00410 private:
00411 func_wrapper m_held_func;
00412 };
00413
00414
00415
00417
00418 template <class func_wrapper>
00419 inline void
00420 make_generic_command(tcl::interpreter& interp,
00421 func_wrapper f,
00422 const char* cmd_name,
00423 const char* usage,
00424 const arg_spec& spec,
00425 const rutz::file_pos& src_pos)
00426 {
00427 typedef typename rutz::func_traits<func_wrapper>::retn_t retn_t;
00428 tcl::command_group::make(interp,
00429 generic_function<retn_t, func_wrapper>::make(f),
00430 cmd_name, usage, spec, src_pos);
00431 }
00432
00433
00434
00436
00437 template <class func_wrapper>
00438 inline void
00439 make_generic_vec_command(tcl::interpreter& interp,
00440 func_wrapper f,
00441 const char* cmd_name,
00442 const char* usage,
00443 const arg_spec& spec,
00444 unsigned int keyarg,
00445 const rutz::file_pos& src_pos)
00446 {
00447 typedef typename rutz::func_traits<func_wrapper>::retn_t retn_t;
00448 rutz::shared_ptr<tcl::command> cmd =
00449 tcl::command_group::make(interp,
00450 generic_function<retn_t, func_wrapper>::make(f),
00451 cmd_name, usage, spec, src_pos);
00452 tcl::use_vec_dispatch(*cmd, keyarg);
00453 }
00454
00456
00457
00458
00460
00461
00463
00464 template <class Func>
00465 inline void
00466 make_command(tcl::interpreter& interp,
00467 Func f,
00468 const char* cmd_name,
00469 const char* usage,
00470 const rutz::file_pos& src_pos)
00471 {
00472 make_generic_command
00473 (interp, build_func_wrapper(f), cmd_name, usage,
00474 arg_spec(rutz::func_traits<Func>::num_args + 1, -1, true),
00475 src_pos);
00476 }
00477
00478
00480
00481 template <class Func>
00482 inline void
00483 make_vec_command(tcl::interpreter& interp,
00484 Func f,
00485 const char* cmd_name,
00486 const char* usage,
00487 unsigned int keyarg ,
00488 const rutz::file_pos& src_pos)
00489 {
00490 make_generic_vec_command
00491 (interp, build_func_wrapper(f), cmd_name, usage,
00492 arg_spec(rutz::func_traits<Func>::num_args + 1, -1, true),
00493 keyarg, src_pos);
00494 }
00495
00496 }
00497
00498 static const char __attribute__((used)) vcid_groovx_tcl_makecmd_h_utc20050628162421[] = "$Id: makecmd.h 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00499 #endif // !GROOVX_TCL_MAKECMD_H_UTC20050628162421_DEFINED