Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/questlog/src/external/cpptcl/cpptcl.h @ 10158

Last change on this file since 10158 was 5781, checked in by rgrieder, 15 years ago

Reverted trunk again. We might want to find a way to delete these revisions again (x3n's changes are still available as diff in the commit mails).

  • Property svn:eol-style set to native
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(Tcl_Interp *, bool owner = true);
471     ~interpreter();
472     
473     void make_safe();
474     
475     Tcl_Interp * get() const { return interp_; }
476
477     // free function definitions     
478     
479     template <typename R>
480     void def(std::string const &name, R (*f)(),
481          policies const &p = policies())
482     {
483          add_function(name,
484               boost::shared_ptr<details::callback_base>(
485                    new details::callback0<R>(f)), p);
486     }
487
488     template <typename R, typename T1>
489     void def(std::string const &name, R (*f)(T1),
490          policies const &p = policies())
491     {
492          add_function(name,
493               boost::shared_ptr<details::callback_base>(
494                    new details::callback1<R, T1>(f)), p);
495     }
496
497     template <typename R, typename T1, typename T2>
498     void def(std::string const &name, R (*f)(T1, T2),
499          policies const &p = policies())
500     {
501          add_function(name,
502               boost::shared_ptr<details::callback_base>(
503                    new details::callback2<R, T1, T2>(f)), p);
504     }
505
506     template <typename R, typename T1, typename T2, typename T3>
507     void def(std::string const &name, R (*f)(T1, T2, T3),
508          policies const &p = policies())
509     {
510          add_function(name,
511               boost::shared_ptr<details::callback_base>(
512                    new details::callback3<R, T1, T2, T3>(f)), p);
513     }
514
515     template <typename R, typename T1, typename T2, typename T3, typename T4>
516     void def(std::string const &name, R (*f)(T1, T2, T3, T4),
517          policies const &p = policies())
518     {
519          add_function(name,
520               boost::shared_ptr<details::callback_base>(
521                    new details::callback4<R, T1, T2, T3, T4>(f)), p);
522     }
523
524     template <typename R, typename T1, typename T2, typename T3,
525          typename T4, typename T5>
526     void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5),
527          policies const &p = policies())
528     {
529          add_function(name,
530               boost::shared_ptr<details::callback_base>(
531                    new details::callback5<R, T1, T2, T3, T4, T5>(f)), p);
532     }
533
534     template <typename R, typename T1, typename T2, typename T3,
535          typename T4, typename T5, typename T6>
536     void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5, T6),
537          policies const &p = policies())
538     {
539          add_function(name,
540               boost::shared_ptr<details::callback_base>(
541                    new details::callback6<R, T1, T2, T3, T4, T5, T6>(f)), p);
542     }
543
544     template <typename R, typename T1, typename T2, typename T3,
545          typename T4, typename T5, typename T6, typename T7>
546     void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5, T6, T7),
547          policies const &p = policies())
548     {
549          add_function(name,
550               boost::shared_ptr<details::callback_base>(
551                    new details::callback7<R,
552                    T1, T2, T3, T4, T5, T6, T7>(f)), p);
553     }
554
555     template <typename R, typename T1, typename T2, typename T3,
556          typename T4, typename T5, typename T6, typename T7, typename T8>
557     void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5, T6, T7, T8),
558          policies const &p = policies())
559     {
560          add_function(name,
561               boost::shared_ptr<details::callback_base>(
562                    new details::callback8<R,
563                    T1, T2, T3, T4, T5, T6, T7, T8>(f)), p);
564     }
565
566     template <typename R, typename T1, typename T2, typename T3,
567          typename T4, typename T5, typename T6, typename T7, typename T8,
568          typename T9>
569     void def(std::string const &name,
570          R (*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9),
571          policies const &p = policies())
572     {
573          add_function(name,
574               boost::shared_ptr<details::callback_base>(
575                    new details::callback9<R,
576                    T1, T2, T3, T4, T5, T6, T7, T8, T9>(f)), p);
577     }
578
579
580     // class definitions
581
582     template <class C>
583     details::class_definer<C> class_(std::string const &name)
584     {
585          boost::shared_ptr<details::class_handler<C> > ch(
586               new details::class_handler<C>());
587
588          add_class(name, ch);
589
590          add_constructor(name, ch,
591               boost::shared_ptr<details::callback_base>(
592                    new details::callback0<C*>(&details::construct<
593                         C, void, void, void, void, void, void, void,
594                         void, void>::doit)));
595
596          return details::class_definer<C>(ch);
597     }
598
599     template <class C, typename T1, typename T2, typename T3, typename T4,
600               typename T5, typename T6, typename T7, typename T8,
601               typename T9>
602     details::class_definer<C> class_(std::string const &name,
603          init<T1, T2, T3, T4, T5, T6, T7, T8, T9> const &,
604          policies const &p = policies())
605     {
606          typedef typename details::get_callback_type_for_construct<
607               C, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
608               callback_type;
609
610          boost::shared_ptr<details::class_handler<C> > ch(
611               new details::class_handler<C>());
612
613          add_class(name, ch);
614
615          add_constructor(name, ch,
616               boost::shared_ptr<details::callback_base>(
617                    new callback_type(&details::construct<
618                         C, T1, T2, T3, T4, T5, T6, T7, T8, T9>::doit)), p);
619
620          return details::class_definer<C>(ch);
621     }
622
623     template <class C>
624     details::class_definer<C> class_(
625          std::string const &name, details::no_init_type const &)
626     {
627          boost::shared_ptr<details::class_handler<C> > ch(
628               new details::class_handler<C>());
629
630          add_class(name, ch);
631
632          return details::class_definer<C>(ch);
633     }
634
635     // free script evaluation     
636     details::result eval(std::string const &script);
637     details::result eval(std::istream &s);
638
639     details::result eval(object const &o);
640
641     // the InputIterator should give object& or Tcl_Obj* when dereferenced
642     template <class InputIterator>
643     details::result eval(InputIterator first, InputIterator last);
644
645     // create alias from the *this interpreter to the target interpreter
646     void create_alias(std::string const &cmd,
647          interpreter &targetInterp, std::string const &targetCmd);
648
649     // register a package info (useful when defining packages)
650     void pkg_provide(std::string const &name, std::string const &version);
651
652     // helper for cleaning up callbacks in non-managed interpreters
653     static void clear_definitions(Tcl_Interp *);
654
655private:
656
657     // copy not supported
658     interpreter(const interpreter &);
659     void operator=(const interpreter &);
660
661     void add_function(std::string const &name,
662          boost::shared_ptr<details::callback_base> cb,
663          policies const &p = policies());
664
665     void add_class(std::string const &name,
666          boost::shared_ptr<details::class_handler_base> chb);
667
668     void add_constructor(std::string const &name,
669          boost::shared_ptr<details::class_handler_base> chb,
670          boost::shared_ptr<details::callback_base> cb,
671          policies const &p = policies());
672
673     Tcl_Interp *interp_;
674     bool owner_;
675};
676
677
678// object wrapper
679class object
680{
681public:
682
683     // constructors
684
685     object();
686
687     explicit object(bool b);
688     object(char const *buf, size_t size); // byte array
689     explicit object(double b);
690     explicit object(int i);
691
692     // list creation
693     // the InputIterator should give object& or Tcl_Obj* when dereferenced
694     template <class InputIterator>
695     object(InputIterator first, InputIterator last)
696          : interp_(0)
697     {
698          std::vector<Tcl_Obj*> v;
699          fill_vector(v, first, last);
700          obj_ = Tcl_NewListObj(static_cast<int>(v.size()),
701               v.empty() ? NULL : &v[0]);
702          Tcl_IncrRefCount(obj_);
703     }
704
705     explicit object(long i);
706     explicit object(char const *s);        // string construction
707     explicit object(std::string const &s); // string construction
708
709     explicit object(Tcl_Obj *o, bool shared = false);
710
711     object(object const &other, bool shared = false);
712     ~object();
713
714     // assignment
715
716     object & assign(bool b);
717     object & resize(size_t size);                  // byte array resize
718     object & assign(char const *buf, size_t size); // byte array assignment
719     object & assign(double d);
720     object & assign(int i);
721
722     // list assignment
723     // the InputIterator should give Tcl_Obj* or object& when dereferenced
724     template <class InputIterator>
725     object & assign(InputIterator first, InputIterator last)
726     {
727          std::vector<Tcl_Obj*> v;
728          fill_vector(v, first, last);
729          Tcl_SetListObj(obj_, static_cast<int>(v.size()),
730               v.empty() ? NULL : &v[0]);
731          return *this;
732     }
733
734     object & assign(long l);
735     object & assign(char const *s);        // string assignment
736     object & assign(std::string const &s); // string assignment
737     object & assign(object const &o);
738     object & assign(Tcl_Obj *o);
739
740     object & operator=(bool b)               { return assign(b); }
741     object & operator=(double d)             { return assign(d); }
742     object & operator=(int i)                { return assign(i); }
743     object & operator=(long l)               { return assign(l); }
744     object & operator=(char const *s)        { return assign(s); }
745     object & operator=(std::string const &s) { return assign(s); }
746
747     object & operator=(object const &o)      { return assign(o); }
748     object & swap(object &other);
749
750     // (logically) non-modifying members
751
752     template <typename T>
753     T get(interpreter &i) const;
754
755     char const * get() const;             // string get
756     char const * get(size_t &size) const; // byte array get
757
758     size_t length(interpreter &i) const;  // returns list length
759     object at(interpreter &i, size_t index) const;
760
761     Tcl_Obj * get_object() const { return obj_; }
762
763     // modifying members
764
765     object & append(interpreter &i, object const &o);
766     object & append_list(interpreter &i, object const &o);
767
768     // list replace
769     // the InputIterator should give Tcl_Obj* or object& when dereferenced
770     template <class InputIterator>
771     object & replace(interpreter &i, size_t index, size_t count,
772          InputIterator first, InputIterator last)
773     {
774          std::vector<Tcl_Obj*> v;
775          fill_vector(v, first, last);
776          int res = Tcl_ListObjReplace(i.get(), obj_,
777               static_cast<int>(index), static_cast<int>(count),
778               static_cast<int>(v.size()), v.empty() ? NULL : &v[0]);
779          if (res != TCL_OK)
780          {
781               throw tcl_error(i.get());
782          }
783
784          return *this;
785     }
786
787     object & replace(interpreter &i, size_t index, size_t count,
788          object const &o);
789     object & replace_list(interpreter &i, size_t index, size_t count,
790          object const &o);
791
792     // helper functions for piggy-backing interpreter info
793     void set_interp(Tcl_Interp *interp);
794     Tcl_Interp * get_interp() const;
795
796     // helper function, also used from interpreter::eval
797     template <class InputIterator>
798     static void fill_vector(std::vector<Tcl_Obj*> &v,
799          InputIterator first, InputIterator last)
800     {
801          for (; first != last; ++first)
802          {
803               object o(*first, true);
804               v.push_back(o.obj_);
805          }
806     }
807
808private:
809
810     // helper function used from copy constructors
811     void init(Tcl_Obj *o, bool shared);
812
813     Tcl_Obj *obj_;
814     Tcl_Interp *interp_;
815};
816
817// available specializations for object::get
818template <> bool         object::get<bool>(interpreter &i) const;
819template <> double       object::get<double>(interpreter &i) const;
820template <> int          object::get<int>(interpreter &i) const;
821template <> long         object::get<long>(interpreter &i) const;
822template <> char const * object::get<char const *>(interpreter &i) const;
823template <> std::string  object::get<std::string>(interpreter &i) const;
824template <>
825std::vector<char> object::get<std::vector<char> >(interpreter &i) const;
826
827// the InputIterator should give object& or Tcl_Obj* when dereferenced
828template <class InputIterator>
829details::result interpreter::eval(InputIterator first, InputIterator last)
830{
831     std::vector<Tcl_Obj*> v;
832     object::fill_vector(v, first, last);
833     int cc = Tcl_EvalObjv(interp_,
834          static_cast<int>(v.size()), v.empty() ? NULL : &v[0], 0);
835     if (cc != TCL_OK)
836     {
837          throw tcl_error(interp_);
838     }
839 
840     return details::result(interp_);
841}
842
843namespace details
844{
845
846// additional callback envelopes for variadic functions
847#include "details/callbacks_v.h"
848
849// additional method envelopes for variadic methods
850#include "details/methods_v.h"
851
852} // namespace details
853
854} // namespace Tcl
855
856
857// macro for defining loadable module entry point
858// - used for extending Tcl interpreter
859
860#define CPPTCL_MODULE(name, i) void name##_cpptcl_Init(Tcl::interpreter &i); \
861     extern "C" int name##_Init(Tcl_Interp *interp) \
862     { \
863          Tcl::interpreter i(interp, false); \
864          name##_cpptcl_Init(i); \
865          return TCL_OK; \
866     } \
867     void name##_cpptcl_Init(Tcl::interpreter &i)
868
869
870#endif // CPPTCL_INCLUDED
Note: See TracBrowser for help on using the repository browser.