⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vectortemplates.hpp

📁 orange源码 数据挖掘技术
💻 HPP
📖 第 1 页 / 共 3 页
字号:
/*
    This file is part of Orange.

    Orange is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    Orange is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Orange; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Authors: Janez Demsar, Blaz Zupan, 1996--2002
    Contact: janez.demsar@fri.uni-lj.si
*/


/* 

How to export a vector to Python?

a) If vector is a property of some object (probably inherited from TOrangeVector
or _TOrangeVector), you only need to define it as properties.
For instance, 'Domain' returns 'attributes' as 'VarList' only by defining it
as property_wr.

b) If the class behaves vector-like by using VECTOR_INTERFACE itself, you don't
need to do this. (But you should not forget to write traverse and dropReferences
if the vector contains wrapped oranges!)


This header is needed to define methods of the exported vectors.
Each vector type is exported as a separate type in Python, and they are in no
hereditary relation.

You should open defvectors.py and add the vector to one of its lists, either
one for vectors of wrapped or of unwrapped elements. The difference between
a) and b) is only in list names (the first uses generic names like VarList or
ClassifierList, the other can have names like Preprocess or Filter_sameValue,
although they vector_interface vectors of Preprocessors or ValueRanges).

Run the script.

If the vector contains wrapped elements, find the defined methods in
lib_vectors_auto.txt and copy&paste the methods to a corresponding lib_*.cpp.
You can remove are manually redefine some of them if you need. (But keep notes
of this!).

If the vector contains unwrapped elements, the corresponding methods will be added
to lib_vectors.cpp (this file is generated entirely by defvector.py and you should
not change it). You only need to make sure there are corresponding
convert[(To)|(From)]Python methods defined somewhere (preferably in c2py.hpp).

In any case, run pyxtract.py to include the vector types in corresponding .px files.
*/

#ifndef __VECTORTEMPLATES_HPP
#define __VECTORTEMPLATES_HPP

/********************************

This file includes constructors and specialized methods for Orange vectors

*********************************/

#ifdef _MSC_VER
  #pragma warning (disable : 4786 4114 4018 4267 4244)
#endif

#include "orvector.hpp"
#include "c2py.hpp"


inline bool checkIndex(int &index, int max)
{ if (index<0)
    index += max;
  if ((index<0) || (index>=max)) {
    PyErr_Format(PyExc_IndexError, "index %i out of range 0-%i", index, max-1);
    return false;
  }
  return true;
}


inline bool checkIndices(int &start, int &stop, int max)
{ if (stop>max)
    stop=max;

  if (start>stop) {
    PyErr_Format(PyExc_IndexError, "invalid indices for slice");
    return false;
  }
  return true;
}


/* This contains methods that are same for lists of wrapped and of unwrapped items */
template<class _WrappedListType, class _ListType>
class CommonListMethods {
public:
  typedef typename _ListType::iterator iterator;
  typedef typename _ListType::const_iterator const_iterator;

  static PyObject *_CreateEmptyList(PyTypeObject *type)
  { return WrapNewOrange(mlnew _ListType(), type);
  }

  static int _len(TPyOrange *self)
  { PyTRY
      CAST_TO_err(_ListType, aList, -1);
      return aList->size();
    PyCATCH_1
  }  

  static PyObject *_repeat(TPyOrange *self, int times)
  { PyObject *emtuple = NULL, *emdict = NULL, *newList = NULL;
    try {
      emtuple = PyTuple_New(0);
      emdict = PyDict_New();
      newList = self->ob_type->tp_new(self->ob_type, emtuple, emdict);
      Py_DECREF(emtuple); 
      emtuple = NULL;
      Py_DECREF(emdict);
      emdict = NULL;
      if (!newList)
        return NULL;

      CAST_TO(_ListType, aList)
      NAME_CAST_TO(_ListType, newList, cList)
      while(times-- >0)
        for (const_iterator li = aList->begin(), le = aList->end(); li!=le; li++)
          cList->push_back(*li);

      return newList;
    }
      
    catch (exception err)
      { Py_XDECREF(emtuple);
        Py_XDECREF(emdict);
        Py_XDECREF(newList);
        PYERROR(PyExc_Exception, err.what(), PYNULL);
      }
  }

