Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members

vmethod.h

00001 // Copyright (C) 2001 Jean-Marc Valin
00002 #ifndef _VMETHOD_H_
00003 #define _VMETHOD_H_
00004 
00005 #include <string>
00006 #include <map>
00007 #include "Object.h"
00008 
00009 namespace FD {
00010 
00011 class SymbolSet {
00012   protected:
00013    int currentID;
00014    std::map<std::string,int> translationMap;
00015   public:
00016    SymbolSet()
00017       : currentID(0)
00018    {}
00019    int get(const std::string &str)
00020    {
00021       std::map<std::string,int>::iterator sym = translationMap.find(str);
00022       if (sym == translationMap.end())
00023       {
00024          translationMap.insert(make_pair(str, currentID++));
00025          return currentID-1;
00026       } else {
00027          return sym->second;
00028       }
00029    }
00030 
00031    int get (char *str)
00032    {
00033       return get(std::string(str));
00034    }
00035 
00036    std::string reverseLookup (int ID)
00037    {
00038       std::map<std::string,int>::iterator it = translationMap.begin();
00039       while (it!=translationMap.end())
00040       {
00041          if (it->second == ID)
00042             return it->first;
00043          ++it;
00044       }
00045       return std::string("");
00046    }
00047 };
00048 
00049 
00050 
00051 class VirtualMethods {
00052   protected:
00053    SymbolSet* symbols;
00054 
00055    typedef ObjectRef (*funct_ptr0) (ObjectRef x);
00056    typedef ObjectRef (*funct_ptr1) (ObjectRef x, ObjectRef a);
00057    typedef ObjectRef (*funct_ptr2) (ObjectRef x, ObjectRef a, ObjectRef b);
00058    typedef ObjectRef (*funct_ptr3) (ObjectRef x, ObjectRef a, ObjectRef b, ObjectRef c);
00059 
00060    typedef std::map<const std::type_info *, funct_ptr0> vtableType0;
00061    typedef std::map<const std::type_info *, funct_ptr1> vtableType1;
00062    typedef std::map<const std::type_info *, funct_ptr2> vtableType2;
00063    typedef std::map<const std::type_info *, funct_ptr3> vtableType3;
00064 
00065    std::vector<vtableType0> tables0;
00066    std::vector<vtableType1> tables1;
00067    std::vector<vtableType2> tables2;
00068    std::vector<vtableType3> tables3;
00069   public:
00070    VirtualMethods() 
00071    {
00072       symbols=new SymbolSet;
00073    }
00074 
00075    int lookup(const std::string &str)
00076    {
00077       return symbols->get(str);
00078    }
00079 
00080    int lookup (char *str)
00081    {
00082       return symbols->get(str);
00083    }
00084 
00085    int registerFunct0(funct_ptr0 ptr, const std::type_info *x, std::string name)
00086    {
00087       unsigned int id = symbols->get(name);
00088       if (id >= tables0.size())
00089          tables0.resize(id+1);
00090       tables0[id][x] = ptr;
00091    }
00092 
00093    int registerFunct1(funct_ptr1 ptr, const std::type_info *x, std::string name)
00094    {
00095       unsigned int id = symbols->get(name);
00096       if (id >= tables1.size())
00097          tables1.resize(id+1);
00098       tables1[id][x] = ptr;
00099    }
00100 
00101    int registerFunct2(funct_ptr2 ptr, const std::type_info *x, std::string name)
00102    {
00103       unsigned int id = symbols->get(name);
00104       if (id >= tables2.size())
00105          tables2.resize(id+1);
00106       tables2[id][x] = ptr;
00107    }
00108 
00109    int registerFunct3(funct_ptr3 ptr, const std::type_info *x, std::string name)
00110    {
00111       unsigned int id = symbols->get(name);
00112       if (id >= tables3.size())
00113          tables3.resize(id+1);
00114       tables3[id][x] = ptr;
00115    }
00116 
00117    ObjectRef call(int id, ObjectRef x)
00118    {
00119       const std::type_info *t1 = &typeid(*x);
00120       vtableType0 &vtable=tables0[id];
00121       vtableType0::iterator v1 = vtable.find(t1);
00122       if (v1!=vtable.end())
00123       {
00124          return v1->second(x);
00125       } else {
00126          x->doesNotUnderstand(symbols->reverseLookup(id));
00127          //throw new GeneralException("Virtual function error", __FILE__, __LINE__);
00128       }
00129    }
00130 
00131    ObjectRef call(int id, ObjectRef x, ObjectRef y)
00132    {
00133       const std::type_info *t1 = &typeid(*x);
00134       vtableType1::iterator v1 = tables1[id].find(t1);
00135       if (v1!=tables1[id].end())
00136       {
00137          return v1->second(x,y);
00138       } else {
00139          x->doesNotUnderstand(symbols->reverseLookup(id));
00140          //throw new GeneralException("Virtual function error", __FILE__, __LINE__);
00141       }
00142    }
00143    
00144 };
00145 
00146 
00147 //extern VirtualMethods* vmethod;
00148 VirtualMethods* vmethod();
00149 
00150 #define REGISTER_VTABLE0(name, type, func, id) \
00151         static int dummy_vtable_init_for ## _ ## name ## id =\
00152         vmethod()->registerFunct0(func, &typeid(type), # name);
00153 
00154 }//namespace FD
00155 
00156 #endif

Generated on Wed Oct 5 14:28:56 2005 for FlowDesigner by  doxygen 1.4.4