3
0
mirror of https://github.com/triqs/dft_tools synced 2024-12-24 13:23:37 +01:00

wrapper : remove the need of default constructor

- change the constructor wrapper.
- in the new method, leave the pointer _c to NULL.
- in the init, allocate it.
- It seems ok to leave the object in this non initialized state,
  but that is not so clear from the doc.
  Added check for this pointer == NULL in converters.
This commit is contained in:
Olivier Parcollet 2014-05-30 15:30:27 +02:00
parent 2d071bb74b
commit 31927c9132
3 changed files with 34 additions and 19 deletions

View File

@ -276,7 +276,6 @@ class class_ :
# Init arithmetic
# expect a tuple : "algebra", "scalar1", "scalar2", etc...
self.number_protocol = {}
if not isinstance(arithmetic, tuple) : arithmetic = (arithmetic,)
if arithmetic :
if not isinstance(arithmetic, tuple) : arithmetic = (arithmetic,)
add = arithmetic[0] in ("algebra", "abelian_group", "vector_space", "only_add")
@ -361,15 +360,25 @@ class class_ :
#assert 'calling_pattern' not in kw, "No calling_pattern here"
if 'calling_pattern' not in kw : kw['c_name'] = "__init__"
f = cfunction(is_constructor = True, **kw)
build_type = regular_type_if_view_else_type(self.c_type) if self.c_type_is_view and build_from_regular_type else self.c_type
all_args = ",".join([ ('*' if t in module_.wrapped_types else '') + n for t,n,d in f.args])
#all_args = ",".join([ ('*' if t in module_.wrapped_types else '') + n + (' = ' + d if d else '') for t,n,d in f.args])
if 'calling_pattern' not in kw :
f._calling_pattern = "((%s *)self)->_c ->"%self.py_type + ('operator =' if not self.c_type_is_view else 'rebind') + " (%s (%s));"%(build_type,all_args)
else :
f._calling_pattern = kw['calling_pattern'] + "\n ((%s *)self)->_c ->"%self.py_type + ('operator =' if not self.c_type_is_view else 'rebind') + " (std::move(result));"
##all_args = ",".join([ ('*' if t in module_.wrapped_types else '') + n + (' = ' + d if d else '') for t,n,d in f.args])
# First version, where _new method use the default constructor
#build_type = regular_type_if_view_else_type(self.c_type) if self.c_type_is_view and build_from_regular_type else self.c_type
#if 'calling_pattern' not in kw :
# f._calling_pattern = "((%s *)self)->_c ->"%self.py_type + ('operator =' if not self.c_type_is_view else 'rebind') + " (%s (%s));"%(build_type,all_args)
#else :
# f._calling_pattern = kw['calling_pattern'] + "\n ((%s *)self)->_c ->"%self.py_type + ('operator =' if not self.c_type_is_view else 'rebind') + " (std::move(result));"
# Second version : using no default construction, but leaving the
# pointer null after _new
f._calling_pattern = ''
if 'calling_pattern' in kw :
f._calling_pattern, all_args = kw['calling_pattern'] + '\n', "std::move(result)"
if self.c_type_is_view and build_from_regular_type :
f._calling_pattern += "((%s *)self)->_c = new %s(%s (%s));"%(self.py_type, self.c_type,regular_type_if_view_else_type(self.c_type),all_args)
else :
f._calling_pattern += "((%s *)self)->_c = new %s (%s);"%(self.py_type, self.c_type,all_args)
if not self.constructor :
if not self.constructor :
self.constructor = pyfunction(py_name = "__init__", **kw)
self.constructor.is_constructor = True
self.constructor.overloads.append(f)

View File

@ -151,11 +151,12 @@ static PyObject* ${c.py_type}_new(PyTypeObject *type, PyObject *args, PyObject *
self = (${c.py_type} *)type->tp_alloc(type, 0);
if (self != NULL) {
try {
%if not c.c_type_is_view :
self->_c = new ${c.c_type}{};
%else :
self->_c = new ${c.c_type}{typename ${c.c_type}::regular_type{}}; // no default constructor for views
%endif
self->_c = NULL;
##//%if not c.c_type_is_view :
##// self->_c = new ${c.c_type}{};
##//%else :
##// self->_c = new ${c.c_type}{typename ${c.c_type}::regular_type{}}; // no default constructor for views
##//%endif
}
catch (std::exception const & e) {
std::cout << e.what()<<std::endl;
@ -168,7 +169,7 @@ static PyObject* ${c.py_type}_new(PyTypeObject *type, PyObject *args, PyObject *
// dealloc
static void ${c.py_type}_dealloc(${c.py_type}* self) {
delete self->_c;
if (self->_c != NULL) delete self->_c; // should never be null, but I protect it anyway
self->ob_type->tp_free((PyObject*)self);
}
@ -365,7 +366,6 @@ static PyTypeObject ${c.py_type}Type = {
${c.py_type}_new, /* tp_new */
};
//--------------------- converters for the class c -----------------------------
namespace triqs { namespace py_tools {
@ -381,10 +381,18 @@ template <> struct py_converter<${c.c_type}> {
return (PyObject *)self;
}
static ${c.c_type} & py2c(PyObject * ob){ return *(((${c.py_type}*)ob)->_c);}
static ${c.c_type} & py2c(PyObject * ob){
auto *_c = ((${c.py_type} *)ob)->_c;
if (_c == NULL) TRIQS_RUNTIME_ERROR << "Severe internal error : _c is null in py2c for type ${c.c_type} !";
return *_c;
}
static bool is_convertible(PyObject *ob, bool raise_exception){
if (PyObject_TypeCheck(ob, & ${c.py_type}Type)) return true;
if (PyObject_TypeCheck(ob, & ${c.py_type}Type)) {
if (((${c.py_type} *)ob)->_c != NULL) return true;
if (raise_exception) PyErr_SetString(PyExc_TypeError, "Severe internal error : Python object of ${c.py_type} has a _c NULL pointer !!");
return false;
}
if (raise_exception) PyErr_SetString(PyExc_TypeError, "Python object is not a ${c.py_type}");
return false;
}

View File

@ -39,8 +39,6 @@ namespace lattice {
///
tight_binding(bravais_lattice const& bl, std::vector<std::vector<long>> all_disp, std::vector<matrix<dcomplex>> all_matrices);
tight_binding() = default;
/// Underlying lattice
bravais_lattice const& lattice() const { return bl_; }