Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/archive/tutorialFS09/src/cpptcl/cpptcl.h @ 12373

Last change on this file since 12373 was 2710, checked in by rgrieder, 16 years ago

Merged buildsystem3 containing buildsystem2 containing Adi's buildsystem branch back to the trunk.
Please update the media directory if you were not using buildsystem3 before.

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