  static PyObject *_getslice(TPyOrange *self, int start, int stop)
  { PyObject *emtuple = NULL, *emdict = NULL, *newList = NULL;
    try {
      CAST_TO(_ListType, aList)
      if (!checkIndices(start, stop, aList->size()))
        return NULL;

      emtuple = PyTuple_New(0);
      emdict = PyDict_New();
      newList = self->ob_type->tp_new(self->ob_type, emtuple, emdict);
      Py_DECREF(emtuple); 
      emtuple = NULL;
      Py_DECREF(emdict);
      emdict = NULL;
      if (!newList)
        return NULL;

      NAME_CAST_TO(_ListType, newList, cList)
      for(iterator si=aList->begin()+start, sei=aList->begin()+stop; si!=sei; si++)
        cList->push_back(*si);

      return newList;
    }
      
    catch (exception err)
      { Py_XDECREF(emtuple);
        Py_XDECREF(emdict);
        Py_XDECREF(newList);
        PYERROR(PyExc_Exception, err.what(), PYNULL);
      }
  }


/* -------------------------------------------------------------------------------------------------- */

  static PyObject *_reverse(TPyOrange *self)
  { PyTRY
      CAST_TO(_ListType, aList);
      std::reverse(aList->begin(), aList->end());
      RETURN_NONE;
    PyCATCH
  }


  static PyObject *_reduce(TPyOrange *self)
  { 
    PyTRY

      PyObject *res = Orange__reduce__((PyObject *)self, NULL, NULL);
      if (!res)
        return NULL;

      CAST_TO(_ListType, aList)
      if (aList->size()) {
        _PyTuple_Resize(&res, 4);
        PyTuple_SET_ITEM(res, 3, PySeqIter_New((PyObject *)self));
      }

      return res;
    PyCATCH
  }
};



template<class _WrappedListType, class _ListType, class _WrappedElement, TOrangeType *_PyElementType>
class ListOfWrappedMethods : public CommonListMethods<_WrappedListType, _ListType> {
public:
  typedef typename _ListType::iterator iterator;
  typedef typename _ListType::const_iterator const_iterator;

  static bool _fromPython(PyObject *obj, _WrappedElement &res)
  { if (obj == Py_None) {
      res = _WrappedElement();
      return true;
    }
  
    if (!obj || !PyObject_TypeCheck(obj, (PyTypeObject *)_PyElementType)) {
      if (_PyElementType->ot_inherited.tp_new) {
        PyObject *pyel = objectOnTheFly(obj, (PyTypeObject *)_PyElementType);
        if (pyel) {
          res = PyOrange_AS_Orange(pyel);
          return true;
        }
      }
        
      PyErr_Format(PyExc_TypeError, "expected '%s', got '%s'", _PyElementType->ot_inherited.tp_name, obj ? obj->ob_type->tp_name : "NULL");
      res = _WrappedElement();
      return false;
    }
  
    res = _WrappedElement(PyOrange_AS_Orange(obj));
    return true;
  }

