really finish traits copy-constructor bug fix

This commit is contained in:
Efi Fogel 2007-08-28 14:18:41 +00:00
parent 93011c08b4
commit 33d5de45ad
1 changed files with 209 additions and 438 deletions

View File

@ -27,6 +27,7 @@
*/ */
#include <boost/type_traits.hpp> #include <boost/type_traits.hpp>
#include <boost/mpl/if.hpp>
#include <CGAL/Arrangement_on_surface_2.h> #include <CGAL/Arrangement_on_surface_2.h>
#include <CGAL/Arr_accessor.h> #include <CGAL/Arr_accessor.h>
@ -196,217 +197,124 @@ void insert(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
} }
/*! Insert a range of x-monotone curves into an empty arrangement /*! Insert a range of x-monotone curves into an empty arrangement
* This generic functor is instantiated when the type * \param arr the resulting arrangement
* Construct_visitor::Traits_2 is not the same as the type GeomTraits. * \param begin the begining of the curve range
* In this case, we instantiate a local variable of the former and provide * \param end past-the-end curve range
* the later as a single parameter to the constructor
*/ */
template <bool b> template <typename GeomTraits, typename TopTraits, typename InputIterator>
struct Arr_empty_inserter { void insert_empty(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
/*! Insert a range of x-monotone curves into an empty arrangement
* \param arr the resulting arrangement
* \param begin the begining of the curve range
* \param end past-the-end curve range
*/
template <typename GeomTraits, typename TopTraits, typename InputIterator>
void operator()(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
InputIterator begin_xcurves, InputIterator end_xcurves) InputIterator begin_xcurves, InputIterator end_xcurves)
{ {
GeomTraits * geom_traits = arr.geometry_traits(); typedef typename TopTraits::Sweep_line_construction_visitor
typedef typename TopTraits::Sweep_line_construction_visitor Construct_visitor;
Construct_visitor; typedef typename Construct_visitor::Traits_2 Construct_traits;
Construct_visitor visitor(&arr);
typename Construct_visitor::Traits_2 traits(*geom_traits);
// Define a sweep-line instance and perform the sweep: GeomTraits * geom_traits = arr.geometry_traits();
Sweep_line_2<typename Construct_visitor::Traits_2, Construct_visitor visitor(&arr);
Construct_visitor,
typename Construct_visitor::Subcurve,
typename Construct_visitor::Event>
sweep_line(&traits, &visitor);
sweep_line.sweep(begin_xcurves, end_xcurves);
}
/*! Insert a range of x-monotone curves into an empty arrangement /* If the type Construct_visitor::Traits_2 is the same as the type GeomTraits,
* \param arr the resulting arrangement * use a reference to GeomTraits to avoid constructing a new one.
* \param begin the begining of the curve range * Otherwise, instantiate a local variable of the former and provide
* \param end past-the-end curve range * the later as a single parameter to the constructor
*/ */
template <typename GeomTraits, typename TopTraits, typename boost::mpl::if_<boost::is_same<GeomTraits, Construct_traits>,
typename XcInputIterator, typename PInputIterator> Construct_traits&, Construct_traits>::type
void operator()(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, traits = *geom_traits;
// Define a sweep-line instance and perform the sweep:
Sweep_line_2<typename Construct_visitor::Traits_2, Construct_visitor,
typename Construct_visitor::Subcurve,
typename Construct_visitor::Event>
sweep_line(&traits, &visitor);
sweep_line.sweep(begin_xcurves, end_xcurves);
}
/*! Insert a range of x-monotone curves and a range of isolated points into
* an empty arrangement
* \param arr the resulting arrangement
* \param begin_xcurves the begining of the curve range
* \param end_xcurves past-the-end curve range
* \param begin_points the begining of the point range
* \param end_points past-the-end point range
*/
template <typename GeomTraits, typename TopTraits,
typename XcInputIterator, typename PInputIterator>
void insert_empty(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
XcInputIterator begin_xcurves, XcInputIterator end_xcurves, XcInputIterator begin_xcurves, XcInputIterator end_xcurves,
PInputIterator begin_points, PInputIterator end_points) PInputIterator begin_points, PInputIterator end_points)
{ {
GeomTraits * geom_traits = arr.geometry_traits(); typedef typename TopTraits::Sweep_line_construction_visitor
typedef typename TopTraits::Sweep_line_construction_visitor Construct_visitor;
Construct_visitor; typedef typename Construct_visitor::Traits_2 Construct_traits;
Construct_visitor visitor(&arr);
typename Construct_visitor::Traits_2 traits(*geom_traits); GeomTraits * geom_traits = arr.geometry_traits();
// Define a sweep-line instance and perform the sweep. Construct_visitor visitor(&arr);
Sweep_line_2<typename Construct_visitor::Traits_2,
Construct_visitor,
typename Construct_visitor::Subcurve,
typename Construct_visitor::Event>
sweep_line(&traits, &visitor);
sweep_line.sweep(begin_xcurves, end_xcurves, begin_points, end_points);
}
};
/*! Insert a range of x-monotone curves into an empty arrangement /* If the type Construct_visitor::Traits_2 is the same as the type GeomTraits,
* This specialized functor is instantiated when the type * use a reference to GeomTraits to avoid constructing a new one.
* Construct_visitor::Traits_2 is the same as the type GeomTraits. * Otherwise, instantiate a local variable of the former and provide
* In this case, we simply assign the former to a reference of the later * the later as a single parameter to the constructor
* to avoid an erroneous call to a copy constructor.
*/
template <>
struct Arr_empty_inserter<true> {
/*! Insert a range of x-monotone curves into an empty arrangement
* \param arr the resulting arrangement
* \param begin the begining of the curve range
* \param end past-the-end curve range
*/ */
template <typename GeomTraits, typename TopTraits, typename InputIterator> typename boost::mpl::if_<boost::is_same<GeomTraits, Construct_traits>,
void operator()(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, Construct_traits&, Construct_traits>::type
InputIterator begin_xcurves, InputIterator end_xcurves) traits = *geom_traits;
{
GeomTraits * geom_traits = arr.geometry_traits(); // Define a sweep-line instance and perform the sweep.
typedef typename TopTraits::Sweep_line_construction_visitor Sweep_line_2<typename Construct_visitor::Traits_2, Construct_visitor,
Construct_visitor; typename Construct_visitor::Subcurve,
Construct_visitor visitor(&arr); typename Construct_visitor::Event>
typename Construct_visitor::Traits_2 & traits = *geom_traits; sweep_line(&traits, &visitor);
sweep_line.sweep(begin_xcurves, end_xcurves, begin_points, end_points);
// Define a sweep-line instance and perform the sweep: }
Sweep_line_2<typename Construct_visitor::Traits_2,
Construct_visitor,
typename Construct_visitor::Subcurve,
typename Construct_visitor::Event>
sweep_line(&traits, &visitor);
sweep_line.sweep(begin_xcurves, end_xcurves);
}
/*! Insert a range of x-monotone curves into an empty arrangement
* \param arr the resulting arrangement
* \param begin the begining of the curve range
* \param end past-the-end curve range
*/
template <typename GeomTraits, typename TopTraits,
typename XcInputIterator, typename PInputIterator>
void operator()(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
XcInputIterator begin_xcurves, XcInputIterator end_xcurves,
PInputIterator begin_points, PInputIterator end_points)
{
GeomTraits * geom_traits = arr.geometry_traits();
typedef typename TopTraits::Sweep_line_construction_visitor
Construct_visitor;
Construct_visitor visitor(&arr);
typename Construct_visitor::Traits_2 & traits = *geom_traits;
// Define a sweep-line instance and perform the sweep.
Sweep_line_2<typename Construct_visitor::Traits_2,
Construct_visitor,
typename Construct_visitor::Subcurve,
typename Construct_visitor::Event>
sweep_line(&traits, &visitor);
sweep_line.sweep(begin_xcurves, end_xcurves, end_points, end_points);
}
};
/*! Insert a range of x-monotone curves into a non-empty arrangement /*! Insert a range of x-monotone curves into a non-empty arrangement
* This generic functor is instantiated when the type * \param arr the resulting arrangement
* Construct_visitor::Traits_2 is not the same as the type GeomTraits. * \param begin the begining of the curve range
* In this case, we instantiate a local variable of the former and provide * \param end past-the-end curve range
* the later as a single parameter to the constructor
*/ */
template <bool b> template <typename GeomTraits, typename TopTraits,
struct Arr_non_empty_inserter { typename XcInputIterator, typename PInputIterator>
/*! Insert a range of x-monotone curves into a non-empty arrangement void insert_non_empty(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
* \param arr the resulting arrangement XcInputIterator begin_xcurves,
* \param begin the begining of the curve range XcInputIterator end_xcurves,
* \param end past-the-end curve range PInputIterator begin_points, PInputIterator end_points)
*/ {
template <typename GeomTraits, typename TopTraits, typedef typename TopTraits::Sweep_line_insertion_visitor
typename XcInputIterator, typename PInputIterator> Insert_visitor;
void operator()(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, typedef typename Insert_visitor::Traits_2 Insert_traits;
XcInputIterator begin_xcurves, XcInputIterator end_xcurves, typedef typename Insert_visitor::Traits_2::X_monotone_curve_2
PInputIterator begin_points, PInputIterator end_points)
{
GeomTraits * geom_traits = arr.geometry_traits();
typedef typename TopTraits::Sweep_line_insertion_visitor
Insert_visitor;
Insert_visitor visitor(&arr);
typename Insert_visitor::Traits_2 traits(*geom_traits);
// Create a set of existing as well as new curves and points.
typedef typename Insert_visitor::Traits_2::X_monotone_curve_2
Ex_x_monotone_curve_2; Ex_x_monotone_curve_2;
typedef typename Insert_visitor::Traits_2::Point_2 Ex_point_2; typedef typename Insert_visitor::Traits_2::Point_2 Ex_point_2;
std::list<Ex_x_monotone_curve_2> ex_cvs;
std::list<Ex_point_2> ex_pts; GeomTraits * geom_traits = arr.geometry_traits();
Insert_visitor visitor(&arr);
prepare_for_sweep(arr,
begin_xcurves, end_xcurves, // the x-monotone curves
begin_points, end_points, // the points (if any)
std::back_inserter(ex_cvs),
std::back_inserter(ex_pts),
&traits);
// Define a basic sweep-line instance and perform the sweep. /* If the type Insert_visitor::Traits_2 is the same as the type GeomTraits,
Sweep_line_2<typename Insert_visitor::Traits_2, Insert_visitor, * use a reference to GeomTraits to avoid constructing a new one.
typename Insert_visitor::Subcurve, * Otherwise, instantiate a local variable of the former and provide
typename Insert_visitor::Event> * the later as a single parameter to the constructor
sweep_line(&traits, &visitor);
sweep_line.sweep (ex_cvs.begin(), ex_cvs.end(),
ex_pts.begin(), ex_pts.end());
}
};
/*! Insert a range of x-monotone curves into a non-empty arrangement
* This specialized functor is instantiated when the type
* Construct_visitor::Traits_2 is the same as the type GeomTraits.
* In this case, we simply assign the former to a reference of the later
* to avoid an erroneous call to a copy constructor.
*/
template <>
struct Arr_non_empty_inserter<true> {
/*! Insert a range of x-monotone curves into a non-empty arrangement
* \param arr the resulting arrangement
* \param begin the begining of the curve range
* \param end past-the-end curve range
*/ */
template <typename GeomTraits, typename TopTraits, typename boost::mpl::if_<boost::is_same<GeomTraits, Insert_traits>,
typename XcInputIterator, typename PInputIterator> Insert_traits&, Insert_traits>::type
void operator()(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, traits = *geom_traits;
XcInputIterator begin_xcurves, XcInputIterator end_xcurves,
PInputIterator begin_points, PInputIterator end_points)
{
GeomTraits * geom_traits = arr.geometry_traits();
typedef typename TopTraits::Sweep_line_insertion_visitor
Insert_visitor;
Insert_visitor visitor(&arr);
typename Insert_visitor::Traits_2 & traits = geom_traits;
// Create a set of existing as well as new curves and points. // Create a set of existing as well as new curves and points.
typedef typename Insert_visitor::Traits_2::X_monotone_curve_2 std::list<Ex_x_monotone_curve_2> ex_cvs;
Ex_x_monotone_curve_2; std::list<Ex_point_2> ex_pts;
typedef typename Insert_visitor::Traits_2::Point_2 Ex_point_2;
std::list<Ex_x_monotone_curve_2> ex_cvs;
std::list<Ex_point_2> ex_pts;
prepare_for_sweep(arr, prepare_for_sweep(arr,
begin_xcurves, end_xcurves, // the x-monotone curves begin_xcurves, end_xcurves, // the x-monotone curves
begin_points, end_points, // the points (if any) begin_points, end_points, // the points (if any)
std::back_inserter(ex_cvs), std::back_inserter(ex_cvs),
std::back_inserter(ex_pts), std::back_inserter(ex_pts),
&traits); &traits);
// Define a basic sweep-line instance and perform the sweep. // Define a basic sweep-line instance and perform the sweep.
Sweep_line_2<typename Insert_visitor::Traits_2, Insert_visitor, Sweep_line_2<typename Insert_visitor::Traits_2, Insert_visitor,
typename Insert_visitor::Subcurve, typename Insert_visitor::Subcurve,
typename Insert_visitor::Event> typename Insert_visitor::Event>
sweep_line(&traits, &visitor); sweep_line(&traits, &visitor);
sweep_line.sweep (ex_cvs.begin(), ex_cvs.end(), sweep_line.sweep(ex_cvs.begin(), ex_cvs.end(),ex_pts.begin(), ex_pts.end());
ex_pts.begin(), ex_pts.end());
}
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -449,24 +357,12 @@ void insert (Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
std::back_inserter(xcurves), std::back_inserter(iso_points), std::back_inserter(xcurves), std::back_inserter(iso_points),
geom_traits); geom_traits);
if (arr.is_empty()) { if (arr.is_empty())
// The arrangement is empty: use the construction visitor.
typedef typename TopTraits::Sweep_line_construction_visitor
Construct_visitor;
typedef typename Construct_visitor::Traits_2 Visitor_traits;
Arr_empty_inserter<boost::is_same<GeomTraits, Visitor_traits>::value>
insert_empty;
insert_empty(arr, xcurves.begin(), xcurves.end(), insert_empty(arr, xcurves.begin(), xcurves.end(),
iso_points.begin(), iso_points.end()); iso_points.begin(), iso_points.end());
} else { else
// The arrangement is not empty: use the insertion visitor.
typedef typename TopTraits::Sweep_line_insertion_visitor Insert_visitor;
typedef typename Insert_visitor::Traits_2 Visitor_traits;
Arr_non_empty_inserter<boost::is_same<GeomTraits, Visitor_traits>::value>
insert_non_empty;
insert_non_empty(arr, xcurves.begin(), xcurves.end(), insert_non_empty(arr, xcurves.begin(), xcurves.end(),
iso_points.begin(), iso_points.end()); iso_points.begin(), iso_points.end());
}
// Notify the arrangement observers that the global operation has been // Notify the arrangement observers that the global operation has been
// completed. // completed.
@ -504,23 +400,11 @@ void insert(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
// Choose the operation depending on whether the input arrangement is // Choose the operation depending on whether the input arrangement is
// empty (then we construct it from scratch), or not (where we just insert // empty (then we construct it from scratch), or not (where we just insert
// the new curves). // the new curves).
if (arr.is_empty()) { if (arr.is_empty())
// The arrangement is empty: use the construction visitor.
typedef typename TopTraits::Sweep_line_construction_visitor
Construct_visitor;
typedef typename Construct_visitor::Traits_2 Visitor_traits;
Arr_empty_inserter<boost::is_same<GeomTraits, Visitor_traits>::value>
insert_empty;
insert_empty(arr, begin, end); insert_empty(arr, begin, end);
}
else { else {
// The arrangement is not empty: use the insertion visitor. // The arrangement is not empty: use the insertion visitor.
typedef typename TopTraits::Sweep_line_insertion_visitor Insert_visitor; std::list<typename GeomTraits::Point_2> empty;
typedef typename Insert_visitor::Traits_2 Visitor_traits;
typedef typename GeomTraits::Point_2 Point_2;
Arr_non_empty_inserter<boost::is_same<GeomTraits, Visitor_traits>::value>
insert_non_empty;
std::list<Point_2> empty;
insert_non_empty(arr, begin, end, empty.begin(), empty.end()); insert_non_empty(arr, begin, end, empty.begin(), empty.end());
} }
@ -803,222 +687,121 @@ insert_non_intersecting_curve
} }
/*! Insert a range of x-monotone curves into an empty arrangement /*! Insert a range of x-monotone curves into an empty arrangement
* This generic functor is instantiated when the type * \param arr the resulting arrangement
* Construct_visitor::Traits_2 is not the same as the type GeomTraits. * \param begin the begining of the curve range
* In this case, we instantiate a local variable of the former and provide * \param end past-the-end curve range
* the later as a single parameter to the constructor
*/ */
template <bool b> template <typename GeomTraits, typename TopTraits, typename InputIterator>
struct Arr_empty_basic_inserter { void non_intersecting_insert_empty(Arrangement_on_surface_2<GeomTraits,
/*! Insert a range of x-monotone curves into an empty arrangement TopTraits>& arr,
* \param arr the resulting arrangement InputIterator begin_xcurves,
* \param begin the begining of the curve range InputIterator end_xcurves)
* \param end past-the-end curve range {
*/ GeomTraits * geom_traits = arr.geometry_traits();
template <typename GeomTraits, typename TopTraits, typename InputIterator> typedef typename TopTraits::Sweep_line_non_intersecting_construction_visitor
void operator()(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
InputIterator begin_xcurves, InputIterator end_xcurves)
{
GeomTraits * geom_traits = arr.geometry_traits();
typedef typename TopTraits::Sweep_line_non_intersecting_construction_visitor
Construct_visitor; Construct_visitor;
Construct_visitor visitor(&arr); Construct_visitor visitor(&arr);
typename Construct_visitor::Traits_2 traits(*geom_traits); typename Construct_visitor::Traits_2 traits(*geom_traits);
// Define a basic sweep-line instance (which is not supposed to handle // Define a basic sweep-line instance (which is not supposed to handle
// insersections) and perform the sweep. // insersections) and perform the sweep.
Basic_sweep_line_2<typename Construct_visitor::Traits_2, Construct_visitor, Basic_sweep_line_2<typename Construct_visitor::Traits_2, Construct_visitor,
typename Construct_visitor::Subcurve, typename Construct_visitor::Subcurve,
typename Construct_visitor::Event> typename Construct_visitor::Event>
sweep_line(&traits, &visitor); sweep_line(&traits, &visitor);
sweep_line.sweep(begin_xcurves, end_xcurves); sweep_line.sweep(begin_xcurves, end_xcurves);
} }
/*! Insert a range of x-monotone curves into an empty arrangement
* \param arr the resulting arrangement
* \param begin the begining of the curve range
* \param end past-the-end curve range
*/
template <typename GeomTraits, typename TopTraits,
typename XcInputIterator, typename PInputIterator>
void operator()(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
XcInputIterator begin_xcurves, XcInputIterator end_xcurves,
PInputIterator begin_points, PInputIterator end_points)
{
GeomTraits * geom_traits = arr.geometry_traits();
typedef typename TopTraits::Sweep_line_non_intersecting_construction_visitor
Construct_visitor;
Construct_visitor visitor(&arr);
typename Construct_visitor::Traits_2 traits(*geom_traits);
// Define a basic sweep-line instance (which is not supposed to handle
// insersections) and perform the sweep.
Basic_sweep_line_2<typename Construct_visitor::Traits_2,
Construct_visitor,
typename Construct_visitor::Subcurve,
typename Construct_visitor::Event>
sweep_line(&traits, &visitor);
sweep_line.sweep(begin_xcurves, end_xcurves, begin_points, end_points);
}
};
/*! Insert a range of x-monotone curves into an empty arrangement /*! Insert a range of x-monotone curves into an empty arrangement
* This specialized functor is instantiated when the type * \param arr the resulting arrangement
* Construct_visitor::Traits_2 is the same as the type GeomTraits. * \param begin the begining of the curve range
* In this case, we simply assign the former to a reference of the later * \param end past-the-end curve range
* to avoid an erroneous call to a copy constructor.
*/ */
template <> template <typename GeomTraits, typename TopTraits,
struct Arr_empty_basic_inserter<true> { typename XcInputIterator, typename PInputIterator>
/*! Insert a range of x-monotone curves into an empty arrangement void non_intersecting_insert_empty(Arrangement_on_surface_2<GeomTraits,
* \param arr the resulting arrangement TopTraits>& arr,
* \param begin the begining of the curve range XcInputIterator begin_xcurves,
* \param end past-the-end curve range XcInputIterator end_xcurves,
PInputIterator begin_points,
PInputIterator end_points)
{
typedef typename TopTraits::Sweep_line_non_intersecting_construction_visitor
Construct_visitor;
typedef typename Construct_visitor::Traits_2 Construct_traits;
GeomTraits * geom_traits = arr.geometry_traits();
Construct_visitor visitor(&arr);
/* If the type Construct_visitor::Traits_2 is the same as the type GeomTraits,
* use a reference to GeomTraits to avoid constructing a new one.
* Otherwise, instantiate a local variable of the former and provide
* the later as a single parameter to the constructor
*/ */
template <typename GeomTraits, typename TopTraits, typename InputIterator> typename boost::mpl::if_<boost::is_same<GeomTraits, Construct_traits>,
void operator()(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, Construct_traits&, Construct_traits>::type
InputIterator begin_xcurves, InputIterator end_xcurves) traits = *geom_traits;
{
GeomTraits * geom_traits = arr.geometry_traits();
typedef typename TopTraits::Sweep_line_non_intersecting_construction_visitor
Construct_visitor;
Construct_visitor visitor(&arr);
typename Construct_visitor::Traits_2 & traits = *geom_traits;
// Define a basic sweep-line instance (which is not supposed to handle // Define a basic sweep-line instance (which is not supposed to handle
// insersections) and perform the sweep. // insersections) and perform the sweep.
Basic_sweep_line_2<typename Construct_visitor::Traits_2, Basic_sweep_line_2<typename Construct_visitor::Traits_2, Construct_visitor,
Construct_visitor, typename Construct_visitor::Subcurve,
typename Construct_visitor::Subcurve, typename Construct_visitor::Event>
typename Construct_visitor::Event> sweep_line(&traits, &visitor);
sweep_line(&traits, &visitor); sweep_line.sweep(begin_xcurves, end_xcurves, begin_points, end_points);
sweep_line.sweep(begin_xcurves, end_xcurves); }
}
/*! Insert a range of x-monotone curves into an empty arrangement
* \param arr the resulting arrangement
* \param begin the begining of the curve range
* \param end past-the-end curve range
*/
template <typename GeomTraits, typename TopTraits,
typename XcInputIterator, typename PInputIterator>
void operator()(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr,
XcInputIterator begin_xcurves, XcInputIterator end_xcurves,
PInputIterator begin_points, PInputIterator end_points)
{
GeomTraits * geom_traits = arr.geometry_traits();
typedef typename TopTraits::Sweep_line_non_intersecting_construction_visitor
Construct_visitor;
Construct_visitor visitor(&arr);
typename Construct_visitor::Traits_2 & traits = *geom_traits;
// Define a basic sweep-line instance (which is not supposed to handle
// insersections) and perform the sweep.
Basic_sweep_line_2<typename Construct_visitor::Traits_2,
Construct_visitor,
typename Construct_visitor::Subcurve,
typename Construct_visitor::Event>
sweep_line(&traits, &visitor);
sweep_line.sweep(begin_xcurves, end_xcurves, begin_points, end_points);
}
};
/*! Insert a range of x-monotone curves into a non-empty arrangement /*! Insert a range of x-monotone curves into a non-empty arrangement
* This generic functor is instantiated when the type * \param arr the resulting arrangement
* Construct_visitor::Traits_2 is not the same as the type GeomTraits. * \param begin the begining of the curve range
* In this case, we instantiate a local variable of the former and provide * \param end past-the-end curve range
* the later as a single parameter to the constructor
*/ */
template <bool b> template <typename GeomTraits, typename TopTraits,
struct Arr_non_empty_basic_inserter { typename XcInputIterator, typename PInputIterator>
/*! Insert a range of x-monotone curves into a non-empty arrangement void non_intersecting_insert_non_empty(Arrangement_on_surface_2<GeomTraits,
* \param arr the resulting arrangement TopTraits>& arr,
* \param begin the begining of the curve range XcInputIterator begin_xcurves,
* \param end past-the-end curve range XcInputIterator end_xcurves,
*/ PInputIterator begin_points,
template <typename GeomTraits, typename TopTraits, PInputIterator end_points)
typename XcInputIterator, typename PInputIterator> {
void operator()(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, typedef typename TopTraits::Sweep_line_non_intersecting_insertion_visitor
XcInputIterator begin_xcurves, XcInputIterator end_xcurves, Insert_visitor;
PInputIterator begin_points, PInputIterator end_points) typedef typename Insert_visitor::Traits_2 Insert_traits;
{ typedef typename Insert_visitor::Traits_2::X_monotone_curve_2
GeomTraits * geom_traits = arr.geometry_traits();
typedef typename TopTraits::Sweep_line_non_intersecting_insertion_visitor
Insert_visitor;
Insert_visitor visitor(&arr);
typename Insert_visitor::Traits_2 traits(*geom_traits);
// Create a set of existing as well as new curves and points.
typedef typename Insert_visitor::Traits_2::X_monotone_curve_2
Ex_x_monotone_curve_2; Ex_x_monotone_curve_2;
typedef typename Insert_visitor::Traits_2::Point_2 Ex_point_2; typedef typename Insert_visitor::Traits_2::Point_2 Ex_point_2;
std::list<Ex_x_monotone_curve_2> ex_cvs;
std::list<Ex_point_2> ex_pts;
prepare_for_sweep(arr,
begin_xcurves, end_xcurves, // the x-monotone curves
begin_points, end_points, // the points (if any)
std::back_inserter(ex_cvs),
std::back_inserter(ex_pts),
&traits);
// Define a basic sweep-line instance and perform the sweep. GeomTraits * geom_traits = arr.geometry_traits();
Basic_sweep_line_2<typename Insert_visitor::Traits_2, Insert_visitor, Insert_visitor visitor(&arr);
typename Insert_visitor::Subcurve,
typename Insert_visitor::Event>
sweep_line(&traits, &visitor);
sweep_line.sweep (ex_cvs.begin(), ex_cvs.end(),
ex_pts.begin(), ex_pts.end());
}
};
/*! Insert a range of x-monotone curves into a non-empty arrangement /* If the type Construct_visitor::Traits_2 is the same as the type GeomTraits,
* This specialized functor is instantiated when the type * use a reference to GeomTraits to avoid constructing a new one.
* Construct_visitor::Traits_2 is the same as the type GeomTraits. * Otherwise, instantiate a local variable of the former and provide
* In this case, we simply assign the former to a reference of the later * the later as a single parameter to the constructor
* to avoid an erroneous call to a copy constructor.
*/
template <>
struct Arr_non_empty_basic_inserter<true> {
/*! Insert a range of x-monotone curves into a non-empty arrangement
* \param arr the resulting arrangement
* \param begin the begining of the curve range
* \param end past-the-end curve range
*/ */
template <typename GeomTraits, typename TopTraits, typename boost::mpl::if_<boost::is_same<GeomTraits, Insert_traits>,
typename XcInputIterator, typename PInputIterator> Insert_traits&, Insert_traits>::type
void operator()(Arrangement_on_surface_2<GeomTraits, TopTraits>& arr, traits = *geom_traits;
XcInputIterator begin_xcurves, XcInputIterator end_xcurves,
PInputIterator begin_points, PInputIterator end_points)
{
GeomTraits * geom_traits = arr.geometry_traits();
typedef typename TopTraits::Sweep_line_non_intersecting_insertion_visitor
Insert_visitor;
Insert_visitor visitor(&arr);
typename Insert_visitor::Traits_2 & traits = geom_traits;
// Create a set of existing as well as new curves and points.
typedef typename Insert_visitor::Traits_2::X_monotone_curve_2
Ex_x_monotone_curve_2;
typedef typename Insert_visitor::Traits_2::Point_2 Ex_point_2;
std::list<Ex_x_monotone_curve_2> ex_cvs;
std::list<Ex_point_2> ex_pts;
prepare_for_sweep(arr, // Create a set of existing as well as new curves and points.
begin_xcurves, end_xcurves, // The x-monotone curves std::list<Ex_x_monotone_curve_2> ex_cvs;
begin_points, end_points, // The points (if any) std::list<Ex_point_2> ex_pts;
std::back_inserter(ex_cvs),
std::back_inserter(ex_pts), prepare_for_sweep(arr,
&traits); begin_xcurves, end_xcurves, // the x-monotone curves
begin_points, end_points, // the points (if any)
std::back_inserter(ex_cvs),
std::back_inserter(ex_pts),
&traits);
// Define a basic sweep-line instance and perform the sweep. // Define a basic sweep-line instance and perform the sweep.
Basic_sweep_line_2<typename Insert_visitor::Traits_2, Insert_visitor, Basic_sweep_line_2<typename Insert_visitor::Traits_2, Insert_visitor,
typename Insert_visitor::Subcurve, typename Insert_visitor::Subcurve,
typename Insert_visitor::Event> typename Insert_visitor::Event>
sweep_line(&traits, &visitor); sweep_line(&traits, &visitor);
sweep_line.sweep(ex_cvs.begin(), ex_cvs.end(), sweep_line.sweep(ex_cvs.begin(), ex_cvs.end(), ex_pts.begin(), ex_pts.end());
ex_pts.begin(), ex_pts.end()); }
}
};
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Insert a range of pairwise interior-disjoint x-monotone curves into // Insert a range of pairwise interior-disjoint x-monotone curves into
@ -1042,24 +825,12 @@ void insert_non_intersecting_curves
// Choose the operation depending on whether the input arrangement is // Choose the operation depending on whether the input arrangement is
// empty (then we construct it from scratch), or not (where we just insert // empty (then we construct it from scratch), or not (where we just insert
// the new curves). // the new curves).
if (arr.is_empty()) { if (arr.is_empty())
// The arrangement is empty: use the construction visitor. non_intersecting_insert_empty(arr, begin, end);
typedef typename TopTraits::Sweep_line_non_intersecting_construction_visitor else {
Construct_visitor; std::list<typename GeomTraits::Point_2> empty;
typedef typename Construct_visitor::Traits_2 Visitor_traits; non_intersecting_insert_non_empty(arr, begin, end,
Arr_empty_basic_inserter<boost::is_same<GeomTraits,Visitor_traits>::value> empty.begin(), empty.end());
insert_empty;
insert_empty(arr, begin, end);
} else {
// The arrangement is not empty: use the insertion visitor.
typedef typename TopTraits::Sweep_line_non_intersecting_insertion_visitor
Insert_visitor;
typedef typename Insert_visitor::Traits_2 Visitor_traits;
typedef typename GeomTraits::Point_2 Point_2;
Arr_non_empty_basic_inserter<boost::is_same<GeomTraits,Visitor_traits>::
value> insert_non_empty;
std::list<Point_2> empty;
insert_non_empty(arr, begin, end, empty.begin(), empty.end());
} }
// Notify the arrangement observers that the global operation has been // Notify the arrangement observers that the global operation has been