I try to integrate cgal library to my python program. I made some test by following diverse tutorial. And I try to do a template but I have an error when I compile and I don't know how to fixe it. I use pybind11 to integrate cgal.
Part of my mesher.cpp code :
template <typename T>
class TypedInputIterator
{
public:
typedef T value_type;
typedef T& reference;
typedef T* pointer;
explicit TypedInputIterator(py::iterator& py_iter):
py_iter_(py_iter){}
explicit TypedInputIterator(py::iterator&& py_iter):
py_iter_(py_iter){}
value_type operator*(){
return (*py_iter_).template cast<value_type>();
}
TypedInputIterator operator++(int){
auto copy = *this;
++py_iter_;
return copy;
}
TypedInputIterator& operator++(){
++py_iter_;
return *this;
}
bool operator != (TypedInputIterator &rhs) {
return py_iter_ != rhs.py_iter_;
}
bool operator == (TypedInputIterator &rhs) {
return py_iter_ == rhs.py_iter_;
}
private:
py::iterator py_iter_;
};
PYBIND11_MODULE(cgal_mesher, m)
{
py::class_<Point>(m, "Point")
.def(py::init<int,int>(), py::arg("x"), py::arg("y"))
.def(py::init<double,double>(), py::arg("x"), py::arg("y"))
.def_property_readonly("x", &Point::x)
.def_property_readonly("y", &Point::y)
.def("__repr__",
[](const Point &p){
std::string r("Point(");
r += boost::lexical_cast<std::string>(p.x());
r += ", ";
r += boost::lexical_cast<std::string>(p.y());
r +=")";
return r;
})
.def("__hash__",
[](const Point &p){
std::hash<double> double_hash;
auto x_hash = double_hash(p.x());
auto y_hash = double_hash(p.y());
return y_hash ^ x_hash + 0x9e1779b9 + (y_hash << 6) + (y_hash >> 2);
})
.def("__eq__",
[](const Point &p, const Point & q) {
return p == q;
})
;
py::class_<Mesher>(m, "Mesher")
.def(py::init<CDT&>())
.def("seeds_from", [](Mesher & mesher, py::iterable iterable)
{
py::iterator iterator = py::iter(iterable);
TypedInputIterator<Point> points_begin(iterator);
TypedInputIterator<Point> points_end(py::iterator::sentinel());
mesher.set_seeds(points_begin, points_end);
})
;
}
I know that the error append to this line :
mesher.set_seeds(points_begin, points_end);
because when I comment it, there is no error message anymore.
The error message :
[ 50%] Building CXX object CMakeFiles/cgal_mesher.dir/src/mesher/cgal_mesher.cpp.o /usr/bin/c++
-DCGAL_USE_CORE=1 -DCGAL_USE_GMP -DCGAL_USE_MPFR -Dcgal_mesher_EXPORTS -isystem /home/admin-suz/anaconda3/include -I/home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/build/temp.linux-x86_64-3.6
-isystem /usr/local/include -I/home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/src/mesher
-I/home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/lib/pybind11/include
-I/home/admin-suz/anaconda3/include/python3.6m -DVERSION_INFO=\"0.1\" -O3 -DNDEBUG -fPIC -fvisibility=hidden -std=c++14 -flto -fno-fat-lto-objects -frounding-math -o CMakeFiles/cgal_mesher.dir/src/mesher/cgal_mesher.cpp.o -c /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/src/mesher/cgal_mesher.cpp In file included from /usr/include/c++/5/bits/forward_list.h:38:0,
from /usr/include/c++/5/forward_list:38,
from /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/lib/pybind11/include/pybind11/detail/common.h:140,
from /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/lib/pybind11/include/pybind11/pytypes.h:12,
from /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/lib/pybind11/include/pybind11/cast.h:13,
from /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/lib/pybind11/include/pybind11/attr.h:13,
from /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/lib/pybind11/include/pybind11/pybind11.h:43,
from /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/src/mesher/cgal_mesher.cpp:1: /usr/include/c++/5/bits/stl_algobase.h: In instantiation of ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = TypedInputIterator<CGAL::Point_2<CGAL::Epick> >; _OI = std::back_insert_iterator<std::__cxx11::list<CGAL::Point_2<CGAL::Epick>, std::allocator<CGAL::Point_2<CGAL::Epick> > > >]’: /usr/include/c++/5/bits/stl_algobase.h:438:45: required from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = TypedInputIterator<CGAL::Point_2<CGAL::Epick> >; _OI = std::back_insert_iterator<std::__cxx11::list<CGAL::Point_2<CGAL::Epick>, std::allocator<CGAL::Point_2<CGAL::Epick> > > >]’ /usr/include/c++/5/bits/stl_algobase.h:471:8: required from ‘_OI std::copy(_II, _II, _OI) [with _II = TypedInputIterator<CGAL::Point_2<CGAL::Epick> >; _OI = std::back_insert_iterator<std::__cxx11::list<CGAL::Point_2<CGAL::Epick>, std::allocator<CGAL::Point_2<CGAL::Epick> > > >]’ /usr/local/include/CGAL/Delaunay_mesher_2.h:137:14: required from ‘void CGAL::Delaunay_mesher_2<Tr, Crit>::set_seeds(InputIterator, InputIterator, bool, bool) [with InputIterator = TypedInputIterator<CGAL::Point_2<CGAL::Epick> >; Tr = CGAL::Constrained_Delaunay_triangulation_2<CGAL::Epick, CGAL::Triangulation_data_structure_2<CGAL::Delaunay_mesh_vertex_base_2<CGAL::Epick>, CGAL::Delaunay_mesh_face_base_2<CGAL::Epick> > >; Crit = CGAL::Delaunay_mesh_size_criteria_2<CGAL::Constrained_Delaunay_triangulation_2<CGAL::Epick, CGAL::Triangulation_data_structure_2<CGAL::Delaunay_mesh_vertex_base_2<CGAL::Epick>, CGAL::Delaunay_mesh_face_base_2<CGAL::Epick> > > >]’ /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/src/mesher/cgal_mesher.cpp:169:66: required from here /usr/include/c++/5/bits/stl_algobase.h:393:57: error: no type named ‘value_type’ in ‘struct std::iterator_traits<TypedInputIterator<CGAL::Point_2<CGAL::Epick> >
>’
typedef typename iterator_traits<_II>::value_type _ValueTypeI;
^ /usr/include/c++/5/bits/stl_algobase.h:395:64: error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<TypedInputIterator<CGAL::Point_2<CGAL::Epick> >
>’
typedef typename iterator_traits<_II>::iterator_category _Category;
^ /usr/include/c++/5/bits/stl_algobase.h:399:9: error: no type named ‘value_type’ in ‘struct std::iterator_traits<TypedInputIterator<CGAL::Point_2<CGAL::Epick> >
>’
&& __are_same<_ValueTypeI, _ValueTypeO>::__value);
^ /usr/include/c++/5/bits/stl_algobase.h:402:44: error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<TypedInputIterator<CGAL::Point_2<CGAL::Epick> >
>’
_Category>::__copy_m(__first, __last, __result);
^ CMakeFiles/cgal_mesher.dir/build.make:65 : la recette pour la cible « CMakeFiles/cgal_mesher.dir/src/mesher/cgal_mesher.cpp.o » a échouée make[2]: *** [CMakeFiles/cgal_mesher.dir/src/mesher/cgal_mesher.cpp.o] Erreur 1 make[2] : on quitte le répertoire « /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/build/temp.linux-x86_64-3.6 » CMakeFiles/Makefile2:70 : la recette pour la cible « CMakeFiles/cgal_mesher.dir/all » a échouée make[1]: *** [CMakeFiles/cgal_mesher.dir/all] Erreur 2 make[1] : on quitte le répertoire « /home/admin-suz/Documents/Code/Interface_CGAL_python/mesher/build/temp.linux-x86_64-3.6 » Makefile:97 : la recette pour la cible « all » a échouée
Thank you for your help.
I'm using ubuntu 16.4 and python 3.6.
My original code which you've used, above, was compiled with Clang rather than gcc. If you read this article https://www.fluentcpp.com/2018/05/08/std-iterator-deprecated/ you will see that there are differences in how std::iterator_traits
is implemented for Clang. It seems my code provides sufficient type information for the Clang implementation of iterator_traits
to work, but not enough for the gcc implementation.
In particular, the code for TypedInputIterator
defines value_type
, reference
and pointer
, but neither iterator_category
nor difference_type
. Therefore, two two missing typedefs need to be added with the other typedefs near the top of the iterator class:
typedef std::input_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
This gives the full set of five. You'll should also include two headers to make these types available:
#include <iterator>
#include <cstddef>