Merge remote-tracking branch 'origin/BGL-use_iterator_adaptor-GF'

Bug-fix branch for the BGL API.

Approved by the Release Manager.
Tested in CGAL-4.6-Ic-132.
This commit is contained in:
Laurent Rineau 2015-02-19 17:40:32 +01:00
commit 518368e470
4 changed files with 241 additions and 82 deletions

View File

@ -0,0 +1,31 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <iostream>
#include <fstream>
#include <boost/graph/connected_components.hpp>
#include <boost/foreach.hpp>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef CGAL::Surface_mesh<Point> Mesh;
typedef boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
int main(int argc, char* argv[])
{
Mesh sm;
std::ifstream in((argc>1)?argv[1]:"data/prim.off");
in >> sm;
Mesh::Property_map<vertex_descriptor,int> ccmap;
ccmap = sm.add_property_map<vertex_descriptor,int>("v:CC").first;
int num = connected_components(sm, ccmap);
std::cout << num << " connected components" << std::endl;
BOOST_FOREACH(vertex_descriptor v, vertices(sm)){
std::cout << v << " is in component " << ccmap[v] << std::endl;
}
return 0;
}

View File

@ -1,5 +1,5 @@
OFF OFF
8 7 0 11 7 0
# vertices # vertices
-1 -1 1 -1 -1 1
-1 1 1 -1 1 1
@ -9,6 +9,10 @@ OFF
-1 1 -1 -1 1 -1
1 1 -1 1 1 -1
1 -1 -1 1 -1 -1
2 2 2
3 2 2
3 3 3
# facets # facets
3 3 2 1 3 3 2 1
3 3 1 0 3 3 1 0
@ -17,3 +21,4 @@ OFF
4 3 7 6 2 4 3 7 6 2
4 4 7 3 0 4 4 7 3 0
4 4 5 6 7 4 4 5 6 7
3 8 9 10

View File

@ -23,7 +23,7 @@
#include <stdexcept> #include <stdexcept>
#include <boost/graph/graph_traits.hpp> #include <boost/graph/graph_traits.hpp>
#include <boost/iterator/transform_iterator.hpp> #include <boost/iterator/iterator_adaptor.hpp>
#include <CGAL/Iterator_range.h> #include <CGAL/Iterator_range.h>
#include <CGAL/assertions.h> #include <CGAL/assertions.h>
@ -478,11 +478,18 @@ class Halfedge_around_target_circulator;
template <typename Graph> template <typename Graph>
class Halfedge_around_source_circulator class Halfedge_around_source_circulator
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
: public boost::transform_iterator<internal::OppositeHalfedge<Graph>, Halfedge_around_target_circulator<Graph> > : public boost::iterator_adaptor<
Halfedge_around_source_circulator<Graph> // Derived
, Halfedge_around_target_circulator<Graph> // Base
, typename boost::graph_traits<Graph>::halfedge_descriptor // Value
, Bidirectional_circulator_tag // CategoryOrTraversal
, typename boost::graph_traits<Graph>::halfedge_descriptor // Reference
>
#endif #endif
{ {
private:
internal::OppositeHalfedge<Graph> opp;
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
typedef boost::transform_iterator<internal::OppositeHalfedge<Graph>, Halfedge_around_target_circulator<Graph> > Base;
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor; typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
#endif #endif
@ -490,7 +497,6 @@ class Halfedge_around_source_circulator
public: public:
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
typedef Bidirectional_circulator_tag iterator_category;
typedef std::size_t size_type; typedef std::size_t size_type;
#endif #endif
@ -498,12 +504,32 @@ public:
{} {}
Halfedge_around_source_circulator(halfedge_descriptor hd, const Graph& g) Halfedge_around_source_circulator(halfedge_descriptor hd, const Graph& g)
: Base(Halfedge_around_target_circulator<Graph>(hd,g), internal::OppositeHalfedge<Graph>(g)) : Halfedge_around_source_circulator::iterator_adaptor_(Halfedge_around_target_circulator<Graph>(hd,g)), opp(g)
{} {}
Halfedge_around_source_circulator(vertex_descriptor vd, const Graph& g) Halfedge_around_source_circulator(vertex_descriptor vd, const Graph& g)
: Base(Halfedge_around_target_circulator<Graph>(halfedge(vd,g),g), internal::OppositeHalfedge<Graph>(g)) : Halfedge_around_source_circulator::iterator_adaptor_(Halfedge_around_target_circulator<Graph>(halfedge(vd,g),g)), opp(g)
{} {}
// design patter: "safe bool"
// will be replaced by explicit operator bool with C++11
typedef void (Halfedge_around_source_circulator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {}
operator bool_type() const
{
return (! (this->base_reference() == NULL)) ?
&Halfedge_around_source_circulator::this_type_does_not_support_comparisons : 0;
}
bool operator== (void*) const
{
return this->base_reference() == NULL;
}
private:
friend class boost::iterator_core_access;
typename boost::graph_traits<Graph>::halfedge_descriptor dereference() const { return opp(*this->base_reference()); }
}; };
@ -519,11 +545,17 @@ public:
template <typename Graph> template <typename Graph>
class Face_around_target_circulator class Face_around_target_circulator
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
: public boost::transform_iterator<internal::Face<Graph>, Halfedge_around_target_circulator<Graph> > : public boost::iterator_adaptor<
Face_around_target_circulator<Graph> // Derived
, Halfedge_around_target_circulator<Graph> // Base
, typename boost::graph_traits<Graph>::face_descriptor // Value
, Bidirectional_circulator_tag // CategoryOrTraversal
, typename boost::graph_traits<Graph>::face_descriptor // Reference
>
#endif #endif
{ {
typedef boost::transform_iterator<internal::Face<Graph>, Halfedge_around_target_circulator<Graph> > Base;
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
internal::Face<Graph> fct;
public: public:
@ -531,10 +563,9 @@ public:
{} {}
Face_around_target_circulator(halfedge_descriptor hd, const Graph& g) Face_around_target_circulator(halfedge_descriptor hd, const Graph& g)
: Base(Halfedge_around_target_circulator<Graph>(hd,g), internal::Face<Graph>(g)) : Face_around_target_circulator::iterator_adaptor_(Halfedge_around_target_circulator<Graph>(hd,g)), fct(g)
{} {}
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
typedef Bidirectional_circulator_tag iterator_category;
typedef std::size_t size_type; typedef std::size_t size_type;
// design patter: "safe bool" // design patter: "safe bool"
@ -545,14 +576,19 @@ public:
operator bool_type() const operator bool_type() const
{ {
return (! (this->base() == NULL)) ? return (! (this->base_reference() == NULL)) ?
&Face_around_target_circulator::this_type_does_not_support_comparisons : 0; &Face_around_target_circulator::this_type_does_not_support_comparisons : 0;
} }
bool operator== (void*) const bool operator== (void*) const
{ {
return this->base() == NULL; return this->base_reference() == NULL;
} }
private:
friend class boost::iterator_core_access;
typename boost::graph_traits<Graph>::face_descriptor dereference() const { return fct(*this->base_reference()); }
#endif #endif
}; };
@ -712,7 +748,7 @@ public:
operator bool_type() const operator bool_type() const
{ {
return (! (this->base() == NULL)) ? return (! (g == NULL)) ?
&Halfedge_around_face_circulator::this_type_does_not_support_comparisons : 0; &Halfedge_around_face_circulator::this_type_does_not_support_comparisons : 0;
} }
@ -820,23 +856,28 @@ halfedges_around_face(typename boost::graph_traits<Graph>::halfedge_descriptor h
template <typename Graph> template <typename Graph>
class Face_around_face_iterator class Face_around_face_iterator
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
: public boost::transform_iterator<internal::Face<Graph>, Halfedge_around_face_iterator<Graph> > : public boost::iterator_adaptor<
Face_around_face_iterator<Graph> // Derived
, Halfedge_around_face_iterator<Graph> // Base
, typename boost::graph_traits<Graph>::face_descriptor // Value
, std::bidirectional_iterator_tag // CategoryOrTraversal
, typename boost::graph_traits<Graph>::face_descriptor // Reference
>
#endif #endif
{ {
typedef boost::transform_iterator<internal::Face<Graph>, Halfedge_around_face_iterator<Graph> > Base;
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
internal::Face<Graph> fct;
public: public:
#ifndef DOXYGEN_RUNNING
typedef std::bidirectional_iterator_tag iterator_category;
#endif
Face_around_face_iterator() Face_around_face_iterator()
{} {}
Face_around_face_iterator(halfedge_descriptor h, const Graph& g, int n = 0) Face_around_face_iterator(halfedge_descriptor h, const Graph& g, int n = 0)
: Base(Halfedge_around_face_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n), internal::Face<Graph>(g)) : Face_around_face_iterator::iterator_adaptor_(Halfedge_around_face_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n)), fct(g)
{} {}
private:
friend class boost::iterator_core_access;
typename boost::graph_traits<Graph>::face_descriptor dereference() const { return fct(*this->base_reference()); }
}; };
@ -860,24 +901,32 @@ class Face_around_face_circulator
template <typename Graph> template <typename Graph>
class Face_around_target_iterator class Face_around_target_iterator
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
: public boost::transform_iterator<internal::Face<Graph>, Halfedge_around_target_iterator<Graph> > : public boost::iterator_adaptor<
Face_around_target_iterator<Graph> // Derived
, Halfedge_around_target_iterator<Graph> // Base
, typename boost::graph_traits<Graph>::face_descriptor // Value
, std::bidirectional_iterator_tag // CategoryOrTraversal
, typename boost::graph_traits<Graph>::face_descriptor // Reference
>
#endif #endif
{ {
typedef boost::transform_iterator<internal::Face<Graph>, Halfedge_around_target_iterator<Graph> > Base;
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
internal::Face<Graph> fct;
public: public:
#ifndef DOXYGEN_RUNNING
typedef std::bidirectional_iterator_tag iterator_category;
#endif
Face_around_target_iterator() Face_around_target_iterator()
{} {}
Face_around_target_iterator(halfedge_descriptor h, const Graph& g, int n = 0) Face_around_target_iterator(halfedge_descriptor h, const Graph& g, int n = 0)
: Base(Halfedge_around_target_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n), internal::Face<Graph>(g)) : Face_around_target_iterator::iterator_adaptor_(Halfedge_around_target_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n)), fct(g)
{} {}
private:
friend class boost::iterator_core_access;
typename boost::graph_traits<Graph>::face_descriptor dereference() const { return fct(*this->base_reference()); }
}; };
/** /**
@ -906,16 +955,21 @@ faces_around_face(typename boost::graph_traits<Graph>::halfedge_descriptor h, co
template <typename Graph> template <typename Graph>
class Vertex_around_face_circulator class Vertex_around_face_circulator
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
: public boost::transform_iterator<internal::Target<Graph>, Halfedge_around_face_circulator<Graph> > : public boost::iterator_adaptor<
Vertex_around_face_circulator<Graph> // Derived
, Halfedge_around_face_circulator<Graph> // Base
, typename boost::graph_traits<Graph>::vertex_descriptor // Value
, Bidirectional_circulator_tag // CategoryOrTraversal
, typename boost::graph_traits<Graph>::vertex_descriptor // Reference
>
#endif #endif
{ {
typedef boost::transform_iterator<internal::Target<Graph>, Halfedge_around_face_circulator<Graph> > Base; internal::Target<Graph> fct;
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
public: public:
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
typedef Bidirectional_circulator_tag iterator_category;
typedef std::size_t size_type; typedef std::size_t size_type;
#endif #endif
@ -923,7 +977,7 @@ public:
{} {}
Vertex_around_face_circulator(halfedge_descriptor h, const Graph& g) Vertex_around_face_circulator(halfedge_descriptor h, const Graph& g)
: Base(Halfedge_around_face_circulator<Graph>(h,g), internal::Target<Graph>(g)) : Vertex_around_face_circulator::iterator_adaptor_(Halfedge_around_face_circulator<Graph>(h,g)), fct(g)
{} {}
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
@ -935,36 +989,42 @@ public:
operator bool_type() const operator bool_type() const
{ {
return (! (this->base() == NULL)) ? return (! (this->base_reference() == NULL)) ?
&Vertex_around_face_circulator::this_type_does_not_support_comparisons : 0; &Vertex_around_face_circulator::this_type_does_not_support_comparisons : 0;
} }
bool operator== (void*) const bool operator== (void*) const
{ {
return this->base()== NULL; return this->base_reference()== NULL;
} }
private:
friend class boost::iterator_core_access;
typename boost::graph_traits<Graph>::vertex_descriptor dereference() const { return fct(*this->base_reference()); }
#endif #endif
}; };
template <typename Graph> template <typename Graph>
class Vertex_around_face_iterator class Vertex_around_face_iterator
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
: public boost::transform_iterator<internal::Target<Graph>, Halfedge_around_face_iterator<Graph> > : public boost::iterator_adaptor<
Vertex_around_face_iterator<Graph> // Derived
, Halfedge_around_face_iterator<Graph> // Base
, typename boost::graph_traits<Graph>::vertex_descriptor // Value
, std::bidirectional_iterator_tag // CategoryOrTraversal
, typename boost::graph_traits<Graph>::vertex_descriptor // Reference
>
#endif #endif
{ {
typedef boost::transform_iterator<internal::Target<Graph>, Halfedge_around_face_iterator<Graph> > Base;
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
internal::Target<Graph> fct;
public: public:
#ifndef DOXYGEN_RUNNING
typedef std::bidirectional_iterator_tag iterator_category;
#endif
Vertex_around_face_iterator() Vertex_around_face_iterator()
{} {}
Vertex_around_face_iterator(halfedge_descriptor h, const Graph& g, int n = 0) Vertex_around_face_iterator(halfedge_descriptor h, const Graph& g, int n = 0)
: Base(Halfedge_around_face_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n), internal::Target<Graph>(g)) : Vertex_around_face_iterator::iterator_adaptor_(Halfedge_around_face_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n)), fct(g)
{} {}
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
@ -976,14 +1036,17 @@ public:
operator bool_type() const operator bool_type() const
{ {
return (! (this->base() == NULL)) ? return (! (this->base_reference() == NULL)) ?
&Vertex_around_face_iterator::this_type_does_not_support_comparisons : 0; &Vertex_around_face_iterator::this_type_does_not_support_comparisons : 0;
} }
bool operator== (void*) const bool operator== (void*) const
{ {
return this->base()== NULL; return this->base_reference()== NULL;
} }
private:
friend class boost::iterator_core_access;
typename boost::graph_traits<Graph>::vertex_descriptor dereference() const { return fct(*this->base_reference()); }
#endif #endif
}; };
@ -1000,15 +1063,19 @@ public:
template <typename Graph> template <typename Graph>
class Vertex_around_target_circulator class Vertex_around_target_circulator
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
: public boost::transform_iterator<internal::Source<Graph>, Halfedge_around_target_circulator<Graph> > : public boost::iterator_adaptor<
Vertex_around_target_circulator<Graph> // Derived
, Halfedge_around_target_circulator<Graph> // Base
, typename boost::graph_traits<Graph>::vertex_descriptor // Value
, Bidirectional_circulator_tag // CategoryOrTraversal
, typename boost::graph_traits<Graph>::vertex_descriptor // Reference
>
#endif #endif
{ {
typedef boost::transform_iterator<internal::Source<Graph>, Halfedge_around_target_circulator<Graph> > Base; internal::Source<Graph> fct;
public: public:
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
typedef Bidirectional_circulator_tag iterator_category;
typedef std::size_t size_type; typedef std::size_t size_type;
#endif #endif
@ -1016,7 +1083,7 @@ public:
{} {}
Vertex_around_target_circulator(halfedge_descriptor h, const Graph& g) Vertex_around_target_circulator(halfedge_descriptor h, const Graph& g)
: Base(Halfedge_around_target_circulator<Graph>(h,g), internal::Source<Graph>(g)) : Vertex_around_target_circulator::iterator_adaptor_(Halfedge_around_target_circulator<Graph>(h,g)), fct(g)
{} {}
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
@ -1028,9 +1095,18 @@ public:
operator bool_type() const operator bool_type() const
{ {
return (! (this->base() == NULL)) ? return (! (this->base_reference() == NULL)) ?
&Vertex_around_target_circulator::this_type_does_not_support_comparisons : 0; &Vertex_around_target_circulator::this_type_does_not_support_comparisons : 0;
} }
bool operator== (void*) const
{
return this->base_reference()== NULL;
}
private:
friend class boost::iterator_core_access;
typename boost::graph_traits<Graph>::vertex_descriptor dereference() const { return fct(*this->base_reference()); }
#endif #endif
}; };
@ -1040,20 +1116,25 @@ public:
template <typename Graph> template <typename Graph>
class Vertex_around_target_iterator class Vertex_around_target_iterator
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
: public boost::transform_iterator<internal::Source<Graph>, Halfedge_around_target_iterator<Graph> > : public boost::iterator_adaptor<
Vertex_around_target_iterator<Graph> // Derived
, Halfedge_around_target_iterator<Graph> // Base
, typename boost::graph_traits<Graph>::vertex_descriptor // Value
, std::bidirectional_iterator_tag // CategoryOrTraversal
, typename boost::graph_traits<Graph>::vertex_descriptor // Reference
>
#endif #endif
{ {
typedef boost::transform_iterator<internal::Source<Graph>, Halfedge_around_target_iterator<Graph> > Base;
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
internal::Source<Graph> fct;
public: public:
typedef std::bidirectional_iterator_tag iterator_category;
Vertex_around_target_iterator() Vertex_around_target_iterator()
{} {}
Vertex_around_target_iterator(halfedge_descriptor h, const Graph& g, int n = 0) Vertex_around_target_iterator(halfedge_descriptor h, const Graph& g, int n = 0)
: Base(Halfedge_around_target_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n), internal::Source<Graph>(g)) : Vertex_around_target_iterator::iterator_adaptor_(Halfedge_around_target_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n)), fct(g)
{} {}
#ifndef DOXYGEN_RUNNING #ifndef DOXYGEN_RUNNING
@ -1065,9 +1146,12 @@ public:
operator bool_type() const operator bool_type() const
{ {
return (! (this->base() == NULL)) ? return (! (this->base_reference() == NULL)) ?
&Vertex_around_target_iterator::this_type_does_not_support_comparisons : 0; &Vertex_around_target_iterator::this_type_does_not_support_comparisons : 0;
} }
private:
friend class boost::iterator_core_access;
typename boost::graph_traits<Graph>::vertex_descriptor dereference() const { return fct(*this->base_reference()); }
#endif #endif
}; };
@ -1120,57 +1204,69 @@ vertices_around_face(typename boost::graph_traits<Graph>::halfedge_descriptor h,
return make_range(I(h,g), I(h,g,1)); return make_range(I(h,g), I(h,g,1));
} }
template <typename Graph>
template <class Graph>
class Out_edge_iterator class Out_edge_iterator
: public boost::transform_iterator<internal::OppositeEdge<Graph>, Halfedge_around_target_iterator<Graph> > : public boost::iterator_adaptor<
Out_edge_iterator<Graph> // Derived
, Halfedge_around_target_iterator<Graph> // Base
, typename boost::graph_traits<Graph>::edge_descriptor // Value
, std::bidirectional_iterator_tag // CategoryOrTraversal
, typename boost::graph_traits<Graph>::edge_descriptor // Reference
>
{ {
typedef boost::transform_iterator<internal::OppositeEdge<Graph>, Halfedge_around_target_iterator<Graph> > Base;
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
private:
internal::OppositeEdge<Graph> opp;
public: public:
typedef std::bidirectional_iterator_tag iterator_category;
Out_edge_iterator() Out_edge_iterator()
{} {}
Out_edge_iterator(halfedge_descriptor h, const Graph& g, int n = 0) Out_edge_iterator(halfedge_descriptor h, const Graph& g, int n = 0)
: Base(Halfedge_around_target_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n), internal::OppositeEdge<Graph>(g)) : Out_edge_iterator::iterator_adaptor_(Halfedge_around_target_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n)), opp(g) {}
{}
// design patter: "safe bool" // design patter: "safe bool"
// will be replaced by explicit operator bool with C++11 // will be replaced by explicit operator bool with C++11
typedef void (Out_edge_iterator::*bool_type)() const; typedef void (Out_edge_iterator::*bool_type)() const;
void this_type_does_not_support_comparisons() const {} void this_type_does_not_support_comparisons() const {}
operator bool_type() const operator bool_type() const
{ {
return (! (this->base() == NULL)) ? return (! (this->base_reference() == NULL)) ?
&Out_edge_iterator::this_type_does_not_support_comparisons : 0; &Out_edge_iterator::this_type_does_not_support_comparisons : 0;
} }
};
private:
friend class boost::iterator_core_access;
typename boost::graph_traits<Graph>::edge_descriptor dereference() const { return opp(*this->base_reference()); }
};
template <typename Graph>
template <class Graph>
class In_edge_iterator class In_edge_iterator
: public boost::transform_iterator<internal::Edge<Graph>, Halfedge_around_target_iterator<Graph> > : public boost::iterator_adaptor<
In_edge_iterator<Graph> // Derived
, Halfedge_around_target_iterator<Graph> // Base
, typename boost::graph_traits<Graph>::edge_descriptor // Value
, std::bidirectional_iterator_tag // CategoryOrTraversal
, typename boost::graph_traits<Graph>::edge_descriptor // Reference
>
{ {
typedef boost::transform_iterator<internal::Edge<Graph>, Halfedge_around_target_iterator<Graph> > Base;
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
private:
internal::Edge<Graph> fct;
public: public:
typedef std::bidirectional_iterator_tag iterator_category;
In_edge_iterator() In_edge_iterator()
{} {}
In_edge_iterator(halfedge_descriptor h, const Graph& g, int n = 0) In_edge_iterator(halfedge_descriptor h, const Graph& g, int n = 0)
: Base(Halfedge_around_target_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n), internal::Edge<Graph>(g)) : In_edge_iterator::iterator_adaptor_(Halfedge_around_target_iterator<Graph>(h,g,(h==halfedge_descriptor())?1:n)), fct(g)
{} {}
// design patter: "safe bool" // design patter: "safe bool"
// will be replaced by explicit operator bool with C++11 // will be replaced by explicit operator bool with C++11
typedef void (In_edge_iterator::*bool_type)() const; typedef void (In_edge_iterator::*bool_type)() const;
@ -1179,11 +1275,17 @@ public:
operator bool_type() const operator bool_type() const
{ {
return (! (this->base() == NULL)) ? return (! (this->base_reference() == NULL)) ?
&In_edge_iterator::this_type_does_not_support_comparisons : 0; &In_edge_iterator::this_type_does_not_support_comparisons : 0;
} }
}; private:
friend class boost::iterator_core_access;
typename boost::graph_traits<Graph>::edge_descriptor dereference() const { return fct(*this->base_reference()); }
};

View File

@ -5,6 +5,8 @@
#include <CGAL/boost/graph/iterator.h> #include <CGAL/boost/graph/iterator.h>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/concept/assert.hpp>
#include <CGAL/Circulator/Circulator_concepts.h>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
@ -17,6 +19,7 @@ typedef GraphTraits::vertex_descriptor vertex_descriptor;
typedef GraphTraits::halfedge_descriptor halfedge_descriptor; typedef GraphTraits::halfedge_descriptor halfedge_descriptor;
typedef GraphTraits::edge_descriptor edge_descriptor; typedef GraphTraits::edge_descriptor edge_descriptor;
typedef GraphTraits::out_edge_iterator out_edge_iterator; typedef GraphTraits::out_edge_iterator out_edge_iterator;
typedef GraphTraits::in_edge_iterator in_edge_iterator;
typedef CGAL::Halfedge_around_face_circulator<Polyhedron> halfedge_around_face_circulator; typedef CGAL::Halfedge_around_face_circulator<Polyhedron> halfedge_around_face_circulator;
typedef CGAL::Halfedge_around_target_circulator<Polyhedron> halfedge_around_target_circulator; typedef CGAL::Halfedge_around_target_circulator<Polyhedron> halfedge_around_target_circulator;
@ -27,9 +30,27 @@ typedef CGAL::Halfedge_around_source_circulator<Polyhedron> halfedge_around_sour
typedef CGAL::Halfedge_around_target_iterator<Polyhedron> halfedge_around_target_iterator; typedef CGAL::Halfedge_around_target_iterator<Polyhedron> halfedge_around_target_iterator;
typedef CGAL::Halfedge_around_face_iterator<Polyhedron> halfedge_around_face_iterator; typedef CGAL::Halfedge_around_face_iterator<Polyhedron> halfedge_around_face_iterator;
typedef CGAL::Face_around_face_iterator<Polyhedron> face_around_face_iterator;
typedef CGAL::Vertex_around_target_iterator<Polyhedron> vertex_around_target_iterator;
int main(int, char* argv[]) int main(int, char* argv[])
{ {
BOOST_CONCEPT_ASSERT((CGAL::Concepts::BidirectionalCirculator<halfedge_around_face_circulator>)) CGAL_UNUSED;
BOOST_CONCEPT_ASSERT((CGAL::Concepts::BidirectionalCirculator<halfedge_around_target_circulator>)) CGAL_UNUSED;
BOOST_CONCEPT_ASSERT((CGAL::Concepts::BidirectionalCirculator<vertex_around_target_circulator>)) CGAL_UNUSED;
BOOST_CONCEPT_ASSERT((CGAL::Concepts::BidirectionalCirculator<face_around_target_circulator>)) CGAL_UNUSED;
BOOST_CONCEPT_ASSERT((CGAL::Concepts::BidirectionalCirculator<halfedge_around_source_circulator>)) CGAL_UNUSED;
BOOST_CONCEPT_ASSERT((CGAL::Concepts::BidirectionalCirculator<halfedge_around_source_circulator>)) CGAL_UNUSED;
BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator<face_around_face_iterator>));
BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator<halfedge_around_face_iterator>));
BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator<halfedge_around_target_iterator>));
BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator<vertex_around_target_iterator>));
BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator<in_edge_iterator>));
BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator<out_edge_iterator>));
std::ifstream in(argv[1]); std::ifstream in(argv[1]);
Polyhedron P; Polyhedron P;
in >> P; in >> P;