📄 cpptcl.h
字号:
//// Copyright (C) 2004-2006, Maciej Sobczak//// Permission to copy, use, modify, sell and distribute this software// is granted provided this copyright notice appears in all copies.// This software is provided "as is" without express or implied// warranty, and with no claim as to its suitability for any purpose.//#ifndef CPPTCL_INCLUDED#define CPPTCL_INCLUDED#include <tcl.h>#include <string>#include <stdexcept>#include <sstream>#include <map>#include <vector>#include <boost/shared_ptr.hpp>#include <boost/bind.hpp>namespace Tcl{// exception class used for reporting all Tcl errorsclass tcl_error : public std::runtime_error{public: explicit tcl_error(std::string const &msg) : std::runtime_error(msg) {} explicit tcl_error(Tcl_Interp *interp) : std::runtime_error(Tcl_GetString(Tcl_GetObjResult(interp))) {}};// call policiesstruct policies{ policies() : variadic_(false) {} policies & factory(std::string const &name); // note: this is additive policies & sink(int index); policies & variadic(); std::string factory_; std::vector<int> sinks_; bool variadic_;};// syntax short-cutspolicies factory(std::string const &name);policies sink(int index);policies variadic();class interpreter;class object;namespace details{// wrapper for the evaluation resultclass result{public: result(Tcl_Interp *interp); operator bool() const; operator double() const; operator int() const; operator long() const; operator std::string() const; operator object() const;private: Tcl_Interp *interp_;};// helper functions used to set the result valuevoid set_result(Tcl_Interp *interp, bool b);void set_result(Tcl_Interp *interp, int i);void set_result(Tcl_Interp *interp, long i);void set_result(Tcl_Interp *interp, double d);void set_result(Tcl_Interp *interp, std::string const &s);void set_result(Tcl_Interp *interp, void *p);void set_result(Tcl_Interp *interp, object const &o);// helper functor for converting Tcl objects to the given type#include "details/conversions.h"// dispatchers able to capture (or ignore) the result#include "details/dispatchers.h"// helper for checking for required number of parameters// (throws tcl_error when not met)void check_params_no(int objc, int required);// helper for gathering optional params in variadic functionsobject get_var_params(Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[], int from, policies const &pol);// the callback_base is used to store callback handlers in a polynorphic mapclass callback_base{public: virtual ~callback_base() {} virtual void invoke(Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[], policies const &pol) = 0;};// base class for object command handlers// and for class handlersclass object_cmd_base{public: // destructor not needed, but exists to shut up the compiler warnings virtual ~object_cmd_base() {} virtual void invoke(void *p, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[], policies const &pol) = 0;};// base class for all class handlers, still abstractclass class_handler_base : public object_cmd_base{public: typedef std::map<std::string, policies> policies_map_type; class_handler_base(); void register_method(std::string const &name, boost::shared_ptr<object_cmd_base> ocb, policies const &p); policies & get_policies(std::string const &name);protected: typedef std::map< std::string, boost::shared_ptr<object_cmd_base> > method_map_type; // a map of methods for the given class method_map_type methods_; policies_map_type policies_;};// class handler - responsible for executing class methodstemplate <class C>class class_handler : public class_handler_base{public: virtual void invoke(void *pv, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[], policies const &pol) { C * p = static_cast<C*>(pv); if (objc < 2) { throw tcl_error("Too few arguments."); } std::string methodName(Tcl_GetString(objv[1])); if (methodName == "-delete") { Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])); delete p; return; } // dispatch on the method name method_map_type::iterator it = methods_.find(methodName); if (it == methods_.end()) { throw tcl_error("Method " + methodName + " not found."); } it->second->invoke(pv, interp, objc, objv, pol); }};// factory functions for creating class objects#include "details/constructors.h"// actual callback envelopes#include "details/callbacks.h"// actual method envelopes#include "details/methods.h"// helper meta function for figuring appropriate constructor callback#include "details/metahelpers.h"// this class is used to provide the "def" interface for defining// class member functionstemplate <class C>class class_definer{public: class_definer(boost::shared_ptr<class_handler<C> > ch) : ch_(ch) {} template <typename R> class_definer & def(std::string const &name, R (C::*f)(), policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method0<C, R>(f)), p); return *this; } template <typename R> class_definer & def(std::string const &name, R (C::*f)() const, policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method0<C, R>(f)), p); return *this; } template <typename R, typename T1> class_definer & def(std::string const &name, R (C::*f)(T1), policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method1<C, R, T1>(f)), p); return *this; } template <typename R, typename T1> class_definer & def(std::string const &name, R (C::*f)(T1) const, policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method1<C, R, T1>(f)), p); return *this; } template <typename R, typename T1, typename T2> class_definer & def(std::string const &name, R (C::*f)(T1, T2), policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method2<C, R, T1, T2>(f)), p); return *this; } template <typename R, typename T1, typename T2> class_definer & def(std::string const &name, R (C::*f)(T1, T2) const, policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method2<C, R, T1, T2>(f)), p); return *this; } template <typename R, typename T1, typename T2, typename T3> class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3), policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method3<C, R, T1, T2, T3>(f)), p); return *this; } template <typename R, typename T1, typename T2, typename T3> class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3) const, policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method3<C, R, T1, T2, T3>(f)), p); return *this; } template <typename R, typename T1, typename T2, typename T3, typename T4> class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4), policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method4<C, R, T1, T2, T3, T4>(f)), p); return *this; } template <typename R, typename T1, typename T2, typename T3, typename T4> class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4) const, policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method4<C, R, T1, T2, T3, T4>(f)), p); return *this; } template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5> class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4, T5), policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method5<C, R, T1, T2, T3, T4, T5>(f)), p); return *this; } template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5> class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4, T5) const, policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method5<C, R, T1, T2, T3, T4, T5>(f)), p); return *this; } template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4, T5, T6), policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method6<C, R, T1, T2, T3, T4, T5, T6>(f)), p); return *this; } template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6> class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4, T5, T6) const, policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method6<C, R, T1, T2, T3, T4, T5, T6>(f)), p); return *this; } template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4, T5, T6, T7), policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method7<C, R, T1, T2, T3, T4, T5, T6, T7>(f)), p); return *this; } template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4, T5, T6, T7) const, policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method7<C, R, T1, T2, T3, T4, T5, T6, T7>(f)), p); return *this; } template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8), policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method8<C, R, T1, T2, T3, T4, T5, T6, T7, T8>(f)), p); return *this; } template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8> class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8) const, policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method8<C, R, T1, T2, T3, T4, T5, T6, T7, T8>(f)), p); return *this; } template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9), policies const &p = policies()) { ch_->register_method(name, boost::shared_ptr<details::object_cmd_base>( new details::method9<C, R, T1, T2, T3, T4, T5, T6, T7, T8, T9>(f)), p); return *this; } template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9> class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9) const, policies const &p = policies()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -