File:  [CENS] / python / pyGiNaC / wrappers4 / converters.cpp
Revision 1.9: download - view: text, annotated - select for diffs - revision graph
Mon Nov 26 22:37:44 2001 UTC (16 years ago) by pearu
Branches: MAIN
CVS tags: HEAD
See NEWS.txt (impl. matrix)

/*
  This file is part of the PyGiNaC package.
  http://cens.ioc.ee/projects/pyginac/

  $Revision: 1.9 $
  $Id: converters.cpp,v 1.9 2001-11-26 22:37:44 pearu Exp $
 
  Copyright 2001 Pearu Peterson all rights reserved,
  Pearu Peterson <pearu@cens.ioc.ee>
  Permission to use, modify, and distribute this software is given under the
  terms of the LGPL.  See http://www.fsf.org
 
  NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
*/

BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE

#ifndef PYGINAC_CONVERTERS_CPP
#define PYGINAC_CONVERTERS_CPP

#define ExInstance_Check(op) ((!((op)->ob_type == NULL)) && (\
      (op)->ob_type == (PyTypeObject*)ex_py_class))
#define PYOBJ_IS_EX(o) (ExInstance_Check(o) || (PyInstance_Check(o) && PyObject_HasAttrString(o,"ex")))

GiNaC::ex & pyobj_get_ex_nonconst(PyObject* o);
const GiNaC::ex & pyobj_get_ex(PyObject* o);
GiNaC::ex & ex_nonconst_from_py(PyObject*);
const GiNaC::exvector & from_python (PyObject*,
				     py::type<const GiNaC::exvector &>);
const GiNaC::exlist & from_python (PyObject*,
				   py::type<const GiNaC::exlist &>);
PyObject * exvector_to_tuple(const GiNaC::exvector &,
			     unsigned);
const GiNaC::paramset & from_python(PyObject* o,
				    py::type<const GiNaC::paramset &>);

#else

GiNaC::ex & pyobj_get_ex_nonconst(PyObject* o) {
  if (ExInstance_Check(o))
    return from_python(o, py::type<GiNaC::ex &>());
  if (PyInstance_Check(o) && PyObject_HasAttrString(o,"ex")) {
    PyObject *obj = PyObject_GetAttrString(o,"ex");
    if (ExInstance_Check(obj))
      return from_python(obj, py::type<GiNaC::ex &>());
  }
  PyErr_SetString(PyExc_TypeError,
		  (std::string("pyobj_get_ex_nonconst() expected _ginac.ex|ex but got ")+PyString_AsString(PyObject_Repr(PyObject_Type(o)))).c_str());
  throw py::error_already_set();
}

const GiNaC::ex & pyobj_get_ex(PyObject* o) {
  return pyobj_get_ex_nonconst(o);
}

GiNaC::ex & ex_nonconst_from_py(PyObject* o) {
  if (PYOBJ_IS_EX(o))
    return pyobj_get_ex_nonconst(o);
  if (PyInt_Check(o))
    return *(new GiNaC::ex(PyInt_AS_LONG(o)));
  if (PyFloat_Check(o))
    return *(new GiNaC::ex(PyFloat_AS_DOUBLE(o)));
  if (PyComplex_Check(o))
    return *(new GiNaC::ex(GiNaC::numeric(cln::complex(PyComplex_RealAsDouble(o),
						       PyComplex_ImagAsDouble(o)))));
  if (PySequence_Check(o))
    return *(new GiNaC::ex(from_python(o, py::type<GiNaC::lst &>())));
  PyErr_SetString(PyExc_TypeError,
		  (std::string("ex_nonconst_from_py() expected _ginac.ex|ex|int|float|complex but got ")+PyString_AsString(PyObject_Repr(PyObject_Type(o)))).c_str());
  throw py::error_already_set();
}

const GiNaC::exvector & from_python (PyObject* o,
				     py::type<const GiNaC::exvector &>) {
  GiNaC::exvector &v = *new GiNaC::exvector();
  if (PYOBJ_IS_EX(o))
    v.push_back(pyobj_get_ex_nonconst(o));
  //if (ExInstance_Check(o))
  //  v.push_back(from_python(o, py::type<GiNaC::ex &>()));
  else if (PySequence_Check(o)) {
    std::size_t l = PySequence_Length(o);
    for(std::size_t i = 0; i < l; ++i)
      v.push_back(ex_from_py(PySequence_GetItem(o,i)));
  } else
    v.push_back(ex_from_py(o));
  return v;
}

const GiNaC::exlist & from_python (PyObject* o,
				   py::type<const GiNaC::exlist &>) {
  GiNaC::exlist &v = *new GiNaC::exlist();
  if (PYOBJ_IS_EX(o))
    v.push_back(pyobj_get_ex_nonconst(o));
  else if (PySequence_Check(o)) {
    int l = PySequence_Length(o);
    if (l<0)
      throw py::error_already_set();
    for(int i = 0; i < l; ++i)
      v.push_back(ex_from_py(PySequence_GetItem(o,i)));
  }
  else
    v.push_back(ex_from_py(o));
  return v;
}

PyObject * exvector_to_tuple(const GiNaC::exvector & seq,
			     unsigned len) {
  unsigned size = seq.size();
  PyObject* v = PyTuple_New(len);
  if (v==NULL)
    throw py::error_already_set();
  for (unsigned i=0;i<size;++i)
    if (PyTuple_SetItem(v,i,BOOST_PYTHON_CONVERSION::to_python(seq[i])))
      throw py::error_already_set();
  return v;
}

const GiNaC::paramset & from_python(PyObject* o,
				    py::type<const GiNaC::paramset &>) {
  GiNaC::paramset & ps = *new GiNaC::paramset();
  if (PySequence_Check(o)) {
    int l = PySequence_Length(o);
    if (l<0)
      throw py::error_already_set();
    for(int i=0;i<l;++i) {
      PyObject * item = PySequence_GetItem(o,i);
      if (item==0)
	throw py::error_already_set();
      if (PyInt_Check(item)) {
	long j = PyInt_AsLong(item);
	if (j<0)
	  goto fail;
	ps.insert(j);
      }
      else
	goto fail;
    }
    return ps;
  }
  if (PyInt_Check(o)) {
    long j = PyInt_AsLong(o);
    if (j<0)
      goto fail;
    ps.insert(j);
    return ps;
  }
 fail:
  PyErr_SetString(PyExc_TypeError,
		  "from_python(paramset) expected pos-int-sequence|pos-int.");
  throw py::error_already_set();  
}

#endif

BOOST_PYTHON_END_CONVERSION_NAMESPACE

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>