  static _WrappedListType P_FromArguments(PyObject *arg, PyTypeObject *type = (PyTypeObject *)&PyOrOrange_Type)
  { PyObject *iterator = PyObject_GetIter(arg);
    if (!iterator) {
      PyErr_Format(PyExc_TypeError, "invalid arguments for '%s' constructor (sequence expected)", TYPENAME(typeid(_ListType)));
      return _WrappedListType();
    }

    _WrappedListType aList = _WrappedListType(mlnew _ListType(), type);

    int i = 0;
    for(PyObject *item = PyIter_Next(iterator); item; item = PyIter_Next(iterator), i++) {
      _WrappedElement obj;
      if (!_fromPython(item, obj)) {
        PyErr_Format(PyExc_TypeError, "element at index %i is of wrong type ('%s')", i, item->ob_type->tp_name);
        Py_DECREF(item);
        Py_DECREF(iterator);
        return _WrappedListType();
      }
      Py_DECREF(item);
      aList->push_back(obj);
    }

    return aList;
  }

  
  static PyObject *_FromArguments(PyTypeObject *type, PyObject *arg)
  { _WrappedListType obj = P_FromArguments(arg, type);
    if (!obj)
      return NULL;
    else
      return WrapOrange(obj);
  }


  static PyObject *_new(PyTypeObject *type, PyObject *args, PyObject *)
  { if (!args || (PySequence_Check(args) && !PySequence_Size(args)))
      return _CreateEmptyList(type);

    if (PyTuple_Check(args) && PyTuple_Size(args)==1) {
      PyObject *arg=PyTuple_GetItem(args, 0);
      if (PySequence_Check(arg))
        return _FromArguments(type, arg);
    }

    return _FromArguments(type, args);
  }

  static PyObject *_getitem(TPyOrange *self, int index)
  { PyTRY
      CAST_TO(_ListType, aList)
      return checkIndex(index, aList->size()) ? WrapOrange(aList->operator[](index)) : PYNULL;
    PyCATCH
  }

  static int _setitem(TPyOrange *self, int index, PyObject *item)
  { PyTRY
      CAST_TO_err(_ListType, aList, -1)
      if (!checkIndex(index, aList->size()))
        return -1;
      if (item==NULL) {
        aList->erase(aList->begin()+index);
      }
      else {
        _WrappedElement citem;
        if (!_fromPython(item, citem))
          return -1;
        aList->operator[](index)=citem;
      }

      return 0;
    PyCATCH_1
  }

  static int _setslice(TPyOrange *self, int start, int stop, PyObject *args)
  { PyTRY
      CAST_TO_err(_ListType, aList, -1)
      if (!checkIndices(start, stop, aList->size()))
        return -1;

      if (args==NULL) {
        aList->erase(aList->begin()+start, aList->begin()+stop);
        return 0;
       }

      PyObject *emdict = NULL, *newList = NULL;
      try {
        PyObject *emdict = PyDict_New();
        PyObject *newList = _new(self->ob_type, args, emdict);
        Py_DECREF(emdict); emdict=NULL;
        if (!newList)
          return -1;

        NAME_CAST_TO_err(_ListType, newList, nList, -1)
        aList->erase(aList->begin()+start, aList->begin()+stop);
        aList->insert(aList->begin()+start, nList->begin(), nList->end());

        Py_DECREF(newList);
        newList = NULL;
        return 0;
      }

      catch (exception err)
        { Py_XDECREF(emdict);
          Py_XDECREF(newList);
          throw;
        }
    PyCATCH_1
  }

  static PyObject *_richcmp(TPyOrange *self, PyObject *other, int op)
  { PyTRY
      PyObject *myItem = NULL, *hisItem = NULL;
      try {
        if (!PySequence_Check(other)) {
          Py_INCREF(Py_NotImplemented);
          return Py_NotImplemented;
	      }

        CAST_TO(_ListType, aList)
        int myLen = aList->size();
        int hisLen = PySequence_Size(other);

        if (myLen != hisLen) {
          if (op == Py_EQ) {
            Py_INCREF(Py_False);
            return Py_False;
          }
          if (op == Py_NE) {
            Py_INCREF(Py_True);
            return Py_True;
          }
        }

        int len = myLen < hisLen ? myLen : hisLen;
        int k = 0;
        iterator ii(aList->begin());
        for (int pos=0; !k && (pos<len); pos++) {
          myItem = WrapOrange(*(ii++));
          hisItem = PySequence_GetItem(other, pos);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -