Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/cpp11_v2/src/external/cpptcl/cpptcl.h @ 10771

Last change on this file since 10771 was 10771, checked in by landauf, 9 years ago

using std::shared_ptr instead of boost::shared_ptr (same for weak_ptr)

  • Property svn:eol-style set to native
File size: 27.3 KB
Line 
1//
2// Copyright (C) 2004-2006, Maciej Sobczak
3//
4// Permission to copy, use, modify, sell and distribute this software
5// is granted provided this copyright notice appears in all copies.
6// This software is provided "as is" without express or implied
7// warranty, and with no claim as to its suitability for any purpose.
8//
9
10#ifndef CPPTCL_INCLUDED
11#define CPPTCL_INCLUDED
12
13#include <tcl.h>
14#include <string>
15#include <stdexcept>
16#include <sstream>
17#include <map>
18#include <vector>
19#include <boost/bind.hpp>
20
21
22namespace Tcl
23{
24
25// exception class used for reporting all Tcl errors
26
27class tcl_error : public std::runtime_error
28{
29public:
30     explicit tcl_error(std::string const &msg)
31          : std::runtime_error(msg) {}
32     explicit tcl_error(Tcl_Interp *interp)
33          : std::runtime_error(Tcl_GetString(Tcl_GetObjResult(interp))) {}
34};
35
36// call policies
37
38struct policies
39{
40     policies() : variadic_(false) {}
41
42     policies & factory(std::string const &name);
43
44     // note: this is additive
45     policies & sink(int index);
46
47     policies & variadic();
48
49     std::string factory_;
50     std::vector<int> sinks_;
51     bool variadic_;
52};
53
54// syntax short-cuts
55policies factory(std::string const &name);
56policies sink(int index);
57policies variadic();
58
59
60class interpreter;
61class object;
62
63namespace details
64{
65
66// wrapper for the evaluation result
67class result
68{
69public:
70     result(Tcl_Interp *interp);
71     
72     operator bool() const;
73     operator double() const;
74     operator int() const;
75     operator long() const;
76     operator std::string() const;
77     operator object() const;
78
79private:
80     Tcl_Interp *interp_;
81};
82
83// helper functions used to set the result value
84
85void set_result(Tcl_Interp *interp, bool b);
86void set_result(Tcl_Interp *interp, int i);
87void set_result(Tcl_Interp *interp, long i);
88void set_result(Tcl_Interp *interp, double d);
89void set_result(Tcl_Interp *interp, std::string const &s);
90void set_result(Tcl_Interp *interp, void *p);
91void set_result(Tcl_Interp *interp, object const &o);
92
93// helper functor for converting Tcl objects to the given type
94#include "details/conversions.h"
95
96// dispatchers able to capture (or ignore) the result
97#include "details/dispatchers.h"
98
99// helper for checking for required number of parameters
100// (throws tcl_error when not met)
101void check_params_no(int objc, int required);
102
103// helper for gathering optional params in variadic functions
104object get_var_params(Tcl_Interp *interp,
105     int objc, Tcl_Obj * CONST objv[],
106     int from, policies const &pol);
107
108// the callback_base is used to store callback handlers in a polynorphic map
109class callback_base
110{
111public:
112     virtual ~callback_base() {}
113
114     virtual void invoke(Tcl_Interp *interp,
115          int objc, Tcl_Obj * CONST objv[],
116          policies const &pol) = 0;
117};
118
119
120// base class for object command handlers
121// and for class handlers
122class object_cmd_base
123{
124public:
125     // destructor not needed, but exists to shut up the compiler warnings
126     virtual ~object_cmd_base() {}
127
128     virtual void invoke(void *p, Tcl_Interp *interp,
129          int objc, Tcl_Obj * CONST objv[],
130          policies const &pol) = 0;
131};
132
133// base class for all class handlers, still abstract
134class class_handler_base : public object_cmd_base
135{
136public:
137     typedef std::map<std::string, policies> policies_map_type;
138
139     class_handler_base();
140
141     void register_method(std::string const &name,
142          std::shared_ptr<object_cmd_base> ocb, policies const &p);
143
144     policies & get_policies(std::string const &name);
145
146protected:
147     typedef std::map<
148          std::string,
149          std::shared_ptr<object_cmd_base>
150          > method_map_type;
151
152     // a map of methods for the given class
153     method_map_type methods_;
154
155     policies_map_type policies_;
156};
157
158// class handler - responsible for executing class methods
159template <class C>
160class class_handler : public class_handler_base
161{
162public:
163     virtual void invoke(void *pv, Tcl_Interp *interp,
164          int objc, Tcl_Obj * CONST objv[], policies const &pol)
165     {
166          C * p = static_cast<C*>(pv);
167
168          if (objc < 2)
169          {
170               throw tcl_error("Too few arguments.");
171          }
172         
173          std::string methodName(Tcl_GetString(objv[1]));
174
175          if (methodName == "-delete")
176          {
177               Tcl_DeleteCommand(interp, Tcl_GetString(objv[0]));
178               delete p;
179               return;
180          }
181
182          // dispatch on the method name
183
184          method_map_type::iterator it = methods_.find(methodName);
185          if (it == methods_.end())
186          {
187               throw tcl_error("Method " + methodName + " not found.");
188          }
189
190          it->second->invoke(pv, interp, objc, objv, pol);
191     }
192};
193
194
195// factory functions for creating class objects
196#include "details/constructors.h"
197
198// actual callback envelopes
199#include "details/callbacks.h"
200
201// actual method envelopes
202#include "details/methods.h"
203
204// helper meta function for figuring appropriate constructor callback
205#include "details/metahelpers.h"
206
207
208// this class is used to provide the "def" interface for defining
209// class member functions
210
211template <class C>
212class class_definer
213{
214public:
215     class_definer(std::shared_ptr<class_handler<C> > ch) : ch_(ch) {}
216
217     template <typename R>
218     class_definer & def(std::string const &name, R (C::*f)(),
219          policies const &p = policies())
220     {
221          ch_->register_method(name,
222               std::shared_ptr<details::object_cmd_base>(
223                    new details::method0<C, R>(f)), p);
224          return *this;
225     }
226
227     template <typename R>
228     class_definer & def(std::string const &name, R (C::*f)() const,
229          policies const &p = policies())
230     {
231          ch_->register_method(name,
232               std::shared_ptr<details::object_cmd_base>(
233                    new details::method0<C, R>(f)), p);
234          return *this;
235     }
236
237     template <typename R, typename T1>
238     class_definer & def(std::string const &name, R (C::*f)(T1),
239          policies const &p = policies())
240     {
241          ch_->register_method(name,
242               std::shared_ptr<details::object_cmd_base>(
243                    new details::method1<C, R, T1>(f)), p);
244          return *this;
245     }
246
247     template <typename R, typename T1>
248     class_definer & def(std::string const &name, R (C::*f)(T1) const,
249          policies const &p = policies())
250     {
251          ch_->register_method(name,
252               std::shared_ptr<details::object_cmd_base>(
253                    new details::method1<C, R, T1>(f)), p);
254          return *this;
255     }
256
257     template <typename R, typename T1, typename T2>
258     class_definer & def(std::string const &name, R (C::*f)(T1, T2),
259          policies const &p = policies())
260     {
261          ch_->register_method(name,
262               std::shared_ptr<details::object_cmd_base>(
263                    new details::method2<C, R, T1, T2>(f)), p);
264          return *this;
265     }
266
267     template <typename R, typename T1, typename T2>
268     class_definer & def(std::string const &name, R (C::*f)(T1, T2) const,
269          policies const &p = policies())
270     {
271          ch_->register_method(name,
272               std::shared_ptr<details::object_cmd_base>(
273                    new details::method2<C, R, T1, T2>(f)), p);
274          return *this;
275     }
276
277     template <typename R, typename T1, typename T2, typename T3>
278     class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3),
279          policies const &p = policies())
280     {
281          ch_->register_method(name,
282               std::shared_ptr<details::object_cmd_base>(
283                    new details::method3<C, R, T1, T2, T3>(f)), p);
284          return *this;
285     }
286
287     template <typename R, typename T1, typename T2, typename T3>
288     class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3) const,
289          policies const &p = policies())
290     {
291          ch_->register_method(name,
292               std::shared_ptr<details::object_cmd_base>(
293                    new details::method3<C, R, T1, T2, T3>(f)), p);
294          return *this;
295     }
296
297     template <typename R, typename T1, typename T2, typename T3, typename T4>
298     class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4),
299          policies const &p = policies())
300     {
301          ch_->register_method(name,
302               std::shared_ptr<details::object_cmd_base>(
303                    new details::method4<C, R, T1, T2, T3, T4>(f)), p);
304          return *this;
305     }
306
307     template <typename R, typename T1, typename T2, typename T3, typename T4>
308     class_definer & def(std::string const &name,
309          R (C::*f)(T1, T2, T3, T4) const,
310          policies const &p = policies())
311     {
312          ch_->register_method(name,
313               std::shared_ptr<details::object_cmd_base>(
314                    new details::method4<C, R, T1, T2, T3, T4>(f)), p);
315          return *this;
316     }
317
318     template <typename R, typename T1, typename T2, typename T3, typename T4,
319          typename T5>
320     class_definer & def(std::string const &name,
321          R (C::*f)(T1, T2, T3, T4, T5), policies const &p = policies())
322     {
323          ch_->register_method(name,
324               std::shared_ptr<details::object_cmd_base>(
325                    new details::method5<C, R, T1, T2, T3, T4, T5>(f)), p);
326          return *this;
327     }
328
329     template <typename R, typename T1, typename T2, typename T3, typename T4,
330          typename T5>
331     class_definer & def(std::string const &name,
332          R (C::*f)(T1, T2, T3, T4, T5) const, policies const &p = policies())
333     {
334          ch_->register_method(name,
335               std::shared_ptr<details::object_cmd_base>(
336                    new details::method5<C, R, T1, T2, T3, T4, T5>(f)), p);
337          return *this;
338     }
339
340     template <typename R, typename T1, typename T2, typename T3, typename T4,
341          typename T5, typename T6>
342     class_definer & def(std::string const &name,
343          R (C::*f)(T1, T2, T3, T4, T5, T6), policies const &p = policies())
344     {
345          ch_->register_method(name,
346               std::shared_ptr<details::object_cmd_base>(
347                    new details::method6<C, R, T1, T2, T3, T4, T5, T6>(f)),
348               p);
349          return *this;
350     }
351
352     template <typename R, typename T1, typename T2, typename T3, typename T4,
353          typename T5, typename T6>
354     class_definer & def(std::string const &name,
355          R (C::*f)(T1, T2, T3, T4, T5, T6) const,
356          policies const &p = policies())
357     {
358          ch_->register_method(name,
359               std::shared_ptr<details::object_cmd_base>(
360                    new details::method6<C, R, T1, T2, T3, T4, T5, T6>(f)),
361               p);
362          return *this;
363     }
364
365     template <typename R, typename T1, typename T2, typename T3, typename T4,
366          typename T5, typename T6, typename T7>
367     class_definer & def(std::string const &name,
368          R (C::*f)(T1, T2, T3, T4, T5, T6, T7),
369          policies const &p = policies())
370     {
371          ch_->register_method(name,
372               std::shared_ptr<details::object_cmd_base>(
373                    new details::method7<C, R,
374                    T1, T2, T3, T4, T5, T6, T7>(f)), p);
375          return *this;
376     }
377
378     template <typename R, typename T1, typename T2, typename T3, typename T4,
379          typename T5, typename T6, typename T7>
380     class_definer & def(std::string const &name,
381          R (C::*f)(T1, T2, T3, T4, T5, T6, T7) const,
382          policies const &p = policies())
383     {
384          ch_->register_method(name,
385               std::shared_ptr<details::object_cmd_base>(
386                    new details::method7<C, R,
387                    T1, T2, T3, T4, T5, T6, T7>(f)), p);
388          return *this;
389     }
390
391     template <typename R, typename T1, typename T2, typename T3, typename T4,
392          typename T5, typename T6, typename T7, typename T8>
393     class_definer & def(std::string const &name,
394          R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8),
395          policies const &p = policies())
396     {
397          ch_->register_method(name,
398               std::shared_ptr<details::object_cmd_base>(
399                    new details::method8<C, R,
400                    T1, T2, T3, T4, T5, T6, T7, T8>(f)), p);
401          return *this;
402     }
403
404     template <typename R, typename T1, typename T2, typename T3, typename T4,
405          typename T5, typename T6, typename T7, typename T8>
406     class_definer & def(std::string const &name,
407          R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8) const,
408          policies const &p = policies())
409     {
410          ch_->register_method(name,
411               std::shared_ptr<details::object_cmd_base>(
412                    new details::method8<C, R,
413                    T1, T2, T3, T4, T5, T6, T7, T8>(f)), p);
414          return *this;
415     }
416
417     template <typename R, typename T1, typename T2, typename T3, typename T4,
418          typename T5, typename T6, typename T7, typename T8, typename T9>
419     class_definer & def(std::string const &name,
420          R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9),
421          policies const &p = policies())
422     {
423          ch_->register_method(name,
424               std::shared_ptr<details::object_cmd_base>(
425                    new details::method9<C, R,
426                    T1, T2, T3, T4, T5, T6, T7, T8, T9>(f)), p);
427          return *this;
428     }
429
430     template <typename R, typename T1, typename T2, typename T3, typename T4,
431          typename T5, typename T6, typename T7, typename T8, typename T9>
432     class_definer & def(std::string const &name,
433          R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9) const,
434          policies const &p = policies())
435     {
436          ch_->register_method(name,
437               std::shared_ptr<details::object_cmd_base>(
438                    new details::method9<C, R,
439                    T1, T2, T3, T4, T5, T6, T7, T8, T9>(f)), p);
440          return *this;
441     }
442
443private:
444     std::shared_ptr<class_handler<C> > ch_;
445};
446
447} // namespace details
448
449
450// init type for defining class constructors
451template <typename T1 = void, typename T2 = void, typename T3 = void,
452          typename T4 = void, typename T5 = void, typename T6 = void,
453          typename T7 = void, typename T8 = void, typename T9 = void>
454class init {};
455
456// no_init type and object - to define classes without constructors
457namespace details
458{
459     struct no_init_type {};
460} // namespace details
461extern details::no_init_type no_init;
462
463
464// interpreter wrapper
465class interpreter
466{
467public:
468     interpreter();
469     interpreter(Tcl_Interp *, bool owner = true);
470     ~interpreter();
471     
472     void make_safe();
473     
474     Tcl_Interp * get() const { return interp_; }
475
476     // free function definitions     
477     
478     template <typename R>
479     void def(std::string const &name, R (*f)(),
480          policies const &p = policies())
481     {
482          add_function(name,
483               std::shared_ptr<details::callback_base>(
484                    new details::callback0<R>(f)), p);
485     }
486
487     template <typename R, typename T1>
488     void def(std::string const &name, R (*f)(T1),
489          policies const &p = policies())
490     {
491          add_function(name,
492               std::shared_ptr<details::callback_base>(
493                    new details::callback1<R, T1>(f)), p);
494     }
495
496     template <typename R, typename T1, typename T2>
497     void def(std::string const &name, R (*f)(T1, T2),
498          policies const &p = policies())
499     {
500          add_function(name,
501               std::shared_ptr<details::callback_base>(
502                    new details::callback2<R, T1, T2>(f)), p);
503     }
504
505     template <typename R, typename T1, typename T2, typename T3>
506     void def(std::string const &name, R (*f)(T1, T2, T3),
507          policies const &p = policies())
508     {
509          add_function(name,
510               std::shared_ptr<details::callback_base>(
511                    new details::callback3<R, T1, T2, T3>(f)), p);
512     }
513
514     template <typename R, typename T1, typename T2, typename T3, typename T4>
515     void def(std::string const &name, R (*f)(T1, T2, T3, T4),
516          policies const &p = policies())
517     {
518          add_function(name,
519               std::shared_ptr<details::callback_base>(
520                    new details::callback4<R, T1, T2, T3, T4>(f)), p);
521     }
522
523     template <typename R, typename T1, typename T2, typename T3,
524          typename T4, typename T5>
525     void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5),
526          policies const &p = policies())
527     {
528          add_function(name,
529               std::shared_ptr<details::callback_base>(
530                    new details::callback5<R, T1, T2, T3, T4, T5>(f)), p);
531     }
532
533     template <typename R, typename T1, typename T2, typename T3,
534          typename T4, typename T5, typename T6>
535     void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5, T6),
536          policies const &p = policies())
537     {
538          add_function(name,
539               std::shared_ptr<details::callback_base>(
540                    new details::callback6<R, T1, T2, T3, T4, T5, T6>(f)), p);
541     }
542
543     template <typename R, typename T1, typename T2, typename T3,
544          typename T4, typename T5, typename T6, typename T7>
545     void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5, T6, T7),
546          policies const &p = policies())
547     {
548          add_function(name,
549               std::shared_ptr<details::callback_base>(
550                    new details::callback7<R,
551                    T1, T2, T3, T4, T5, T6, T7>(f)), p);
552     }
553
554     template <typename R, typename T1, typename T2, typename T3,
555          typename T4, typename T5, typename T6, typename T7, typename T8>
556     void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5, T6, T7, T8),
557          policies const &p = policies())
558     {
559          add_function(name,
560               std::shared_ptr<details::callback_base>(
561                    new details::callback8<R,
562                    T1, T2, T3, T4, T5, T6, T7, T8>(f)), p);
563     }
564
565     template <typename R, typename T1, typename T2, typename T3,
566          typename T4, typename T5, typename T6, typename T7, typename T8,
567          typename T9>
568     void def(std::string const &name,
569          R (*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9),
570          policies const &p = policies())
571     {
572          add_function(name,
573               std::shared_ptr<details::callback_base>(
574                    new details::callback9<R,
575                    T1, T2, T3, T4, T5, T6, T7, T8, T9>(f)), p);
576     }
577
578
579     // class definitions
580
581     template <class C>
582     details::class_definer<C> class_(std::string const &name)
583     {
584          std::shared_ptr<details::class_handler<C> > ch(
585               new details::class_handler<C>());
586
587          add_class(name, ch);
588
589          add_constructor(name, ch,
590               std::shared_ptr<details::callback_base>(
591                    new details::callback0<C*>(&details::construct<
592                         C, void, void, void, void, void, void, void,
593                         void, void>::doit)));
594
595          return details::class_definer<C>(ch);
596     }
597
598     template <class C, typename T1, typename T2, typename T3, typename T4,
599               typename T5, typename T6, typename T7, typename T8,
600               typename T9>
601     details::class_definer<C> class_(std::string const &name,
602          init<T1, T2, T3, T4, T5, T6, T7, T8, T9> const &,
603          policies const &p = policies())
604     {
605          typedef typename details::get_callback_type_for_construct<
606               C, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
607               callback_type;
608
609          std::shared_ptr<details::class_handler<C> > ch(
610               new details::class_handler<C>());
611
612          add_class(name, ch);
613
614          add_constructor(name, ch,
615               std::shared_ptr<details::callback_base>(
616                    new callback_type(&details::construct<
617                         C, T1, T2, T3, T4, T5, T6, T7, T8, T9>::doit)), p);
618
619          return details::class_definer<C>(ch);
620     }
621
622     template <class C>
623     details::class_definer<C> class_(
624          std::string const &name, details::no_init_type const &)
625     {
626          std::shared_ptr<details::class_handler<C> > ch(
627               new details::class_handler<C>());
628
629          add_class(name, ch);
630
631          return details::class_definer<C>(ch);
632     }
633
634     // free script evaluation     
635     details::result eval(std::string const &script);
636     details::result eval(std::istream &s);
637
638     details::result eval(object const &o);
639
640     // the InputIterator should give object& or Tcl_Obj* when dereferenced
641     template <class InputIterator>
642     details::result eval(InputIterator first, InputIterator last);
643
644     // create alias from the *this interpreter to the target interpreter
645     void create_alias(std::string const &cmd,
646          interpreter &targetInterp, std::string const &targetCmd);
647
648     // register a package info (useful when defining packages)
649     void pkg_provide(std::string const &name, std::string const &version);
650
651     // helper for cleaning up callbacks in non-managed interpreters
652     static void clear_definitions(Tcl_Interp *);
653
654private:
655
656     // copy not supported
657     interpreter(const interpreter &);
658     void operator=(const interpreter &);
659
660     void add_function(std::string const &name,
661          std::shared_ptr<details::callback_base> cb,
662          policies const &p = policies());
663
664     void add_class(std::string const &name,
665          std::shared_ptr<details::class_handler_base> chb);
666
667     void add_constructor(std::string const &name,
668          std::shared_ptr<details::class_handler_base> chb,
669          std::shared_ptr<details::callback_base> cb,
670          policies const &p = policies());
671
672     Tcl_Interp *interp_;
673     bool owner_;
674};
675
676
677// object wrapper
678class object
679{
680public:
681
682     // constructors
683
684     object();
685
686     explicit object(bool b);
687     object(char const *buf, size_t size); // byte array
688     explicit object(double b);
689     explicit object(int i);
690
691     // list creation
692     // the InputIterator should give object& or Tcl_Obj* when dereferenced
693     template <class InputIterator>
694     object(InputIterator first, InputIterator last)
695          : interp_(0)
696     {
697          std::vector<Tcl_Obj*> v;
698          fill_vector(v, first, last);
699          obj_ = Tcl_NewListObj(static_cast<int>(v.size()),
700               v.empty() ? NULL : &v[0]);
701          Tcl_IncrRefCount(obj_);
702     }
703
704     explicit object(long i);
705     explicit object(char const *s);        // string construction
706     explicit object(std::string const &s); // string construction
707
708     explicit object(Tcl_Obj *o, bool shared = false);
709
710     object(object const &other, bool shared = false);
711     ~object();
712
713     // assignment
714
715     object & assign(bool b);
716     object & resize(size_t size);                  // byte array resize
717     object & assign(char const *buf, size_t size); // byte array assignment
718     object & assign(double d);
719     object & assign(int i);
720
721     // list assignment
722     // the InputIterator should give Tcl_Obj* or object& when dereferenced
723     template <class InputIterator>
724     object & assign(InputIterator first, InputIterator last)
725     {
726          std::vector<Tcl_Obj*> v;
727          fill_vector(v, first, last);
728          Tcl_SetListObj(obj_, static_cast<int>(v.size()),
729               v.empty() ? NULL : &v[0]);
730          return *this;
731     }
732
733     object & assign(long l);
734     object & assign(char const *s);        // string assignment
735     object & assign(std::string const &s); // string assignment
736     object & assign(object const &o);
737     object & assign(Tcl_Obj *o);
738
739     object & operator=(bool b)               { return assign(b); }
740     object & operator=(double d)             { return assign(d); }
741     object & operator=(int i)                { return assign(i); }
742     object & operator=(long l)               { return assign(l); }
743     object & operator=(char const *s)        { return assign(s); }
744     object & operator=(std::string const &s) { return assign(s); }
745
746     object & operator=(object const &o)      { return assign(o); }
747     object & swap(object &other);
748
749     // (logically) non-modifying members
750
751     template <typename T>
752     T get(interpreter &i) const;
753
754     char const * get() const;             // string get
755     char const * get(size_t &size) const; // byte array get
756
757     size_t length(interpreter &i) const;  // returns list length
758     object at(interpreter &i, size_t index) const;
759
760     Tcl_Obj * get_object() const { return obj_; }
761
762     // modifying members
763
764     object & append(interpreter &i, object const &o);
765     object & append_list(interpreter &i, object const &o);
766
767     // list replace
768     // the InputIterator should give Tcl_Obj* or object& when dereferenced
769     template <class InputIterator>
770     object & replace(interpreter &i, size_t index, size_t count,
771          InputIterator first, InputIterator last)
772     {
773          std::vector<Tcl_Obj*> v;
774          fill_vector(v, first, last);
775          int res = Tcl_ListObjReplace(i.get(), obj_,
776               static_cast<int>(index), static_cast<int>(count),
777               static_cast<int>(v.size()), v.empty() ? NULL : &v[0]);
778          if (res != TCL_OK)
779          {
780               throw tcl_error(i.get());
781          }
782
783          return *this;
784     }
785
786     object & replace(interpreter &i, size_t index, size_t count,
787          object const &o);
788     object & replace_list(interpreter &i, size_t index, size_t count,
789          object const &o);
790
791     // helper functions for piggy-backing interpreter info
792     void set_interp(Tcl_Interp *interp);
793     Tcl_Interp * get_interp() const;
794
795     // helper function, also used from interpreter::eval
796     template <class InputIterator>
797     static void fill_vector(std::vector<Tcl_Obj*> &v,
798          InputIterator first, InputIterator last)
799     {
800          for (; first != last; ++first)
801          {
802               object o(*first, true);
803               v.push_back(o.obj_);
804          }
805     }
806
807private:
808
809     // helper function used from copy constructors
810     void init(Tcl_Obj *o, bool shared);
811
812     Tcl_Obj *obj_;
813     Tcl_Interp *interp_;
814};
815
816// available specializations for object::get
817template <> bool         object::get<bool>(interpreter &i) const;
818template <> double       object::get<double>(interpreter &i) const;
819template <> int          object::get<int>(interpreter &i) const;
820template <> long         object::get<long>(interpreter &i) const;
821template <> char const * object::get<char const *>(interpreter &i) const;
822template <> std::string  object::get<std::string>(interpreter &i) const;
823template <>
824std::vector<char> object::get<std::vector<char> >(interpreter &i) const;
825
826// the InputIterator should give object& or Tcl_Obj* when dereferenced
827template <class InputIterator>
828details::result interpreter::eval(InputIterator first, InputIterator last)
829{
830     std::vector<Tcl_Obj*> v;
831     object::fill_vector(v, first, last);
832     int cc = Tcl_EvalObjv(interp_,
833          static_cast<int>(v.size()), v.empty() ? NULL : &v[0], 0);
834     if (cc != TCL_OK)
835     {
836          throw tcl_error(interp_);
837     }
838 
839     return details::result(interp_);
840}
841
842namespace details
843{
844
845// additional callback envelopes for variadic functions
846#include "details/callbacks_v.h"
847
848// additional method envelopes for variadic methods
849#include "details/methods_v.h"
850
851} // namespace details
852
853} // namespace Tcl
854
855
856// macro for defining loadable module entry point
857// - used for extending Tcl interpreter
858
859#define CPPTCL_MODULE(name, i) void name##_cpptcl_Init(Tcl::interpreter &i); \
860     extern "C" int name##_Init(Tcl_Interp *interp) \
861     { \
862          Tcl::interpreter i(interp, false); \
863          name##_cpptcl_Init(i); \
864          return TCL_OK; \
865     } \
866     void name##_cpptcl_Init(Tcl::interpreter &i)
867
868
869#endif // CPPTCL_INCLUDED
Note: See TracBrowser for help on using the repository browser.