3
0
mirror of https://github.com/triqs/dft_tools synced 2024-12-25 13:53:40 +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 # Init arithmetic
# expect a tuple : "algebra", "scalar1", "scalar2", etc... # expect a tuple : "algebra", "scalar1", "scalar2", etc...
self.number_protocol = {} self.number_protocol = {}
if not isinstance(arithmetic, tuple) : arithmetic = (arithmetic,)
if arithmetic : if arithmetic :
if not isinstance(arithmetic, tuple) : arithmetic = (arithmetic,) if not isinstance(arithmetic, tuple) : arithmetic = (arithmetic,)
add = arithmetic[0] in ("algebra", "abelian_group", "vector_space", "only_add") add = arithmetic[0] in ("algebra", "abelian_group", "vector_space", "only_add")
@ -361,13 +360,23 @@ class class_ :
#assert 'calling_pattern' not in kw, "No calling_pattern here" #assert 'calling_pattern' not in kw, "No calling_pattern here"
if 'calling_pattern' not in kw : kw['c_name'] = "__init__" if 'calling_pattern' not in kw : kw['c_name'] = "__init__"
f = cfunction(is_constructor = True, **kw) 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 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]) ##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 : # First version, where _new method use the default constructor
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) #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 : 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));" 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 = pyfunction(py_name = "__init__", **kw)

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); self = (${c.py_type} *)type->tp_alloc(type, 0);
if (self != NULL) { if (self != NULL) {
try { try {
%if not c.c_type_is_view : self->_c = NULL;
self->_c = new ${c.c_type}{}; ##//%if not c.c_type_is_view :
%else : ##// self->_c = new ${c.c_type}{};
self->_c = new ${c.c_type}{typename ${c.c_type}::regular_type{}}; // no default constructor for views ##//%else :
%endif ##// self->_c = new ${c.c_type}{typename ${c.c_type}::regular_type{}}; // no default constructor for views
##//%endif
} }
catch (std::exception const & e) { catch (std::exception const & e) {
std::cout << e.what()<<std::endl; std::cout << e.what()<<std::endl;
@ -168,7 +169,7 @@ static PyObject* ${c.py_type}_new(PyTypeObject *type, PyObject *args, PyObject *
// dealloc // dealloc
static void ${c.py_type}_dealloc(${c.py_type}* self) { 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); self->ob_type->tp_free((PyObject*)self);
} }
@ -365,7 +366,6 @@ static PyTypeObject ${c.py_type}Type = {
${c.py_type}_new, /* tp_new */ ${c.py_type}_new, /* tp_new */
}; };
//--------------------- converters for the class c ----------------------------- //--------------------- converters for the class c -----------------------------
namespace triqs { namespace py_tools { namespace triqs { namespace py_tools {
@ -381,10 +381,18 @@ template <> struct py_converter<${c.c_type}> {
return (PyObject *)self; 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){ 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}"); if (raise_exception) PyErr_SetString(PyExc_TypeError, "Python object is not a ${c.py_type}");
return false; 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(bravais_lattice const& bl, std::vector<std::vector<long>> all_disp, std::vector<matrix<dcomplex>> all_matrices);
tight_binding() = default;
/// Underlying lattice /// Underlying lattice
bravais_lattice const& lattice() const { return bl_; } bravais_lattice const& lattice() const { return bl_; }