mirror of https://github.com/CGAL/cgal
Merge branch 'Kernel_d-rewrite-glisse-old' into Kernel_d-rewrite-glisse
Hopefully the doc will be easier to build this way.
This commit is contained in:
commit
8ddf8255d5
|
|
@ -23,9 +23,33 @@
|
|||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Kernel_traits.h>
|
||||
#include <climits>
|
||||
#include <limits>
|
||||
#ifdef CGAL_EIGEN3_ENABLED
|
||||
#include <Eigen/Core>
|
||||
#endif
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
#ifdef CGAL_EIGEN3_ENABLED
|
||||
const int UNKNOWN_DIMENSION=Eigen::Dynamic;
|
||||
#else
|
||||
const int UNKNOWN_DIMENSION=std::numeric_limits<int>::max();
|
||||
#endif
|
||||
|
||||
// Check that dimension d1 is fine for a kernel of dimension d2.
|
||||
// If d2 is unknown, any d1 is fine.
|
||||
inline bool check_dimension_lt(int d1, int d2){
|
||||
//return (d2==UNKNOWN_DIMENSION)||(d1<d2);
|
||||
return d1<d2;
|
||||
}
|
||||
inline bool check_dimension_le(int d1, int d2){
|
||||
//return (d2==UNKNOWN_DIMENSION)||(d1<=d2);
|
||||
return d1<=d2;
|
||||
}
|
||||
inline bool check_dimension_eq(int d1, int d2){
|
||||
return d2==UNKNOWN_DIMENSION || d1==d2;
|
||||
}
|
||||
|
||||
// These tag classes help dispatching functions based on a geometric dimension.
|
||||
|
||||
template < int dim >
|
||||
|
|
@ -34,7 +58,9 @@ struct Dimension_tag
|
|||
static const int value = dim;
|
||||
};
|
||||
|
||||
struct Dynamic_dimension_tag {};
|
||||
struct Dynamic_dimension_tag {
|
||||
static const int value = UNKNOWN_DIMENSION;
|
||||
};
|
||||
|
||||
|
||||
namespace internal {
|
||||
|
|
@ -69,6 +95,39 @@ struct Feature_dimension
|
|||
typedef typename K::template Feature_dimension<T>::type type;
|
||||
};
|
||||
|
||||
// Change the dimension
|
||||
template<class D,int i=1>struct Increment_dimension {
|
||||
typedef Dynamic_dimension_tag type;
|
||||
};
|
||||
template<int d,int i>struct Increment_dimension<Dimension_tag<d>,i> {
|
||||
typedef Dimension_tag<d+i> type;
|
||||
};
|
||||
|
||||
template<class D1,class D2>struct Product_dimension {
|
||||
typedef Dynamic_dimension_tag type;
|
||||
};
|
||||
template<int d1,int d2>struct Product_dimension<Dimension_tag<d1>,Dimension_tag<d2> > {
|
||||
typedef Dimension_tag<d1*d2> type;
|
||||
};
|
||||
|
||||
#ifdef CGAL_EIGEN3_ENABLED
|
||||
// Convert to Eigen's notion of dimension
|
||||
template <class Dim_> struct Eigen_dimension {
|
||||
enum { value=Eigen::Dynamic };
|
||||
};
|
||||
template <int d> struct Eigen_dimension<Dimension_tag<d> > {
|
||||
enum { value=d };
|
||||
};
|
||||
|
||||
// and convert back
|
||||
template <int d> struct Dimension_eigen {
|
||||
typedef Dimension_tag<d> type;
|
||||
};
|
||||
template <> struct Dimension_eigen<Eigen::Dynamic> {
|
||||
typedef Dynamic_dimension_tag type;
|
||||
};
|
||||
#endif
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_DIMENSION_H
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace CGAL {
|
|||
/*!
|
||||
\ingroup PkgKernelDKernels
|
||||
|
||||
A model for `Kernel_d` that uses %Cartesian coordinates to represent the
|
||||
A model for `Kernel_d` (and even `KernelWithLifting_d`) that uses %Cartesian coordinates to represent the
|
||||
geometric objects. In order for `Cartesian_d` to model Euclidean geometry
|
||||
in \f$ E^d\f$ , for some mathematical field \f$ E\f$ (<I>e.g.</I>,
|
||||
the rationals \f$\mathbb{Q}\f$ or the reals \f$\mathbb{R}\f$), the template parameter `FieldNumberType`
|
||||
|
|
@ -14,7 +14,7 @@ type provided as a model for `FieldNumberType` is only an approximation of a
|
|||
field (such as the built-in type `double`), then the geometry provided by
|
||||
the kernel is only an approximation of Euclidean geometry.
|
||||
|
||||
\cgalModels `Kernel_d`
|
||||
\cgalModels `KernelWithLifting_d`
|
||||
|
||||
\sa `CGAL::Homogeneous_d<RingNumberType>`
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgKernelDKernels
|
||||
|
||||
A model for `Kernel_d` that uses %Cartesian coordinates to represent the
|
||||
geometric objects. The parameter `DimensionTag` is the dimension of the
|
||||
ambient Euclidean space. It may be either `Dimension_tag<d>` \cgalModifBegin where `d` is
|
||||
an integer \cgalModifEnd or
|
||||
`Dynamic_dimension_tag`. \cgalModifBegin In the later case, the dimension of the space is specified for each point when it is constructed, so it doesn't need to be known at compile-time. \cgalModifEnd This kernel supports construction of points from `double`
|
||||
%Cartesian coordinates. It provides exact geometric predicates, but
|
||||
the geometric constructions are not guaranteed to be exact. The geometric
|
||||
predicates are made exact without sacrificing speed thanks to the use of
|
||||
filters.
|
||||
|
||||
This kernel is default constructible and copyable. It does not carry any
|
||||
state so it is possible to use objects created by one instance with
|
||||
functors created by another one.
|
||||
|
||||
Note that this kernel does not completely conform to the `Kernel_d`
|
||||
concept: it is missing the constructions `Lift_to_paraboloid_d` and
|
||||
`Project_along_d_axis_d` which do not make sense with a single fixed
|
||||
dimension.
|
||||
|
||||
Only the interfaces specific to this class are listed here, refer to the
|
||||
concepts for the rest.
|
||||
|
||||
|
||||
\cgalModels `Kernel_d`
|
||||
\cgalModels `DelaunayTriangulationTraits`
|
||||
|
||||
\sa `CGAL::Cartesian_d<FieldNumberType>`
|
||||
\sa `CGAL::Homogeneous_d<RingNumberType>`
|
||||
|
||||
*/
|
||||
template< typename DimensionTag >
|
||||
class Epick_d {
|
||||
public:
|
||||
/*!
|
||||
represents a point in the Euclidean space
|
||||
\cgalModels `DefaultConstructible`
|
||||
\cgalModels `Copyable`
|
||||
\cgalModels `Assignable`
|
||||
*/
|
||||
class Point_d {
|
||||
public:
|
||||
/*! introduces a point with coordinates (x0, x1, ...) where the number of
|
||||
coordinates matches the dimension.
|
||||
\pre `DimensionTag` is a fixed dimension, not `Dynamic_dimension_tag`. */
|
||||
Point_d(double x0, double x1, ...);
|
||||
|
||||
/*! \cgalModifBegin introduces a point with coordinate set `[first,end)`.
|
||||
\pre If `DimensionTag` is a fixed dimension, it matches `distance(first,end)`.
|
||||
\cgalRequires The value type of `InputIterator` is convertible to `FT`.\cgalModifEnd
|
||||
*/
|
||||
template<typename InputIterator>
|
||||
Point_d(InputIterator first, InputIterator end);
|
||||
|
||||
/*! returns the i'th coordinate of a point.
|
||||
\pre `i` is non-negative and less than the dimension. */
|
||||
double operator[](int i)const;
|
||||
|
||||
/*! \cgalModifBegin returns an iterator pointing to the zeroth Cartesian coordinate.\cgalModifEnd */
|
||||
Cartesian_const_iterator_d cartesian_begin()const;
|
||||
/*! \cgalModifBegin returns an iterator pointing beyond the last Cartesian coordinate.\cgalModifEnd */
|
||||
Cartesian_const_iterator_d cartesian_end()const;
|
||||
}
|
||||
/// @}
|
||||
|
||||
}; /* end Epick_d */
|
||||
} /* end namespace CGAL */
|
||||
|
|
@ -4,7 +4,7 @@ namespace CGAL {
|
|||
/*!
|
||||
\ingroup PkgKernelDKernels
|
||||
|
||||
A model for a `Kernel_d` using homogeneous coordinates to represent the
|
||||
A model for a `Kernel_d` (and even `KernelWithLifting_d`) using homogeneous coordinates to represent the
|
||||
geometric objects. In order for `Homogeneous` to model Euclidean geometry
|
||||
in \f$ E^d\f$, for some mathematical ring \f$ E\f$ (<I>e.g.</I>,
|
||||
the integers \f$\mathbb{Z}\f$ or the rationals \f$\mathbb{Q}\f$), the template parameter `RT`
|
||||
|
|
@ -14,7 +14,7 @@ type provided as a model for `RingNumberType` is only an approximation of a
|
|||
ring (such as the built-in type `double`), then the geometry provided by
|
||||
the kernel is only an approximation of Euclidean geometry.
|
||||
|
||||
\cgalModels `Kernel_d`
|
||||
\cgalModels `KernelWithLifting_d`
|
||||
|
||||
\sa `CGAL::Cartesian_d<FieldNumberType>`
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
*/
|
||||
|
||||
class Kernel_d::Lift_to_paraboloid_d {
|
||||
class KernelWithLifting_d::Lift_to_paraboloid_d {
|
||||
public:
|
||||
|
||||
/// \name Operations
|
||||
|
|
@ -14,13 +14,13 @@ public:
|
|||
|
||||
/*!
|
||||
returns \f$ p = (x_0,\ldots,x_{d-1})\f$ lifted to the paraboloid of
|
||||
revolution which is the point \f$ (p_0, \ldots,p_{d-1},\sum_{0 \le i <
|
||||
d}p_i^2)\f$ in \f$ (d+1)\f$-space.
|
||||
revolution which is the point \f$ (x_0, \ldots,x_{d-1},\sum_{0 \le i <
|
||||
d}x_i^2)\f$ in \f$ (d+1)\f$-space.
|
||||
*/
|
||||
Kernel_d::Point_d operator()(const Kernel_d::Point_d&
|
||||
p);
|
||||
|
||||
/// @}
|
||||
|
||||
}; /* end Kernel_d::Lift_to_paraboloid_d */
|
||||
}; /* end KernelWithLifting_d::Lift_to_paraboloid_d */
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
*/
|
||||
|
||||
class Kernel_d::Project_along_d_axis_d {
|
||||
class KernelWithLifting_d::Project_along_d_axis_d {
|
||||
public:
|
||||
|
||||
/// \name Operations
|
||||
|
|
@ -20,5 +20,5 @@ Kernel_d::Point_d operator()(const Kernel_d::Point_d& p);
|
|||
|
||||
/// @}
|
||||
|
||||
}; /* end Kernel_d::Project_along_d_axis_d */
|
||||
}; /* end KernelWithLifting_d::Project_along_d_axis_d */
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
|
||||
/*!
|
||||
\ingroup PkgKernelDKernelConcept
|
||||
\cgalConcept
|
||||
|
||||
The concept of a <I>kernel with lifting</I> is a small refinement of the
|
||||
general kernel concept. It adds 2 functors, the meaning of which would be
|
||||
unclear in kernels of fixed dimension.
|
||||
|
||||
\cgalRefines `Kernel_d`
|
||||
\cgalHasModel `CGAL::Cartesian_d<FieldNumberType>`
|
||||
\cgalHasModel `CGAL::Homogeneous_d<RingNumberType>`
|
||||
*/
|
||||
class KernelWithLifting_d {
|
||||
public:
|
||||
|
||||
/// \name Constructions
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
a model of `KernelWithLifting_d::Lift_to_paraboloid_d`
|
||||
*/
|
||||
typedef unspecified_type Lift_to_paraboloid_d;
|
||||
|
||||
/*!
|
||||
a model of `KernelWithLifting_d::Project_along_d_axis_d`
|
||||
*/
|
||||
typedef unspecified_type Project_along_d_axis_d;
|
||||
|
||||
/// @}
|
||||
|
||||
/// \name Operations
|
||||
/// The following member functions return function objects of the
|
||||
/// types listed above.
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
Kernel_d::Lift_to_paraboloid_d lift_to_paraboloid_d_object() const;
|
||||
|
||||
/*!
|
||||
|
||||
*/
|
||||
Kernel_d::Project_along_d_axis_d project_along_d_axis_d_object() const;
|
||||
|
||||
/// @}
|
||||
|
||||
}; /* end KernelWithLifting_d */
|
||||
|
||||
|
|
@ -20,6 +20,7 @@ replacing operators, especially for equality testing.
|
|||
|
||||
\cgalHasModel `CGAL::Cartesian_d<FieldNumberType>`
|
||||
\cgalHasModel `CGAL::Homogeneous_d<RingNumberType>`
|
||||
\cgalHasModel `CGAL::Epick_d<DimensionTag>`
|
||||
*/
|
||||
class Kernel_d {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ unordered set of elements of the corresponding tuple.
|
|||
|
||||
This extends the syntax of random access iterators to input iterators.
|
||||
If we index the tuple as above then we require that
|
||||
\f$ ++^{(d+1)}\mathit{first} = \mathit{last}\f$.
|
||||
\f$ ++^{(d)}\mathit{first} = \mathit{last}\f$.
|
||||
|
||||
\section Kernel_dKernel Kernel Representations
|
||||
|
||||
|
|
@ -109,12 +109,14 @@ argument for this parameter must fulfill certain requirements on
|
|||
syntax and semantics. The list of requirements defines an abstract
|
||||
kernel concept. In \cgal such a kernel concept is often also called a
|
||||
<I>representation class</I> and denoted by `R`. A representation
|
||||
class provides the actual implementations of the kernel objects. For
|
||||
all kernel objects `Kernel_object`, the types
|
||||
`CGAL::Kernel_object<R>` and `R::Kernel_object` are identical.
|
||||
class provides the actual implementations of the kernel objects.
|
||||
For all kernel objects `Kernel_object` of a representation class `R` based
|
||||
on `Cartesian_d` or `Homogeneous_d`, the types `CGAL::Kernel_object<R>` and
|
||||
`R::Kernel_object` are identical.
|
||||
|
||||
\cgal offers two families of concrete models for the concept
|
||||
representation class, one based on the %Cartesian
|
||||
|
||||
\cgal offers three families of concrete models for the concept
|
||||
representation class, two based on the %Cartesian
|
||||
representation of points and one based on the homogeneous
|
||||
representation of points. The interface of the kernel objects is
|
||||
designed such that it works well with both
|
||||
|
|
@ -140,7 +142,7 @@ strictly speaking, the built-in type `int` does not fulfill the
|
|||
requirements on a field type, since `int`s correspond to elements
|
||||
of a ring rather than a field, especially operation \f$ /\f$ is not the
|
||||
inverse of \f$ *\f$. The requirements on the type `R::RT` are
|
||||
weaker. This type must fulfill the requirements on what is called an
|
||||
weaker. This type must fulfill the requirements on what is called a
|
||||
<I>Euclidean ring type</I> in \cgal. This roughly means that
|
||||
`R::RT` is a type for which operations \f$ +\f$, \f$ -\f$, \f$ *\f$ are
|
||||
defined with semantics (approximately) corresponding to those of a
|
||||
|
|
@ -205,10 +207,29 @@ circumvented. With `Homogeneous_d<RingNumberType>`,
|
|||
`Homogeneous_d<RingNumberType,LinearAlgebra>::%LA` is mapped to the
|
||||
type `LinearAlgebra`.
|
||||
|
||||
\subsection Kernel_dEpickKernel Epick_d Kernel
|
||||
|
||||
The kernel `Epick_d<DimensionTag>`, short for Exact Predicates Inexact
|
||||
Constructions Kernel is a kernel particularly useful when the dimension of
|
||||
the space is known at compile-time; \cgalModifBegin `DimensionTag` is then
|
||||
`Dimension_tag<d>` where `d` is an integer representing the dimension. It
|
||||
may also be used with parameter `Dynamic_dimension_tag`, in which case the
|
||||
dimension does not need to be known at compile-time.\cgalModifEnd
|
||||
It uses a Cartesian representation and
|
||||
supports construction of points from `double` coordinates. It provides exact
|
||||
geometric predicates, but the geometric constructions are not guaranteed to
|
||||
be exact.
|
||||
|
||||
Note that it provides few interfaces in addition to those documented in the
|
||||
`Kernel_d` concept. In particular, the type of a point is only available as
|
||||
`Epick_d<DimensionTag>::Point_d`, <B>not</B> `Point_d<Epick_d<DimensionTag>>`.
|
||||
|
||||
|
||||
\subsection Kernel_dNamingconventions Naming conventions
|
||||
|
||||
The use of representation classes not only avoids problems, it also
|
||||
makes all \cgal classes very uniform. They <B>always</B> consist of:
|
||||
makes all \cgal classes very uniform. Like `Cartesian_d<double>::Point_d`,
|
||||
they <B>always</B> consist of:
|
||||
<OL>
|
||||
|
||||
<LI>The <I>capitalized base name</I> of the geometric object, such as
|
||||
|
|
@ -216,9 +237,10 @@ makes all \cgal classes very uniform. They <B>always</B> consist of:
|
|||
|
||||
<LI>Followed by `_d`.
|
||||
|
||||
<LI>A <I>representation class</I> as parameter, which itself is
|
||||
parameterized with a number type, such as
|
||||
`Cartesian_d<double>` or `Homogeneous_d<leda_integer>`.
|
||||
<LI>A <I>representation class</I>, which itself may be parameterized with a
|
||||
number type, such as `Cartesian_d<double>` or `Homogeneous_d<leda_integer>`,
|
||||
where the type can be found, \cgalModifBegin except for `Epick_d<DimensionTag>` where the
|
||||
number type is implicitly `double`\cgalModifEnd .
|
||||
</OL>
|
||||
|
||||
\subsection Kernel_dKernelasaTraitsClass Kernel as a Traits Class
|
||||
|
|
@ -231,7 +253,7 @@ library you can use a kernel as a traits class. For some algorithms
|
|||
you even do not have to specify the kernel; it is detected
|
||||
automatically using the types of the geometric objects passed to the
|
||||
algorithm. In some other cases, the algorithms or data structures
|
||||
needs more than is provided by a kernel. In these cases, a kernel can
|
||||
need more than is provided by a kernel. In these cases, a kernel can
|
||||
not be used as a traits class.
|
||||
|
||||
\subsection Kernel_dChoosingaKernel Choosing a Kernel
|
||||
|
|
@ -266,6 +288,11 @@ they need speed and can live with approximate results, or even
|
|||
algorithms that, from time to time, crash or compute incorrect results
|
||||
due to accumulated rounding errors.
|
||||
|
||||
The `Epick_d` kernel provides a compromise using `double` coordinates. It
|
||||
evaluates predicates exactly, which is slower than plain `double`
|
||||
computations, but still faster than using an exact number type thanks to
|
||||
filtering techniques. Constructions are inexact, computed with `double`.
|
||||
|
||||
\subsection Kernel_dInclusionofHeaderFiles Inclusion of Header Files
|
||||
|
||||
You need just to include a representation class to obtain the
|
||||
|
|
@ -516,6 +543,10 @@ Stefan Schirra.
|
|||
This work was supported by ESPRIT IV Long Term Research Projects
|
||||
No. 21957 (CGAL) and No. 28155 (GALIA).
|
||||
|
||||
The Epick_d kernel was partially supported by the IST Programme of the EU
|
||||
(FET Open) Project under Contract No IST-25582 – (CGL - Computational
|
||||
Geometric Learning).
|
||||
|
||||
*/
|
||||
} /* namespace CGAL */
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@
|
|||
|
||||
## Kernels ##
|
||||
- `CGAL::Cartesian_d<FieldNumberType>`
|
||||
- `CGAL::Homogeneous<RingNumberType>`
|
||||
- `CGAL::Homogeneous_d<RingNumberType>`
|
||||
- `CGAL::Epick_d<DimensionTag>`
|
||||
|
||||
## %Kernel Objects ##
|
||||
- `CGAL::Point_d<Kernel>`
|
||||
|
|
|
|||
|
|
@ -132,6 +132,12 @@ circumvented. With \ccc{Homogeneous_d<RingNumberType>},
|
|||
\ccc{Homogeneous_d<RingNumberType,LinearAlgebra>::LA} is mapped to the
|
||||
type \ccc{LinearAlgebra}.
|
||||
|
||||
\subsection{Epick Kernel}
|
||||
|
||||
The kernel \ccc{Epick_d<dimension>}, short for Exact Predicates Inexact Constructions Kernel is an experimental kernel useful when the dimension of the space is known at compile-time. It uses a Cartesian representation and supports construction of points from \ccc{double} coordinates. It provides exact geometric predicates, but inexact geometric constructions.
|
||||
|
||||
Note that it is a rather strict model of the \ccc{Kernel_d} concept. The type of a point is \ccc{Epick_d<dimension>::Point_d}, {\bf not} \ccc{Point_d<Epick_d<dimension>>}.
|
||||
|
||||
\subsection{Naming conventions}
|
||||
|
||||
The use of representation classes not only avoids problems, it also
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
\begin{ccRefClass}{Epick_d<dimension>}
|
||||
|
||||
\ccInclude{CGAL/Epick_d.h}
|
||||
|
||||
\ccDefinition
|
||||
A model for \ccc{Kernel_d} and \ccc{DelaunayTriangulationTraits} that
|
||||
uses Cartesian coordinates to represent the geometric objects. The
|
||||
integer parameter \ccc{dimension} is the dimension of the ambient
|
||||
Euclidean space. It supports construction of points from \ccc{double}
|
||||
Cartesian coordinates. It provides exact geometric predicates, but
|
||||
inexact geometric constructions. The geometric predicates are made exact
|
||||
without sacrificing speed thanks to the use of filters.
|
||||
|
||||
This kernel is default constructible and copyable. It does not carry any
|
||||
state so it is possible to use objects created by one instance with
|
||||
functors created by another one.
|
||||
|
||||
Note that this kernel does not completely conform to the \ccc{Kernel_d}
|
||||
concept: it is missing the constructions \ccc{Lift_to_paraboloid_d} and
|
||||
\ccc{Project_along_d_axis_d} which do not make sense with a fixed
|
||||
dimension.
|
||||
|
||||
\ccIsModel
|
||||
\ccRefConceptPage{Kernel_d}
|
||||
|
||||
\ccRefConceptPage{DelaunayTriangulationTraits}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccRefIdfierPage{CGAL::Epick_d<dimension>::Point_d}
|
||||
|
||||
\ccRefIdfierPage{CGAL::Cartesian_d<FieldNumberType>}
|
||||
|
||||
\ccRefIdfierPage{CGAL::Homogeneous_d<RingNumberType>}
|
||||
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
\begin{ccRefClass} {Epick_d<dimension>::Point_d}
|
||||
|
||||
\ccDefinition
|
||||
An object of the class \ccRefName\ is a point in the Euclidean space $\E^{dimension}$.
|
||||
|
||||
This class is DefaultConstructible, Copyable, Assignable, and provides the following additional interfaces:
|
||||
|
||||
\ccCreation
|
||||
\ccCreationVariable{p}
|
||||
\ccConstructor{Point_d(double x_0, \ldots, double x_{dimension-1});}
|
||||
{introduces a point \ccVar\ initialized to $(x_0, \ldots, x_{dimension-1})$.}
|
||||
|
||||
\ccOperations
|
||||
\ccMethod{double operator[](int i) const;}
|
||||
{returns the i'th Cartesian coordinate of \ccVar.
|
||||
\ccPrecond $0\leq i < dimension$.}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
\begin{ccRefClass}{Homogeneous<RingNumberType>}
|
||||
\begin{ccRefClass}{Homogeneous_d<RingNumberType>}
|
||||
\ccInclude{CGAL/Homogeneous_d.h}
|
||||
|
||||
\ccDefinition
|
||||
|
|
@ -16,6 +16,6 @@ the kernel is only an approximation of Euclidean geometry.
|
|||
\ccRefConceptPage{Kernel_d}
|
||||
|
||||
\ccSeeAlso
|
||||
\ccRefIdfierPage{CGAL::Cartesian_d<FieldumberType>}
|
||||
\ccRefIdfierPage{CGAL::Cartesian_d<FieldNumberType>}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
|
|||
|
|
@ -170,6 +170,6 @@ corresponding functions are:
|
|||
|
||||
\ccHasModels
|
||||
|
||||
\ccc{Cartesian_d<FieldNumberType>}, \ccc{Homogeneous_d<RingNumberType>}
|
||||
\ccc{Cartesian_d<FieldNumberType>}, \ccc{Homogeneous_d<RingNumberType>}, \ccc{Epick_d<dimension>}
|
||||
|
||||
\end{ccRefConcept}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
\input{Kernel_d_ref/Cartesian_d.tex}
|
||||
\gdef\ccRefPageBreak{\ccTrue}
|
||||
\input{Kernel_d_ref/Homogeneous_d.tex}
|
||||
\input{Kernel_d_ref/Epick_d.tex}
|
||||
|
||||
\clearpage
|
||||
\section{Kernel Objects}
|
||||
|
|
@ -36,6 +37,7 @@
|
|||
\input{Kernel_d_ref/Sphere_d.tex}
|
||||
\input{Kernel_d_ref/Iso_box_d.tex}
|
||||
\input{Kernel_d_ref/Aff_transformation_d.tex}
|
||||
\input{Kernel_d_ref/Epick_d_Point_d.tex}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
\begin{ccRefClass}{Cartesian_complete<Base,bool force=false,Derived=Default>}
|
||||
\ccInclude{CGAL/NewKernel_d/Cartesian_complete.h}
|
||||
|
||||
\ccDefinition
|
||||
A model for \ccc{Kernel}, that takes a \ccc{Kernel} model \ccc{Base}
|
||||
which provides at least \ccc{Point} and extends it by defining a number
|
||||
of classical types and functors. The \ccc{force} parameter says whether
|
||||
the class should override existing objects from \ccc{Base}.
|
||||
\ccc{Derived} is the name of the ``final'' class for CRTP patterns,
|
||||
which by default is \ccc{Cartesian_complete} itself.
|
||||
|
||||
This is in particular expected to be enough for the \ccc{Triangulation}
|
||||
package.
|
||||
|
||||
\ccIsModel
|
||||
\ccRefConceptPage{Kernel}
|
||||
|
||||
\ccImplementation
|
||||
This is split in classes \ccc{Cartesian_complete_predicates},
|
||||
\ccc{Cartesian_complete_computations},
|
||||
\ccc{Cartesian_complete_constructions},
|
||||
\ccc{Cartesian_complete_functors} (a reunion of the previous three),
|
||||
\ccc{Cartesian_complete_types}, all with the same parameters.
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
\begin{ccRefClass}{Cartesian_filter_K<Base,AK,EK>}
|
||||
\ccInclude{CGAL/NewKernel_d/Cartesian_filter_K.h}
|
||||
|
||||
\ccDefinition
|
||||
A model for \ccc{Kernel} that derives from \ccc{Base} (already a
|
||||
\ccc{Kernel}) and redefines the predicates as filtered predicates
|
||||
using \ccc{AK} as the approximate kernel and \ccc{EK} as the exact
|
||||
kernel.
|
||||
|
||||
\ccIsModel
|
||||
\ccRefConceptPage{Kernel}
|
||||
|
||||
Constructors???
|
||||
|
||||
NOTYET:
|
||||
\begin{itemize}
|
||||
\item If \ccc{Base::Functor<Tag>::Is_exact::value} is true, don't filter.
|
||||
\item \ccc{Functor<Tag,No_filter_tag>::type} is taken from Base.
|
||||
\end{itemize}
|
||||
|
||||
\ccImplementation
|
||||
The implementation uses \ccc{CGAL::Filtered_predicate} and
|
||||
\ccc{CGAL::KernelD_converter}.
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
\begin{ccRefClass}{Cartesian_mini_d<FT,Dim>}
|
||||
\ccInclude{CGAL/NewKernel_d/Cartesian_mini_d.h}
|
||||
|
||||
\ccDefinition
|
||||
A minimal model for \ccc{Kernel} where \ccc{FT} and
|
||||
\ccc{Default_ambient_dimension} are provided as template arguments.
|
||||
This kernel provides the \ccc{Point} concept and not much more.
|
||||
|
||||
The class takes several other template parameters (in particular to
|
||||
specify \ccc{LA}) that are undocumented for now.
|
||||
|
||||
\ccIsModel
|
||||
\ccRefConceptPage{Kernel}
|
||||
\ccRefConceptPage{Point}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
\begin{ccRefClass}{Cartesian_wrap<Base>}
|
||||
\ccInclude{CGAL/NewKernel_d/Cartesian_wrap.h}
|
||||
|
||||
\ccDefinition
|
||||
This class derives from a \ccc{Kernel} \ccc{Base} and replaces a number
|
||||
of types (point, segment) with wrappers that have intuitive member
|
||||
functions that call the corresponding functors. For instance, the
|
||||
constructors forward to \ccc{Functor<Construct_ttag<Tag>>::type},
|
||||
\ccc{Point::operator[]} forwards to
|
||||
\ccc{Functor<Compute_cartesian_coordinate_tag>::type},
|
||||
\ccc{operator+(Vector,Vector)} forwards to
|
||||
\ccc{Functor<Construct_sum_of_vectors_tag>::type}, etc.
|
||||
|
||||
For stateful kernels, the wrappers will store a pointer to the kernel
|
||||
instance. This means in particular that for such a kernel, one can't
|
||||
just create a point from its coordinates (like \ccc{Point M(1,2,3);}),
|
||||
they have to create it using some functor or an operation on existing
|
||||
objects.
|
||||
|
||||
\ccIsModel
|
||||
\ccRefConceptPage{Kernel}
|
||||
|
||||
\ccImplementation
|
||||
The implementation \emph{tries} to avoid any extra copying that could be
|
||||
caused by the wrapping.
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
\begin{ccRefClass}{Define_segment<Base,Derived=Default>}
|
||||
\ccInclude{CGAL/NewKernel_d/Define_segment.h}
|
||||
|
||||
\ccDefinition
|
||||
A model for \ccc{Kernel}, that takes a \ccc{Kernel} model \ccc{Base}
|
||||
which provides at least \ccc{Point} and extends it by providing
|
||||
\ccc{Segment}.
|
||||
\ccc{Derived} is the name of the ``final'' class for CRTP patterns,
|
||||
which by default is \ccc{Define_segment} itself.
|
||||
|
||||
\ccIsModel
|
||||
\ccRefConceptPage{Kernel}
|
||||
\ccRefConceptPage{Segment}
|
||||
|
||||
\ccImplementation
|
||||
The segment type is defined as an \ccc{std::pair} of points.
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
\begin{ccRefFunctionObjectClass}{KernelD_converter<K1,K2,List=K1::Object_list>}
|
||||
\ccInclude{CGAL/NewKernel_d/KernelD_converter.h}
|
||||
|
||||
\ccDefinition
|
||||
A function object that converts objects from kernel \ccc{K1} to kernel \ccc{K2}. By default, it uses identity on \ccc{int}, \ccc{Origin} and \ccc{Null_vector}. It uses \ccc{NT_converter} for \ccc{RT} and \ccc{FT}. It uses \ccc{K1::Functor<Convert_ttag<Tag>::type} for \ccc{K1::Type<Tag>::type} (the list of possible \ccc{Tag} is taken from \ccc{List}). It can recursively convert iterators and \ccc{std::vector} of objects it already knows how to convert. It also unwraps a \ccc{CGAL::Object}, converts the content and rewraps it.
|
||||
|
||||
\ccCreation
|
||||
\ccConstructor{KernelD_converter(K1 const&,K2 const&)}{main constructor}
|
||||
\ccConstructor{KernelD_converter()}{default constructor, only if \ccc{K1} and \ccc{K2} are stateless.}
|
||||
|
||||
\ccOperations
|
||||
\ccMethod{K2::SomeThing operator()(K1::SomeThing) const;}{returns a converted object.}
|
||||
|
||||
\end{ccRefFunctionObjectClass}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
\begin{ccRefClass}{Kernel_2_interface<Base>}
|
||||
\ccInclude{CGAL/NewKernel_d/Kernel_2_interface.h}
|
||||
|
||||
\ccDefinition
|
||||
This class derives from a \ccc{Kernel} \ccc{Base} and defines a number
|
||||
of typedefs and functions to give it an interface close to that of the
|
||||
classical \ccc{Kernel_23}, restricted to 2D. As an example, it contains:
|
||||
|
||||
\ccc{typedef Type<Point_tag>::type Point_2}\\
|
||||
\ccc{struct Less_x_2}\\
|
||||
\ccc{Less_x_2 less_x_2_object()const}
|
||||
|
||||
Assuming that \ccc{Base} provides everything required, this provides
|
||||
an interface suitable for the \ccc{Triangulation_2} package.
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
\begin{ccRefClass}{Kernel_3_interface<Base>}
|
||||
\ccInclude{CGAL/NewKernel_d/Kernel_3_interface.h}
|
||||
|
||||
\ccDefinition
|
||||
This class derives from a \ccc{Kernel} \ccc{Base} and defines a number
|
||||
of typedefs and functions to give it an interface close to that of the
|
||||
classical \ccc{Kernel_23}, restricted to 3D. As an example, it contains:
|
||||
|
||||
\ccc{typedef Type<Point_tag>::type Point_3}\\
|
||||
\ccc{struct Side_of_oriented_sphere_3}\\
|
||||
\ccc{Side_of_oriented_sphere_3 side_of_oriented_sphere_3_object()const}
|
||||
|
||||
Assuming that \ccc{Base} provides everything required, this provides
|
||||
an interface suitable for the \ccc{Triangulation_2} package.
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
\begin{ccRefClass}{Kernel_d_interface<Base>}
|
||||
\ccInclude{CGAL/NewKernel_d/Kernel_d_interface.h}
|
||||
|
||||
\ccDefinition
|
||||
This class derives from a \ccc{Kernel} \ccc{Base} and defines a number
|
||||
of typedefs and functions to give it an interface close to that of the
|
||||
classical \ccc{Kernel_d}. As an example, it contains:
|
||||
|
||||
\ccc{typedef Type<Point_tag>::type Point_d}\\
|
||||
\ccc{typedef Functor<Compare_lexicographically_tag>::type Compare_lexicographically_d}\\
|
||||
\ccc{Compare_lexicographically_d compare_lexicographically_d_object()const{ return Compare_lexicographically_d(*this); }}
|
||||
|
||||
Assuming that \ccc{Base} provides everything required, this provides
|
||||
an interface suitable for the \ccc{Triangulation} package.
|
||||
|
||||
\ccIsModel
|
||||
\ccRefConceptPage{Triangulation_traits}
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
\begin{ccRefConcept}[Kernel::]{Functor<Tag,Option=Default>}
|
||||
Functors have a constructor that takes a \ccc{Kernel} as argument. If the kernel is stateless (as tested with \ccc{boost::is_empty<Kernel>}), functors may (must???) also have a default constructor. Functors follow the \ccc{result_of}-protocol.
|
||||
|
||||
Member functions provided by each functor are described in their concept. Some special cases are:
|
||||
\begin{itemize}
|
||||
\item A constructor is a functor represented by a tag \ccc{Construct_ttag<Some_tag>}. It contains member functions \ccc{Kernel::Type<Some_tag>::type operator()(Args...) const}.
|
||||
\item A converter is a functor represented by a tag \ccc{Convert_ttag<Some_tag>}. It contains a member function \ccc{template <class K2, class Converter> K2::Type<Some_tag>::type operator()(K2 const&, Converter, Kernel::Type<Some_tag>::type) const}. As an example, a segment converter could first extract its extremities with \ccc{Kernel::Functor<Construct_segment_extremity_tag>}, then convert them to \ccc{K2::Type<Point_tag>} using \ccc{Converter} and finally build a \ccc{K2::Type<Segment_tag>} with \ccc{K2::Functor<Construct_segment_tag>}.
|
||||
%TODO: clarify this Converter business
|
||||
\end{itemize}
|
||||
|
||||
\ccc{Option} is used to specify a specific version of the functor. For instance, for a predicate, you might ask for a fast inexact version with \ccc{Fast_tag}.
|
||||
|
||||
For each functor tag \ccc{Tag}, \ccc{map_functor_type<Tag>::type} shall be
|
||||
\ccc{Predicate_tag}, \ccc{Construct_tag}, \ccc{Compute_tag} or \ccc{Misc_tag}
|
||||
depending on the kind of functor it is. Predicates output a discrete value, for instance \ccc{Kernel::Boolean}. Computations output a number of type \ccc{Kernel::FT} or \ccc{Kernel::RT}. Constructions output an object of type \ccc{Kernel::Type<map_result_tag<Tag>::type>::type} where \ccc{map_result_tag} is specialized to specify the tag of the result. All others are miscellaneous.
|
||||
|
||||
|
||||
\end{ccRefConcept}
|
||||
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
\begin{ccRefClass}{Lazy_kernel<EK,AK,E2A=KernelD_converter<EK,AK>>}
|
||||
\ccInclude{CGAL/NewKernel_d/Lazy_kernel.h}
|
||||
|
||||
\ccDefinition
|
||||
A model for \ccc{Kernel}.
|
||||
\ccc{AK} is an approximate kernel (with an interval number type) and \ccc{EK}
|
||||
is an exact kernel.
|
||||
|
||||
\ccIsModel
|
||||
\ccRefConceptPage{Kernel}
|
||||
|
||||
\ccImplementation
|
||||
For each object, this kernel stores both an approximate object from
|
||||
\ccc{AK} and either an exact object from \ccc{EK} or a graph that
|
||||
allows it to compute such an exact object when needed.
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
\begin{ccPkgDescription}{dD Kernel}
|
||||
\ccPkgSummary{
|
||||
A new d-dimensional kernel.
|
||||
}
|
||||
\ccPkgIntroducedInCGAL{42.0}
|
||||
\ccPkgLicense{\ccLicenseLGPL}
|
||||
\end{ccPkgDescription}
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
\begin{ccRefConcept}{Point}
|
||||
The concept of a {\em Point} is defined by a set of requirements on
|
||||
the provision of certain types in a \ccc{Kernel}.
|
||||
|
||||
\ccRefines
|
||||
\ccc{Kernel}
|
||||
|
||||
\ccNestedType{Object_list}{shall contain at least \ccc{Point_tag} and \ccc{Point_cartesian_const_iterator_tag}.}
|
||||
|
||||
\ccNestedType{Type<Point_tag>::type}{shall be CopyConstructible.}
|
||||
\ccNestedType{Type<Point_cartesian_const_iterator_tag>::type}{shall be a forward iterator (except that it may return an rvalue) whose \ccc{value_type} is \ccc{Kernel::Type<Point_tag>::type}.}
|
||||
|
||||
\ccNestedType{Functor<Convert_ttag<Point_tag>>::type}{[Optional] A default converter it available to \ccc{Kernel_converter}, but may be unsuitable if your Point type is too original.}
|
||||
\ccNestedType{Functor<Construct_ttag<Point_cartesian_const_iterator_tag>>::type}{shall provide \ccc{Type<Point_cartesian_const_iterator_tag>::type operator()(Type<Point_tag>::type const&, Extremity_tag)const} where \ccc{Extemity_tag} is \ccc{Begin_tag} or \ccc{End_tag}.}
|
||||
\ccNestedType{Functor<Compute_cartesian_coordinate_tag>::type}{shall provide \ccc{FT operator()(Type<Point_tag>::type,int k)const} which returns the $k$th Cartesian coordinate of the point.}
|
||||
\ccNestedType{Functor<Point_dimension_tag>::type}{shall provide \ccc{int operator()(Type<Point_tag>::type)const} which returns the dimension of a point.}
|
||||
\ccNestedType{Functor<Construct_ttag<Point_tag>>::type}{shall provide:\\
|
||||
\ccc{Type<Point_tag>::type operator()(int dim)const} which constructs a point at the origin;\\
|
||||
\ccc{Type<Point_tag>::type operator()()const} the same, when \ccc{Default_ambient_dimension} is known;\\
|
||||
\ccc{Type<Point_tag>::type operator()(Type<Point_tag>::type)const} which copies (???);\\
|
||||
\ccc{Type<Point_tag>::type operator()(Iter, Iter, Cartesian_tag)const} which reads the Cartesian coordinates from the iterators;\\
|
||||
\ccc{Type<Point_tag>::type operator()(Iter, Iter)const} same as above;\\
|
||||
\ccc{Type<Point_tag>::type operator()(FT...)const} which reads the Cartesian coordinates from the arguments, when \ccc{Default_ambient_dimension} is known.
|
||||
}
|
||||
|
||||
\end{ccRefConcept}
|
||||
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
% +------------------------------------------------------------------------+
|
||||
% | Reference manual page: PreKernel.tex
|
||||
% +------------------------------------------------------------------------+
|
||||
% | 21.05.2012 Marc Glisse
|
||||
% | Package: NewKernel_d
|
||||
% |
|
||||
\RCSdef{\RCSPreKernelRev}{$Id$}
|
||||
\RCSdefDate{\RCSPreKernelDate}{$Date$}
|
||||
% |
|
||||
\ccRefPageBegin
|
||||
%%RefPage: end of header, begin of main body
|
||||
% +------------------------------------------------------------------------+
|
||||
|
||||
|
||||
\begin{ccRefConcept}{PreKernel}
|
||||
|
||||
%% \ccHtmlCrossLink{} %% add further rules for cross referencing links
|
||||
%% \ccHtmlIndexC[concept]{} %% add further index entries
|
||||
|
||||
\ccDefinition
|
||||
|
||||
%copied from Kernel_23
|
||||
The concept of a {\em prekernel} is defined by a set of requirements on
|
||||
the provision of certain types and access member functions to create
|
||||
objects of these types. The types are function object classes to be used
|
||||
within the algorithms and data structures of \cgal. This allows you to
|
||||
use any model of a kernel as a traits class in the Cgal algorithms and
|
||||
data structures, unless they require types beyond those provided by a
|
||||
kernel.
|
||||
|
||||
A kernel provides types, construction objects, and generalized
|
||||
predicates. The former replace constructors of the kernel classes and
|
||||
constructive procedures in the kernel. There are also function objects
|
||||
replacing operators, especially for equality testing.
|
||||
|
||||
Types and functors are identified by tags, which may be any type (like
|
||||
\ccc{CGAL::Segment_tag}). As a special case, the construction functor of
|
||||
a type identified by \ccc{Some_tag} is identified by the tag
|
||||
\ccc{Construct_ttag<Some_tag>}, and the conversion functor by
|
||||
\ccc{Convert_ttag<Some_tag>}.
|
||||
|
||||
Depending on \ccc{Default_ambient_dimension}, a kernel has 2
|
||||
constructors, a default constructor and a constructor that takes as
|
||||
argument an \ccc{int} for the dimension.
|
||||
|
||||
|
||||
%\ccGeneralizes
|
||||
%
|
||||
%ThisConcept \\
|
||||
%ThatConcept
|
||||
|
||||
\ccTypes
|
||||
|
||||
\ccNestedType{Default_ambient_dimension}{\ccc{Dimension_tag<d>} where \ccc{d} is the ambient dimension or \ccc{Dynamic_dimension_tag} if the dimension is unknown.}
|
||||
\ccGlue
|
||||
\ccNestedType{Max_ambient_dimension}{\ccc{Dimension_tag<d>} where \ccc{d} is an upper bound on the ambient dimension or \ccc{Dynamic_dimension_tag}.}
|
||||
|
||||
\ccNestedType{FT}{a model of \ccc{FieldNumberType}}
|
||||
\ccGlue
|
||||
\ccNestedType{RT}{a model of \ccc{RingNumberType}}
|
||||
|
||||
% Not documented in the first version
|
||||
\ccNestedType{LA}{a model of \ccc{LinearAlgebraSomething} using \ccc{RT}}
|
||||
|
||||
The following types describe the return types of predicates. They typically
|
||||
map to \ccc{bool} and \cgal\ kernel enum types, except when an interval arithmetic
|
||||
number type is used such as within the filtering kernels, in which case it is
|
||||
\ccc{Uncertain<bool>} or similar.
|
||||
|
||||
\ccNestedType{Boolean}{\ccc{bool} or \ccc{Uncertain<bool>}}
|
||||
\ccGlue
|
||||
\ccNestedType{Sign}{\ccc{CGAL::Sign} or \ccc{Uncertain<CGAL::Sign>}}
|
||||
\ccGlue
|
||||
\ccNestedType{Comparison_result}{\ccc{CGAL::Comparison_result} or \ccc{Uncertain<CGAL::Comparison_result>}}
|
||||
\ccGlue
|
||||
\ccNestedType{Orientation}{\ccc{CGAL::Orientation} or \ccc{Uncertain<CGAL::Orientation>}}
|
||||
\ccGlue
|
||||
\ccNestedType{Oriented_side}{\ccc{CGAL::Oriented_side} or \ccc{Uncertain<CGAL::Oriented_side>}}
|
||||
\ccGlue
|
||||
\ccNestedType{Bounded_side}{\ccc{CGAL::Bounded_side} or \ccc{Uncertain<CGAL::Bounded_side>}}
|
||||
\ccGlue
|
||||
\ccNestedType{Angle}{\ccc{CGAL::Angle} or \ccc{Uncertain<CGAL::Angle>}}
|
||||
|
||||
\ccHeading{Geometric Objects}
|
||||
|
||||
%\ccNestedType{template <class Tag> struct Type<Tag>}{This nested template class defines an object type \ccc{type}. For instance, \ccc{Type<Point_tag>::type} is the type of points.}
|
||||
\ccNestedType{Point, \ldots}{Geometric object type}
|
||||
|
||||
\ccNestedType{Object_list}{A typedef for \ccc{typeset<Point_tag,...>}
|
||||
with the list of tags corresponding to the provided geometric object
|
||||
types.}
|
||||
|
||||
\ccHeading{Iterators}
|
||||
|
||||
\ccNestedType{Point_cartesian_const_iterator, \ldots}{Iterator}
|
||||
|
||||
\ccNestedType{Iterator_list}{A typedef for
|
||||
\ccc{typeset<Point_cartesian_const_iterator_tag,...>} with the list of
|
||||
tags corresponding to the provided iterators.}
|
||||
|
||||
|
||||
\ccHeading{Function objects}
|
||||
|
||||
\ccNestedType{template <class Tag, class Option> struct Functor<Tag,Option=Default>}{This nested template class defines a functor type \ccc{type}. For instance, \ccc{Functor<Orientation_tag>::type} is the orientation predicate. Functors that are not provided should all be \ccc{Null_functor}.}
|
||||
|
||||
|
||||
\ccCreation
|
||||
\ccCreationVariable{kernel} %% choose variable name
|
||||
|
||||
\ccConstructor{PreKernel();}{default constructor.}
|
||||
\ccConstructor{PreKernel(int d);}{constructor for dimension $d$.}
|
||||
|
||||
\ccOperations
|
||||
|
||||
\ccMethod{int dimension();}{returns the dimension (or UNKNOWN\_DIMENSION)}
|
||||
|
||||
\ccHasModels
|
||||
|
||||
\ccc{Some_class},
|
||||
\ccc{Some_other_class}.
|
||||
|
||||
\ccSeeAlso
|
||||
|
||||
Kernel\_d
|
||||
%Some\_other\_concept,
|
||||
%%\ccc{some_other_function}.
|
||||
|
||||
%\ccExample
|
||||
%
|
||||
%A short example program.
|
||||
%Instead of a short program fragment, a full running program can be
|
||||
%included using the
|
||||
%\verb|\ccIncludeExampleCode{Package/PreKernel.C}|
|
||||
%macro. The program example would be part of the source code distribution and
|
||||
%also part of the automatic test suite.
|
||||
%
|
||||
%\begin{ccExampleCode}
|
||||
%void your_example_code() {
|
||||
%}
|
||||
%\end{ccExampleCode}
|
||||
|
||||
%% \ccIncludeExampleCode{Package/PreKernel.C}
|
||||
|
||||
\end{ccRefConcept}
|
||||
|
||||
% +------------------------------------------------------------------------+
|
||||
%%RefPage: end of main body, begin of footer
|
||||
\ccRefPageEnd
|
||||
% EOF
|
||||
% +------------------------------------------------------------------------+
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
\begin{ccRefConcept}{Segment}
|
||||
The concept of a {\em Segment} is defined by a set of requirements on
|
||||
the provision of certain types in a \ccc{Kernel} that already provides
|
||||
the concept of a \ccc{Point}.
|
||||
|
||||
\ccRefines
|
||||
\ccc{Point}
|
||||
|
||||
\ccNestedType{Object_list}{shall contain at least \ccc{Segment_tag}.}
|
||||
|
||||
\ccNestedType{Type<Segment_tag>::type}{shall be CopyConstructible.}
|
||||
|
||||
\ccNestedType{Functor<Convert_ttag<Segment_tag>>::type}{[Optional] A default converter it available to \ccc{Kernel_converter}, but may be unsuitable if your Segment type is too original.}
|
||||
\ccNestedType{Functor<Construct_segment_extremity_tag>::type}{shall
|
||||
provide \ccc{Type<Point_tag>::type operator()(Type<Segment_tag>::type,
|
||||
int k)const} which returns the $k$th ($0$ or $1$) extremity of the segment.}
|
||||
\ccNestedType{Functor<Construct_ttag<Segment_tag>>::type}{shall provide:\\
|
||||
\ccc{Type<Segment_tag>::type
|
||||
operator()(Type<Point_tag>::type,Type<Point_tag>::type)const} which
|
||||
constructs a segment from its extremities;\\
|
||||
\ccc{Type<Segment_tag>::type operator()(piecewise_construct_t,
|
||||
tuple<U...> u, tuple<V...> v)const} which calls
|
||||
\ccc{Functor<Construct_ttag<Point_tag>>::type} on the content of each
|
||||
tuple to create the extremities.
|
||||
}
|
||||
|
||||
\end{ccRefConcept}
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
% +------------------------------------------------------------------------+
|
||||
% | CBP Reference Manual: main.tex
|
||||
% +------------------------------------------------------------------------+
|
||||
% | Automatically generated driver file for the reference manual chapter
|
||||
% | of this package. Do not edit manually, you may loose your changes.
|
||||
% +------------------------------------------------------------------------+
|
||||
|
||||
\input{NewKernel_d_ref/Cartesian_complete.tex}
|
||||
\input{NewKernel_d_ref/Cartesian_filter_K.tex}
|
||||
\input{NewKernel_d_ref/Cartesian_mini_d.tex}
|
||||
\input{NewKernel_d_ref/Cartesian_wrap.tex}
|
||||
\input{NewKernel_d_ref/Define_segment.tex}
|
||||
\input{NewKernel_d_ref/KernelD_converter.tex}
|
||||
\input{NewKernel_d_ref/Kernel_2_interface.tex}
|
||||
\input{NewKernel_d_ref/Kernel_3_interface.tex}
|
||||
\input{NewKernel_d_ref/Kernel_d_interface.tex}
|
||||
\input{NewKernel_d_ref/Kernel_functor.tex}
|
||||
\input{NewKernel_d_ref/Lazy_kernel.tex}
|
||||
\input{NewKernel_d_ref/PkgDescription.tex}
|
||||
\input{NewKernel_d_ref/Point.tex}
|
||||
\input{NewKernel_d_ref/PreKernel.tex}
|
||||
\input{NewKernel_d_ref/Segment.tex}
|
||||
\input{NewKernel_d_ref/typeset.tex}
|
||||
|
||||
%% EOF
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
\begin{ccRefClass}{typeset<...>}
|
||||
\ccInclude{CGAL/typeset.h}
|
||||
|
||||
\ccDefinition
|
||||
This class provides a set of types, where each type appears at most once. Iterating through the set should be done by looking at \ccc{head} and recursing on \ccc{tail}, testing whether a set is empty by comparing it to \ccc{typeset<>}.
|
||||
|
||||
\ccNestedType{head}{One element from the list.}
|
||||
\ccNestedType{tail}{A typeset of the other elements from list.}
|
||||
\ccNestedType{add<X>::type}{A typeset with \ccc{X} added to the list.}
|
||||
\ccNestedType{contains<X>::value}{A boolean that says whether \ccc{X} is in the list.}
|
||||
|
||||
In C++11, \ccc{add<X>} is already a typeset so one can omit \ccc{::type}, and \ccc{contains<X>} derives from \ccc{true_type} or \ccc{false_type}.
|
||||
|
||||
\ccImplementation
|
||||
In C++11, the list looks like \ccc{typeset<type1,type2,type3>} whereas in C++03 it looks like \ccc{typeset<type1,typeset<type2,typeset<type3,typeset<> > > >} (an alternative would have been \ccc{typeset<type1,type2,type3,void,void,void,void>}, as in \ccc{boost::tuple}).
|
||||
|
||||
\end{ccRefClass}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef CGAL_EPICK_D_H
|
||||
#define CGAL_EPICK_D_H
|
||||
#include <CGAL/Kernel_d/Cartesian_base.h>
|
||||
#include <CGAL/Kernel_d/Cartesian_static_filters.h>
|
||||
#include <CGAL/Kernel_d/Cartesian_filter_K.h>
|
||||
#include <CGAL/Kernel_d/Wrapper/Cartesian_wrap.h>
|
||||
#include <CGAL/Kernel_d/Kernel_d_interface.h>
|
||||
#include <CGAL/Gmpq.h>
|
||||
#include <CGAL/Interval_nt.h>
|
||||
|
||||
|
||||
namespace CGAL {
|
||||
#define CGAL_BASE \
|
||||
Cartesian_filter_K< \
|
||||
Cartesian_base_d<double, Dim>, \
|
||||
Cartesian_base_d<Interval_nt_advanced, Dim>, \
|
||||
Cartesian_base_d<Gmpq, Dim> \
|
||||
>
|
||||
template<class Dim>
|
||||
struct Epick_d_help1
|
||||
: CGAL_BASE
|
||||
{
|
||||
CGAL_CONSTEXPR Epick_d_help1(){}
|
||||
CGAL_CONSTEXPR Epick_d_help1(int d):CGAL_BASE(d){}
|
||||
};
|
||||
#undef CGAL_BASE
|
||||
#define CGAL_BASE \
|
||||
Cartesian_static_filters<Dim,Epick_d_help1<Dim>,Epick_d_help2<Dim> >
|
||||
template<class Dim>
|
||||
struct Epick_d_help2
|
||||
: CGAL_BASE
|
||||
{
|
||||
CGAL_CONSTEXPR Epick_d_help2(){}
|
||||
CGAL_CONSTEXPR Epick_d_help2(int d):CGAL_BASE(d){}
|
||||
};
|
||||
#undef CGAL_BASE
|
||||
#define CGAL_BASE \
|
||||
Kernel_d_interface< \
|
||||
Cartesian_wrap< \
|
||||
Epick_d_help2<Dim>, \
|
||||
Epick_d<Dim> > >
|
||||
template<class Dim>
|
||||
struct Epick_d
|
||||
: CGAL_BASE
|
||||
{
|
||||
CGAL_CONSTEXPR Epick_d(){}
|
||||
CGAL_CONSTEXPR Epick_d(int d):CGAL_BASE(d){}
|
||||
};
|
||||
#undef CGAL_BASE
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
// Copyright (c) 2001-2005 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; version 2.1 of the License.
|
||||
// See the file LICENSE.LGPL distributed with CGAL.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
//
|
||||
//
|
||||
// Author(s) : Sylvain Pion
|
||||
|
||||
#ifndef CGAL_FILTERED_PREDICATE_H
|
||||
#define CGAL_FILTERED_PREDICATE_H
|
||||
|
||||
#include <string>
|
||||
#include <CGAL/config.h>
|
||||
#include <CGAL/Interval_nt.h>
|
||||
#include <CGAL/Uncertain.h>
|
||||
#include <CGAL/Profile_counter.h>
|
||||
#include <CGAL/store_kernel.h>
|
||||
#include <boost/preprocessor.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
// This template class is a wrapper that implements the filtering for any
|
||||
// predicate (dynamic filters with IA).
|
||||
|
||||
// TODO :
|
||||
// - each predicate in the default kernel should define a tag that says if it
|
||||
// wants to be filtered or not (=> all homogeneous predicate define this
|
||||
// tag). We could even test-suite that automatically. It makes a strong
|
||||
// new requirement on the kernel though...
|
||||
// Could be done with a traits mechanism ?
|
||||
// A default template could use the current IA, but other tags or whatever
|
||||
// could specify no filtering at all, or static filtering...
|
||||
// - same thing for constructions => virtual operator() ?
|
||||
// - similarly, constructions should have a tag saying if they can throw or
|
||||
// not, or we let all this up to the compiler optimizer to figure out ?
|
||||
// - Some caching could be done at the Point_2 level.
|
||||
|
||||
|
||||
template <class EP, class AP, class C2E, class C2A, bool Protection = true>
|
||||
class Filtered_predicate2
|
||||
{
|
||||
//TODO: pack (at least use a tuple)
|
||||
//FIXME: is it better to store those, or just store enough to recreate them
|
||||
//(i.e. possibly references to the kernels)?
|
||||
EP ep;
|
||||
AP ap;
|
||||
C2E c2e;
|
||||
C2A c2a;
|
||||
|
||||
typedef typename AP::result_type Ares;
|
||||
|
||||
public:
|
||||
|
||||
typedef AP Approximate_predicate;
|
||||
typedef EP Exact_predicate;
|
||||
typedef C2E To_exact_converter;
|
||||
typedef C2A To_approximate_converter;
|
||||
|
||||
// FIXME: should use result_of, see emails by Nico
|
||||
typedef typename EP::result_type result_type;
|
||||
// AP::result_type must be convertible to EP::result_type.
|
||||
|
||||
Filtered_predicate2()
|
||||
{}
|
||||
|
||||
template <class K>
|
||||
Filtered_predicate2(const K& k)
|
||||
: ep(k.exact_kernel()), ap(k.approximate_kernel()), c2e(k,k.exact_kernel()), c2a(k,k.approximate_kernel())
|
||||
{}
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
template <typename... Args>
|
||||
result_type
|
||||
operator()(Args&&... args) const
|
||||
{
|
||||
CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp);
|
||||
// Protection is outside the try block as VC8 has the CGAL_CFG_FPU_ROUNDING_MODE_UNWINDING_VC_BUG
|
||||
{
|
||||
Protect_FPU_rounding<Protection> p;
|
||||
try
|
||||
{
|
||||
// No forward here, the arguments may still be needed
|
||||
Ares res = ap(c2a(args)...);
|
||||
if (is_certain(res))
|
||||
return get_certain(res);
|
||||
}
|
||||
catch (Uncertain_conversion_exception) {}
|
||||
}
|
||||
CGAL_BRANCH_PROFILER_BRANCH(tmp);
|
||||
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST);
|
||||
return ep(c2e(std::forward<Args>(args))...);
|
||||
}
|
||||
#else
|
||||
|
||||
#define VAR(Z,N,C) C(a##N)
|
||||
#define CODE(Z,N,_) \
|
||||
template <BOOST_PP_ENUM_PARAMS(N,class A)> \
|
||||
result_type \
|
||||
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a)) const \
|
||||
{ \
|
||||
CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); \
|
||||
{ \
|
||||
Protect_FPU_rounding<Protection> p; \
|
||||
try \
|
||||
{ \
|
||||
Ares res = ap(BOOST_PP_ENUM(N,VAR,c2a)); \
|
||||
if (is_certain(res)) \
|
||||
return get_certain(res); \
|
||||
} \
|
||||
catch (Uncertain_conversion_exception) {} \
|
||||
} \
|
||||
CGAL_BRANCH_PROFILER_BRANCH(tmp); \
|
||||
Protect_FPU_rounding<!Protection> p(CGAL_FE_TONEAREST); \
|
||||
return ep(BOOST_PP_ENUM(N,VAR,c2e)); \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1, 10, CODE, _ )
|
||||
#undef CODE
|
||||
#undef VAR
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_FILTERED_PREDICATE_H
|
||||
|
|
@ -0,0 +1,323 @@
|
|||
// Copyright (c) 1999,2001,2003 Utrecht University (The Netherlands),
|
||||
// ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany),
|
||||
// INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
|
||||
// (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria),
|
||||
// and Tel-Aviv University (Israel). All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public License as
|
||||
// published by the Free Software Foundation; version 2.1 of the License.
|
||||
// See the file LICENSE.LGPL distributed with CGAL.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
//
|
||||
//
|
||||
// Author(s) : Stefan Schirra, Sylvain Pion
|
||||
|
||||
#ifndef CGAL_HANDLE_FOR_H
|
||||
#define CGAL_HANDLE_FOR_H
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <CGAL/memory.h>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <CGAL/marcutils.h>
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4345) // Avoid warning http://msdn.microsoft.com/en-us/library/wewb47ee(VS.80).aspx
|
||||
#endif
|
||||
namespace CGAL {
|
||||
|
||||
template <class T, class Alloc = CGAL_ALLOCATOR(T) >
|
||||
class Handle_for
|
||||
{
|
||||
// Wrapper that adds the reference counter.
|
||||
struct RefCounted {
|
||||
T t;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
typedef typename Alloc::template rebind<RefCounted>::other Allocator;
|
||||
typedef typename Allocator::pointer pointer_;
|
||||
|
||||
static Allocator allocator;
|
||||
pointer_ ptr_;
|
||||
|
||||
public:
|
||||
|
||||
typedef T element_type;
|
||||
|
||||
typedef std::ptrdiff_t Id_type ;
|
||||
|
||||
Handle_for()
|
||||
: ptr_(allocator.allocate(1))
|
||||
{
|
||||
new (&(ptr_->t)) element_type(); // we get the warning here
|
||||
ptr_->count = 1;
|
||||
}
|
||||
|
||||
Handle_for(const element_type& t)
|
||||
: ptr_(allocator.allocate(1))
|
||||
{
|
||||
new (&(ptr_->t)) element_type(t);
|
||||
ptr_->count = 1;
|
||||
}
|
||||
|
||||
#ifndef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE
|
||||
Handle_for(element_type && t)
|
||||
: ptr_(allocator.allocate(1))
|
||||
{
|
||||
new (&(ptr_->t)) element_type(std::move(t));
|
||||
ptr_->count = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* I comment this one for now, since it's preventing the automatic conversions
|
||||
to take place. We'll see if it's a problem later.
|
||||
template < typename T1 >
|
||||
Handle_for(const T1& t1)
|
||||
: ptr_(allocator.allocate(1))
|
||||
{
|
||||
new (&(ptr_->t)) T(t1);
|
||||
ptr_->count = 1;
|
||||
}
|
||||
*/
|
||||
|
||||
#if !defined CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES && !defined CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE
|
||||
template < typename T1, typename T2, typename... Args >
|
||||
Handle_for(T1 && t1, T2 && t2, Args && ... args)
|
||||
: ptr_(allocator.allocate(1))
|
||||
{
|
||||
new (&(ptr_->t)) element_type(std::forward<T1>(t1), std::forward<T2>(t2), std::forward<Args>(args)...);
|
||||
ptr_->count = 1;
|
||||
}
|
||||
|
||||
template < typename F, typename... Args >
|
||||
Handle_for(Eval_functor &&, F && f, Args && ... args)
|
||||
: ptr_(allocator.allocate(1))
|
||||
{
|
||||
new (&(ptr_->t)) element_type(std::forward<F>(f)(std::forward<Args>(args)...));
|
||||
ptr_->count = 1;
|
||||
}
|
||||
#else
|
||||
#define CODE(Z,N,_) template <BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
Handle_for(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: ptr_(allocator.allocate(1)) \
|
||||
{ \
|
||||
new (&(ptr_->t)) element_type(BOOST_PP_ENUM_PARAMS(N,t)); \
|
||||
ptr_->count = 1; \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(2,11,CODE,_)
|
||||
#undef CODE
|
||||
#define CODE(Z,N,_) template <class F,BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
Handle_for(Eval_functor,F const&f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: ptr_(allocator.allocate(1)) \
|
||||
{ \
|
||||
new (&(ptr_->t)) element_type(f(BOOST_PP_ENUM_PARAMS(N,t))); \
|
||||
ptr_->count = 1; \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_)
|
||||
#undef CODE
|
||||
template <class F>
|
||||
Handle_for(Eval_functor,F const&f)
|
||||
: ptr_(allocator.allocate(1))
|
||||
{
|
||||
new (&(ptr_->t)) element_type(f());
|
||||
ptr_->count = 1;
|
||||
}
|
||||
#endif // CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES
|
||||
|
||||
Handle_for(const Handle_for& h)
|
||||
: ptr_(h.ptr_)
|
||||
{
|
||||
++(ptr_->count);
|
||||
}
|
||||
|
||||
Handle_for&
|
||||
operator=(const Handle_for& h)
|
||||
{
|
||||
Handle_for tmp = h;
|
||||
swap(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Handle_for&
|
||||
operator=(const element_type &t)
|
||||
{
|
||||
if (is_shared())
|
||||
*this = Handle_for(t);
|
||||
else
|
||||
ptr_->t = t;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE
|
||||
// Note : I don't see a way to make a useful move constructor, apart
|
||||
// from e.g. using NULL as a ptr value, but this is drastic.
|
||||
|
||||
Handle_for&
|
||||
operator=(Handle_for && h)
|
||||
{
|
||||
swap(h);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Handle_for&
|
||||
operator=(element_type && t)
|
||||
{
|
||||
if (is_shared())
|
||||
*this = Handle_for(std::move(t));
|
||||
else
|
||||
ptr_->t = std::move(t);
|
||||
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
~Handle_for()
|
||||
{
|
||||
if (! is_shared() ) {
|
||||
allocator.destroy( ptr_);
|
||||
allocator.deallocate( ptr_, 1);
|
||||
}
|
||||
else
|
||||
--(ptr_->count);
|
||||
}
|
||||
|
||||
void
|
||||
initialize_with(const element_type& t)
|
||||
{
|
||||
// kept for backward compatibility. Use operator=(t) instead.
|
||||
*this = t;
|
||||
}
|
||||
|
||||
Id_type id() const { return Ptr() - static_cast<T const*>(0); }
|
||||
|
||||
bool identical(const Handle_for& h) const { return Ptr() == h.Ptr(); }
|
||||
|
||||
|
||||
// Ptr() is the "public" access to the pointer to the object.
|
||||
// The non-const version asserts that the instance is not shared.
|
||||
const element_type *
|
||||
Ptr() const
|
||||
{
|
||||
return &(ptr_->t);
|
||||
}
|
||||
|
||||
/*
|
||||
// The assertion triggers in a couple of places, so I comment it for now.
|
||||
T *
|
||||
Ptr()
|
||||
{
|
||||
CGAL_assertion(!is_shared());
|
||||
return &(ptr_->t);
|
||||
}
|
||||
*/
|
||||
|
||||
bool
|
||||
is_shared() const
|
||||
{
|
||||
return ptr_->count > 1;
|
||||
}
|
||||
|
||||
bool
|
||||
unique() const
|
||||
{
|
||||
return !is_shared();
|
||||
}
|
||||
|
||||
long
|
||||
use_count() const
|
||||
{
|
||||
return ptr_->count;
|
||||
}
|
||||
|
||||
void
|
||||
swap(Handle_for& h)
|
||||
{
|
||||
std::swap(ptr_, h.ptr_);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void
|
||||
copy_on_write()
|
||||
{
|
||||
if ( is_shared() )
|
||||
{
|
||||
pointer_ tmp_ptr = allocator.allocate(1);
|
||||
new (&(tmp_ptr->t)) element_type(ptr_->t);
|
||||
tmp_ptr->count = 1;
|
||||
--(ptr_->count);
|
||||
ptr_ = tmp_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
// ptr() is the protected access to the pointer. Both const and non-const.
|
||||
// Redundant with Ptr().
|
||||
element_type *
|
||||
ptr()
|
||||
{ return &(ptr_->t); }
|
||||
|
||||
const element_type *
|
||||
ptr() const
|
||||
{ return &(ptr_->t); }
|
||||
};
|
||||
|
||||
|
||||
template <class T, class Allocator>
|
||||
typename Handle_for<T, Allocator>::Allocator
|
||||
Handle_for<T, Allocator>::allocator;
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline
|
||||
void
|
||||
swap(Handle_for<T, Allocator> &h1, Handle_for<T, Allocator> &h2)
|
||||
{
|
||||
h1.swap(h2);
|
||||
}
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline
|
||||
bool
|
||||
identical(const Handle_for<T, Allocator> &h1,
|
||||
const Handle_for<T, Allocator> &h2)
|
||||
{
|
||||
return h1.identical(h2);
|
||||
}
|
||||
|
||||
template <class T> inline bool identical(const T &t1, const T &t2) { return &t1 == &t2; }
|
||||
|
||||
template <class T, class Allocator>
|
||||
inline
|
||||
const T&
|
||||
get(const Handle_for<T, Allocator> &h)
|
||||
{
|
||||
return *(h.Ptr());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
const T&
|
||||
get(const T &t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // CGAL_HANDLE_FOR_H
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
#ifndef CGAL_KERNEL_D_CARTESIAN_LA_BASE_H
|
||||
#define CGAL_KERNEL_D_CARTESIAN_LA_BASE_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Origin.h>
|
||||
|
||||
#include <CGAL/representation_tags.h>
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Uncertain.h>
|
||||
#include <CGAL/typeset.h>
|
||||
#include <CGAL/Kernel_d/Dimension_base.h>
|
||||
#include <CGAL/Kernel_d/Cartesian_LA_functors.h>
|
||||
#include <CGAL/Vector/array.h>
|
||||
#ifdef CGAL_EIGEN3_ENABLED
|
||||
#include <CGAL/LA_eigen/LA.h>
|
||||
#else
|
||||
#include <CGAL/LA_default/LA.h>
|
||||
#endif
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template < typename FT_, typename Dim_,
|
||||
#if 0
|
||||
typename Vec_=Array_vector<FT_, Dim_>,
|
||||
#else
|
||||
typename Vec_=LA_eigen<FT_, Dim_>,
|
||||
#endif
|
||||
typename LA_=LA_eigen<FT_,Dim_> >
|
||||
/* Default LA to Vec or to LA_eigen? */
|
||||
struct Cartesian_LA_base_d : public Dimension_base<Dim_>
|
||||
{
|
||||
typedef Cartesian_LA_base_d<FT_,Dim_> Self;
|
||||
typedef Cartesian_tag Rep_tag;
|
||||
typedef Cartesian_tag Kernel_tag;
|
||||
typedef Dim_ Default_ambient_dimension;
|
||||
typedef Dim_ Max_ambient_dimension;
|
||||
typedef LA_ LA;
|
||||
|
||||
typedef Vec_ LA_vector;
|
||||
typedef typename LA_vector::Vector Point;
|
||||
typedef typename LA_vector::Vector Vector;
|
||||
typedef typename LA_vector::Vector Vector_;
|
||||
typedef typename LA_vector::Construct_vector Constructor;
|
||||
typedef typename LA_vector::Vector_const_iterator Point_cartesian_const_iterator;
|
||||
typedef typename LA_vector::Vector_const_iterator Vector_cartesian_const_iterator;
|
||||
|
||||
template<class, class=void> struct Type {};
|
||||
template<class D> struct Type< Point_tag, D> { typedef Vector_ type; };
|
||||
template<class D> struct Type<Vector_tag, D> { typedef Vector_ type; };
|
||||
template<class D> struct Type< FT_tag, D> { typedef FT_ type; };
|
||||
template<class D> struct Type< RT_tag, D> { typedef FT_ type; };
|
||||
|
||||
typedef typeset<Point_tag>
|
||||
::add<Vector_tag>::type
|
||||
// FIXME: Segment has nothing to do here.
|
||||
::add<Segment_tag>::type
|
||||
Object_list;
|
||||
|
||||
typedef typeset< Point_cartesian_const_iterator_tag>::type
|
||||
::add<Vector_cartesian_const_iterator_tag>::type
|
||||
Iterator_list;
|
||||
|
||||
template<class, class=void, bool=true> struct Functor {
|
||||
typedef Null_functor type;
|
||||
};
|
||||
template<class D> struct Functor<Construct_ttag<Vector_tag>,D> {
|
||||
typedef CartesianDVectorBase::Construct_LA_vector<Self,Null_vector> type;
|
||||
};
|
||||
template<class D> struct Functor<Construct_ttag<Point_tag>,D> {
|
||||
typedef CartesianDVectorBase::Construct_LA_vector<Self,Origin> type;
|
||||
};
|
||||
template<class D> struct Functor<Construct_ttag<Point_cartesian_const_iterator_tag>,D> {
|
||||
typedef CartesianDVectorBase::Construct_cartesian_const_iterator<Self> type;
|
||||
};
|
||||
template<class D> struct Functor<Construct_ttag<Vector_cartesian_const_iterator_tag>,D> {
|
||||
typedef CartesianDVectorBase::Construct_cartesian_const_iterator<Self> type;
|
||||
};
|
||||
template<class D> struct Functor<Sum_of_vectors_tag,D,
|
||||
LA_vector::template Property<Has_vector_plus_minus_tag>::value> {
|
||||
typedef CartesianDVectorBase::Sum_of_vectors<Self> type;
|
||||
};
|
||||
template<class D> struct Functor<Difference_of_vectors_tag,D,
|
||||
LA_vector::template Property<Has_vector_plus_minus_tag>::value> {
|
||||
typedef CartesianDVectorBase::Difference_of_vectors<Self> type;
|
||||
};
|
||||
template<class D> struct Functor<Opposite_vector_tag,D,
|
||||
LA_vector::template Property<Has_vector_plus_minus_tag>::value> {
|
||||
typedef CartesianDVectorBase::Opposite_vector<Self> type;
|
||||
};
|
||||
template<class D> struct Functor<Midpoint_tag,D,
|
||||
LA_vector::template Property<Has_vector_plus_minus_tag>::value &&
|
||||
LA_vector::template Property<Has_vector_scalar_ops_tag>::value> {
|
||||
typedef CartesianDVectorBase::Midpoint<Self> type;
|
||||
};
|
||||
template<class D> struct Functor<Compute_point_cartesian_coordinate_tag,D> {
|
||||
typedef CartesianDVectorBase::Compute_cartesian_coordinate<Self> type;
|
||||
};
|
||||
template<class D> struct Functor<Compute_vector_cartesian_coordinate_tag,D> {
|
||||
typedef CartesianDVectorBase::Compute_cartesian_coordinate<Self> type;
|
||||
};
|
||||
template<class D> struct Functor<Point_dimension_tag,D> {
|
||||
typedef CartesianDVectorBase::PV_dimension<Self> type;
|
||||
};
|
||||
template<class D> struct Functor<Vector_dimension_tag,D> {
|
||||
typedef CartesianDVectorBase::PV_dimension<Self> type;
|
||||
};
|
||||
template<class D> struct Functor<Orientation_of_vectors_tag,D,
|
||||
LA_vector::template Property<Has_determinant_of_iterator_to_vectors_tag>::value> {
|
||||
typedef CartesianDVectorBase::Orientation_of_vectors<Self> type;
|
||||
};
|
||||
template<class D> struct Functor<Orientation_of_points_tag,D,
|
||||
LA_vector::template Property<Has_determinant_of_iterator_to_points_tag>::value> {
|
||||
typedef CartesianDVectorBase::Orientation_of_points<Self> type;
|
||||
};
|
||||
template<class D> struct Functor<Scalar_product_tag,D,
|
||||
LA_vector::template Property<Has_dot_product_tag>::value> {
|
||||
typedef CartesianDVectorBase::Scalar_product<Self> type;
|
||||
};
|
||||
template<class D> struct Functor<Squared_distance_to_origin_tag,D,
|
||||
LA_vector::template Property<Stores_squared_norm_tag>::value> {
|
||||
typedef CartesianDVectorBase::Squared_distance_to_origin_stored<Self> type;
|
||||
};
|
||||
template<class D> struct Functor<Squared_distance_to_origin_tag,D,
|
||||
!LA_vector::template Property<Stores_squared_norm_tag>::value &&
|
||||
LA_vector::template Property<Has_dot_product_tag>::value> {
|
||||
typedef CartesianDVectorBase::Squared_distance_to_origin_via_dotprod<Self> type;
|
||||
};
|
||||
|
||||
CGAL_CONSTEXPR Cartesian_LA_base_d(){}
|
||||
CGAL_CONSTEXPR Cartesian_LA_base_d(int d):Dimension_base<Dim_>(d){}
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_KERNEL_D_CARTESIAN_LA_BASE_H
|
||||
|
|
@ -0,0 +1,313 @@
|
|||
#ifndef CGAL_CARTESIAN_LA_FUNCTORS_H
|
||||
#define CGAL_CARTESIAN_LA_FUNCTORS_H
|
||||
|
||||
#include <CGAL/marcutils.h>
|
||||
#include <CGAL/is_iterator.h>
|
||||
#include <CGAL/argument_swaps.h>
|
||||
#include <CGAL/Kernel/Return_base_tag.h>
|
||||
#include <CGAL/transforming_iterator.h>
|
||||
#include <CGAL/store_kernel.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace CartesianDVectorBase {
|
||||
#ifndef CGAL_CXX0X
|
||||
namespace internal {
|
||||
template<class R_,int dim_> struct Construct_LA_vector_ {
|
||||
struct Never_use {};
|
||||
void operator()(Never_use)const;
|
||||
};
|
||||
#define CODE(Z,N,_) template<class R> struct Construct_LA_vector_<R,N> { \
|
||||
typedef typename R::Constructor Constructor; \
|
||||
typedef typename Get_type<R, RT_tag>::type RT; \
|
||||
typedef typename R::Vector_ result_type; \
|
||||
result_type operator() \
|
||||
(BOOST_PP_ENUM_PARAMS(N,RT const& t)) const { \
|
||||
return typename Constructor::Values()(BOOST_PP_ENUM_PARAMS(N,t)); \
|
||||
} \
|
||||
result_type operator() \
|
||||
(BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(N),RT const& t)) const { \
|
||||
return typename Constructor::Values_divide()(t##N,BOOST_PP_ENUM_PARAMS(N,t)); \
|
||||
} \
|
||||
};
|
||||
BOOST_PP_REPEAT_FROM_TO(2, 11, CODE, _ )
|
||||
#undef CODE
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class R_,class Zero_> struct Construct_LA_vector
|
||||
: private Store_kernel<R_>
|
||||
#ifndef CGAL_CXX0X
|
||||
, public internal::Construct_LA_vector_<R_,R_::Default_ambient_dimension::value>
|
||||
#endif
|
||||
{
|
||||
//CGAL_FUNCTOR_INIT_IGNORE(Construct_LA_vector)
|
||||
CGAL_FUNCTOR_INIT_STORE(Construct_LA_vector)
|
||||
typedef R_ R;
|
||||
typedef typename R::Constructor Constructor;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename Get_type<R, FT_tag>::type FT;
|
||||
typedef typename R::Vector_ result_type;
|
||||
typedef typename R_::Default_ambient_dimension Dimension;
|
||||
static const int static_dim=Dimension::value;
|
||||
result_type operator()(int d)const{
|
||||
CGAL_assertion(check_dimension_eq(d,this->kernel().dimension()));
|
||||
return typename Constructor::Dimension()(d);
|
||||
}
|
||||
result_type operator()()const{
|
||||
return typename Constructor::Dimension()(this->kernel().dimension());
|
||||
}
|
||||
result_type operator()(Zero_ const&)const{
|
||||
return typename Constructor::Dimension()(this->kernel().dimension());
|
||||
}
|
||||
result_type operator()(result_type const& v)const{
|
||||
return v;
|
||||
}
|
||||
#ifdef CGAL_CXX0X
|
||||
result_type operator()(result_type&& v)const{
|
||||
return std::move(v);
|
||||
}
|
||||
#endif
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...U>
|
||||
typename std::enable_if<Constructible_from_each<RT,U...>::value &&
|
||||
(sizeof...(U)==static_dim), result_type>::type
|
||||
operator()(U&&...u)const{
|
||||
return typename Constructor::Values()(std::forward<U>(u)...);
|
||||
}
|
||||
//template<class...U,class=typename std::enable_if<Constructible_from_each<RT,U...>::value>::type,class=typename std::enable_if<(sizeof...(U)==static_dim+1)>::type,class=void>
|
||||
template<class...U>
|
||||
typename std::enable_if<Constructible_from_each<RT,U...>::value &&
|
||||
(sizeof...(U)==static_dim+1), result_type>::type
|
||||
operator()(U&&...u)const{
|
||||
return Apply_to_last_then_rest()(typename Constructor::Values_divide(),std::forward<U>(u)...);
|
||||
}
|
||||
#else
|
||||
using internal::Construct_LA_vector_<R_,R::Default_ambient_dimension::value>::operator();
|
||||
#endif
|
||||
template<class Iter> inline
|
||||
typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
|
||||
(Iter f,Iter g,Cartesian_tag t)const
|
||||
{
|
||||
return this->operator()(std::distance(f,g),f,g,t);
|
||||
}
|
||||
template<class Iter> inline
|
||||
typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
|
||||
(int d,Iter f,Iter g,Cartesian_tag)const
|
||||
{
|
||||
CGAL_assertion(d==std::distance(f,g));
|
||||
CGAL_assertion(check_dimension_eq(d,this->kernel().dimension()));
|
||||
return typename Constructor::Iterator()(d,f,g);
|
||||
}
|
||||
template<class Iter> inline
|
||||
typename boost::enable_if<is_iterator_type<Iter,std::bidirectional_iterator_tag>,result_type>::type operator()
|
||||
(Iter f,Iter g,Homogeneous_tag)const
|
||||
{
|
||||
--g;
|
||||
return this->operator()(std::distance(f,g),f,g,*g);
|
||||
}
|
||||
template<class Iter> inline
|
||||
typename boost::enable_if<is_iterator_type<Iter,std::bidirectional_iterator_tag>,result_type>::type operator()
|
||||
(int d,Iter f,Iter g,Homogeneous_tag)const
|
||||
{
|
||||
--g;
|
||||
return this->operator()(d,f,g,*g);
|
||||
}
|
||||
template<class Iter> inline
|
||||
typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
|
||||
(Iter f,Iter g)const
|
||||
{
|
||||
// Shouldn't it try comparing dist(f,g) to the dimension if it is known?
|
||||
return this->operator()(f,g,typename R::Rep_tag());
|
||||
}
|
||||
template<class Iter> inline
|
||||
typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
|
||||
(int d,Iter f,Iter g)const
|
||||
{
|
||||
return this->operator()(d,f,g,typename R::Rep_tag());
|
||||
}
|
||||
|
||||
// Last homogeneous coordinate given separately
|
||||
template<class Iter,class NT> inline
|
||||
typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
|
||||
(int d,Iter f,Iter g,NT const&l)const
|
||||
{
|
||||
CGAL_assertion(d==std::distance(f,g));
|
||||
CGAL_assertion(check_dimension_eq(d,this->kernel().dimension()));
|
||||
// RT? better be safe for now
|
||||
return typename Constructor::Iterator()(d,CGAL::make_transforming_iterator(f,Divide<FT,NT>(l)),CGAL::make_transforming_iterator(g,Divide<FT,NT>(l)));
|
||||
}
|
||||
template<class Iter,class NT> inline
|
||||
typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
|
||||
(Iter f,Iter g,NT const&l)const
|
||||
{
|
||||
return this->operator()(std::distance(f,g),f,g,l);
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct Compute_cartesian_coordinate {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Compute_cartesian_coordinate)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename R::Vector_ first_argument_type;
|
||||
typedef int second_argument_type;
|
||||
typedef Tag_true Is_exact;
|
||||
#ifdef CGAL_CXX0X
|
||||
typedef decltype(std::declval<const first_argument_type>()[0]) result_type;
|
||||
#else
|
||||
typedef RT const& result_type;
|
||||
// RT const& doesn't work with some LA (Eigen2 for instance) so we
|
||||
// should use plain RT or find a way to detect this.
|
||||
#endif
|
||||
|
||||
result_type operator()(first_argument_type const& v,int i)const{
|
||||
return v[i];
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct Construct_cartesian_const_iterator {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Construct_cartesian_const_iterator)
|
||||
typedef R_ R;
|
||||
typedef typename R::Vector_ argument_type;
|
||||
typedef typename R::LA_vector S_;
|
||||
typedef typename R::Point_cartesian_const_iterator result_type;
|
||||
// same as Vector
|
||||
typedef Tag_true Is_exact;
|
||||
|
||||
result_type operator()(argument_type const& v,Begin_tag)const{
|
||||
return S_::vector_begin(v);
|
||||
}
|
||||
result_type operator()(argument_type const& v,End_tag)const{
|
||||
return S_::vector_end(v);
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct Midpoint {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Midpoint)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Point_tag>::type first_argument_type;
|
||||
typedef typename Get_type<R, Point_tag>::type second_argument_type;
|
||||
typedef typename Get_type<R, Point_tag>::type result_type;
|
||||
|
||||
result_type operator()(result_type const& a, result_type const& b)const{
|
||||
return (a+b)/2;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct Sum_of_vectors {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Sum_of_vectors)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Vector_tag>::type first_argument_type;
|
||||
typedef typename Get_type<R, Vector_tag>::type second_argument_type;
|
||||
typedef typename Get_type<R, Vector_tag>::type result_type;
|
||||
|
||||
result_type operator()(result_type const& a, result_type const& b)const{
|
||||
return a+b;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct Difference_of_vectors {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Difference_of_vectors)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Vector_tag>::type first_argument_type;
|
||||
typedef typename Get_type<R, Vector_tag>::type second_argument_type;
|
||||
typedef typename Get_type<R, Vector_tag>::type result_type;
|
||||
|
||||
result_type operator()(result_type const& a, result_type const& b)const{
|
||||
return a-b;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct Opposite_vector {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Opposite_vector)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Vector_tag>::type result_type;
|
||||
typedef typename Get_type<R, Vector_tag>::type argument_type;
|
||||
|
||||
result_type operator()(result_type const& v)const{
|
||||
return -v;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct Scalar_product {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Scalar_product)
|
||||
typedef R_ R;
|
||||
typedef typename R::LA_vector LA;
|
||||
typedef typename Get_type<R, RT_tag>::type result_type;
|
||||
typedef typename Get_type<R, Vector_tag>::type first_argument_type;
|
||||
typedef typename Get_type<R, Vector_tag>::type second_argument_type;
|
||||
|
||||
result_type operator()(first_argument_type const& a, second_argument_type const& b)const{
|
||||
return LA::dot_product(a,b);
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct Squared_distance_to_origin_stored {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Squared_distance_to_origin_stored)
|
||||
typedef R_ R;
|
||||
typedef typename R::LA_vector LA;
|
||||
typedef typename Get_type<R, RT_tag>::type result_type;
|
||||
typedef typename Get_type<R, Point_tag>::type argument_type;
|
||||
|
||||
result_type operator()(argument_type const& a)const{
|
||||
return LA::squared_norm(a);
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct Squared_distance_to_origin_via_dotprod {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Squared_distance_to_origin_via_dotprod)
|
||||
typedef R_ R;
|
||||
typedef typename R::LA_vector LA;
|
||||
typedef typename Get_type<R, RT_tag>::type result_type;
|
||||
typedef typename Get_type<R, Point_tag>::type argument_type;
|
||||
|
||||
result_type operator()(argument_type const& a)const{
|
||||
return LA::dot_product(a,a);
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct Orientation_of_vectors {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Orientation_of_vectors)
|
||||
typedef R_ R;
|
||||
typedef typename R::Vector_cartesian_const_iterator first_argument_type;
|
||||
typedef typename R::Vector_cartesian_const_iterator second_argument_type;
|
||||
typedef typename Get_type<R, Orientation_tag>::type result_type;
|
||||
typedef typename R::LA_vector LA;
|
||||
|
||||
template<class Iter>
|
||||
result_type operator()(Iter const& f, Iter const& e) const {
|
||||
return LA::determinant_of_iterators_to_vectors(f,e);
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct Orientation_of_points {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Orientation_of_points)
|
||||
typedef R_ R;
|
||||
typedef typename R::Point_cartesian_const_iterator first_argument_type;
|
||||
typedef typename R::Point_cartesian_const_iterator second_argument_type;
|
||||
typedef typename Get_type<R, Orientation_tag>::type result_type;
|
||||
typedef typename R::LA_vector LA;
|
||||
|
||||
template<class Iter>
|
||||
result_type operator()(Iter const& f, Iter const& e) const {
|
||||
return LA::determinant_of_iterators_to_points(f,e);
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct PV_dimension {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(PV_dimension)
|
||||
typedef R_ R;
|
||||
typedef typename R::Vector_ argument_type;
|
||||
typedef int result_type;
|
||||
typedef typename R::LA_vector LA;
|
||||
typedef Tag_true Is_exact;
|
||||
|
||||
template<class T>
|
||||
result_type operator()(T const& v) const {
|
||||
return LA::size_of_vector(v);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
} // namespace CGAL
|
||||
#endif // CGAL_CARTESIAN_LA_FUNCTORS_H
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef CGAL_KERNEL_D_CARTESIAN_BASE_H
|
||||
#define CGAL_KERNEL_D_CARTESIAN_BASE_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Kernel_d/Cartesian_complete.h>
|
||||
#include <CGAL/Kernel_d/Cartesian_LA_base.h>
|
||||
|
||||
namespace CGAL {
|
||||
#define CGAL_BASE \
|
||||
Cartesian_LA_base_d< FT_, Dim_ >
|
||||
template < typename FT_, typename Dim_, typename Derived_=Default>
|
||||
struct Cartesian_base_d : public CGAL_BASE
|
||||
{
|
||||
CGAL_CONSTEXPR Cartesian_base_d(){}
|
||||
CGAL_CONSTEXPR Cartesian_base_d(int d):CGAL_BASE(d){}
|
||||
};
|
||||
#undef CGAL_BASE
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_KERNEL_D_CARTESIAN_BASE_H
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
#ifndef CGAL_KERNEL_D_CARTESIAN_CHANGE_FT_H
|
||||
#define CGAL_KERNEL_D_CARTESIAN_CHANGE_FT_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/NT_converter.h>
|
||||
#include <CGAL/transforming_iterator.h>
|
||||
#include <CGAL/Kernel_d/Cartesian_complete.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template < typename Base_, typename FT_, typename LA_=CGAL::LA_eigen<FT_,typename Base_::Default_ambient_dimension> >
|
||||
struct Cartesian_change_FT_base : public
|
||||
Base_
|
||||
{
|
||||
CGAL_CONSTEXPR Cartesian_change_FT_base(){}
|
||||
CGAL_CONSTEXPR Cartesian_change_FT_base(int d):Base_(d){}
|
||||
|
||||
typedef Cartesian_change_FT_base Self;
|
||||
typedef Base_ Kernel_base;
|
||||
typedef LA_ LA;
|
||||
|
||||
template <class T, class D=void> struct Type : Inherit_type<Base_, T> {};
|
||||
template <class D> struct Type <FT_tag, D> { typedef FT_ type; };
|
||||
template <class D> struct Type <RT_tag, D> { typedef FT_ type; };
|
||||
|
||||
typedef NT_converter<typename Get_type<Kernel_base, FT_tag>::type,FT_> FT_converter;
|
||||
typedef transforming_iterator<FT_converter,typename Kernel_base::Point_cartesian_const_iterator> Point_cartesian_const_iterator;
|
||||
typedef transforming_iterator<FT_converter,typename Kernel_base::Vector_cartesian_const_iterator> Vector_cartesian_const_iterator;
|
||||
//FIXME: use Iterator_list!
|
||||
/*
|
||||
template<class T,bool=BOOSTD is_same<typename iterator_tag_traits<T>::value_tag,FT_tag>::value>
|
||||
struct Iterator : Get_type<Kernel_base,T> {};
|
||||
template<class T> struct Iterator<T,true> {
|
||||
typedef transforming_iterator<FT_converter,typename Get_type<Kernel_base,T>::type> type;
|
||||
};
|
||||
*/
|
||||
|
||||
template<class Tag_,class Type_>
|
||||
struct Construct_cartesian_const_iterator_ {
|
||||
typedef typename Get_functor<Kernel_base, Tag_>::type Functor_base;
|
||||
Construct_cartesian_const_iterator_(){}
|
||||
Construct_cartesian_const_iterator_(Self const&r):f(r){}
|
||||
Functor_base f;
|
||||
typedef Type_ result_type;
|
||||
template<class T>
|
||||
result_type operator()(T const& v, Begin_tag)const{
|
||||
return make_transforming_iterator(f(v,Begin_tag()),FT_converter());
|
||||
}
|
||||
template<class T>
|
||||
result_type operator()(T const& v, End_tag)const{
|
||||
return make_transforming_iterator(f(v,End_tag()),FT_converter());
|
||||
}
|
||||
};
|
||||
typedef Construct_cartesian_const_iterator_<Construct_ttag<Point_cartesian_const_iterator_tag>,Point_cartesian_const_iterator> Construct_point_cartesian_const_iterator;
|
||||
typedef Construct_cartesian_const_iterator_<Construct_ttag<Vector_cartesian_const_iterator_tag>,Vector_cartesian_const_iterator> Construct_vector_cartesian_const_iterator;
|
||||
|
||||
template<class Tag_>
|
||||
struct Compute_cartesian_coordinate {
|
||||
typedef typename Get_functor<Kernel_base, Tag_>::type Functor_base;
|
||||
Compute_cartesian_coordinate(){}
|
||||
Compute_cartesian_coordinate(Self const&r):f(r){}
|
||||
Functor_base f;
|
||||
typedef FT_ result_type;
|
||||
template<class Obj_>
|
||||
result_type operator()(Obj_ const& v,int i)const{
|
||||
return FT_converter()(f(v,i));
|
||||
}
|
||||
};
|
||||
|
||||
template<class T,class U=void,class=typename Get_functor_category<Cartesian_change_FT_base,T>::type> struct Functor :
|
||||
Inherit_functor<Kernel_base,T,U> { };
|
||||
template<class T,class U> struct Functor<T,U,Compute_tag> { };
|
||||
template<class T,class U> struct Functor<T,U,Predicate_tag> { };
|
||||
template<class D> struct Functor<Compute_point_cartesian_coordinate_tag,D,Compute_tag> {
|
||||
typedef Compute_cartesian_coordinate<Compute_point_cartesian_coordinate_tag> type;
|
||||
};
|
||||
template<class D> struct Functor<Compute_vector_cartesian_coordinate_tag,D,Compute_tag> {
|
||||
typedef Compute_cartesian_coordinate<Compute_vector_cartesian_coordinate_tag> type;
|
||||
};
|
||||
template<class D> struct Functor<Construct_ttag<Point_cartesian_const_iterator_tag>,D,Construct_iterator_tag> {
|
||||
typedef Construct_point_cartesian_const_iterator type;
|
||||
};
|
||||
template<class D> struct Functor<Construct_ttag<Vector_cartesian_const_iterator_tag>,D,Construct_iterator_tag> {
|
||||
typedef Construct_vector_cartesian_const_iterator type;
|
||||
};
|
||||
};
|
||||
|
||||
template < typename Base_, typename FT_>
|
||||
struct Cartesian_change_FT : public
|
||||
Cartesian_change_FT_base<Base_,FT_>
|
||||
{
|
||||
CGAL_CONSTEXPR Cartesian_change_FT(){}
|
||||
CGAL_CONSTEXPR Cartesian_change_FT(int d):Cartesian_change_FT_base<Base_,FT_>(d){}
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_KERNEL_D_CARTESIAN_CHANGE_FT_H
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef CGAL_KERNEL_D_CARTESIAN_COMPLETE_H
|
||||
#define CGAL_KERNEL_D_CARTESIAN_COMPLETE_H
|
||||
|
||||
#include <CGAL/Kernel_d/function_objects_cartesian.h>
|
||||
#include <CGAL/Kernel_d/Cartesian_per_dimension.h>
|
||||
#include <CGAL/Kernel_d/Types/Segment.h>
|
||||
#include <CGAL/Kernel_d/Types/Sphere.h>
|
||||
#include <CGAL/Kernel_d/Types/Hyperplane.h>
|
||||
#include <CGAL/Kernel_d/Types/Aff_transformation.h>
|
||||
#include <CGAL/Kernel_d/Types/Line.h>
|
||||
#include <CGAL/Kernel_d/Types/Ray.h>
|
||||
#include <CGAL/Kernel_d/Types/Iso_box.h>
|
||||
|
||||
#endif // CGAL_KERNEL_D_CARTESIAN_COMPLETE_H
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef CGAL_KERNEL_D_CARTESIAN_FILTER_K_H
|
||||
#define CGAL_KERNEL_D_CARTESIAN_FILTER_K_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Kernel_d/KernelD_converter.h>
|
||||
#include <CGAL/Filtered_predicate2.h>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template < typename Base_, typename AK_, typename EK_ >
|
||||
struct Cartesian_filter_K : public Base_,
|
||||
private Store_kernel<AK_>, private Store_kernel2<EK_>
|
||||
{
|
||||
CGAL_CONSTEXPR Cartesian_filter_K(){}
|
||||
CGAL_CONSTEXPR Cartesian_filter_K(int d):Base_(d){}
|
||||
//FIXME: or do we want an instance of AK and EK belonging to this kernel,
|
||||
//instead of a reference to external ones?
|
||||
CGAL_CONSTEXPR Cartesian_filter_K(AK_ const&a,EK_ const&b):Base_(),Store_kernel<AK_>(a),Store_kernel2<EK_>(b){}
|
||||
CGAL_CONSTEXPR Cartesian_filter_K(int d,AK_ const&a,EK_ const&b):Base_(d),Store_kernel<AK_>(a),Store_kernel2<EK_>(b){}
|
||||
typedef Base_ Kernel_base;
|
||||
typedef AK_ AK;
|
||||
typedef EK_ EK;
|
||||
typedef typename Store_kernel<AK_>::reference_type AK_rt;
|
||||
AK_rt approximate_kernel()const{return this->kernel();}
|
||||
typedef typename Store_kernel2<EK_>::reference2_type EK_rt;
|
||||
EK_rt exact_kernel()const{return this->kernel2();}
|
||||
|
||||
//TODO: C2A/C2E could be able to convert *this into this->kernel() or this->kernel2().
|
||||
typedef KernelD_converter<Kernel_base,AK> C2A;
|
||||
typedef KernelD_converter<Kernel_base,EK> C2E;
|
||||
|
||||
template<class T,class D=void,class=typename Get_functor_category<Cartesian_filter_K,T>::type> struct Functor :
|
||||
Inherit_functor<Kernel_base,T,D> {};
|
||||
template<class T,class D> struct Functor<T,D,Predicate_tag> {
|
||||
typedef typename Get_functor<AK, T>::type AP;
|
||||
typedef typename Get_functor<EK, T>::type EP;
|
||||
typedef Filtered_predicate2<EP,AP,C2E,C2A> type;
|
||||
};
|
||||
// TODO:
|
||||
// template<class T> struct Functor<T,No_filter_tag,Predicate_tag> :
|
||||
// Kernel_base::template Functor<T,No_filter_tag> {};
|
||||
// TODO:
|
||||
// detect when Less_cartesian_coordinate doesn't need filtering
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_KERNEL_D_CARTESIAN_FILTER_K_H
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
#ifndef CGAL_KERNEL_D_CARTESIAN_FILTER_NT_H
|
||||
#define CGAL_KERNEL_D_CARTESIAN_FILTER_NT_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Kernel_d/Cartesian_change_FT.h>
|
||||
#include <CGAL/internal/Exact_type_selector.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template < typename Base_ >
|
||||
struct Cartesian_filter_NT : public Base_
|
||||
{
|
||||
CGAL_CONSTEXPR Cartesian_filter_NT(){}
|
||||
CGAL_CONSTEXPR Cartesian_filter_NT(int d):Base_(d){}
|
||||
typedef Base_ Kernel_base;
|
||||
typedef Cartesian_change_FT<Kernel_base,Interval_nt_advanced> K1;
|
||||
typedef typename internal::Exact_field_selector<typename Get_type<Kernel_base, FT_tag>::type>::Type Exact_nt;
|
||||
typedef Cartesian_change_FT<Kernel_base,Exact_nt> K2;
|
||||
|
||||
template<class T,class D=void,class=typename Get_functor_category<Cartesian_filter_NT,T>::type> struct Functor :
|
||||
Inherit_functor<Kernel_base,T,D> {};
|
||||
template<class T,class D> struct Functor<T,D,Predicate_tag> {
|
||||
struct type {
|
||||
//TODO: use compression (derive from a compressed_pair?)
|
||||
typedef typename Get_functor<K1, T>::type P1; P1 p1;
|
||||
typedef typename Get_functor<K2, T>::type P2; P2 p2;
|
||||
typedef typename P2::result_type result_type;
|
||||
type(){}
|
||||
type(Cartesian_filter_NT const&k):p1(reinterpret_cast<K1 const&>(k)),p2(reinterpret_cast<K2 const&>(k)){}
|
||||
//FIXME: if predicate's constructor takes a kernel as argument, how do we translate that? reinterpret_cast is really ugly and possibly unsafe.
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...U> result_type operator()(U&&...u)const{
|
||||
{
|
||||
Protect_FPU_rounding<true> p;
|
||||
try {
|
||||
typename P1::result_type res=p1(u...); // don't forward as u may be reused
|
||||
if(is_certain(res)) return get_certain(res);
|
||||
} catch (Uncertain_conversion_exception) {}
|
||||
}
|
||||
return p2(std::forward<U>(u)...);
|
||||
}
|
||||
#else
|
||||
result_type operator()()const{ // does it make sense to have 0 argument?
|
||||
{
|
||||
Protect_FPU_rounding<true> p;
|
||||
try {
|
||||
typename P1::result_type res=p1();
|
||||
if(is_certain(res)) return get_certain(res);
|
||||
} catch (Uncertain_conversion_exception) {}
|
||||
}
|
||||
return p2();
|
||||
}
|
||||
#define CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t))const{ \
|
||||
{ \
|
||||
Protect_FPU_rounding<true> p; \
|
||||
try { \
|
||||
typename P1::result_type res=p1(BOOST_PP_ENUM_PARAMS(N,t)); \
|
||||
if(is_certain(res)) return get_certain(res); \
|
||||
} catch (Uncertain_conversion_exception) {} \
|
||||
} \
|
||||
return p2(BOOST_PP_ENUM_PARAMS(N,t)); \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_)
|
||||
#undef CODE
|
||||
|
||||
#endif
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_KERNEL_D_CARTESIAN_FILTER_NT_H
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef CGAL_KD_CARTESIAN_PER_DIM_H
|
||||
#define CGAL_KD_CARTESIAN_PER_DIM_H
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <CGAL/predicates/sign_of_determinant.h>
|
||||
|
||||
// Should probably disappear.
|
||||
|
||||
namespace CGAL {
|
||||
template <class Dim_, class R_, class Derived_>
|
||||
struct Cartesian_per_dimension : public R_ {};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
#ifndef CGAL_KD_CARTESIAN_STATIC_FILTERS_H
|
||||
#define CGAL_KD_CARTESIAN_STATIC_FILTERS_H
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <CGAL/internal/Static_filters/tools.h> // bug, should be included by the next one
|
||||
#include <CGAL/internal/Static_filters/Orientation_2.h>
|
||||
#include <boost/type_traits/conditional.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
namespace SFA { // static filter adapter
|
||||
// Note that this would be quite a bit simpler without stateful kernels
|
||||
template <class Base_,class R_> struct Orientation_of_points_2 : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Orientation_of_points_2);
|
||||
typedef typename Get_type<R_, Point_tag>::type Point;
|
||||
typedef typename Get_type<R_, Orientation_tag>::type result_type;
|
||||
typedef typename Get_type<R_, FT_tag>::type FT;
|
||||
typedef typename Get_functor<R_, Compute_point_cartesian_coordinate_tag>::type CC;
|
||||
typedef typename Get_functor<Base_, Orientation_of_points_tag>::type Orientation_base;
|
||||
// TODO: Move this out for easy reuse
|
||||
struct Adapter {
|
||||
struct Point_2 {
|
||||
R_ const&r; CC const&c; Point const& p;
|
||||
Point_2(R_ const&r_, CC const&c_, Point const&p_):r(r_),c(c_),p(p_){}
|
||||
// use result_of instead?
|
||||
typename CC::result_type x()const{return c(p,0);}
|
||||
typename CC::result_type y()const{return c(p,1);}
|
||||
};
|
||||
struct Vector_2 {};
|
||||
struct Circle_2 {};
|
||||
struct Orientation_2 {
|
||||
typedef Orientation_of_points_2::result_type result_type;
|
||||
result_type operator()(Point_2 const&A, Point_2 const&B, Point_2 const&C)const{
|
||||
Point const* t[3]={&A.p,&B.p,&C.p};
|
||||
return Orientation_base(A.r)(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+3));
|
||||
}
|
||||
};
|
||||
};
|
||||
template<class Iter> result_type operator()(Iter f, Iter CGAL_assertion_code(e))const{
|
||||
CC c(this->kernel());
|
||||
Point const& A=*f;
|
||||
Point const& B=*++f;
|
||||
Point const& C=*++f;
|
||||
CGAL_assertion(++f==e);
|
||||
typedef typename Adapter::Point_2 P;
|
||||
return typename internal::Static_filters_predicates::Orientation_2<Adapter>()(P(this->kernel(),c,A),P(this->kernel(),c,B),P(this->kernel(),c,C));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <class Dim_ /* should be implicit */, class R_, class Derived_=Default>
|
||||
struct Cartesian_static_filters : public R_ {
|
||||
CGAL_CONSTEXPR Cartesian_static_filters(){}
|
||||
CGAL_CONSTEXPR Cartesian_static_filters(int d):R_(d){}
|
||||
};
|
||||
|
||||
template <class R_, class Derived_>
|
||||
struct Cartesian_static_filters<Dimension_tag<2>, R_, Derived_> : public R_ {
|
||||
CGAL_CONSTEXPR Cartesian_static_filters(){}
|
||||
CGAL_CONSTEXPR Cartesian_static_filters(int d):R_(d){}
|
||||
typedef Cartesian_static_filters<Dimension_tag<2>, R_, Derived_> Self;
|
||||
typedef typename Default::Get<Derived_,Self>::type Derived;
|
||||
template <class T, class=void> struct Functor : Inherit_functor<R_, T> {};
|
||||
template <class D> struct Functor <Orientation_of_points_tag,D> {
|
||||
typedef
|
||||
//typename boost::conditional<
|
||||
//boost::is_same<D,No_filter_tag>::value,
|
||||
//typename Get_functor<R_, Orientation_of_points_tag>::type,
|
||||
SFA::Orientation_of_points_2<R_,Derived>
|
||||
// >::type
|
||||
type;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
#ifndef CGAL_KD_COAFFINE_H
|
||||
#define CGAL_KD_COAFFINE_H
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <CGAL/functor_tags.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace CartesianDKernelFunctors {
|
||||
struct Flat_orientation {
|
||||
std::vector<int> proj;
|
||||
std::vector<int> rest;
|
||||
};
|
||||
|
||||
// For debugging purposes
|
||||
inline std::ostream& operator<< (std::ostream& o, Flat_orientation const& f) {
|
||||
o << "Proj: ";
|
||||
for(std::vector<int>::const_iterator i=f.proj.begin();
|
||||
i!=f.proj.end(); ++i)
|
||||
o << *i << ' ';
|
||||
o << "\nRest: ";
|
||||
for(std::vector<int>::const_iterator i=f.rest.begin();
|
||||
i!=f.rest.end(); ++i)
|
||||
o << *i << ' ';
|
||||
return o << '\n';
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
namespace coaffine {
|
||||
template<class Mat>
|
||||
inline void debug_matrix(std::ostream& o, Mat const&mat) {
|
||||
for(int i=0;i<mat.rows();++i){
|
||||
for(int j=0;j<mat.cols();++j){
|
||||
o<<mat(i,j)<<' ';
|
||||
}
|
||||
o<<'\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class R_> struct Construct_flat_orientation : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Construct_flat_orientation)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, FT_tag>::type FT;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Increment_dimension<typename R::Max_ambient_dimension>::type Dplusone;
|
||||
typedef typename R::LA::template Rebind_dimension<Dynamic_dimension_tag,Dplusone>::Other LA;
|
||||
typedef typename LA::Square_matrix Matrix;
|
||||
typedef typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type CCC;
|
||||
typedef typename Get_functor<R, Point_dimension_tag>::type PD;
|
||||
typedef Flat_orientation result_type;
|
||||
|
||||
// This implementation is going to suck. Maybe we should push the
|
||||
// functionality into LA.
|
||||
template<class Iter>
|
||||
result_type operator()(Iter f, Iter e)const{
|
||||
PD pd (this->kernel());
|
||||
CCC ccc (this->kernel());
|
||||
int dim = pd(*f);
|
||||
Matrix coord (dim+1, dim+1); // use distance(f,e)? This matrix doesn't need to be square.
|
||||
int col = 0;
|
||||
Flat_orientation o;
|
||||
std::vector<int>& proj=o.proj;
|
||||
std::vector<int>& rest=o.rest; rest.reserve(dim+1);
|
||||
for(int i=0; i<dim+1; ++i) rest.push_back(i);
|
||||
for( ; f != e ; ++col, ++f ) {
|
||||
Point const&p=*f;
|
||||
// use a coordinate iterator instead?
|
||||
for(int i=0; i<dim; ++i) coord(col, i) = ccc(p, i);
|
||||
coord(col,dim)=1;
|
||||
int d = proj.size()+1;
|
||||
Matrix m (d, d);
|
||||
// Fill the matrix with what we already have
|
||||
for(int i=0; i<d; ++i)
|
||||
for(int j=0; j<d-1; ++j)
|
||||
m(i,j) = coord(i, proj[j]);
|
||||
// Try to complete with any other coordinate
|
||||
// TODO: iterate on rest by the end, or use a (forward_)list.
|
||||
for(std::vector<int>::iterator it=rest.begin();;++it) {
|
||||
CGAL_assertion(it!=rest.end());
|
||||
for(int i=0; i<d; ++i) m(i,d-1) = coord(i, *it);
|
||||
if(LA::sign_of_determinant(m)!=0) {
|
||||
proj.push_back(*it);
|
||||
rest.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::sort(proj.begin(),proj.end());
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct Contained_in_affine_hull : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Contained_in_affine_hull)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, FT_tag>::type FT;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_type<R, Bool_tag>::type result_type;
|
||||
typedef typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type CCC;
|
||||
typedef typename Get_functor<R, Point_dimension_tag>::type PD;
|
||||
//typedef typename Increment_dimension<typename R::Default_ambient_dimension>::type D1;
|
||||
//typedef typename Increment_dimension<typename R::Max_ambient_dimension>::type D2;
|
||||
//typedef typename R::LA::template Rebind_dimension<D1,D2>::Other LA;
|
||||
typedef typename Increment_dimension<typename R::Max_ambient_dimension>::type Dplusone;
|
||||
typedef typename R::LA::template Rebind_dimension<Dynamic_dimension_tag,Dplusone>::Other LA;
|
||||
typedef typename LA::Square_matrix Matrix;
|
||||
|
||||
// mostly copied from Construct_flat_orientation. TODO: dedup this code.
|
||||
template<class Iter>
|
||||
result_type operator()(Iter f, Iter e, Point const&x) const {
|
||||
PD pd (this->kernel());
|
||||
CCC ccc (this->kernel());
|
||||
int dim=pd(*f);
|
||||
Matrix coord (dim+1, dim+1); // use distance
|
||||
int col = 0;
|
||||
std::vector<int> proj;
|
||||
std::vector<int> rest; rest.reserve(dim+1);
|
||||
for(int i=0; i<dim+1; ++i) rest.push_back(i);
|
||||
for( ; f != e ; ++col, ++f ) {
|
||||
Point const&p=*f;
|
||||
for(int i=0; i<dim; ++i) coord(col, i) = ccc(p, i);
|
||||
coord(col,dim)=1;
|
||||
int d = proj.size()+1;
|
||||
Matrix m (d, d);
|
||||
for(int i=0; i<d; ++i)
|
||||
for(int j=0; j<d-1; ++j)
|
||||
m(i,j) = coord(i, proj[j]);
|
||||
for(std::vector<int>::iterator it=rest.begin();it!=rest.end();++it) {
|
||||
for(int i=0; i<d; ++i) m(i,d-1) = coord(i, *it);
|
||||
if(LA::sign_of_determinant(m)!=0) {
|
||||
proj.push_back(*it);
|
||||
rest.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int i=0; i<dim; ++i) coord(col, i) = ccc(x, i);
|
||||
coord(col,dim)=1;
|
||||
int d = proj.size()+1;
|
||||
Matrix m (d, d);
|
||||
for(int i=0; i<d; ++i)
|
||||
for(int j=0; j<d-1; ++j)
|
||||
m(i,j) = coord(i, proj[j]);
|
||||
for(std::vector<int>::iterator it=rest.begin();it!=rest.end();++it) {
|
||||
for(int i=0; i<d; ++i) m(i,d-1) = coord(i, *it);
|
||||
if(LA::sign_of_determinant(m)!=0) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct In_flat_orientation : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(In_flat_orientation)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, FT_tag>::type FT;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_type<R, Orientation_tag>::type result_type;
|
||||
typedef typename Increment_dimension<typename R::Default_ambient_dimension>::type D1;
|
||||
typedef typename Increment_dimension<typename R::Max_ambient_dimension>::type D2;
|
||||
typedef typename R::LA::template Rebind_dimension<D1,D2>::Other LA;
|
||||
typedef typename LA::Square_matrix Matrix;
|
||||
|
||||
template<class Iter>
|
||||
result_type operator()(Flat_orientation const&o, Iter f, Iter e) const {
|
||||
// TODO: work in the projection instead of the ambient space.
|
||||
typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
|
||||
typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
|
||||
int d=pd(*f);
|
||||
Matrix m(d+1,d+1);
|
||||
int i=0;
|
||||
for(;f!=e;++f,++i) {
|
||||
Point const& p=*f;
|
||||
m(i,0)=1;
|
||||
for(int j=0;j<d;++j){
|
||||
m(i,j+1)=c(p,j);
|
||||
}
|
||||
}
|
||||
for(std::vector<int>::const_iterator it = o.rest.begin(); it != o.rest.end() /* i<d+1 */; ++i, ++it) {
|
||||
m(i,0)=1;
|
||||
for(int j=0;j<d;++j){
|
||||
m(i,j+1)=0; // unneeded if the matrix is initialized to 0
|
||||
}
|
||||
if(*it != d) m(i,1+*it)=1;
|
||||
}
|
||||
|
||||
return LA::sign_of_determinant(CGAL_MOVE(m));
|
||||
}
|
||||
};
|
||||
|
||||
template<class R_> struct In_flat_side_of_oriented_sphere : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(In_flat_side_of_oriented_sphere)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, FT_tag>::type FT;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_type<R, Orientation_tag>::type result_type;
|
||||
typedef typename Increment_dimension<typename R::Default_ambient_dimension,2>::type D1;
|
||||
typedef typename Increment_dimension<typename R::Max_ambient_dimension,2>::type D2;
|
||||
typedef typename R::LA::template Rebind_dimension<D1,D2>::Other LA;
|
||||
typedef typename LA::Square_matrix Matrix;
|
||||
|
||||
template<class Iter>
|
||||
result_type operator()(Flat_orientation const&o, Iter f, Iter e, Point const&x) const {
|
||||
// TODO: can't work in the projection, but we should at least remove the row of 1s.
|
||||
typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
|
||||
typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
|
||||
int d=pd(*f);
|
||||
Matrix m(d+2,d+2);
|
||||
int i=0;
|
||||
for(;f!=e;++f,++i) {
|
||||
Point const& p=*f;
|
||||
m(i,0)=1;
|
||||
m(i,d+1)=0;
|
||||
for(int j=0;j<d;++j){
|
||||
m(i,j+1)=c(p,j);
|
||||
m(i,d+1)+=CGAL_NTS square(m(i,j+1));
|
||||
}
|
||||
}
|
||||
for(std::vector<int>::const_iterator it = o.rest.begin(); it != o.rest.end() /* i<d+1 */; ++i, ++it) {
|
||||
m(i,0)=1;
|
||||
for(int j=0;j<d;++j){
|
||||
m(i,j+1)=0; // unneeded if the matrix is initialized to 0
|
||||
}
|
||||
if(*it != d) m(i,d+1)=m(i,1+*it)=1;
|
||||
else m(i,d+1)=0;
|
||||
}
|
||||
m(d+1,0)=1;
|
||||
m(d+1,d+1)=0;
|
||||
for(int j=0;j<d;++j){
|
||||
m(d+1,j+1)=c(x,j);
|
||||
m(d+1,d+1)+=CGAL_NTS square(m(d+1,j+1));
|
||||
}
|
||||
|
||||
return -LA::sign_of_determinant(CGAL_MOVE(m));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
CGAL_KD_DEFAULT_TYPE(Flat_orientation_tag,(CGAL::CartesianDKernelFunctors::Flat_orientation),(),());
|
||||
CGAL_KD_DEFAULT_FUNCTOR(In_flat_orientation_tag,(CartesianDKernelFunctors::In_flat_orientation<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag));
|
||||
CGAL_KD_DEFAULT_FUNCTOR(In_flat_side_of_oriented_sphere_tag,(CartesianDKernelFunctors::In_flat_side_of_oriented_sphere<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag));
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Construct_flat_orientation_tag,(CartesianDKernelFunctors::Construct_flat_orientation<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag));
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Contained_in_affine_hull_tag,(CartesianDKernelFunctors::Contained_in_affine_hull<K>),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag));
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef CGAL_DEFINE_KERNEL_TYPES_H
|
||||
#define CGAL_DEFINE_KERNEL_TYPES_H
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/typeset.h>
|
||||
#ifdef CGAL_CXX0X
|
||||
#include <type_traits>
|
||||
#else
|
||||
#include <boost/type_traits.hpp>
|
||||
#endif
|
||||
|
||||
namespace CGAL {
|
||||
namespace internal {
|
||||
template<class K,class Tag_,bool=iterator_tag_traits<Tag_>::is_iterator>
|
||||
struct Type_or_iter : K::template Type<Tag_> {};
|
||||
template<class K,class Tag_>
|
||||
struct Type_or_iter<K, Tag_, true> : K::template Iterator<Tag_> {};
|
||||
}
|
||||
template<class K, class Base=K, class List=typename typeset_union<typename K::Object_list,typename K::Iterator_list>::type> struct Define_kernel_types;
|
||||
template<class K, class Base>
|
||||
struct Define_kernel_types <K, Base, typeset<> > : Base {};
|
||||
template<class K>
|
||||
struct Define_kernel_types <K, void, typeset<> > {};
|
||||
template<class K, class Base, class List>
|
||||
struct Define_kernel_types :
|
||||
Typedef_tag_type<typename List::head,
|
||||
typename internal::Type_or_iter<K,typename List::head>::type,
|
||||
Define_kernel_types<K, Base, typename List::tail>
|
||||
> {};
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef bd_h
|
||||
#define db_h
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/marcutils.h>
|
||||
namespace CGAL {
|
||||
struct Store_dimension_base {
|
||||
//TODO: add some assertions
|
||||
Store_dimension_base(int dim=UNKNOWN_DIMENSION):dim_(dim){}
|
||||
int dimension()const{return dim_;}
|
||||
void set_dimension(int dim){dim_=dim;}
|
||||
private:
|
||||
int dim_;
|
||||
};
|
||||
template<class=Dynamic_dimension_tag>
|
||||
struct Dimension_base {
|
||||
Dimension_base(int = UNKNOWN_DIMENSION){}
|
||||
int dimension() const { return UNKNOWN_DIMENSION; }
|
||||
void set_dimension(int) {}
|
||||
};
|
||||
template<int dim_>
|
||||
struct Dimension_base<Dimension_tag<dim_> > {
|
||||
Dimension_base(){}
|
||||
Dimension_base(int dim){CGAL_assertion(dim_==dim);}
|
||||
int dimension()const{return dim_;}
|
||||
void set_dimension(int dim){CGAL_assertion(dim_==dim);}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
#ifndef CGAL_KERNEL_D_CARTESIAN_CONVERTER_H
|
||||
#define CGAL_KERNEL_D_CARTESIAN_CONVERTER_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/tuple.h>
|
||||
#include <CGAL/typeset.h>
|
||||
#include <CGAL/Object.h>
|
||||
#include <CGAL/NT_converter.h>
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Kernel/mpl.h>
|
||||
#include <CGAL/is_iterator.h>
|
||||
#include <CGAL/transforming_iterator.h>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <CGAL/store_kernel.h>
|
||||
#include <CGAL/Kernel_d/Kernel_object_converter.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace internal {
|
||||
// Reverses order, but that shouldn't matter.
|
||||
template<class K,class T> struct Map_taglist_to_typelist :
|
||||
Map_taglist_to_typelist<K,typename T::tail>::type
|
||||
::template add<typename Get_type<K, typename T::head>::type>
|
||||
{};
|
||||
template<class K> struct Map_taglist_to_typelist<K,typeset<> > : typeset<> {};
|
||||
}
|
||||
|
||||
template<class List = typeset<> >
|
||||
struct Object_converter {
|
||||
typedef Object result_type;
|
||||
template<class F>
|
||||
result_type operator()(Object const& o, F const& f) const {
|
||||
typedef typename List::head H;
|
||||
if (H const* ptr = object_cast<H>(&o))
|
||||
return make_object(f(*ptr));
|
||||
else
|
||||
return Object_converter<typename List::tail>()(o,f);
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct Object_converter <typeset<> > {
|
||||
typedef Object result_type;
|
||||
template<class F>
|
||||
result_type operator()(Object const&,F const&)const {
|
||||
CGAL_error_msg("Cartesiand_converter is unable to determine what is wrapped in the Object");
|
||||
return Object();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//TODO: special case when K1==K2 (or they are very close?)
|
||||
template<class Final_, class K1, class K2, class List>
|
||||
class KernelD_converter_
|
||||
: public KernelD_converter_<Final_,K1,K2,typename List::tail>
|
||||
{
|
||||
typedef typename List::head Tag_;
|
||||
typedef typename List::tail Rest;
|
||||
typedef KernelD_converter_<Final_,K1,K2,Rest> Base;
|
||||
typedef typename Get_type<K1,Tag_>::type K1_Obj;
|
||||
typedef typename Get_type<K2,Tag_>::type K2_Obj;
|
||||
typedef typename Get_functor<K1, Convert_ttag<Tag_> >::type K1_Conv;
|
||||
typedef KO_converter<Tag_,K1,K2> KOC;
|
||||
typedef BOOSTD is_same<K1_Conv, Null_functor> no_converter;
|
||||
typedef typename internal::Map_taglist_to_typelist<K1,Rest>::type::template contains<K1_Obj> duplicate;
|
||||
|
||||
// Disable the conversion in some cases:
|
||||
struct Do_not_use{};
|
||||
typedef typename BOOSTD conditional<
|
||||
// If Point==Vector, keep only one conversion
|
||||
duplicate::value ||
|
||||
// For iterator objects, the default is make_transforming_iterator
|
||||
(iterator_tag_traits<Tag_>::is_iterator && no_converter::value),
|
||||
Do_not_use,K1_Obj>::type argument_type;
|
||||
//typedef typename KOC::argument_type K1_Obj;
|
||||
//typedef typename KOC::result_type K2_Obj;
|
||||
public:
|
||||
using Base::operator(); // don't use directly, just make it accessible to the next level
|
||||
K2_Obj helper(K1_Obj const& o,BOOSTD true_type)const{
|
||||
return KOC()(this->myself().kernel(),this->myself().kernel2(),this->myself(),o);
|
||||
}
|
||||
K2_Obj helper(K1_Obj const& o,BOOSTD false_type)const{
|
||||
return K1_Conv(this->myself().kernel())(this->myself().kernel2(),this->myself(),o);
|
||||
}
|
||||
K2_Obj operator()(argument_type const& o)const{
|
||||
return helper(o,no_converter());
|
||||
}
|
||||
template<class X,int=0> struct result:Base::template result<X>{};
|
||||
template<int i> struct result<Final_(argument_type),i> {typedef K2_Obj type;};
|
||||
};
|
||||
|
||||
template<class Final_, class K1, class K2>
|
||||
class KernelD_converter_<Final_,K1,K2,typeset<> > {
|
||||
public:
|
||||
struct Do_not_use{};
|
||||
void operator()(Do_not_use)const{}
|
||||
template<class T> struct result;
|
||||
Final_& myself(){return *static_cast<Final_*>(this);}
|
||||
Final_ const& myself()const{return *static_cast<Final_ const*>(this);}
|
||||
};
|
||||
|
||||
|
||||
// TODO: use the intersection of Kn::Object_list.
|
||||
template<class K1, class K2, class List_=
|
||||
typename typeset_intersection<typename K1::Object_list, typename K2::Object_list>::type
|
||||
//typeset<Point_tag>::add<Vector_tag>::type/*::add<Segment_tag>::type*/
|
||||
> class KernelD_converter
|
||||
: public Store_kernel<K1>, public Store_kernel2<K2>,
|
||||
public KernelD_converter_<KernelD_converter<K1,K2,List_>,K1,K2,List_>
|
||||
{
|
||||
typedef KernelD_converter Self;
|
||||
typedef Self Final_;
|
||||
typedef KernelD_converter_<Self,K1,K2,List_> Base;
|
||||
typedef typename Get_type<K1, FT_tag>::type FT1;
|
||||
typedef typename Get_type<K2, FT_tag>::type FT2;
|
||||
typedef NT_converter<FT1, FT2> NTc;
|
||||
NTc c; // TODO: compressed storage as this is likely empty and the converter gets passed around (and stored in iterators)
|
||||
|
||||
public:
|
||||
KernelD_converter(){}
|
||||
KernelD_converter(K1 const&a,K2 const&b):Store_kernel<K1>(a),Store_kernel2<K2>(b){}
|
||||
|
||||
// For boost::result_of, used in transforming_iterator
|
||||
template<class T,int i=is_iterator<T>::value?42:0> struct result:Base::template result<T>{};
|
||||
template<class T> struct result<Final_(T),42> {
|
||||
typedef transforming_iterator<Final_,T> type;
|
||||
};
|
||||
template<int i> struct result<Final_(K1),i>{typedef K2 type;};
|
||||
template<int i> struct result<Final_(int),i>{typedef int type;};
|
||||
// Ideally the next 2 would come with Point_tag and Vector_tag, but that's hard...
|
||||
template<int i> struct result<Final_(Origin),i>{typedef Origin type;};
|
||||
template<int i> struct result<Final_(Null_vector),i>{typedef Null_vector type;};
|
||||
template<int i> struct result<Final_(Object),i>{typedef Object type;};
|
||||
template<int i> struct result<Final_(FT1),i>{typedef FT2 type;};
|
||||
|
||||
using Base::operator();
|
||||
typename Store_kernel2<K2>::reference2_type operator()(K1 const&)const{return this->kernel2();}
|
||||
int operator()(int i)const{return i;}
|
||||
Origin operator()(Origin const&o)const{return o;}
|
||||
Null_vector operator()(Null_vector const&v)const{return v;}
|
||||
FT2 operator()(FT1 const&x)const{return c(x);}
|
||||
//RT2 operator()(typename First_if_different<RT1,FT1>::Type const&x)const{return cr(x);}
|
||||
|
||||
typename Get_type<K2, Flat_orientation_tag>::type const&
|
||||
operator()(typename Get_type<K1, Flat_orientation_tag>::type const&o)const
|
||||
{ return o; } // Both kernels should have the same, returning a reference should warn if not.
|
||||
|
||||
template<class It>
|
||||
transforming_iterator<Final_,typename boost::enable_if<is_iterator<It>,It>::type>
|
||||
operator()(It const& it) const {
|
||||
return make_transforming_iterator(it,*this);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
//TODO: use decltype in C++11 instead of result
|
||||
std::vector<typename result<Final_(T)>::type>
|
||||
operator()(const std::vector<T>& v) const {
|
||||
return std::vector<typename result<Final_(T)>::type>(operator()(v.begin()),operator()(v.begin()));
|
||||
}
|
||||
|
||||
//TODO: convert std::list and other containers?
|
||||
|
||||
Object
|
||||
operator()(const Object &obj) const
|
||||
{
|
||||
typedef typename internal::Map_taglist_to_typelist<K1,List_>::type Possibilities;
|
||||
//TODO: add Empty, vector<Point>, etc to the list.
|
||||
return Object_converter<Possibilities>()(obj,*this);
|
||||
}
|
||||
|
||||
//TODO: convert boost::variant
|
||||
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_KERNEL_D_CARTESIAN_CONVERTER_H
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
#ifndef CGAL_KD_KERNEL_2_INTERFACE_H
|
||||
#define CGAL_KD_KERNEL_2_INTERFACE_H
|
||||
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/transforming_iterator.h>
|
||||
#include <CGAL/marcutils.h>
|
||||
#include <CGAL/tuple.h>
|
||||
|
||||
|
||||
namespace CGAL {
|
||||
template <class Base_> struct Kernel_2_interface : public Base_ {
|
||||
typedef Base_ Base;
|
||||
typedef Kernel_2_interface<Base> Kernel;
|
||||
typedef typename Get_type<Base, RT_tag>::type RT;
|
||||
typedef typename Get_type<Base, FT_tag>::type FT;
|
||||
typedef typename Get_type<Base, Bool_tag>::type Boolean;
|
||||
typedef typename Get_type<Base, Sign_tag>::type Sign;
|
||||
typedef typename Get_type<Base, Comparison_result_tag>::type Comparison_result;
|
||||
typedef typename Get_type<Base, Orientation_tag>::type Orientation;
|
||||
typedef typename Get_type<Base, Oriented_side_tag>::type Oriented_side;
|
||||
typedef typename Get_type<Base, Bounded_side_tag>::type Bounded_side;
|
||||
typedef typename Get_type<Base, Angle_tag>::type Angle;
|
||||
typedef typename Get_type<Base, Point_tag>::type Point_2;
|
||||
typedef typename Get_type<Base, Vector_tag>::type Vector_2;
|
||||
typedef typename Get_type<Base, Segment_tag>::type Segment_2;
|
||||
typedef cpp0x::tuple<Point_2,Point_2,Point_2> Triangle_2; // triangulation insists...
|
||||
template <class T,int i> struct Help_2p_i {
|
||||
typedef typename Get_functor<Base, T>::type LT;
|
||||
typedef typename LT::result_type result_type;
|
||||
LT lt;
|
||||
Help_2p_i(Kernel const&k):lt(k){}
|
||||
result_type operator()(Point_2 const&a, Point_2 const&b) {
|
||||
return lt(a,b,i);
|
||||
}
|
||||
};
|
||||
typedef Help_2p_i<Less_point_cartesian_coordinate_tag,0> Less_x_2;
|
||||
typedef Help_2p_i<Less_point_cartesian_coordinate_tag,1> Less_y_2;
|
||||
typedef Help_2p_i<Compare_point_cartesian_coordinate_tag,0> Compare_x_2;
|
||||
typedef Help_2p_i<Compare_point_cartesian_coordinate_tag,1> Compare_y_2;
|
||||
struct Compare_distance_2 {
|
||||
typedef typename Get_functor<Base, Compare_distance_tag>::type CD;
|
||||
typedef typename CD::result_type result_type;
|
||||
CD cd;
|
||||
Compare_distance_2(Kernel const&k):cd(k){}
|
||||
result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c) {
|
||||
return cd(a,b,c);
|
||||
}
|
||||
result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c, Point_2 const&d) {
|
||||
return cd(a,b,c,d);
|
||||
}
|
||||
};
|
||||
struct Orientation_2 {
|
||||
typedef typename Get_functor<Base, Orientation_of_points_tag>::type O;
|
||||
typedef typename O::result_type result_type;
|
||||
O o;
|
||||
Orientation_2(Kernel const&k):o(k){}
|
||||
result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c) {
|
||||
//return o(a,b,c);
|
||||
Point_2 const* t[3]={&a,&b,&c};
|
||||
return o(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+3));
|
||||
|
||||
}
|
||||
};
|
||||
struct Side_of_oriented_circle_2 {
|
||||
typedef typename Get_functor<Base, Side_of_oriented_sphere_tag>::type SOS;
|
||||
typedef typename SOS::result_type result_type;
|
||||
SOS sos;
|
||||
Side_of_oriented_circle_2(Kernel const&k):sos(k){}
|
||||
result_type operator()(Point_2 const&a, Point_2 const&b, Point_2 const&c, Point_2 const&d) {
|
||||
//return sos(a,b,c,d);
|
||||
Point_2 const* t[4]={&a,&b,&c,&d};
|
||||
return sos(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+4));
|
||||
}
|
||||
};
|
||||
Less_x_2 less_x_2_object()const{ return Less_x_2(*this); }
|
||||
Less_y_2 less_y_2_object()const{ return Less_y_2(*this); }
|
||||
Compare_x_2 compare_x_2_object()const{ return Compare_x_2(*this); }
|
||||
Compare_y_2 compare_y_2_object()const{ return Compare_y_2(*this); }
|
||||
Compare_distance_2 compare_distance_2_object()const{ return Compare_distance_2(*this); }
|
||||
Orientation_2 orientation_2_object()const{ return Orientation_2(*this); }
|
||||
Side_of_oriented_circle_2 side_of_oriented_circle_2_object()const{ return Side_of_oriented_circle_2(*this); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
#ifndef CGAL_KD_KERNEL_3_INTERFACE_H
|
||||
#define CGAL_KD_KERNEL_3_INTERFACE_H
|
||||
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/transforming_iterator.h>
|
||||
#include <CGAL/marcutils.h>
|
||||
#include <CGAL/tuple.h>
|
||||
|
||||
|
||||
namespace CGAL {
|
||||
template <class Base_> struct Kernel_3_interface : public Base_ {
|
||||
typedef Base_ Base;
|
||||
typedef Kernel_3_interface<Base> Kernel;
|
||||
typedef typename Get_type<Base, RT_tag>::type RT;
|
||||
typedef typename Get_type<Base, FT_tag>::type FT;
|
||||
typedef typename Get_type<Base, Bool_tag>::type Boolean;
|
||||
typedef typename Get_type<Base, Sign_tag>::type Sign;
|
||||
typedef typename Get_type<Base, Comparison_result_tag>::type Comparison_result;
|
||||
typedef typename Get_type<Base, Orientation_tag>::type Orientation;
|
||||
typedef typename Get_type<Base, Oriented_side_tag>::type Oriented_side;
|
||||
typedef typename Get_type<Base, Bounded_side_tag>::type Bounded_side;
|
||||
typedef typename Get_type<Base, Angle_tag>::type Angle;
|
||||
typedef typename Get_type<Base, Point_tag>::type Point_3;
|
||||
typedef typename Get_type<Base, Vector_tag>::type Vector_3;
|
||||
typedef typename Get_type<Base, Segment_tag>::type Segment_3;
|
||||
typedef cpp0x::tuple<Point_3,Point_3,Point_3> Triangle_3; // placeholder
|
||||
typedef cpp0x::tuple<Point_3,Point_3,Point_3,Point_3> Tetrahedron_3; // placeholder
|
||||
struct Compare_xyz_3 {
|
||||
typedef typename Get_functor<Base, Compare_lexicographically_tag>::type CL;
|
||||
typedef typename CL::result_type result_type;
|
||||
CL cl;
|
||||
Compare_xyz_3(Kernel const&k):cl(k){}
|
||||
result_type operator()(Point_3 const&a, Point_3 const&b) {
|
||||
return cl(a,b);
|
||||
}
|
||||
};
|
||||
struct Compare_distance_3 {
|
||||
typedef typename Get_functor<Base, Compare_distance_tag>::type CD;
|
||||
typedef typename CD::result_type result_type;
|
||||
CD cd;
|
||||
Compare_distance_3(Kernel const&k):cd(k){}
|
||||
result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c) {
|
||||
return cd(a,b,c);
|
||||
}
|
||||
result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c, Point_3 const&d) {
|
||||
return cd(a,b,c,d);
|
||||
}
|
||||
};
|
||||
struct Orientation_3 {
|
||||
typedef typename Get_functor<Base, Orientation_of_points_tag>::type O;
|
||||
typedef typename O::result_type result_type;
|
||||
O o;
|
||||
Orientation_3(Kernel const&k):o(k){}
|
||||
result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c, Point_3 const&d) {
|
||||
//return o(a,b,c,d);
|
||||
Point_3 const* t[4]={&a,&b,&c,&d};
|
||||
return o(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+4));
|
||||
|
||||
}
|
||||
};
|
||||
struct Side_of_oriented_sphere_3 {
|
||||
typedef typename Get_functor<Base, Side_of_oriented_sphere_tag>::type SOS;
|
||||
typedef typename SOS::result_type result_type;
|
||||
SOS sos;
|
||||
Side_of_oriented_sphere_3(Kernel const&k):sos(k){}
|
||||
result_type operator()(Point_3 const&a, Point_3 const&b, Point_3 const&c, Point_3 const&d, Point_3 const&e) {
|
||||
//return sos(a,b,c,d);
|
||||
Point_3 const* t[5]={&a,&b,&c,&d,&e};
|
||||
return sos(make_transforming_iterator<Dereference_functor>(t+0),make_transforming_iterator<Dereference_functor>(t+5));
|
||||
}
|
||||
};
|
||||
|
||||
// I don't have the Coplanar predicates (yet)
|
||||
|
||||
|
||||
Compare_xyz_3 compare_xyz_3_object()const{ return Compare_xyz_3(*this); }
|
||||
Compare_distance_3 compare_distance_3_object()const{ return Compare_distance_3(*this); }
|
||||
Orientation_3 orientation_3_object()const{ return Orientation_3(*this); }
|
||||
Side_of_oriented_sphere_3 side_of_oriented_sphere_3_object()const{ return Side_of_oriented_sphere_3(*this); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
#ifndef CGAL_KD_KERNEL_D_INTERFACE_H
|
||||
#define CGAL_KD_KERNEL_D_INTERFACE_H
|
||||
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/transforming_iterator.h>
|
||||
#include <CGAL/marcutils.h>
|
||||
#include <CGAL/tuple.h>
|
||||
|
||||
|
||||
namespace CGAL {
|
||||
template <class Base_> struct Kernel_d_interface : public Base_ {
|
||||
CGAL_CONSTEXPR Kernel_d_interface(){}
|
||||
CGAL_CONSTEXPR Kernel_d_interface(int d):Base_(d){}
|
||||
|
||||
typedef Base_ Base;
|
||||
typedef Kernel_d_interface<Base> Kernel;
|
||||
typedef Base_ R_; // for the macros
|
||||
typedef typename Get_type<Base, RT_tag>::type RT;
|
||||
typedef typename Get_type<Base, FT_tag>::type FT;
|
||||
typedef typename Get_type<Base, Bool_tag>::type Boolean;
|
||||
typedef typename Get_type<Base, Sign_tag>::type Sign;
|
||||
typedef typename Get_type<Base, Comparison_result_tag>::type Comparison_result;
|
||||
typedef typename Get_type<Base, Orientation_tag>::type Orientation;
|
||||
typedef typename Get_type<Base, Oriented_side_tag>::type Oriented_side;
|
||||
typedef typename Get_type<Base, Bounded_side_tag>::type Bounded_side;
|
||||
typedef typename Get_type<Base, Angle_tag>::type Angle;
|
||||
typedef typename Get_type<Base, Flat_orientation_tag>::type Flat_orientation_d;
|
||||
typedef typename Get_type<Base, Point_tag>::type Point_d;
|
||||
typedef typename Get_type<Base, Vector_tag>::type Vector_d;
|
||||
typedef typename Get_type<Base, Segment_tag>::type Segment_d;
|
||||
typedef typename Get_type<Base, Sphere_tag>::type Sphere_d;
|
||||
typedef typename Get_type<Base, Hyperplane_tag>::type Hyperplane_d;
|
||||
typedef Vector_d Direction_d;
|
||||
typedef typename Get_type<Base, Line_tag>::type Line_d;
|
||||
typedef typename Get_type<Base, Ray_tag>::type Ray_d;
|
||||
typedef typename Get_type<Base, Iso_box_tag>::type Iso_box_d;
|
||||
typedef typename Get_type<Base, Aff_transformation_tag>::type Aff_transformation_d;
|
||||
typedef typename Get_functor<Base, Compute_point_cartesian_coordinate_tag>::type Compute_coordinate_d;
|
||||
typedef typename Get_functor<Base, Compare_lexicographically_tag>::type Compare_lexicographically_d;
|
||||
typedef typename Get_functor<Base, Equal_points_tag>::type Equal_d;
|
||||
typedef typename Get_functor<Base, Less_lexicographically_tag>::type Less_lexicographically_d;
|
||||
typedef typename Get_functor<Base, Less_or_equal_lexicographically_tag>::type Less_or_equal_lexicographically_d;
|
||||
// FIXME: and vectors?
|
||||
typedef typename Get_functor<Base, Orientation_of_points_tag>::type Orientation_d;
|
||||
typedef typename Get_functor<Base, Less_point_cartesian_coordinate_tag>::type Less_coordinate_d;
|
||||
typedef typename Get_functor<Base, Point_dimension_tag>::type Point_dimension_d;
|
||||
typedef typename Get_functor<Base, Side_of_oriented_sphere_tag>::type Side_of_oriented_sphere_d;
|
||||
typedef typename Get_functor<Base, Contained_in_affine_hull_tag>::type Contained_in_affine_hull_d;
|
||||
typedef typename Get_functor<Base, Construct_flat_orientation_tag>::type Construct_flat_orientation_d;
|
||||
typedef typename Get_functor<Base, In_flat_orientation_tag>::type In_flat_orientation_d;
|
||||
typedef typename Get_functor<Base, In_flat_side_of_oriented_sphere_tag>::type In_flat_side_of_oriented_sphere_d;
|
||||
typedef typename Get_functor<Base, Point_to_vector_tag>::type Point_to_vector_d;
|
||||
typedef typename Get_functor<Base, Vector_to_point_tag>::type Vector_to_point_d;
|
||||
typedef typename Get_functor<Base, Construct_ttag<Point_tag> >::type Construct_point_d;
|
||||
typedef typename Get_functor<Base, Construct_ttag<Vector_tag> >::type Construct_vector_d;
|
||||
typedef typename Get_functor<Base, Construct_ttag<Segment_tag> >::type Construct_segment_d;
|
||||
typedef typename Get_functor<Base, Construct_ttag<Sphere_tag> >::type Construct_sphere_d;
|
||||
typedef typename Get_functor<Base, Construct_ttag<Hyperplane_tag> >::type Construct_hyperplane_d;
|
||||
typedef Construct_vector_d Construct_direction_d;
|
||||
typedef typename Get_functor<Base, Construct_ttag<Line_tag> >::type Construct_line_d;
|
||||
typedef typename Get_functor<Base, Construct_ttag<Ray_tag> >::type Construct_ray_d;
|
||||
typedef typename Get_functor<Base, Construct_ttag<Iso_box_tag> >::type Construct_iso_box_d;
|
||||
typedef typename Get_functor<Base, Construct_ttag<Aff_transformation_tag> >::type Construct_aff_transformation_d;
|
||||
typedef typename Get_functor<Base, Midpoint_tag>::type Midpoint_d;
|
||||
struct Component_accessor_d : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Component_accessor_d)
|
||||
int dimension(Point_d const&p){
|
||||
return this->kernel().point_dimension_d_object()(p);
|
||||
}
|
||||
FT cartesian(Point_d const&p, int i){
|
||||
return this->kernel().compute_coordinate_d_object()(p);
|
||||
}
|
||||
RT homogeneous(Point_d const&p, int i){
|
||||
throw "not implemented yet";
|
||||
return 0;
|
||||
// FIXME
|
||||
//return this->kernel().compute_coordinate_d_object()(p);
|
||||
}
|
||||
};
|
||||
struct Construct_cartesian_const_iterator_d : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Construct_cartesian_const_iterator_d)
|
||||
typedef typename Get_functor<Base, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CPI;
|
||||
typedef typename Get_functor<Base, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CVI;
|
||||
typedef typename CGAL::decay<typename boost::result_of<CPI(Point_d,CGAL::Begin_tag)>::type>::type result_type;
|
||||
// Kernel_d requires a common iterator type for points and vectors
|
||||
// TODO: provide this mixed functor in preKernel?
|
||||
CGAL_static_assertion((boost::is_same<typename CGAL::decay<typename boost::result_of<CVI(Vector_d,CGAL::Begin_tag)>::type>::type, result_type>::value));
|
||||
template <class Tag_>
|
||||
result_type operator()(Point_d const&p, Tag_ t)const{
|
||||
return CPI(this->kernel())(p,t);
|
||||
}
|
||||
template <class Tag_>
|
||||
result_type operator()(typename First_if_different<Vector_d,Point_d>::Type const&v, Tag_ t)const{
|
||||
return CVI(this->kernel())(v,t);
|
||||
}
|
||||
|
||||
template <class Obj>
|
||||
result_type operator()(Obj const&o)const{
|
||||
return operator()(o, Begin_tag());
|
||||
}
|
||||
result_type operator()(Point_d const&p, int)const{
|
||||
return operator()(p, End_tag());
|
||||
}
|
||||
result_type operator()(typename First_if_different<Vector_d,Point_d>::Type const&v, int)const{
|
||||
return operator()(v, End_tag());
|
||||
}
|
||||
};
|
||||
typedef typename Construct_cartesian_const_iterator_d::result_type Cartesian_const_iterator_d;
|
||||
typedef typename Get_functor<Base, Squared_distance_tag>::type Squared_distance_d;
|
||||
//typedef typename Get_functor<Base, Affine_rank_tag>::type Affine_rank_d;
|
||||
//typedef typename Get_functor<Base, Affinely_independent_tag>::type Affinely_independent_d;
|
||||
//typedef typename Get_functor<Base, Contained_in_linear_hull_tag>::type Contained_in_linear_hull_d;
|
||||
//typedef typename Get_functor<Base, Contained_in_simplex_tag>::type Contained_in_simplex_d;
|
||||
typedef typename Get_functor<Base, Has_on_positive_side_tag>::type Has_on_positive_side_d;
|
||||
//typedef typename Get_functor<Base, Linear_rank_tag>::type Linear_rank_d;
|
||||
//typedef typename Get_functor<Base, Linearly_independent_tag>::type Linearly_independent_d;
|
||||
typedef typename Get_functor<Base, Oriented_side_tag>::type Oriented_side_d;
|
||||
//typedef typename Get_functor<Base, Side_of_bounded_sphere_tag>::type Side_of_bounded_sphere_d;
|
||||
|
||||
typedef typename Get_functor<Base, Center_of_sphere_tag>::type Center_of_sphere_d;
|
||||
typedef typename Get_functor<Base, Value_at_tag>::type Value_at_d;
|
||||
typedef typename Get_functor<Base, Point_of_sphere_tag>::type Point_of_sphere_d;
|
||||
typedef typename Get_functor<Base, Orthogonal_vector_tag>::type Orthogonal_vector_d;
|
||||
//typedef typename Get_functor<Base, Linear_base_tag>::type Linear_base_d;
|
||||
|
||||
//typedef ??? Intersect_d;
|
||||
|
||||
|
||||
Compute_coordinate_d compute_coordinate_d_object()const{ return Compute_coordinate_d(*this); }
|
||||
Compare_lexicographically_d compare_lexicographically_d_object()const{ return Compare_lexicographically_d(*this); }
|
||||
Equal_d equal_d_object()const{ return Equal_d(*this); }
|
||||
Less_lexicographically_d less_lexicographically_d_object()const{ return Less_lexicographically_d(*this); }
|
||||
Less_or_equal_lexicographically_d less_or_equal_lexicographically_d_object()const{ return Less_or_equal_lexicographically_d(*this); }
|
||||
Less_coordinate_d less_coordinate_d_object()const{ return Less_coordinate_d(*this); }
|
||||
Orientation_d orientation_d_object()const{ return Orientation_d(*this); }
|
||||
Point_dimension_d point_dimension_d_object()const{ return Point_dimension_d(*this); }
|
||||
Side_of_oriented_sphere_d side_of_oriented_sphere_d_object()const{ return Side_of_oriented_sphere_d(*this); }
|
||||
Contained_in_affine_hull_d contained_in_affine_hull_d_object()const{ return Contained_in_affine_hull_d(*this); }
|
||||
Construct_flat_orientation_d construct_flat_orientation_d_object()const{ return Construct_flat_orientation_d(*this); }
|
||||
In_flat_orientation_d in_flat_orientation_d_object()const{ return In_flat_orientation_d(*this); }
|
||||
In_flat_side_of_oriented_sphere_d in_flat_side_of_oriented_sphere_d_object()const{ return In_flat_side_of_oriented_sphere_d(*this); }
|
||||
Point_to_vector_d point_to_vector_d_object()const{ return Point_to_vector_d(*this); }
|
||||
Vector_to_point_d vector_to_point_d_object()const{ return Vector_to_point_d(*this); }
|
||||
Midpoint_d midpoint_d_object()const{ return Midpoint_d(*this); }
|
||||
Component_accessor_d component_accessor_d_object()const{ return Component_accessor_d(*this); }
|
||||
Orthogonal_vector_d orthogonal_vector_d_object()const{ return Orthogonal_vector_d(*this); }
|
||||
Construct_cartesian_const_iterator_d construct_cartesian_const_iterator_d_object()const{ return Construct_cartesian_const_iterator_d(*this); }
|
||||
Construct_point_d construct_point_d_object()const{ return Construct_point_d(*this); }
|
||||
Construct_vector_d construct_vector_d_object()const{ return Construct_vector_d(*this); }
|
||||
Construct_segment_d construct_segment_d_object()const{ return Construct_segment_d(*this); }
|
||||
Construct_sphere_d construct_sphere_d_object()const{ return Construct_sphere_d(*this); }
|
||||
Construct_hyperplane_d construct_hyperplane_d_object()const{ return Construct_hyperplane_d(*this); }
|
||||
Squared_distance_d squared_distance_d_object()const{ return Squared_distance_d(*this); }
|
||||
Construct_direction_d construct_direction_d_object()const{ return Construct_direction_d(*this); }
|
||||
Construct_line_d construct_line_d_object()const{ return Construct_line_d(*this); }
|
||||
Construct_ray_d construct_ray_d_object()const{ return Construct_ray_d(*this); }
|
||||
Construct_iso_box_d construct_iso_box_d_object()const{ return Construct_iso_box_d(*this); }
|
||||
Construct_aff_transformation_d construct_aff_transformation_d_object()const{ return Construct_aff_transformation_d(*this); }
|
||||
|
||||
// Dummies for those required functors missing a concept.
|
||||
typedef Null_functor Position_on_line_d;
|
||||
Position_on_line_d position_on_line_d_object()const{return Null_functor();}
|
||||
typedef Null_functor Barycentric_coordinates_d;
|
||||
Barycentric_coordinates_d barycentric_coordinates_d_object()const{return Null_functor();}
|
||||
|
||||
/* Not provided because they don't make sense here:
|
||||
Lift_to_paraboloid_d
|
||||
Project_along_d_axis_d
|
||||
*/
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CGAL_KD_KERNEL_D_INTERFACE_H
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
#ifndef CGAL_KD_KO_CONVERTER_H
|
||||
#define CGAL_KD_KO_CONVERTER_H
|
||||
#include <CGAL/marcutils.h>
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Kernel/mpl.h> // First_if_different
|
||||
namespace CGAL {
|
||||
template <class Tag_, class K1, class K2> struct KO_converter;
|
||||
//TODO: It would probably be better if this was a Misc Functor in K1.
|
||||
// This way K1 could chose how it wants to present its points (sparse
|
||||
// iterator?) and derived classes would inherit it.
|
||||
|
||||
namespace internal {
|
||||
template <class D /*=Dynamic_dimension_tag*/, class K1, class K2>
|
||||
struct Point_converter_help {
|
||||
typedef typename Get_type<K1, Point_tag>::type argument_type;
|
||||
typedef typename Get_type<K2, Point_tag>::type result_type;
|
||||
template <class C>
|
||||
result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& p) const {
|
||||
typename Get_functor<K1, Construct_ttag<Point_cartesian_const_iterator_tag> >::type i(k1);
|
||||
typename Get_functor<K2, Construct_ttag<Point_tag> >::type cp(k2);
|
||||
return cp(conv(i(p,Begin_tag())),conv(i(p,End_tag())));
|
||||
}
|
||||
};
|
||||
#ifdef CGAL_CXX0X
|
||||
// This doesn't seem so useful, the compiler should be able to handle
|
||||
// the iterators just as efficiently.
|
||||
template <int d, class K1, class K2>
|
||||
struct Point_converter_help<Dimension_tag<d>,K1,K2> {
|
||||
typedef typename Get_type<K1, Point_tag>::type argument_type;
|
||||
typedef typename Get_type<K2, Point_tag>::type result_type;
|
||||
template <class C,int...I>
|
||||
result_type help(Indices<I...>, K1 const& k1, K2 const& k2, C const& conv, argument_type const& p) const {
|
||||
typename Get_functor<K1, Compute_point_cartesian_coordinate_tag>::type cc(k1);
|
||||
typename Get_functor<K2, Construct_ttag<Point_tag> >::type cp(k2);
|
||||
return cp(conv(cc(p,I))...);
|
||||
}
|
||||
template <class C>
|
||||
result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& p) const {
|
||||
return help(typename N_increasing_indices<d>::type(),k1,k2,conv,p);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
}
|
||||
template <class K1, class K2> struct KO_converter<Point_tag,K1,K2>
|
||||
: internal::Point_converter_help<typename K1::Default_ambient_dimension,K1,K2>
|
||||
{};
|
||||
|
||||
template <class K1, class K2> struct KO_converter<Vector_tag,K1,K2>{
|
||||
typedef typename Get_type<K1, Vector_tag>::type K1_Vector;
|
||||
|
||||
// Disabling is now done in KernelD_converter
|
||||
// // can't use vector without at least a placeholder point because of this
|
||||
// typedef typename K1:: Point K1_Point;
|
||||
// typedef typename First_if_different<K1_Vector,K1_Point>::Type argument_type;
|
||||
|
||||
typedef K1_Vector argument_type;
|
||||
typedef typename Get_type<K2, Vector_tag>::type result_type;
|
||||
template <class C>
|
||||
result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& v) const {
|
||||
typename Get_functor<K1, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type i(k1);
|
||||
typename Get_functor<K2, Construct_ttag<Vector_tag> >::type cp(k2);
|
||||
return cp(conv(i(v,Begin_tag())),conv(i(v,End_tag())));
|
||||
}
|
||||
};
|
||||
|
||||
template <class K1, class K2> struct KO_converter<Segment_tag,K1,K2>{
|
||||
typedef typename Get_type<K1, Segment_tag>::type argument_type;
|
||||
typedef typename Get_type<K2, Segment_tag>::type result_type;
|
||||
template <class C>
|
||||
result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& s) const {
|
||||
typename Get_functor<K1, Segment_extremity_tag>::type f(k1);
|
||||
typename Get_functor<K2, Construct_ttag<Segment_tag> >::type cs(k2);
|
||||
return cs(conv(f(s,0)),conv(f(s,1)));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
#ifndef CGAL_KERNEL_D_LAZY_CARTESIAN_H
|
||||
#define CGAL_KERNEL_D_LAZY_CARTESIAN_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/algorithm.h>
|
||||
#include <CGAL/Lazy.h>
|
||||
#include <CGAL/Default.h>
|
||||
#include <CGAL/Filtered_predicate2.h>
|
||||
#include <CGAL/iterator_from_indices.h>
|
||||
#include <CGAL/Kernel_d/Define_kernel_types.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template<class K,class T>
|
||||
struct Nth_iterator_element : private Store_kernel<K> {
|
||||
Nth_iterator_element(){}
|
||||
Nth_iterator_element(K const&k):Store_kernel<K>(k){}
|
||||
typedef typename Get_type<K, typename iterator_tag_traits<T>::value_tag>::type result_type;
|
||||
template<class U> result_type operator()(CGAL_FORWARDABLE(U) u, int i) const {
|
||||
typename Get_functor<K, Construct_ttag<T> >::type ci(this->kernel());
|
||||
return *cpp0x::next(ci(CGAL_FORWARD(U,u),Begin_tag()),i);
|
||||
}
|
||||
};
|
||||
//typedef typename Functor<typename iterator_tag_traits<T>::nth_element>::type nth_elem;
|
||||
template<class K, class T, bool = iterator_tag_traits<T>::has_nth_element>
|
||||
struct Select_nth_element_functor {
|
||||
typedef Nth_iterator_element<K, T> type;
|
||||
};
|
||||
template<class K, class T>
|
||||
struct Select_nth_element_functor <K, T, true> :
|
||||
Get_functor<K, typename iterator_tag_traits<T>::nth_element> {};
|
||||
|
||||
namespace internal {
|
||||
template<class A,class B,class C,bool/*is_NT=false*/>
|
||||
struct Lazy_construction_maybe_nt {
|
||||
typedef Lazy_construction<A,B,C> type;
|
||||
};
|
||||
template<class A,class B,class C>
|
||||
struct Lazy_construction_maybe_nt<A,B,C,true> {
|
||||
typedef Lazy_construction_nt<A,B,C> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <class EK_, class AK_, class E2A_, class Kernel_>
|
||||
struct Lazy_cartesian_types
|
||||
{
|
||||
typedef typename typeset_intersection<
|
||||
typename AK_::Object_list,
|
||||
typename EK_::Object_list
|
||||
>::type Object_list;
|
||||
|
||||
typedef typename typeset_intersection<
|
||||
typename AK_::Iterator_list,
|
||||
typename EK_::Iterator_list
|
||||
>::type Iterator_list;
|
||||
|
||||
template <class T,class=typename Get_type_category<Kernel_,T>::type> struct Type {};
|
||||
template <class T> struct Type<T,Object_tag> {
|
||||
typedef Lazy<
|
||||
typename Get_type<AK_,T>::type,
|
||||
typename Get_type<EK_,T>::type,
|
||||
typename Get_type<EK_, FT_tag>::type,
|
||||
E2A_> type;
|
||||
};
|
||||
template <class T> struct Type<T,Number_tag> {
|
||||
typedef CGAL::Lazy_exact_nt<typename Get_type<EK_,T>::type> type;
|
||||
};
|
||||
|
||||
template <class T> struct Iterator {
|
||||
typedef typename iterator_tag_traits<T>::value_tag Vt;
|
||||
typedef typename Type<Vt>::type V;
|
||||
typedef typename Select_nth_element_functor<AK_,T>::type AF;
|
||||
typedef typename Select_nth_element_functor<EK_,T>::type EF;
|
||||
|
||||
typedef typename internal::Lazy_construction_maybe_nt<
|
||||
Kernel_, AF, EF, is_NT_tag<Vt>::value
|
||||
>::type nth_elem;
|
||||
|
||||
typedef Iterator_from_indices<
|
||||
const typename Type<typename iterator_tag_traits<T>::container>::type,
|
||||
const V, V, nth_elem
|
||||
> type;
|
||||
};
|
||||
};
|
||||
|
||||
template <class EK_, class AK_, class E2A_/*, class Kernel_=Default*/>
|
||||
struct Lazy_cartesian : Dimension_base<typename EK_::Default_ambient_dimension>,
|
||||
Lazy_cartesian_types<EK_,AK_,E2A_,Lazy_cartesian<EK_,AK_,E2A_> >
|
||||
{
|
||||
//CGAL_CONSTEXPR Lazy_cartesian(){}
|
||||
//CGAL_CONSTEXPR Lazy_cartesian(int d):Base_(d){}
|
||||
|
||||
//TODO: Do we want to store an AK and an EK? Or just references?
|
||||
//FIXME: references would be better I guess.
|
||||
//TODO: In any case, make sure that we don't end up storing this kernel for
|
||||
//nothing (it is not empty but references empty kernels or something)
|
||||
AK_ ak; EK_ ek;
|
||||
AK_ const& approximate_kernel()const{return ak;}
|
||||
EK_ const& exact_kernel()const{return ek;}
|
||||
|
||||
typedef Lazy_cartesian Self;
|
||||
typedef Lazy_cartesian_types<EK_,AK_,E2A_,Self> Base;
|
||||
//typedef typename Default::Get<Kernel_,Self>::type Kernel;
|
||||
typedef Self Kernel;
|
||||
typedef AK_ Approximate_kernel;
|
||||
typedef EK_ Exact_kernel;
|
||||
typedef E2A_ E2A;
|
||||
typedef Approx_converter<Kernel, Approximate_kernel> C2A;
|
||||
typedef Exact_converter<Kernel, Exact_kernel> C2E;
|
||||
|
||||
typedef typename Exact_kernel::Rep_tag Rep_tag;
|
||||
typedef typename Exact_kernel::Kernel_tag Kernel_tag;
|
||||
typedef typename Exact_kernel::Default_ambient_dimension Default_ambient_dimension;
|
||||
typedef typename Exact_kernel::Max_ambient_dimension Max_ambient_dimension;
|
||||
//typedef typename Exact_kernel::Flat_orientation Flat_orientation;
|
||||
// Check that Approximate_kernel agrees with all that...
|
||||
|
||||
template<class T,class D=void,class=typename Get_functor_category<Lazy_cartesian,T,D>::type> struct Functor {
|
||||
typedef Null_functor type;
|
||||
};
|
||||
//FIXME: what do we do with D here?
|
||||
template<class T,class D> struct Functor<T,D,Predicate_tag> {
|
||||
typedef typename Get_functor<Approximate_kernel, T>::type FA;
|
||||
typedef typename Get_functor<Exact_kernel, T>::type FE;
|
||||
typedef Filtered_predicate2<FE,FA,C2E,C2A> type;
|
||||
};
|
||||
template<class T,class D> struct Functor<T,D,Compute_tag> {
|
||||
typedef typename Get_functor<Approximate_kernel, T>::type FA;
|
||||
typedef typename Get_functor<Exact_kernel, T>::type FE;
|
||||
typedef Lazy_construction_nt<Kernel,FA,FE> type;
|
||||
};
|
||||
template<class T,class D> struct Functor<T,D,Construct_tag> {
|
||||
typedef typename Get_functor<Approximate_kernel, T>::type FA;
|
||||
typedef typename Get_functor<Exact_kernel, T>::type FE;
|
||||
typedef Lazy_construction<Kernel,FA,FE> type;
|
||||
};
|
||||
|
||||
//typedef typename Iterator<Point_cartesian_const_iterator_tag>::type Point_cartesian_const_iterator;
|
||||
//typedef typename Iterator<Vector_cartesian_const_iterator_tag>::type Vector_cartesian_const_iterator;
|
||||
|
||||
template<class U>
|
||||
struct Construct_iter : private Store_kernel<Kernel> {
|
||||
Construct_iter(){}
|
||||
Construct_iter(Kernel const&k):Store_kernel<Kernel>(k){}
|
||||
//FIXME: pass the kernel to the functor in the iterator
|
||||
typedef U result_type;
|
||||
template<class T>
|
||||
result_type operator()(T const& t,Begin_tag)const{
|
||||
return result_type(t,0,this->kernel());
|
||||
}
|
||||
template<class T>
|
||||
result_type operator()(T const& t,End_tag)const{
|
||||
return result_type(t,Self().dimension(),this->kernel());
|
||||
}
|
||||
};
|
||||
template<class T,class D> struct Functor<T,D,Construct_iterator_tag> {
|
||||
typedef Construct_iter<typename Base::template Iterator<typename map_result_tag<T>::type>::type> type;
|
||||
};
|
||||
|
||||
|
||||
//TODO: what about other functors of the Misc category?
|
||||
// for Point_dimension, we should apply it to the approximate point
|
||||
// for printing, we should??? just not do printing this way?
|
||||
};
|
||||
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_KERNEL_D_LAZY_CARTESIAN_H
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef CGAL_KD_TYPE_AFF_TRANSFORMATION_H
|
||||
#define CGAL_KD_TYPE_AFF_TRANSFORMATION_H
|
||||
#include <CGAL/store_kernel.h>
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
|
||||
// Dummy, that's all the Kernel_d concept requires, so a useful class will wait.
|
||||
|
||||
namespace CGAL {
|
||||
template<class R_>
|
||||
struct Aff_transformation {
|
||||
typedef R_ R;
|
||||
};
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Construct_aff_transformation {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Construct_aff_transformation)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Aff_transformation_tag>::type result_type;
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...T>
|
||||
result_type operator()(T&&...)const{return result_type();}
|
||||
#else
|
||||
result_type operator()()const{
|
||||
return result_type();
|
||||
}
|
||||
#define CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class U)> \
|
||||
result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const& BOOST_PP_INTERCEPT))const{ \
|
||||
return result_type(); \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1, 9, CODE, _ )
|
||||
#undef CODE
|
||||
|
||||
#endif
|
||||
};
|
||||
}
|
||||
CGAL_KD_DEFAULT_TYPE(Aff_transformation_tag,(CGAL::Aff_transformation<K>),(),());
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Aff_transformation_tag>,(CartesianDKernelFunctors::Construct_aff_transformation<K>),(Aff_transformation_tag),());
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
#ifndef CGAL_KD_TYPE_HYPERPLANE_H
|
||||
#define CGAL_KD_TYPE_HYPERPLANE_H
|
||||
#include <CGAL/store_kernel.h>
|
||||
namespace CGAL {
|
||||
template <class R_> class Hyperplane {
|
||||
typedef typename Get_type<R_, FT_tag>::type FT_;
|
||||
typedef typename Get_type<R_, Vector_tag>::type Vector_;
|
||||
Vector_ v_;
|
||||
FT_ s_;
|
||||
|
||||
public:
|
||||
Hyperplane(Vector_ const&v, FT_ const&s): v_(v), s_(s) {}
|
||||
// TODO: Add a piecewise constructor?
|
||||
|
||||
Vector_ orthogonal_vector()const{return v_;}
|
||||
FT_ translation()const{return s_;}
|
||||
};
|
||||
namespace CartesianDKernelFunctors {
|
||||
template <class R_> struct Construct_hyperplane : Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Construct_hyperplane)
|
||||
typedef typename Get_type<R_, Hyperplane_tag>::type result_type;
|
||||
typedef typename Get_type<R_, Vector_tag>::type Vector;
|
||||
typedef typename Get_type<R_, FT_tag>::type FT;
|
||||
typedef typename R_::LA LA;
|
||||
result_type operator()(Vector const&a, FT const&b)const{
|
||||
return result_type(a,b);
|
||||
}
|
||||
template <class Iter>
|
||||
result_type operator()(Iter f, Iter e)const{
|
||||
throw "not implemented yet!";
|
||||
}
|
||||
};
|
||||
template <class R_> struct Orthogonal_vector {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Orthogonal_vector)
|
||||
typedef typename Get_type<R_, Hyperplane_tag>::type Hyperplane;
|
||||
typedef typename Get_type<R_, Vector_tag>::type result_type;
|
||||
result_type operator()(Hyperplane const&s)const{
|
||||
return s.orthogonal_vector();
|
||||
}
|
||||
};
|
||||
template <class R_> struct Hyperplane_translation {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Hyperplane_translation)
|
||||
typedef typename Get_type<R_, Hyperplane_tag>::type Hyperplane;
|
||||
typedef typename Get_type<R_, FT_tag>::type result_type;
|
||||
// TODO: Is_exact?
|
||||
result_type operator()(Hyperplane const&s)const{
|
||||
return s.translation();
|
||||
}
|
||||
};
|
||||
template <class R_> struct Value_at : Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Value_at)
|
||||
typedef typename Get_type<R_, Hyperplane_tag>::type Hyperplane;
|
||||
typedef typename Get_type<R_, Vector_tag>::type Vector;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point;
|
||||
typedef typename Get_type<R_, FT_tag>::type FT;
|
||||
typedef FT result_type;
|
||||
typedef typename Get_functor<R_, Scalar_product_tag>::type Dot;
|
||||
typedef typename Get_functor<R_, Point_to_vector_tag>::type P2V;
|
||||
result_type operator()(Hyperplane const&h, Point const&p)const{
|
||||
Dot dot(this->kernel());
|
||||
P2V p2v(this->kernel());
|
||||
return dot(h.orthogonal_vector(),p2v(p));
|
||||
// Use Orthogonal_vector to make it generic?
|
||||
// Copy the code from Scalar_product to avoid p2v?
|
||||
}
|
||||
template <class Iter>
|
||||
result_type operator()(Iter f, Iter e)const{
|
||||
throw "not implemented yet!";
|
||||
}
|
||||
};
|
||||
}
|
||||
//TODO: Add a condition that the hyperplane type is the one from this file.
|
||||
CGAL_KD_DEFAULT_TYPE(Hyperplane_tag,(CGAL::Hyperplane<K>),(Vector_tag),());
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Hyperplane_tag>,(CartesianDKernelFunctors::Construct_hyperplane<K>),(Vector_tag,Hyperplane_tag),());
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Orthogonal_vector_tag,(CartesianDKernelFunctors::Orthogonal_vector<K>),(Vector_tag,Hyperplane_tag),());
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Hyperplane_translation_tag,(CartesianDKernelFunctors::Hyperplane_translation<K>),(Hyperplane_tag),());
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Value_at_tag,(CartesianDKernelFunctors::Value_at<K>),(Point_tag,Vector_tag,Hyperplane_tag),(Scalar_product_tag,Point_to_vector_tag));
|
||||
} // namespace CGAL
|
||||
#endif
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef CGAL_KERNELD_TYPES_ISO_BOX_H
|
||||
#define CGAL_KERNELD_TYPES_ISO_BOX_H
|
||||
#include <utility>
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Kernel/mpl.h>
|
||||
#include <CGAL/transforming_pair_iterator.h>
|
||||
namespace CGAL {
|
||||
template <class R_> class Iso_box {
|
||||
typedef typename Get_type<R_, FT_tag>::type FT_;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point_;
|
||||
typedef std::pair<Point_,Point_> Data_;
|
||||
Data_ data;
|
||||
public:
|
||||
Iso_box(){}
|
||||
Iso_box(Point_ const&a, Point_ const&b): data(a,b) {}
|
||||
Point_ min()const{
|
||||
return data.first;
|
||||
}
|
||||
Point_ max()const{
|
||||
return data.second;
|
||||
}
|
||||
};
|
||||
namespace CartesianDKernelFunctors {
|
||||
template <class R_> struct Construct_iso_box : Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Construct_iso_box)
|
||||
typedef typename Get_type<R_, Iso_box_tag>::type result_type;
|
||||
typedef typename Get_type<R_, RT_tag>::type RT;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point;
|
||||
typedef typename Get_functor<R_, Construct_ttag<Point_tag> >::type Cp_;
|
||||
typedef typename Get_functor<R_, Construct_ttag<Point_cartesian_const_iterator_tag> >::type Ci_;
|
||||
result_type operator()(Point const&a, Point const&b)const{
|
||||
Cp_ cp(this->kernel());
|
||||
Ci_ ci(this->kernel());
|
||||
return result_type(cp(
|
||||
make_transforming_pair_iterator(ci(a,Begin_tag()), ci(b,Begin_tag()), Min<RT>()),
|
||||
make_transforming_pair_iterator(ci(a,End_tag()), ci(b,End_tag()), Min<RT>())),
|
||||
cp(
|
||||
make_transforming_pair_iterator(ci(a,Begin_tag()), ci(b,Begin_tag()), Max<RT>()),
|
||||
make_transforming_pair_iterator(ci(a,End_tag()), ci(b,End_tag()), Max<RT>())));
|
||||
}
|
||||
};
|
||||
}
|
||||
CGAL_KD_DEFAULT_TYPE(Iso_box_tag,(CGAL::Iso_box<K>),(Point_tag),());
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Iso_box_tag>,(CartesianDKernelFunctors::Construct_iso_box<K>),(Iso_box_tag,Point_tag),(Construct_ttag<Point_cartesian_const_iterator_tag>,Construct_ttag<Point_tag>));
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_KERNELD_TYPES_ISO_BOX_H
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef CGAL_KERNELD_TYPES_LINE_H
|
||||
#define CGAL_KERNELD_TYPES_LINE_H
|
||||
#include <utility>
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Kernel/mpl.h>
|
||||
namespace CGAL {
|
||||
template <class R_> class Line {
|
||||
typedef typename Get_type<R_, FT_tag>::type FT_;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point_;
|
||||
typedef std::pair<Point_,Point_> Data_;
|
||||
Data_ data;
|
||||
public:
|
||||
Line(){}
|
||||
Line(Point_ const&a, Point_ const&b): data(a,b) {}
|
||||
Point_ point(int i)const{
|
||||
if(i==0) return data.first;
|
||||
if(i==1) return data.second;
|
||||
throw "not implemented";
|
||||
}
|
||||
Line opposite()const{
|
||||
return Line(data.second,data.first);
|
||||
}
|
||||
};
|
||||
namespace CartesianDKernelFunctors {
|
||||
template <class R_> struct Construct_line : Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Construct_line)
|
||||
typedef typename Get_type<R_, Line_tag>::type result_type;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point;
|
||||
typedef typename Get_type<R_, Vector_tag>::type Vector;
|
||||
typedef typename Get_functor<R_, Translated_point_tag>::type Tp_;
|
||||
//typedef typename Get_functor<R_, Difference_of_points_tag>::type Dp_;
|
||||
//typedef typename Get_functor<R_, Scaled_vector_tag>::type Sv_;
|
||||
result_type operator()(Point const&a, Point const&b)const{
|
||||
return result_type(a,b);
|
||||
}
|
||||
result_type operator()(Point const&a, typename First_if_different<Vector,Point>::Type const&b)const{
|
||||
Tp_ tp(this->kernel());
|
||||
return result_type(a,tp(a,b));
|
||||
}
|
||||
};
|
||||
}
|
||||
CGAL_KD_DEFAULT_TYPE(Line_tag,(CGAL::Line<K>),(Point_tag),());
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Line_tag>,(CartesianDKernelFunctors::Construct_line<K>),(Line_tag,Point_tag,Vector_tag),(Translated_point_tag));
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_KERNELD_TYPES_LINE_H
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef CGAL_KERNELD_TYPES_RAY_H
|
||||
#define CGAL_KERNELD_TYPES_RAY_H
|
||||
#include <utility>
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Kernel/mpl.h>
|
||||
namespace CGAL {
|
||||
template <class R_> class Ray {
|
||||
typedef typename Get_type<R_, FT_tag>::type FT_;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point_;
|
||||
typedef typename Get_type<R_, Vector_tag>::type Vector_;
|
||||
typedef std::pair<Point_,Vector_> Data_;
|
||||
Data_ data;
|
||||
public:
|
||||
Ray(){}
|
||||
Ray(Point_ const&a, Vector_ const&b): data(a,b) {}
|
||||
Point_ source()const{
|
||||
return data.first;
|
||||
}
|
||||
// FIXME: return a R_::Direction?
|
||||
Vector_ direction()const{
|
||||
return data.second;
|
||||
}
|
||||
};
|
||||
namespace CartesianDKernelFunctors {
|
||||
template <class R_> struct Construct_ray : Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Construct_ray)
|
||||
typedef typename Get_type<R_, Ray_tag>::type result_type;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point;
|
||||
typedef typename Get_type<R_, Vector_tag>::type Vector;
|
||||
typedef typename Get_functor<R_, Difference_of_points_tag>::type Dp_;
|
||||
//typedef typename Get_functor<R_, Translated_point_tag>::type Tp_;
|
||||
//typedef typename Get_functor<R_, Scaled_vector_tag>::type Sv_;
|
||||
result_type operator()(Point const&a, Vector const&b)const{
|
||||
return result_type(a,b);
|
||||
}
|
||||
result_type operator()(Point const&a, typename First_if_different<Point,Vector>::Type const&b)const{
|
||||
Dp_ dp(this->kernel());
|
||||
return result_type(a,dp(b,a));
|
||||
}
|
||||
};
|
||||
}
|
||||
CGAL_KD_DEFAULT_TYPE(Ray_tag,(CGAL::Ray<K>),(Point_tag,Vector_tag),());
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Ray_tag>,(CartesianDKernelFunctors::Construct_ray<K>),(Point_tag,Ray_tag,Vector_tag),(Difference_of_points_tag));
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_KERNELD_TYPES_RAY_H
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
#ifndef CGAL_KERNELD_SEGMENTD_H
|
||||
#define CGAL_KERNELD_SEGMENTD_H
|
||||
#include <utility>
|
||||
#include <CGAL/functor_tags.h>
|
||||
namespace CGAL {
|
||||
template <class R_> class Segment {
|
||||
typedef typename Get_type<R_, FT_tag>::type FT_;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point_;
|
||||
//typedef typename R_::Vector Vector_;
|
||||
//typedef typename Get_functor<R_, Construct_ttag<Vector_tag> >::type Cv_;
|
||||
// typedef typename R_::Squared_distance Csd_;
|
||||
typedef std::pair<Point_,Point_> Data_;
|
||||
Data_ data;
|
||||
public:
|
||||
//typedef Segmentd<R_> Segment;
|
||||
#ifdef CGAL_CXX0X
|
||||
//FIXME: don't forward directly, piecewise_constuct should call the point construction functor (I guess? or is it unnecessary?)
|
||||
template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Segment>>::value>::type>
|
||||
Segment(U&&...u):data(std::forward<U>(u)...){}
|
||||
#else
|
||||
Segment(){}
|
||||
Segment(Point_ const&a, Point_ const&b): data(a,b) {}
|
||||
//template<class A,class T1,class T2>
|
||||
//Segment(A const&,T1 const&t1,T2 const&t2)
|
||||
#endif
|
||||
Point_ source()const{return data.first;}
|
||||
Point_ target()const{return data.second;}
|
||||
Point_ operator[](int i)const{
|
||||
if((i%2)==0)
|
||||
return source();
|
||||
else
|
||||
return target();
|
||||
}
|
||||
Segment opposite()const{
|
||||
return Segment(target(),source());
|
||||
}
|
||||
//Vector_ vector()const{
|
||||
// return Cv_()(data.first,data.second);
|
||||
//}
|
||||
// FT_ squared_length()const{
|
||||
// return Csd_()(data.first,data.second);
|
||||
// }
|
||||
};
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
|
||||
template<class R_> struct Construct_segment {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Construct_segment)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point;
|
||||
typedef typename Get_type<R_, Segment_tag>::type Segment;
|
||||
typedef typename Get_functor<R_, Construct_ttag<Point_tag> >::type CP;
|
||||
typedef Segment result_type;
|
||||
result_type operator()(Point const&a, Point const&b)const{
|
||||
return result_type(a,b);
|
||||
}
|
||||
// T should only be std::piecewise_construct_t, but we shouldn't fail if it doesn't exist.
|
||||
template<class T,class U,class V>
|
||||
result_type operator()(CGAL_FORWARDABLE(T),CGAL_FORWARDABLE(U) u,CGAL_FORWARDABLE(V) v)const{
|
||||
CP cp(this->kernel());
|
||||
result_type r = {{
|
||||
call_on_tuple_elements<Point>(cp, CGAL_FORWARD(U,u)),
|
||||
call_on_tuple_elements<Point>(cp, CGAL_FORWARD(V,v)) }};
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
// This should be part of Construct_point, according to Kernel_23 conventions
|
||||
template<class R_> struct Segment_extremity {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Segment_extremity)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point;
|
||||
typedef typename Get_type<R_, Segment_tag>::type Segment;
|
||||
typedef Point result_type;
|
||||
result_type operator()(Segment const&s, int i)const{
|
||||
if(i==0) return s.source();
|
||||
CGAL_assertion(i==1);
|
||||
return s.target();
|
||||
}
|
||||
#ifdef CGAL_CXX0X
|
||||
result_type operator()(Segment &&s, int i)const{
|
||||
if(i==0) return std::move(s.source());
|
||||
CGAL_assertion(i==1);
|
||||
return std::move(s.target());
|
||||
}
|
||||
#endif
|
||||
};
|
||||
} // CartesianDKernelFunctors
|
||||
|
||||
CGAL_KD_DEFAULT_TYPE(Segment_tag,(CGAL::Segment<K>),(Point_tag),());
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Segment_tag>,(CartesianDKernelFunctors::Construct_segment<K>),(Segment_tag,Point_tag),(Construct_ttag<Point_tag>));
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Segment_extremity_tag,(CartesianDKernelFunctors::Segment_extremity<K>),(Segment_tag,Point_tag),());
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_KERNELD_SEGMENTD_H
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
#ifndef CGAL_KD_TYPE_SPHERE_H
|
||||
#define CGAL_KD_TYPE_SPHERE_H
|
||||
#include <CGAL/store_kernel.h>
|
||||
#include <boost/iterator/counting_iterator.hpp>
|
||||
namespace CGAL {
|
||||
template <class R_> class Sphere {
|
||||
typedef typename Get_type<R_, FT_tag>::type FT_;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point_;
|
||||
Point_ c_;
|
||||
FT_ r2_;
|
||||
|
||||
public:
|
||||
Sphere(Point_ const&p, FT_ const&r2): c_(p), r2_(r2) {}
|
||||
// TODO: Add a piecewise constructor?
|
||||
|
||||
Point_ const& center()const{return c_;}
|
||||
FT_ const& squared_radius()const{return r2_;}
|
||||
};
|
||||
namespace CartesianDKernelFunctors {
|
||||
template <class R_> struct Construct_sphere : Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Construct_sphere)
|
||||
typedef typename Get_type<R_, Sphere_tag>::type result_type;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point;
|
||||
typedef typename Get_type<R_, FT_tag>::type FT;
|
||||
typedef typename R_::LA LA;
|
||||
result_type operator()(Point const&a, FT const&b)const{
|
||||
return result_type(a,b);
|
||||
}
|
||||
template <class Iter>
|
||||
result_type operator()(Iter f, Iter e)const{
|
||||
throw "not implemented yet!";
|
||||
}
|
||||
};
|
||||
template <class R_> struct Center_of_sphere {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Center_of_sphere)
|
||||
typedef typename Get_type<R_, Sphere_tag>::type Sphere;
|
||||
typedef typename Get_type<R_, Point_tag>::type const& result_type;
|
||||
result_type operator()(Sphere const&s)const{
|
||||
return s.center();
|
||||
}
|
||||
};
|
||||
template <class R_> struct Squared_radius {
|
||||
CGAL_FUNCTOR_INIT_IGNORE(Squared_radius)
|
||||
typedef typename Get_type<R_, Sphere_tag>::type Sphere;
|
||||
typedef typename Get_type<R_, FT_tag>::type const& result_type;
|
||||
// TODO: Is_exact?
|
||||
result_type operator()(Sphere const&s)const{
|
||||
return s.squared_radius();
|
||||
}
|
||||
};
|
||||
// FIXME: Move it to the generic functors, using the two above and conditional to the existence of sqrt(FT)
|
||||
template<class R_> struct Point_of_sphere : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Point_of_sphere)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, FT_tag>::type FT;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_type<R, Sphere_tag>::type Sphere;
|
||||
typedef typename Get_functor<R, Construct_ttag<Point_tag> >::type CP;
|
||||
typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
|
||||
typedef typename Get_functor<R, Point_dimension_tag>::type PD;
|
||||
typedef Point result_type;
|
||||
typedef Sphere first_argument_type;
|
||||
typedef int second_argument_type;
|
||||
struct Trans : std::binary_function<FT,FT,int> {
|
||||
FT const& r_; int idx; bool sgn;
|
||||
Trans (int n, FT const& r, bool b) : r_(r), idx(n), sgn(b) {}
|
||||
FT operator()(FT const&x, int i)const{
|
||||
return (i == idx) ? sgn ? x + r_ : x - r_ : x;
|
||||
}
|
||||
};
|
||||
result_type operator()(Sphere const&s, int i)const{
|
||||
CI ci(this->kernel());
|
||||
PD pd(this->kernel());
|
||||
typedef boost::counting_iterator<int,std::random_access_iterator_tag> Count;
|
||||
Point const&c = s.center();
|
||||
int d=pd(c);
|
||||
bool last = (i == d);
|
||||
Trans t(last ? 0 : i, sqrt(s.radius()), !last);
|
||||
return CP(this->kernel())(make_transforming_pair_iterator(ci(c,Begin_tag()),Count(0),t),make_transforming_pair_iterator(ci(c,End_tag()),Count(d+1),t));
|
||||
}
|
||||
};
|
||||
}
|
||||
CGAL_KD_DEFAULT_TYPE(Sphere_tag,(CGAL::Sphere<K>),(Point_tag),());
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag<Sphere_tag>,(CartesianDKernelFunctors::Construct_sphere<K>),(Sphere_tag,Point_tag),());
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Center_of_sphere_tag,(CartesianDKernelFunctors::Center_of_sphere<K>),(Sphere_tag,Point_tag),());
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Squared_radius_tag,(CartesianDKernelFunctors::Squared_radius<K>),(Sphere_tag),());
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Point_of_sphere_tag,(CartesianDKernelFunctors::Point_of_sphere<K>),(Sphere_tag,Point_tag),(Construct_ttag<Point_tag>, Construct_ttag<Point_cartesian_const_iterator_tag>));
|
||||
} // namespace CGAL
|
||||
#endif
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
#ifndef CGAL_KERNEL_D_CARTESIAN_WRAP_H
|
||||
#define CGAL_KERNEL_D_CARTESIAN_WRAP_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/is_iterator.h>
|
||||
|
||||
#include <CGAL/Kernel_d/Wrapper/Point_d.h>
|
||||
#include <CGAL/Kernel_d/Wrapper/Vector_d.h>
|
||||
#include <CGAL/Kernel_d/Wrapper/Segment_d.h>
|
||||
#include <CGAL/Kernel_d/Wrapper/Sphere_d.h>
|
||||
|
||||
#include <CGAL/Kernel_d/Wrapper/Ref_count_obj.h>
|
||||
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/mpl/contains.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
|
||||
//TODO: do we want to store the kernel ref in the Object wrappers? It would allow for additions and operator[] and things like that to work, but objects would still need to be created by functors.
|
||||
|
||||
namespace CGAL {
|
||||
namespace internal {
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(Is_wrapper)
|
||||
template<class T,bool=has_Is_wrapper<T>::value> struct Is_wrapper {
|
||||
enum { value=false };
|
||||
typedef Tag_false type;
|
||||
};
|
||||
template<class T> struct Is_wrapper<T,true> {
|
||||
typedef typename T::Is_wrapper type;
|
||||
enum { value=type::value };
|
||||
};
|
||||
|
||||
template<class T,bool=is_iterator<T>::value> struct Is_wrapper_iterator {
|
||||
enum { value=false };
|
||||
typedef Tag_false type;
|
||||
};
|
||||
template<class T> struct Is_wrapper_iterator<T,true> :
|
||||
Is_wrapper<typename std::iterator_traits<T>::value_type>
|
||||
{ };
|
||||
|
||||
struct Forward_rep {
|
||||
//TODO: make a good C++0X version with perfect forwarding
|
||||
//#ifdef CGAL_CXX0X
|
||||
//template <class T,class=typename std::enable_if<!Is_wrapper<typename std::decay<T>::type>::value&&!Is_wrapper_iterator<typename std::decay<T>::type>::value>::type>
|
||||
//T&& operator()(typename std::remove_reference<T>::type&& t) const {return static_cast<T&&>(t);};
|
||||
//template <class T,class=typename std::enable_if<!Is_wrapper<typename std::decay<T>::type>::value&&!Is_wrapper_iterator<typename std::decay<T>::type>::value>::type>
|
||||
//T&& operator()(typename std::remove_reference<T>::type& t) const {return static_cast<T&&>(t);};
|
||||
//
|
||||
//template <class T,class=typename std::enable_if<Is_wrapper<typename std::decay<T>::type>::value>::type>
|
||||
//typename Type_copy_cvref<T,typename std::decay<T>::type::Rep>::type&&
|
||||
//operator()(T&& t) const {
|
||||
// return static_cast<typename Type_copy_cvref<T,typename std::decay<T>::type::Rep>::type&&>(t.rep());
|
||||
//};
|
||||
//
|
||||
//template <class T,class=typename std::enable_if<Is_wrapper_iterator<typename std::decay<T>::type>::value>::type>
|
||||
//transforming_iterator<Forward_rep,typename std::decay<T>::type>
|
||||
//operator()(T&& t) const {
|
||||
// return make_transforming_iterator(std::forward<T>(t),Forward_rep());
|
||||
//};
|
||||
//#else
|
||||
template <class T,bool=Is_wrapper<T>::value,bool=Is_wrapper_iterator<T>::value> struct result_;
|
||||
template <class T> struct result_<T,false,false>{typedef T const& type;};
|
||||
template <class T> struct result_<T,true,false>{typedef typename decay<T>::type::Rep const& type;};
|
||||
template <class T> struct result_<T,false,true>{typedef transforming_iterator<Forward_rep,typename decay<T>::type> type;};
|
||||
template<class> struct result;
|
||||
template<class T> struct result<Forward_rep(T)> : result_<T> {};
|
||||
|
||||
template <class T> typename boost::disable_if<boost::mpl::or_<Is_wrapper<T>,Is_wrapper_iterator<T> >,T>::type const& operator()(T const& t) const {return t;}
|
||||
|
||||
template <class T> typename boost::enable_if<Is_wrapper<T>,T>::type::Rep const& operator()(T const& t) const {return t.rep();}
|
||||
|
||||
template <class T> transforming_iterator<Forward_rep,typename boost::enable_if<Is_wrapper_iterator<T>,T>::type> operator()(T const& t) const {return make_transforming_iterator(t,Forward_rep());}
|
||||
//#endif
|
||||
};
|
||||
}
|
||||
|
||||
template <class B, class K, class T, bool = Provides_type<B, T>::value>
|
||||
struct Map_wrapping_type : Get_type<B, T> {};
|
||||
#define CGAL_REGISTER_OBJECT_WRAPPER(X) \
|
||||
template <class B, class K> \
|
||||
struct Map_wrapping_type <B, K, X##_tag, true> { \
|
||||
typedef X##_d<K> type; \
|
||||
}
|
||||
CGAL_REGISTER_OBJECT_WRAPPER(Point);
|
||||
CGAL_REGISTER_OBJECT_WRAPPER(Vector);
|
||||
CGAL_REGISTER_OBJECT_WRAPPER(Segment);
|
||||
CGAL_REGISTER_OBJECT_WRAPPER(Sphere);
|
||||
#undef CGAL_REGISTER_OBJECT_WRAPPER
|
||||
|
||||
// Note: this tends to be an all or nothing thing currently, wrapping
|
||||
// only some types breaks, probably because we don't check whether the
|
||||
// return type is indeed wrapped.
|
||||
template < typename Base_ , typename Derived_ = Default >
|
||||
struct Cartesian_wrap : public Base_
|
||||
{
|
||||
CGAL_CONSTEXPR Cartesian_wrap(){}
|
||||
CGAL_CONSTEXPR Cartesian_wrap(int d):Base_(d){}
|
||||
typedef Base_ Kernel_base;
|
||||
typedef Cartesian_wrap Self;
|
||||
typedef typename Default::Get<Derived_, Self>::type Derived;
|
||||
// FIXME: The list doesn't belong here.
|
||||
typedef boost::mpl::vector<Point_tag,Segment_tag,Sphere_tag,Vector_tag> Wrapped_list;
|
||||
|
||||
template <class T>
|
||||
struct Type : Map_wrapping_type<Base_, Derived, T> {};
|
||||
|
||||
//Translate the arguments
|
||||
template <class T, class D = void,
|
||||
class=typename Get_functor_category<Derived,T>::type,
|
||||
bool=Provides_functor<Kernel_base, T>::value,
|
||||
bool=boost::mpl::contains<Wrapped_list,typename map_result_tag<T>::type>::type::value>
|
||||
struct Functor {
|
||||
typedef typename Get_functor<Kernel_base, T>::type B;
|
||||
struct type {
|
||||
B b;
|
||||
type(){}
|
||||
type(Self const&k):b(k){}
|
||||
typedef typename B::result_type result_type;
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...U> result_type operator()(U&&...u)const{
|
||||
return b(internal::Forward_rep()(u)...);
|
||||
}
|
||||
#else
|
||||
#define VAR(Z,N,_) internal::Forward_rep()(u##N)
|
||||
#define CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class U)> result_type \
|
||||
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \
|
||||
return b(BOOST_PP_ENUM(N,VAR,)); \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_)
|
||||
#undef CODE
|
||||
#undef VAR
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
// Preserve the difference between Null_functor and nothing.
|
||||
template <class T, class D, class C, bool b>
|
||||
struct Functor <T, D, C, false, b>
|
||||
: Get_functor <Kernel_base, T> {};
|
||||
|
||||
//Translate both the arguments and the result
|
||||
//TODO: Check Is_wrapper instead of relying on map_result_tag?
|
||||
template<class T,class D> struct Functor<T,D,Construct_tag,true,true> {
|
||||
typedef typename Get_functor<Kernel_base, T>::type B;
|
||||
struct type {
|
||||
B b;
|
||||
type(){}
|
||||
type(Self const&k):b(k){}
|
||||
typedef typename map_result_tag<T>::type result_tag;
|
||||
// FIXME: Self or Derived?
|
||||
typedef typename Get_type<Self,result_tag>::type result_type;
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...U> result_type operator()(U&&...u)const{
|
||||
return result_type(Eval_functor(),b,internal::Forward_rep()(u)...);
|
||||
}
|
||||
#else
|
||||
#define VAR(Z,N,_) internal::Forward_rep()(u##N)
|
||||
#define CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class U)> result_type \
|
||||
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \
|
||||
return result_type(Eval_functor(),b,BOOST_PP_ENUM(N,VAR,)); \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_)
|
||||
#undef CODE
|
||||
#undef VAR
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
template < typename Base_ >
|
||||
struct Cartesian_refcount : public Base_
|
||||
{
|
||||
CGAL_CONSTEXPR Cartesian_refcount(){}
|
||||
CGAL_CONSTEXPR Cartesian_refcount(int d):Base_(d){}
|
||||
typedef Base_ Kernel_base;
|
||||
typedef Cartesian_refcount Self;
|
||||
|
||||
// FIXME: Use object_list, or a list passed as argument, or anything
|
||||
// automatic.
|
||||
template <class T, class=void> struct Type : Get_type<Base_, T> {};
|
||||
#define CGAL_Kernel_obj(X,Y) \
|
||||
template <class D> struct Type<X##_tag, D> { typedef Ref_count_obj<Cartesian_refcount, X##_tag> type; };
|
||||
|
||||
CGAL_Kernel_obj(Point,point)
|
||||
CGAL_Kernel_obj(Vector,vector)
|
||||
#undef CGAL_Kernel_obj
|
||||
|
||||
template<class T> struct Dispatch {
|
||||
//typedef typename map_functor_type<T>::type f_t;
|
||||
typedef typename map_result_tag<T>::type r_t;
|
||||
enum {
|
||||
is_nul = boost::is_same<typename Get_functor<Kernel_base, T>::type,Null_functor>::value,
|
||||
ret_rcobj = boost::is_same<r_t,Point_tag>::value || boost::is_same<r_t,Vector_tag>::value
|
||||
};
|
||||
};
|
||||
|
||||
//Translate the arguments
|
||||
template<class T,class D=void,bool=Dispatch<T>::is_nul,bool=Dispatch<T>::ret_rcobj> struct Functor {
|
||||
typedef typename Get_functor<Kernel_base, T>::type B;
|
||||
struct type {
|
||||
B b;
|
||||
type(){}
|
||||
type(Self const&k):b(k){}
|
||||
typedef typename B::result_type result_type;
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...U> result_type operator()(U&&...u)const{
|
||||
return b(internal::Forward_rep()(u)...);
|
||||
}
|
||||
#else
|
||||
result_type operator()()const{
|
||||
return b();
|
||||
}
|
||||
#define VAR(Z,N,_) internal::Forward_rep()(u##N)
|
||||
#define CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class U)> result_type \
|
||||
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \
|
||||
return b(BOOST_PP_ENUM(N,VAR,)); \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_)
|
||||
#undef CODE
|
||||
#undef VAR
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
//Translate both the arguments and the result
|
||||
template<class T,class D,bool b> struct Functor<T,D,true,b> {
|
||||
typedef Null_functor type;
|
||||
};
|
||||
|
||||
template<class T,class D> struct Functor<T,D,false,true> {
|
||||
typedef typename Get_functor<Kernel_base, T>::type B;
|
||||
struct type {
|
||||
B b;
|
||||
type(){}
|
||||
type(Self const&k):b(k){}
|
||||
typedef typename map_result_tag<T>::type result_tag;
|
||||
typedef typename Get_type<Self,result_tag>::type result_type;
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...U> result_type operator()(U&&...u)const{
|
||||
return result_type(Eval_functor(),b,internal::Forward_rep()(u)...);
|
||||
}
|
||||
#else
|
||||
result_type operator()()const{
|
||||
return result_type(Eval_functor(),b);
|
||||
}
|
||||
#define VAR(Z,N,_) internal::Forward_rep()(u##N)
|
||||
#define CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class U)> result_type \
|
||||
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \
|
||||
return result_type(Eval_functor(),b,BOOST_PP_ENUM(N,VAR,)); \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_)
|
||||
#undef CODE
|
||||
#undef VAR
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_KERNEL_D_CARTESIAN_WRAP_H
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
#ifndef CGAL_WRAPPER_POINT_D_H
|
||||
#define CGAL_WRAPPER_POINT_D_H
|
||||
|
||||
#include <CGAL/Origin.h>
|
||||
#include <CGAL/Kernel/mpl.h>
|
||||
#include <CGAL/representation_tags.h>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <CGAL/Kernel/Return_base_tag.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
#ifndef CGAL_CXX0X
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
#endif
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class R_>
|
||||
class Point_d : public Get_type<typename R_::Kernel_base, Point_tag>::type
|
||||
// Deriving won't work if the point is just a __m256d.
|
||||
// Test boost/std::is_class for instance
|
||||
{
|
||||
typedef typename Get_type<R_, RT_tag>::type RT_;
|
||||
typedef typename Get_type<R_, FT_tag>::type FT_;
|
||||
typedef typename R_::Kernel_base Kbase;
|
||||
typedef typename Get_type<R_, Vector_tag>::type Vector_;
|
||||
typedef typename Get_functor<Kbase, Construct_ttag<Point_tag> >::type CPBase;
|
||||
typedef typename Get_functor<Kbase, Compute_point_cartesian_coordinate_tag>::type CCBase;
|
||||
|
||||
typedef Point_d Self;
|
||||
BOOST_STATIC_ASSERT((boost::is_same<Self, typename Get_type<R_, Point_tag>::type>::value));
|
||||
|
||||
public:
|
||||
|
||||
typedef Tag_true Is_wrapper;
|
||||
typedef typename R_::Default_ambient_dimension Ambient_dimension;
|
||||
typedef Dimension_tag<0> Feature_dimension;
|
||||
|
||||
//typedef typename R_::Point_cartesian_const_iterator Cartesian_const_iterator;
|
||||
typedef typename Get_type<Kbase, Point_tag>::type Rep;
|
||||
|
||||
const Rep& rep() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
Rep& rep()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
typedef R_ R;
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Point_d> >::value>::type> explicit Point_d(U&&...u)
|
||||
: Rep(CPBase()(std::forward<U>(u)...)){}
|
||||
|
||||
// // called from Construct_point_d
|
||||
// template<class...U> explicit Point_d(Eval_functor&&,U&&...u)
|
||||
// : Rep(Eval_functor(), std::forward<U>(u)...){}
|
||||
template<class F,class...U> explicit Point_d(Eval_functor&&,F&&f,U&&...u)
|
||||
: Rep(std::forward<F>(f)(std::forward<U>(u)...)){}
|
||||
|
||||
#if 0
|
||||
// the new standard may make this necessary
|
||||
Point_d(Point_d const&)=default;
|
||||
Point_d(Point_d &);//=default;
|
||||
Point_d(Point_d &&)=default;
|
||||
#endif
|
||||
|
||||
// try not to use these
|
||||
Point_d(Rep const& v) : Rep(v) {}
|
||||
Point_d(Rep& v) : Rep(static_cast<Rep const&>(v)) {}
|
||||
Point_d(Rep&& v) : Rep(std::move(v)) {}
|
||||
|
||||
// this one should be implicit
|
||||
Point_d(Origin const& v)
|
||||
: Rep(CPBase()(v)) {}
|
||||
Point_d(Origin& v)
|
||||
: Rep(CPBase()(v)) {}
|
||||
Point_d(Origin&& v)
|
||||
: Rep(CPBase()(std::move(v))) {}
|
||||
|
||||
#else
|
||||
|
||||
Point_d() : Rep(CPBase()()) {}
|
||||
|
||||
Point_d(Rep const& v) : Rep(v) {} // try not to use it
|
||||
|
||||
#define CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
explicit Point_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: Rep(CPBase()( \
|
||||
BOOST_PP_ENUM_PARAMS(N,t))) {} \
|
||||
\
|
||||
template<class F,BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
Point_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {}
|
||||
/*
|
||||
template<BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
Point_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {}
|
||||
*/
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_)
|
||||
#undef CODE
|
||||
|
||||
// this one should be implicit
|
||||
Point_d(Origin const& o)
|
||||
: Rep(CPBase()(o)) {}
|
||||
|
||||
#endif
|
||||
|
||||
typename boost::result_of<CCBase(Rep,int)>::type cartesian(int i)const{
|
||||
return CCBase()(rep(),i);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Direction_d direction() const
|
||||
{
|
||||
return R().construct_direction_d_object()(*this);
|
||||
}
|
||||
|
||||
Vector_d transform(const Aff_transformation_d &t) const
|
||||
{
|
||||
return t.transform(*this);
|
||||
}
|
||||
|
||||
Vector_d operator/(const RT& c) const
|
||||
{
|
||||
return R().construct_divided_vector_d_object()(*this,c);
|
||||
}
|
||||
|
||||
Vector_d operator/(const typename First_if_different<FT_,RT>::Type & c) const
|
||||
{
|
||||
return R().construct_divided_vector_d_object()(*this,c);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_x_3, Vector_3>::type
|
||||
x() const
|
||||
{
|
||||
return R().compute_x_3_object()(*this);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_y_3, Vector_3>::type
|
||||
y() const
|
||||
{
|
||||
return R().compute_y_3_object()(*this);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_z_3, Vector_3>::type
|
||||
z() const
|
||||
{
|
||||
return R().compute_z_3_object()(*this);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_hx_3, Vector_3>::type
|
||||
hx() const
|
||||
{
|
||||
return R().compute_hx_3_object()(*this);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_hy_3, Vector_3>::type
|
||||
hy() const
|
||||
{
|
||||
return R().compute_hy_3_object()(*this);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_hz_3, Vector_3>::type
|
||||
hz() const
|
||||
{
|
||||
return R().compute_hz_3_object()(*this);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_hw_3, Vector_3>::type
|
||||
hw() const
|
||||
{
|
||||
return R().compute_hw_3_object()(*this);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_x_3, Vector_3>::type
|
||||
cartesian(int i) const
|
||||
{
|
||||
CGAL_kernel_precondition( (i == 0) || (i == 1) || (i == 2) );
|
||||
if (i==0) return x();
|
||||
if (i==1) return y();
|
||||
return z();
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_hw_3, Vector_3>::type
|
||||
homogeneous(int i) const
|
||||
{
|
||||
CGAL_kernel_precondition( (i >= 0) || (i <= 3) );
|
||||
if (i==0) return hx();
|
||||
if (i==1) return hy();
|
||||
if (i==2) return hz();
|
||||
return hw();
|
||||
}
|
||||
|
||||
int dimension() const // bad idea?
|
||||
{
|
||||
return rep.dimension();
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_x_3, Vector_3>::type
|
||||
operator[](int i) const
|
||||
{
|
||||
return cartesian(i);
|
||||
}
|
||||
|
||||
Cartesian_const_iterator cartesian_begin() const
|
||||
{
|
||||
return typename R::Construct_cartesian_const_iterator_3()(*this);
|
||||
}
|
||||
|
||||
Cartesian_const_iterator cartesian_end() const
|
||||
{
|
||||
return typename R::Construct_cartesian_const_iterator_3()(*this,3);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_squared_length_3, Vector_3>::type
|
||||
squared_length() const
|
||||
{
|
||||
return R().compute_squared_length_3_object()(*this);
|
||||
}
|
||||
*/
|
||||
};
|
||||
#if 0
|
||||
template <class R_> Point_d<R_>::Point_d(Point_d &)=default;
|
||||
#endif
|
||||
|
||||
//TODO: IO
|
||||
|
||||
//template <class R_>
|
||||
//Vector_d<R_> operator+(const Vector_d<R_>& v,const Vector_d<R_>& w) const
|
||||
//{
|
||||
// return typename R::template Construct<Sum_of_vectors_tag>::type()(v,w);
|
||||
//}
|
||||
//
|
||||
//template <class R_>
|
||||
//Vector_d<R_> operator-(const Vector_d<R_>& v,const Vector_d<R_>& w) const
|
||||
//{
|
||||
// return typename R::template Construct<Difference_of_vectors_tag>::type()(v,w);
|
||||
//}
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_WRAPPER_POINT_D_H
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
#ifndef CGAL_WRAPPER_REF_COUNT_OBJ_H
|
||||
#define CGAL_WRAPPER_REF_COUNT_OBJ_H
|
||||
|
||||
#include <CGAL/Origin.h>
|
||||
#include <CGAL/Handle_for.h>
|
||||
#include <CGAL/Kernel/mpl.h>
|
||||
#include <CGAL/representation_tags.h>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <CGAL/Kernel/Return_base_tag.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
#ifndef CGAL_CXX0X
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
#endif
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
// no need for a fancy interface here, people can use the Point_d wrapper on
|
||||
// top.
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class R_, class Tag_>
|
||||
class Ref_count_obj
|
||||
{
|
||||
typedef typename R_::Kernel_base Kbase;
|
||||
typedef typename Get_functor<Kbase, Construct_ttag<Tag_> >::type CBase;
|
||||
|
||||
typedef Ref_count_obj Self;
|
||||
BOOST_STATIC_ASSERT((boost::is_same<Self, typename Get_type<R_, Tag_>::type>::value));
|
||||
|
||||
public:
|
||||
typedef R_ R;
|
||||
|
||||
typedef Tag_true Is_wrapper;
|
||||
typedef typename R_::Default_ambient_dimension Ambient_dimension;
|
||||
//typedef Dimension_tag<0> Feature_dimension;
|
||||
|
||||
typedef typename Get_type<Kbase, Tag_>::type Rep;
|
||||
typedef Handle_for<Rep> Data;
|
||||
|
||||
private:
|
||||
Data data;
|
||||
public:
|
||||
|
||||
const Rep& rep() const
|
||||
{
|
||||
return CGAL::get(data);
|
||||
}
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Ref_count_obj> >::value>::type> explicit Ref_count_obj(U&&...u)
|
||||
: data(Eval_functor(),CBase(),std::forward<U>(u)...){}
|
||||
|
||||
template<class F,class...U> explicit Ref_count_obj(Eval_functor&&,F&&f,U&&...u)
|
||||
: data(Eval_functor(),std::forward<F>(f),std::forward<U>(u)...){}
|
||||
|
||||
// try not to use these
|
||||
Ref_count_obj(Rep const& v) : data(v) {}
|
||||
Ref_count_obj(Rep& v) : data(static_cast<Rep const&>(v)) {}
|
||||
Ref_count_obj(Rep&& v) : data(std::move(v)) {}
|
||||
|
||||
// Do we really need this for point?
|
||||
// // this one should be implicit
|
||||
// Ref_count_obj(Origin const& v)
|
||||
// : data(Eval_functor(),CBase(),v) {}
|
||||
// Ref_count_obj(Origin& v)
|
||||
// : data(Eval_functor(),CBase(),v) {}
|
||||
// Ref_count_obj(Origin&& v)
|
||||
// : data(Eval_functor(),CBase(),std::move(v)) {}
|
||||
|
||||
#else
|
||||
|
||||
Ref_count_obj() : data(Eval_functor(),CBase()) {}
|
||||
|
||||
Ref_count_obj(Rep const& v) : data(v) {} // try not to use it
|
||||
|
||||
#define CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
explicit Ref_count_obj(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: data(Eval_functor(),CBase(),BOOST_PP_ENUM_PARAMS(N,t)) {} \
|
||||
\
|
||||
template<class F,BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
Ref_count_obj(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: data(Eval_functor(),f,BOOST_PP_ENUM_PARAMS(N,t)) {}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_)
|
||||
#undef CODE
|
||||
template<class F>
|
||||
Ref_count_obj(Eval_functor,F const& f)
|
||||
: data(Eval_functor(),f) {}
|
||||
|
||||
// // this one should be implicit
|
||||
// Ref_count_obj(Origin const& o)
|
||||
// : data(Eval_functor(),CBase(),o) {}
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
#ifndef CGAL_WRAPPER_SEGMENT_D_H
|
||||
#define CGAL_WRAPPER_SEGMENT_D_H
|
||||
|
||||
#include <CGAL/Origin.h>
|
||||
#include <CGAL/Kernel/mpl.h>
|
||||
#include <CGAL/representation_tags.h>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <CGAL/Kernel/Return_base_tag.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
#ifndef CGAL_CXX0X
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
#endif
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class R_>
|
||||
class Segment_d : public Get_type<typename R_::Kernel_base, Segment_tag>::type
|
||||
{
|
||||
typedef typename Get_type<R_, RT_tag>::type RT_;
|
||||
typedef typename Get_type<R_, FT_tag>::type FT_;
|
||||
typedef typename R_::Kernel_base Kbase;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point_;
|
||||
typedef typename Get_functor<Kbase, Construct_ttag<Point_tag> >::type CPBase;
|
||||
typedef typename Get_functor<Kbase, Construct_ttag<Segment_tag> >::type CSBase;
|
||||
typedef typename Get_functor<Kbase, Segment_extremity_tag>::type CSEBase;
|
||||
|
||||
typedef Segment_d Self;
|
||||
BOOST_STATIC_ASSERT((boost::is_same<Self, typename Get_type<R_, Segment_tag>::type>::value));
|
||||
|
||||
public:
|
||||
|
||||
typedef Tag_true Is_wrapper;
|
||||
typedef typename R_::Default_ambient_dimension Ambient_dimension;
|
||||
typedef Dimension_tag<1> Feature_dimension;
|
||||
|
||||
typedef typename Get_type<Kbase, Segment_tag>::type Rep;
|
||||
|
||||
const Rep& rep() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
Rep& rep()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
typedef R_ R;
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Segment_d> >::value>::type> explicit Segment_d(U&&...u)
|
||||
: Rep(CSBase()(std::forward<U>(u)...)){}
|
||||
|
||||
// // called from Construct_point_d
|
||||
// template<class...U> explicit Point_d(Eval_functor&&,U&&...u)
|
||||
// : Rep(Eval_functor(), std::forward<U>(u)...){}
|
||||
template<class F,class...U> explicit Segment_d(Eval_functor&&,F&&f,U&&...u)
|
||||
: Rep(std::forward<F>(f)(std::forward<U>(u)...)){}
|
||||
|
||||
#if 0
|
||||
// the new standard may make this necessary
|
||||
Point_d(Point_d const&)=default;
|
||||
Point_d(Point_d &);//=default;
|
||||
Point_d(Point_d &&)=default;
|
||||
#endif
|
||||
|
||||
// try not to use these
|
||||
Segment_d(Rep const& v) : Rep(v) {}
|
||||
Segment_d(Rep& v) : Rep(static_cast<Rep const&>(v)) {}
|
||||
Segment_d(Rep&& v) : Rep(std::move(v)) {}
|
||||
|
||||
#else
|
||||
|
||||
Segment_d() : Rep(CSBase()()) {}
|
||||
|
||||
Segment_d(Rep const& v) : Rep(v) {} // try not to use it
|
||||
|
||||
#define CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
explicit Segment_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: Rep(CSBase()( \
|
||||
BOOST_PP_ENUM_PARAMS(N,t))) {} \
|
||||
\
|
||||
template<class F,BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
Segment_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {}
|
||||
/*
|
||||
template<BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
Point_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {}
|
||||
*/
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_)
|
||||
#undef CODE
|
||||
|
||||
#endif
|
||||
|
||||
//TODO: if CSEBase returns a reference to a base point, cast it to a
|
||||
//reference to a wrapper point. Ugly but should be safe.
|
||||
Point_ source()const{
|
||||
return Point_(Eval_functor(),CSEBase(),rep(),0);
|
||||
}
|
||||
Point_ target()const{
|
||||
return Point_(Eval_functor(),CSEBase(),rep(),1);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_WRAPPER_SEGMENT_D_H
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
#ifndef CGAL_WRAPPER_SPHERE_D_H
|
||||
#define CGAL_WRAPPER_SPHERE_D_H
|
||||
|
||||
#include <CGAL/representation_tags.h>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <CGAL/Kernel/Return_base_tag.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
#ifndef CGAL_CXX0X
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
#endif
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class R_>
|
||||
class Sphere_d : public Get_type<typename R_::Kernel_base, Sphere_tag>::type
|
||||
{
|
||||
typedef typename Get_type<R_, FT_tag>::type FT_;
|
||||
typedef typename R_::Kernel_base Kbase;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point_;
|
||||
typedef typename Get_functor<Kbase, Construct_ttag<Sphere_tag> >::type CSBase;
|
||||
typedef typename Get_functor<Kbase, Center_of_sphere_tag>::type COSBase;
|
||||
typedef typename Get_functor<Kbase, Squared_radius_tag>::type SRBase;
|
||||
|
||||
typedef Sphere_d Self;
|
||||
BOOST_STATIC_ASSERT((boost::is_same<Self, typename Get_type<R_, Sphere_tag>::type>::value));
|
||||
|
||||
public:
|
||||
|
||||
typedef Tag_true Is_wrapper;
|
||||
typedef typename R_::Default_ambient_dimension Ambient_dimension;
|
||||
typedef typename Increment_dimension<Ambient_dimension,-1>::type Feature_dimension;
|
||||
|
||||
typedef typename Get_type<Kbase, Sphere_tag>::type Rep;
|
||||
|
||||
const Rep& rep() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
Rep& rep()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
typedef R_ R;
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Sphere_d> >::value>::type> explicit Sphere_d(U&&...u)
|
||||
: Rep(CSBase()(std::forward<U>(u)...)){}
|
||||
|
||||
// // called from Construct_point_d
|
||||
// template<class...U> explicit Point_d(Eval_functor&&,U&&...u)
|
||||
// : Rep(Eval_functor(), std::forward<U>(u)...){}
|
||||
template<class F,class...U> explicit Sphere_d(Eval_functor&&,F&&f,U&&...u)
|
||||
: Rep(std::forward<F>(f)(std::forward<U>(u)...)){}
|
||||
|
||||
#if 0
|
||||
// the new standard may make this necessary
|
||||
Point_d(Point_d const&)=default;
|
||||
Point_d(Point_d &);//=default;
|
||||
Point_d(Point_d &&)=default;
|
||||
#endif
|
||||
|
||||
// try not to use these
|
||||
Sphere_d(Rep const& v) : Rep(v) {}
|
||||
Sphere_d(Rep& v) : Rep(static_cast<Rep const&>(v)) {}
|
||||
Sphere_d(Rep&& v) : Rep(std::move(v)) {}
|
||||
|
||||
#else
|
||||
|
||||
Sphere_d() : Rep(CSBase()()) {}
|
||||
|
||||
Sphere_d(Rep const& v) : Rep(v) {} // try not to use it
|
||||
|
||||
#define CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
explicit Sphere_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: Rep(CSBase()( \
|
||||
BOOST_PP_ENUM_PARAMS(N,t))) {} \
|
||||
\
|
||||
template<class F,BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
Sphere_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {}
|
||||
/*
|
||||
template<BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
Point_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {}
|
||||
*/
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_)
|
||||
#undef CODE
|
||||
|
||||
#endif
|
||||
|
||||
//TODO: if COSBase returns a reference to a base point, cast it to a
|
||||
//reference to a wrapper point. Ugly but should be safe.
|
||||
Point_ center()const{
|
||||
return Point_(Eval_functor(),COSBase(),rep());
|
||||
}
|
||||
FT_ squared_radius()const{
|
||||
return SRBase()(rep());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_WRAPPER_SPHERE_D_H
|
||||
|
|
@ -0,0 +1,250 @@
|
|||
#ifndef CGAL_WRAPPER_VECTOR_D_H
|
||||
#define CGAL_WRAPPER_VECTOR_D_H
|
||||
|
||||
#include <CGAL/Origin.h>
|
||||
#include <CGAL/Kernel/mpl.h>
|
||||
#include <CGAL/representation_tags.h>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <CGAL/Kernel/Return_base_tag.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
#ifndef CGAL_CXX0X
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
#endif
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class R_>
|
||||
class Vector_d : public Get_type<typename R_::Kernel_base, Vector_tag>::type
|
||||
{
|
||||
typedef typename Get_type<R_, RT_tag>::type RT_;
|
||||
typedef typename Get_type<R_, FT_tag>::type FT_;
|
||||
typedef typename R_::Kernel_base Kbase;
|
||||
typedef typename Get_type<R_, Point_tag>::type Point_;
|
||||
typedef typename Get_functor<Kbase, Construct_ttag<Vector_tag> >::type CVBase;
|
||||
typedef typename Get_functor<Kbase, Compute_vector_cartesian_coordinate_tag>::type CCBase;
|
||||
|
||||
typedef Vector_d Self;
|
||||
BOOST_STATIC_ASSERT((boost::is_same<Self, typename Get_type<R_, Vector_tag>::type>::value));
|
||||
|
||||
public:
|
||||
|
||||
typedef Tag_true Is_wrapper;
|
||||
typedef typename R_::Default_ambient_dimension Ambient_dimension;
|
||||
typedef Dimension_tag<0> Feature_dimension;
|
||||
|
||||
//typedef typename R_::Vector_cartesian_const_iterator Cartesian_const_iterator;
|
||||
typedef typename Get_type<Kbase, Vector_tag>::type Rep;
|
||||
|
||||
const Rep& rep() const
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
Rep& rep()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
typedef R_ R;
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...U,class=typename std::enable_if<!std::is_same<std::tuple<typename std::decay<U>::type...>,std::tuple<Vector_d> >::value>::type> explicit Vector_d(U&&...u)
|
||||
: Rep(CVBase()(std::forward<U>(u)...)){}
|
||||
|
||||
// // called from Construct_vector_d
|
||||
// template<class...U> explicit Vector_d(Eval_functor&&,U&&...u)
|
||||
// : Rep(Eval_functor(), std::forward<U>(u)...){}
|
||||
template<class F,class...U> explicit Vector_d(Eval_functor&&,F&&f,U&&...u)
|
||||
: Rep(std::forward<F>(f)(std::forward<U>(u)...)){}
|
||||
|
||||
#if 0
|
||||
// the new standard may make this necessary
|
||||
Vector_d(Vector_d const&)=default;
|
||||
Vector_d(Vector_d &);//=default;
|
||||
Vector_d(Vector_d &&)=default;
|
||||
#endif
|
||||
|
||||
// try not to use these
|
||||
Vector_d(Rep const& v) : Rep(v) {}
|
||||
Vector_d(Rep& v) : Rep(static_cast<Rep const&>(v)) {}
|
||||
Vector_d(Rep&& v) : Rep(std::move(v)) {}
|
||||
|
||||
// this one should be implicit
|
||||
Vector_d(Null_vector const& v)
|
||||
: Rep(CVBase()(v)) {}
|
||||
Vector_d(Null_vector& v)
|
||||
: Rep(CVBase()(v)) {}
|
||||
Vector_d(Null_vector&& v)
|
||||
: Rep(CVBase()(std::move(v))) {}
|
||||
|
||||
#else
|
||||
|
||||
Vector_d() : Rep(CVBase()()) {}
|
||||
|
||||
Vector_d(Rep const& v) : Rep(v) {} // try not to use it
|
||||
|
||||
#define CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
explicit Vector_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: Rep(CVBase()( \
|
||||
BOOST_PP_ENUM_PARAMS(N,t))) {} \
|
||||
\
|
||||
template<class F,BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
Vector_d(Eval_functor,F const& f,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: Rep(f(BOOST_PP_ENUM_PARAMS(N,t))) {}
|
||||
/*
|
||||
template<BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
Vector_d(Eval_functor,BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \
|
||||
: Rep(Eval_functor(), BOOST_PP_ENUM_PARAMS(N,t)) {}
|
||||
*/
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_)
|
||||
#undef CODE
|
||||
|
||||
// this one should be implicit
|
||||
Vector_d(Null_vector const& v)
|
||||
: Rep(CVBase()(v)) {}
|
||||
|
||||
#endif
|
||||
|
||||
typename boost::result_of<CCBase(Rep,int)>::type cartesian(int i)const{
|
||||
return CCBase()(rep(),i);
|
||||
}
|
||||
|
||||
Vector_d operator-() const
|
||||
{
|
||||
return typename Get_functor<R, Opposite_vector_tag>::type()(*this);
|
||||
}
|
||||
|
||||
/*
|
||||
Direction_d direction() const
|
||||
{
|
||||
return R().construct_direction_d_object()(*this);
|
||||
}
|
||||
|
||||
Vector_d transform(const Aff_transformation_d &t) const
|
||||
{
|
||||
return t.transform(*this);
|
||||
}
|
||||
|
||||
Vector_d operator/(const RT& c) const
|
||||
{
|
||||
return R().construct_divided_vector_d_object()(*this,c);
|
||||
}
|
||||
|
||||
Vector_d operator/(const typename First_if_different<FT_,RT>::Type & c) const
|
||||
{
|
||||
return R().construct_divided_vector_d_object()(*this,c);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_x_3, Vector_3>::type
|
||||
x() const
|
||||
{
|
||||
return R().compute_x_3_object()(*this);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_y_3, Vector_3>::type
|
||||
y() const
|
||||
{
|
||||
return R().compute_y_3_object()(*this);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_z_3, Vector_3>::type
|
||||
z() const
|
||||
{
|
||||
return R().compute_z_3_object()(*this);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_hx_3, Vector_3>::type
|
||||
hx() const
|
||||
{
|
||||
return R().compute_hx_3_object()(*this);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_hy_3, Vector_3>::type
|
||||
hy() const
|
||||
{
|
||||
return R().compute_hy_3_object()(*this);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_hz_3, Vector_3>::type
|
||||
hz() const
|
||||
{
|
||||
return R().compute_hz_3_object()(*this);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_hw_3, Vector_3>::type
|
||||
hw() const
|
||||
{
|
||||
return R().compute_hw_3_object()(*this);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_x_3, Vector_3>::type
|
||||
cartesian(int i) const
|
||||
{
|
||||
CGAL_kernel_precondition( (i == 0) || (i == 1) || (i == 2) );
|
||||
if (i==0) return x();
|
||||
if (i==1) return y();
|
||||
return z();
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_hw_3, Vector_3>::type
|
||||
homogeneous(int i) const
|
||||
{
|
||||
CGAL_kernel_precondition( (i >= 0) || (i <= 3) );
|
||||
if (i==0) return hx();
|
||||
if (i==1) return hy();
|
||||
if (i==2) return hz();
|
||||
return hw();
|
||||
}
|
||||
|
||||
int dimension() const // bad idea?
|
||||
{
|
||||
return rep.dimension();
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_x_3, Vector_3>::type
|
||||
operator[](int i) const
|
||||
{
|
||||
return cartesian(i);
|
||||
}
|
||||
|
||||
Cartesian_const_iterator cartesian_begin() const
|
||||
{
|
||||
return typename R::Construct_cartesian_const_iterator_3()(*this);
|
||||
}
|
||||
|
||||
Cartesian_const_iterator cartesian_end() const
|
||||
{
|
||||
return typename R::Construct_cartesian_const_iterator_3()(*this,3);
|
||||
}
|
||||
|
||||
typename Qualified_result_of<typename R::Compute_squared_length_3, Vector_3>::type
|
||||
squared_length() const
|
||||
{
|
||||
return R().compute_squared_length_3_object()(*this);
|
||||
}
|
||||
*/
|
||||
};
|
||||
#if 0
|
||||
template <class R_> Vector_d<R_>::Vector_d(Vector_d &)=default;
|
||||
#endif
|
||||
|
||||
//TODO: IO
|
||||
|
||||
template <class R_>
|
||||
Vector_d<R_> operator+(const Vector_d<R_>& v,const Vector_d<R_>& w)
|
||||
{
|
||||
return typename Get_functor<R_, Sum_of_vectors_tag>::type()(v,w);
|
||||
}
|
||||
|
||||
template <class R_>
|
||||
Vector_d<R_> operator-(const Vector_d<R_>& v,const Vector_d<R_>& w)
|
||||
{
|
||||
return typename Get_functor<R_, Difference_of_vectors_tag>::type()(v,w);
|
||||
}
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_WRAPPER_VECTOR_D_H
|
||||
|
|
@ -0,0 +1,796 @@
|
|||
#ifndef CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H
|
||||
#define CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H
|
||||
|
||||
#include <CGAL/marcutils.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <CGAL/Uncertain.h>
|
||||
#include <CGAL/store_kernel.h>
|
||||
#include <CGAL/is_iterator.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
#include <CGAL/Kernel/Return_base_tag.h>
|
||||
#include <CGAL/transforming_iterator.h>
|
||||
#include <CGAL/transforming_pair_iterator.h>
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/functor_properties.h>
|
||||
#include <CGAL/predicates/sign_of_determinant.h>
|
||||
#include <functional>
|
||||
#ifdef CGAL_CXX0X
|
||||
#include <initializer_list>
|
||||
#endif
|
||||
|
||||
namespace CGAL {
|
||||
namespace CartesianDKernelFunctors {
|
||||
namespace internal {
|
||||
template<class,int> struct Dimension_at_most { enum { value = false }; };
|
||||
template<int a,int b> struct Dimension_at_most<Dimension_tag<a>,b> {
|
||||
enum { value = (a <= b) };
|
||||
};
|
||||
}
|
||||
|
||||
template<class R_,class D_=typename R_::Default_ambient_dimension,bool=internal::Dimension_at_most<D_,6>::value> struct Orientation_of_points : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Orientation_of_points)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_type<R, Orientation_tag>::type result_type;
|
||||
typedef typename R::LA::Square_matrix Matrix;
|
||||
|
||||
template<class Iter>
|
||||
result_type operator()(Iter f, Iter e)const{
|
||||
typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
|
||||
typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
|
||||
Point const& p0=*f++;
|
||||
int d=pd(p0);
|
||||
Matrix m(d,d);
|
||||
for(int i=0;f!=e;++f,++i) {
|
||||
Point const& p=*f;
|
||||
for(int j=0;j<d;++j){
|
||||
m(i,j)=c(p,j)-c(p0,j);
|
||||
// should we cache the coordinates of p0 in case they are computed?
|
||||
}
|
||||
}
|
||||
return R::LA::sign_of_determinant(CGAL_MOVE(m));
|
||||
}
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
// Since the dimension is at least 2, there are at least 3 points and no ambiguity with iterators.
|
||||
// template <class...U,class=typename std::enable_if<std::is_same<Dimension_tag<sizeof...(U)-1>,typename R::Default_ambient_dimension>::value>::type>
|
||||
template <class...U,class=typename std::enable_if<(sizeof...(U)>=3)>::type>
|
||||
result_type operator()(U&&...u) const {
|
||||
return operator()({std::forward<U>(u)...});
|
||||
}
|
||||
|
||||
template <class P>
|
||||
result_type operator()(std::initializer_list<P> l) const {
|
||||
return operator()(l.begin(),l.end());
|
||||
}
|
||||
#else
|
||||
//should we make it template to avoid instantiation for wrong dim?
|
||||
//or iterate outside the class?
|
||||
#define VAR(Z,J,I) m(I,J)=c(p##I,J)-c(x,J);
|
||||
#define VAR2(Z,I,N) BOOST_PP_REPEAT(N,VAR,I)
|
||||
#define CODE(Z,N,_) \
|
||||
result_type operator()(Point const&x, BOOST_PP_ENUM_PARAMS(N,Point const&p)) const { \
|
||||
typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel()); \
|
||||
Matrix m(N,N); \
|
||||
BOOST_PP_REPEAT(N,VAR2,N) \
|
||||
return R::LA::sign_of_determinant(CGAL_MOVE(m)); \
|
||||
}
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(7, 10, CODE, _ )
|
||||
// No need to do it for <=6, since that uses a different code path
|
||||
#undef CODE
|
||||
#undef VAR2
|
||||
#undef VAR
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class R_,int d> struct Orientation_of_points<R_,Dimension_tag<d>,true> : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Orientation_of_points)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_type<R, Orientation_tag>::type result_type;
|
||||
template<class>struct Help;
|
||||
template<int...I>struct Help<Indices<I...> > {
|
||||
template<class C,class P,class T> result_type operator()(C const&c,P const&x,T&&t)const{
|
||||
return sign_of_determinant(c(std::get<I/d>(t),I%d)-c(x,I%d)...);
|
||||
}
|
||||
};
|
||||
template<class P0,class...P> result_type operator()(P0 const&x,P&&...p)const{
|
||||
static_assert(d==sizeof...(P),"Wrong number of arguments");
|
||||
typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
|
||||
return Help<typename N_increasing_indices<d*d>::type>()(c,x,std::forward_as_tuple(std::forward<P>(p)...));
|
||||
}
|
||||
|
||||
|
||||
template<int N,class Iter,class...U> result_type help2(Dimension_tag<N>, Iter f, Iter const&e, U&&...u)const{
|
||||
auto const&p=*f;
|
||||
return help2(Dimension_tag<N-1>(),++f,e,std::forward<U>(u)...,p);
|
||||
}
|
||||
template<class Iter,class...U> result_type help2(Dimension_tag<0>, Iter CGAL_assertion_code(f), Iter const& CGAL_assertion_code(e), U&&...u)const{
|
||||
CGAL_assertion(f==e);
|
||||
return operator()(std::forward<U>(u)...);
|
||||
}
|
||||
template<class Iter>
|
||||
result_type operator()(Iter f, Iter e)const{
|
||||
return help2(Dimension_tag<d+1>(),f,e);
|
||||
}
|
||||
};
|
||||
#else
|
||||
#define VAR(Z,J,I) c(p##I,J)-x##J
|
||||
#define VAR2(Z,I,N) BOOST_PP_ENUM(N,VAR,I)
|
||||
#define VAR3(Z,N,_) Point const&p##N=*++f;
|
||||
#define VAR4(Z,N,_) RT const&x##N=c(x,N);
|
||||
#define CODE(Z,N,_) \
|
||||
template<class R_> struct Orientation_of_points<R_,Dimension_tag<N>,true> : private Store_kernel<R_> { \
|
||||
CGAL_FUNCTOR_INIT_STORE(Orientation_of_points) \
|
||||
typedef R_ R; \
|
||||
typedef typename Get_type<R, RT_tag>::type RT; \
|
||||
typedef typename Get_type<R, Point_tag>::type Point; \
|
||||
typedef typename Get_type<R, Orientation_tag>::type result_type; \
|
||||
result_type operator()(Point const&x, BOOST_PP_ENUM_PARAMS(N,Point const&p)) const { \
|
||||
typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel()); \
|
||||
BOOST_PP_REPEAT(N,VAR4,) \
|
||||
return sign_of_determinant(BOOST_PP_ENUM(N,VAR2,N)); \
|
||||
} \
|
||||
template<class Iter> \
|
||||
result_type operator()(Iter f, Iter CGAL_assertion_code(e))const{ \
|
||||
Point const&x=*f; \
|
||||
BOOST_PP_REPEAT(N,VAR3,) \
|
||||
CGAL_assertion(++f==e); \
|
||||
return operator()(x,BOOST_PP_ENUM_PARAMS(N,p)); \
|
||||
} \
|
||||
};
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(2, 7, CODE, _ )
|
||||
#undef CODE
|
||||
#undef VAR2
|
||||
#undef VAR
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Orientation_of_points_tag,(CartesianDKernelFunctors::Orientation_of_points<K>),(Point_tag),(Point_dimension_tag,Compute_point_cartesian_coordinate_tag));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Orientation_of_vectors : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Orientation_of_vectors)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Vector_tag>::type Vector;
|
||||
typedef typename Get_type<R, Orientation_tag>::type result_type;
|
||||
typedef typename R::LA::Square_matrix Matrix;
|
||||
|
||||
template<class Iter>
|
||||
result_type operator()(Iter f, Iter e)const{
|
||||
typename Get_functor<R, Compute_vector_cartesian_coordinate_tag>::type c(this->kernel());
|
||||
typename Get_functor<R, Point_dimension_tag>::type vd(this->kernel());
|
||||
// FIXME: Uh? Using it on a vector ?!
|
||||
Vector const& v0=*f;
|
||||
int d=vd(v0);
|
||||
Matrix m(d,d);
|
||||
for(int j=0;j<d;++j){
|
||||
m(0,j)=c(v0,j);
|
||||
}
|
||||
for(int i=1;++f!=e;++i) {
|
||||
Vector const& v=*f;
|
||||
for(int j=0;j<d;++j){
|
||||
m(i,j)=c(v,j);
|
||||
}
|
||||
}
|
||||
return R::LA::sign_of_determinant(CGAL_MOVE(m));
|
||||
}
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
template <class...U,class=typename std::enable_if<(sizeof...(U)>=3)>::type>
|
||||
result_type operator()(U&&...u) const {
|
||||
return operator()({std::forward<U>(u)...});
|
||||
}
|
||||
|
||||
template <class V>
|
||||
result_type operator()(std::initializer_list<V> l) const {
|
||||
return operator()(l.begin(),l.end());
|
||||
}
|
||||
#else
|
||||
//TODO
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Orientation_of_vectors_tag,(CartesianDKernelFunctors::Orientation_of_vectors<K>),(Vector_tag),(Point_dimension_tag,Compute_vector_cartesian_coordinate_tag));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
#if 0
|
||||
template<class R_,bool=boost::is_same<typename R_::Point,typename R_::Vector>::value> struct Orientation : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Orientation)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Vector_tag>::type Vector;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_type<R, Orientation_tag>::type result_type;
|
||||
typedef typename Get_functor<R, Orientation_of_points_tag>::type OP;
|
||||
typedef typename Get_functor<R, Orientation_of_vectors_tag>::type OV;
|
||||
|
||||
//FIXME!!!
|
||||
//when Point and Vector are distinct types, the dispatch should be made
|
||||
//in a way that doesn't instantiate a conversion from Point to Vector
|
||||
template<class Iter>
|
||||
result_type operator()(Iter const&f, Iter const& e)const{
|
||||
typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
|
||||
typename std::iterator_traits<Iter>::difference_type d=std::distance(f,e);
|
||||
int dim=pd(*f); // BAD
|
||||
if(d==dim) return OV(this->kernel())(f,e);
|
||||
CGAL_assertion(d==dim+1);
|
||||
return OP(this->kernel())(f,e);
|
||||
}
|
||||
//TODO: version that takes objects directly instead of iterators
|
||||
};
|
||||
|
||||
template<class R_> struct Orientation<R_,false> : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Orientation)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Vector_tag>::type Vector;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_type<R, Orientation_tag>::type result_type;
|
||||
typedef typename Get_functor<R, Orientation_of_points_tag>::type OP;
|
||||
typedef typename Get_functor<R, Orientation_of_vectors_tag>::type OV;
|
||||
typedef typename R::LA::Square_matrix Matrix;
|
||||
|
||||
//FIXME!!!
|
||||
//when Point and Vector are distinct types, the dispatch should be made
|
||||
//in a way that doesn't instantiate a conversion from Point to Vector
|
||||
template<class Iter>
|
||||
typename boost::enable_if<is_iterator_to<Iter,Point>,result_type>::type
|
||||
operator()(Iter const&f, Iter const& e)const{
|
||||
return OP(this->kernel())(f,e);
|
||||
}
|
||||
template<class Iter>
|
||||
typename boost::enable_if<is_iterator_to<Iter,Vector>,result_type>::type
|
||||
operator()(Iter const&f, Iter const& e)const{
|
||||
return OV(this->kernel())(f,e);
|
||||
}
|
||||
//TODO: version that takes objects directly instead of iterators
|
||||
};
|
||||
#endif
|
||||
|
||||
template<class R_> struct Side_of_oriented_sphere : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Side_of_oriented_sphere)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_type<R, Oriented_side_tag>::type result_type;
|
||||
typedef typename Increment_dimension<typename R::Default_ambient_dimension>::type D1;
|
||||
typedef typename Increment_dimension<typename R::Max_ambient_dimension>::type D2;
|
||||
typedef typename R::LA::template Rebind_dimension<D1,D2>::Other LA;
|
||||
typedef typename LA::Square_matrix Matrix;
|
||||
|
||||
template<class Iter>
|
||||
result_type operator()(Iter f, Iter const& e)const{
|
||||
Point const& p0=*f++; // *--e ?
|
||||
return this->operator()(f,e,p0);
|
||||
}
|
||||
|
||||
template<class Iter>
|
||||
result_type operator()(Iter f, Iter const& e, Point const& p0) const {
|
||||
typedef typename Get_functor<R, Squared_distance_to_origin_tag>::type Sqdo;
|
||||
typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type c(this->kernel());
|
||||
typename Get_functor<R, Point_dimension_tag>::type pd(this->kernel());
|
||||
|
||||
int d=pd(p0);
|
||||
Matrix m(d+1,d+1);
|
||||
if(CGAL::Is_stored<Sqdo>::value) {
|
||||
Sqdo sqdo(this->kernel());
|
||||
for(int i=0;f!=e;++f,++i) {
|
||||
Point const& p=*f;
|
||||
for(int j=0;j<d;++j){
|
||||
RT const& x=c(p,j);
|
||||
m(i,j)=x-c(p0,j);
|
||||
}
|
||||
m(i,d) = sqdo(p) - sqdo(p0);
|
||||
}
|
||||
} else {
|
||||
for(int i=0;f!=e;++f,++i) {
|
||||
Point const& p=*f;
|
||||
m(i,d) = 0;
|
||||
for(int j=0;j<d;++j){
|
||||
RT const& x=c(p,j);
|
||||
m(i,j)=x-c(p0,j);
|
||||
m(i,d)+=CGAL::square(m(i,j));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(d%2)
|
||||
return -LA::sign_of_determinant(CGAL_MOVE(m));
|
||||
else
|
||||
return LA::sign_of_determinant(CGAL_MOVE(m));
|
||||
}
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
template <class...U,class=typename std::enable_if<(sizeof...(U)>=4)>::type>
|
||||
result_type operator()(U&&...u) const {
|
||||
return operator()({std::forward<U>(u)...});
|
||||
}
|
||||
|
||||
template <class P>
|
||||
result_type operator()(std::initializer_list<P> l) const {
|
||||
return operator()(l.begin(),l.end());
|
||||
}
|
||||
#else
|
||||
//TODO
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Side_of_oriented_sphere_tag,(CartesianDKernelFunctors::Side_of_oriented_sphere<K>),(Point_tag),(Point_dimension_tag,Squared_distance_to_origin_tag,Compute_point_cartesian_coordinate_tag));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Point_to_vector : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Point_to_vector)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename Get_type<R, Vector_tag>::type Vector;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_functor<R, Construct_ttag<Vector_tag> >::type CV;
|
||||
typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
|
||||
typedef Vector result_type;
|
||||
typedef Point argument_type;
|
||||
result_type operator()(argument_type const&v)const{
|
||||
CI ci(this->kernel());
|
||||
return CV(this->kernel())(ci(v,Begin_tag(),ci(v,End_tag())));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Point_to_vector_tag,(CartesianDKernelFunctors::Point_to_vector<K>),(Point_tag,Vector_tag),(Construct_ttag<Vector_tag>, Construct_ttag<Point_cartesian_const_iterator_tag>));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Vector_to_point : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Vector_to_point)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename Get_type<R, Vector_tag>::type Vector;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_functor<R, Construct_ttag<Point_tag> >::type CV;
|
||||
typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CI;
|
||||
typedef Point result_type;
|
||||
typedef Vector argument_type;
|
||||
result_type operator()(argument_type const&v)const{
|
||||
CI ci(this->kernel());
|
||||
return CV(this->kernel())(ci(v,Begin_tag(),ci(v,End_tag())));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Vector_to_point_tag,(CartesianDKernelFunctors::Vector_to_point<K>),(Point_tag,Vector_tag),(Construct_ttag<Point_tag>, Construct_ttag<Vector_cartesian_const_iterator_tag>));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Opposite_vector : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Opposite_vector)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename Get_type<R, Vector_tag>::type Vector;
|
||||
typedef typename Get_functor<R, Construct_ttag<Vector_tag> >::type CV;
|
||||
typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CI;
|
||||
typedef Vector result_type;
|
||||
typedef Vector argument_type;
|
||||
result_type operator()(Vector const&v)const{
|
||||
CI ci(this->kernel());
|
||||
return CV(this->kernel())(make_transforming_iterator(ci(v,Begin_tag()),std::negate<RT>()),make_transforming_iterator(ci(v,End_tag()),std::negate<RT>()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Opposite_vector_tag,(CartesianDKernelFunctors::Opposite_vector<K>),(Vector_tag),(Construct_ttag<Vector_tag>, Construct_ttag<Vector_cartesian_const_iterator_tag>));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Scaled_vector : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Scaled_vector)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, FT_tag>::type FT;
|
||||
typedef typename Get_type<R, Vector_tag>::type Vector;
|
||||
typedef typename Get_functor<R, Construct_ttag<Vector_tag> >::type CV;
|
||||
typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CI;
|
||||
typedef Vector result_type;
|
||||
typedef Vector first_argument_type;
|
||||
typedef FT second_argument_type;
|
||||
result_type operator()(Vector const&v,FT const& s)const{
|
||||
CI ci(this->kernel());
|
||||
return CV(this->kernel())(make_transforming_iterator(ci(v,Begin_tag()),Scale<FT>(s)),make_transforming_iterator(ci(v,End_tag()),Scale<FT>(s)));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Scaled_vector_tag,(CartesianDKernelFunctors::Scaled_vector<K>),(Vector_tag),(Construct_ttag<Vector_tag>, Construct_ttag<Vector_cartesian_const_iterator_tag>));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Sum_of_vectors : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Sum_of_vectors)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename Get_type<R, Vector_tag>::type Vector;
|
||||
typedef typename Get_functor<R, Construct_ttag<Vector_tag> >::type CV;
|
||||
typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CI;
|
||||
typedef Vector result_type;
|
||||
typedef Vector first_argument_type;
|
||||
typedef Vector second_argument_type;
|
||||
result_type operator()(Vector const&a, Vector const&b)const{
|
||||
CI ci(this->kernel());
|
||||
return CV(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),std::plus<RT>()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),std::plus<RT>()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Sum_of_vectors_tag,(CartesianDKernelFunctors::Sum_of_vectors<K>),(Vector_tag),(Construct_ttag<Vector_tag>, Construct_ttag<Vector_cartesian_const_iterator_tag>));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Difference_of_vectors : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Difference_of_vectors)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename Get_type<R, Vector_tag>::type Vector;
|
||||
typedef typename Get_functor<R, Construct_ttag<Vector_tag> >::type CV;
|
||||
typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CI;
|
||||
typedef Vector result_type;
|
||||
typedef Vector first_argument_type;
|
||||
typedef Vector second_argument_type;
|
||||
result_type operator()(Vector const&a, Vector const&b)const{
|
||||
CI ci(this->kernel());
|
||||
return CV(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),std::minus<RT>()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),std::minus<RT>()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Difference_of_vectors_tag,(CartesianDKernelFunctors::Difference_of_vectors<K>),(Vector_tag),(Construct_ttag<Vector_tag>, Construct_ttag<Vector_cartesian_const_iterator_tag>));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Translated_point : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Translated_point)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename Get_type<R, Vector_tag>::type Vector;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_functor<R, Construct_ttag<Point_tag> >::type CP;
|
||||
typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CVI;
|
||||
typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CPI;
|
||||
typedef Point result_type;
|
||||
typedef Point first_argument_type;
|
||||
typedef Vector second_argument_type;
|
||||
result_type operator()(Point const&a, Vector const&b)const{
|
||||
CVI cvi(this->kernel());
|
||||
CPI cpi(this->kernel());
|
||||
return CP(this->kernel())(make_transforming_pair_iterator(cpi(a,Begin_tag()),cvi(b,Begin_tag()),std::plus<RT>()),make_transforming_pair_iterator(cpi(a,End_tag()),cvi(b,End_tag()),std::plus<RT>()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Translated_point_tag,(CartesianDKernelFunctors::Translated_point<K>),(Point_tag, Vector_tag),(Construct_ttag<Point_tag>, Construct_ttag<Vector_cartesian_const_iterator_tag>, Construct_ttag<Point_cartesian_const_iterator_tag>));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Difference_of_points : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Difference_of_points)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_type<R, Vector_tag>::type Vector;
|
||||
typedef typename Get_functor<R, Construct_ttag<Vector_tag> >::type CV;
|
||||
typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
|
||||
typedef Vector result_type;
|
||||
typedef Point first_argument_type;
|
||||
typedef Point second_argument_type;
|
||||
result_type operator()(Point const&a, Point const&b)const{
|
||||
CI ci(this->kernel());
|
||||
return CV(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),std::minus<RT>()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),std::minus<RT>()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Difference_of_points_tag,(CartesianDKernelFunctors::Difference_of_points<K>),(Point_tag, Vector_tag),(Construct_ttag<Vector_tag>, Construct_ttag<Point_cartesian_const_iterator_tag>));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Midpoint : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Midpoint)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, FT_tag>::type FT;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_functor<R, Construct_ttag<Point_tag> >::type CP;
|
||||
typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
|
||||
typedef Point result_type;
|
||||
typedef Point first_argument_type;
|
||||
typedef Point second_argument_type;
|
||||
// There is a division, but it will be cast to RT afterwards anyway, so maybe we could use RT.
|
||||
struct Average : std::binary_function<FT,FT,RT> {
|
||||
FT operator()(FT const&a, RT const&b)const{
|
||||
return (a+b)/2;
|
||||
}
|
||||
};
|
||||
result_type operator()(Point const&a, Point const&b)const{
|
||||
CI ci(this->kernel());
|
||||
//Divide<FT,int> half(2);
|
||||
//return CP(this->kernel())(make_transforming_iterator(make_transforming_pair_iterator(ci.begin(a),ci.begin(b),std::plus<FT>()),half),make_transforming_iterator(make_transforming_pair_iterator(ci.end(a),ci.end(b),std::plus<FT>()),half));
|
||||
return CP(this->kernel())(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),Average()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),Average()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Midpoint_tag,(CartesianDKernelFunctors::Midpoint<K>),(Point_tag),(Construct_ttag<Point_tag>, Construct_ttag<Point_cartesian_const_iterator_tag>));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Squared_length : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Squared_length)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename Get_type<R, Vector_tag>::type Vector;
|
||||
typedef typename Get_functor<R, Construct_ttag<Vector_cartesian_const_iterator_tag> >::type CI;
|
||||
typedef RT result_type;
|
||||
typedef Vector argument_type;
|
||||
result_type operator()(Vector const&a)const{
|
||||
CI ci(this->kernel());
|
||||
typename Algebraic_structure_traits<RT>::Square f;
|
||||
// TODO: avoid this RT(0)+...
|
||||
return std::accumulate(make_transforming_iterator(ci(a,Begin_tag()),f),make_transforming_iterator(ci(a,End_tag()),f),RT(0));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Squared_length_tag,(CartesianDKernelFunctors::Squared_length<K>),(Vector_tag),(Construct_ttag<Vector_cartesian_const_iterator_tag>));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Squared_distance_to_origin : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Squared_distance_to_origin)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
|
||||
typedef RT result_type;
|
||||
typedef Point argument_type;
|
||||
result_type operator()(Point const&a)const{
|
||||
CI ci(this->kernel());
|
||||
typename Algebraic_structure_traits<RT>::Square f;
|
||||
// TODO: avoid this RT(0)+...
|
||||
return std::accumulate(make_transforming_iterator(ci(a,Begin_tag()),f),make_transforming_iterator(ci(a,End_tag()),f),RT(0));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Squared_distance_to_origin_tag,(CartesianDKernelFunctors::Squared_distance_to_origin<K>),(Point_tag),(Construct_ttag<Point_cartesian_const_iterator_tag>));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Squared_distance : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Squared_distance)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, RT_tag>::type RT;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
|
||||
typedef RT result_type;
|
||||
typedef Point first_argument_type;
|
||||
typedef Point second_argument_type;
|
||||
struct Sq_diff : std::binary_function<RT,RT,RT> {
|
||||
RT operator()(RT const&a, RT const&b)const{
|
||||
return CGAL::square(a-b);
|
||||
}
|
||||
};
|
||||
result_type operator()(Point const&a, Point const&b)const{
|
||||
CI ci(this->kernel());
|
||||
Sq_diff f;
|
||||
// TODO: avoid this RT(0)+...
|
||||
return std::accumulate(make_transforming_pair_iterator(ci(a,Begin_tag()),ci(b,Begin_tag()),f),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),f),RT(0));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Squared_distance_tag,(CartesianDKernelFunctors::Squared_distance<K>),(Point_tag),(Construct_ttag<Point_cartesian_const_iterator_tag>));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Compare_distance : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Compare_distance)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_functor<R, Squared_distance_tag>::type CSD;
|
||||
typedef typename Get_type<R, Comparison_result_tag>::type result_type;
|
||||
typedef Point first_argument_type;
|
||||
typedef Point second_argument_type;
|
||||
typedef Point third_argument_type; // why am I doing this already?
|
||||
typedef Point fourth_argument_type;
|
||||
result_type operator()(Point const&a, Point const&b, Point const&c)const{
|
||||
CSD csd(this->kernel());
|
||||
return CGAL_NTS compare(csd(a,b),csd(a,c));
|
||||
}
|
||||
result_type operator()(Point const&a, Point const&b, Point const&c, Point const&d)const{
|
||||
CSD csd(this->kernel());
|
||||
return CGAL_NTS compare(csd(a,b),csd(c,d));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Compare_distance_tag,(CartesianDKernelFunctors::Compare_distance<K>),(Point_tag),(Squared_distance_tag));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Less_point_cartesian_coordinate : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Less_point_cartesian_coordinate)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Bool_tag>::type result_type;
|
||||
typedef typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type Cc;
|
||||
// TODO: This is_exact thing should be reengineered.
|
||||
// the goal is to have a way to tell: don't filter this
|
||||
typedef typename CGAL::Is_exact<Cc> Is_exact;
|
||||
|
||||
template<class V,class W,class I>
|
||||
result_type operator()(V const&a, W const&b, I i)const{
|
||||
Cc c(this->kernel());
|
||||
return c(a,i)<c(b,i);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Less_point_cartesian_coordinate_tag,(CartesianDKernelFunctors::Less_point_cartesian_coordinate<K>),(),(Compute_point_cartesian_coordinate_tag));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Compare_point_cartesian_coordinate : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Compare_point_cartesian_coordinate)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Comparison_result_tag>::type result_type;
|
||||
typedef typename Get_functor<R, Compute_point_cartesian_coordinate_tag>::type Cc;
|
||||
// TODO: This is_exact thing should be reengineered.
|
||||
// the goal is to have a way to tell: don't filter this
|
||||
typedef typename CGAL::Is_exact<Cc> Is_exact;
|
||||
|
||||
template<class V,class W,class I>
|
||||
result_type operator()(V const&a, W const&b, I i)const{
|
||||
Cc c(this->kernel());
|
||||
return CGAL_NTS compare(c(a,i),c(b,i));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Compare_point_cartesian_coordinate_tag,(CartesianDKernelFunctors::Compare_point_cartesian_coordinate<K>),(),(Compute_point_cartesian_coordinate_tag));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Compare_lexicographically : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Compare_lexicographically)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Comparison_result_tag>::type result_type;
|
||||
typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
|
||||
// TODO: This is_exact thing should be reengineered.
|
||||
// the goal is to have a way to tell: don't filter this
|
||||
typedef typename CGAL::Is_exact<CI> Is_exact;
|
||||
|
||||
template<class V,class W>
|
||||
result_type operator()(V const&a, W const&b)const{
|
||||
CI c(this->kernel());
|
||||
#ifdef CGAL_CXX0X
|
||||
auto
|
||||
#else
|
||||
typename CI::result_type
|
||||
#endif
|
||||
a_begin=c(a,Begin_tag()),
|
||||
b_begin=c(b,Begin_tag()),
|
||||
a_end=c(a,End_tag());
|
||||
result_type res;
|
||||
// can't we do slightly better for Uncertain<*> ?
|
||||
// after res=...; if(is_uncertain(res))return indeterminate<result_type>();
|
||||
do res=CGAL_NTS compare(*a_begin++,*b_begin++);
|
||||
while(a_begin!=a_end && res==EQUAL);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Compare_lexicographically_tag,(CartesianDKernelFunctors::Compare_lexicographically<K>),(),(Construct_ttag<Point_cartesian_const_iterator_tag>));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Less_lexicographically : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Less_lexicographically)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Bool_tag>::type result_type;
|
||||
typedef typename Get_functor<R, Compare_lexicographically_tag>::type CL;
|
||||
typedef typename CGAL::Is_exact<CL> Is_exact;
|
||||
|
||||
template <class V, class W>
|
||||
result_type operator() (V const&a, W const&b) const {
|
||||
CL c (this->kernel());
|
||||
return c(a,b) < 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Less_lexicographically_tag,(CartesianDKernelFunctors::Less_lexicographically<K>),(),(Compare_lexicographically_tag));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Less_or_equal_lexicographically : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Less_or_equal_lexicographically)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Bool_tag>::type result_type;
|
||||
typedef typename Get_functor<R, Compare_lexicographically_tag>::type CL;
|
||||
typedef typename CGAL::Is_exact<CL> Is_exact;
|
||||
|
||||
template <class V, class W>
|
||||
result_type operator() (V const&a, W const&b) const {
|
||||
CL c (this->kernel());
|
||||
return c(a,b) <= 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Less_or_equal_lexicographically_tag,(CartesianDKernelFunctors::Less_or_equal_lexicographically<K>),(),(Compare_lexicographically_tag));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Equal_points : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Equal_points)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Bool_tag>::type result_type;
|
||||
typedef typename Get_functor<R, Construct_ttag<Point_cartesian_const_iterator_tag> >::type CI;
|
||||
// TODO: This is_exact thing should be reengineered.
|
||||
// the goal is to have a way to tell: don't filter this
|
||||
typedef typename CGAL::Is_exact<CI> Is_exact;
|
||||
|
||||
template<class V,class W>
|
||||
result_type operator()(V const&a, W const&b)const{
|
||||
CI c(this->kernel());
|
||||
#ifdef CGAL_CXX0X
|
||||
auto
|
||||
#else
|
||||
typename CI::result_type
|
||||
#endif
|
||||
a_begin=c(a,Begin_tag()),
|
||||
b_begin=c(b,Begin_tag()),
|
||||
a_end=c(a,End_tag());
|
||||
result_type res = true;
|
||||
// Is using CGAL::possibly for Uncertain really an optimization?
|
||||
do res = res & (*a_begin++ == *b_begin++);
|
||||
while(a_begin!=a_end && possibly(res));
|
||||
return res;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Equal_points_tag,(CartesianDKernelFunctors::Equal_points<K>),(),(Construct_ttag<Point_cartesian_const_iterator_tag>));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Oriented_side : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Oriented_side)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Oriented_side_tag>::type result_type;
|
||||
typedef typename Get_type<R, Point_tag>::type Point;
|
||||
typedef typename Get_type<R, Hyperplane_tag>::type Hyperplane;
|
||||
typedef typename Get_type<R, Sphere_tag>::type Sphere;
|
||||
typedef typename Get_functor<R, Value_at_tag>::type VA;
|
||||
typedef typename Get_functor<R, Hyperplane_translation_tag>::type HT;
|
||||
typedef typename Get_functor<R, Squared_distance_tag>::type SD;
|
||||
typedef typename Get_functor<R, Squared_radius_tag>::type SR;
|
||||
typedef typename Get_functor<R, Center_of_sphere_tag>::type CS;
|
||||
|
||||
result_type operator()(Hyperplane const&h, Point const&p)const{
|
||||
HT ht(this->kernel());
|
||||
VA va(this->kernel());
|
||||
return CGAL::compare(va(h,p),ht(h));
|
||||
}
|
||||
result_type operator()(Sphere const&s, Point const&p)const{
|
||||
SD sd(this->kernel());
|
||||
SR sr(this->kernel());
|
||||
CS cs(this->kernel());
|
||||
return CGAL::compare(sd(cs(s),p),sr(s));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Oriented_side_tag,(CartesianDKernelFunctors::Oriented_side<K>),(Point_tag,Sphere_tag,Hyperplane_tag),(Value_at_tag,Hyperplane_translation_tag,Squared_distance_tag,Squared_radius_tag,Center_of_sphere_tag));
|
||||
|
||||
namespace CartesianDKernelFunctors {
|
||||
template<class R_> struct Has_on_positive_side : private Store_kernel<R_> {
|
||||
CGAL_FUNCTOR_INIT_STORE(Has_on_positive_side)
|
||||
typedef R_ R;
|
||||
typedef typename Get_type<R, Bool_tag>::type result_type;
|
||||
typedef typename Get_functor<R, Oriented_side_tag>::type OS;
|
||||
|
||||
template <class Obj, class Pt>
|
||||
result_type operator()(Obj const&o, Pt const&p)const{
|
||||
OS os(this->kernel());
|
||||
return os(o,p) == ON_POSITIVE_SIDE;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CGAL_KD_DEFAULT_FUNCTOR(Has_on_positive_side_tag,(CartesianDKernelFunctors::Has_on_positive_side<K>),(),(Oriented_side_tag));
|
||||
|
||||
}
|
||||
#include <CGAL/Kernel_d/Coaffine.h>
|
||||
#endif // CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
#ifndef CGAL_Kernel_pred
|
||||
# define CGAL_Kernel_pred(X, Y)
|
||||
#endif
|
||||
|
||||
#ifndef CGAL_Kernel_comp
|
||||
# define CGAL_Kernel_comp(X, Y)
|
||||
#endif
|
||||
#ifndef CGAL_Kernel_comp1
|
||||
# define CGAL_Kernel_comp1(X, Y) CGAL_Kernel_comp(X, Y)
|
||||
#endif
|
||||
#ifndef CGAL_Kernel_comp2
|
||||
# define CGAL_Kernel_comp2(X, Y) CGAL_Kernel_comp(X, Y)
|
||||
#endif
|
||||
|
||||
#ifndef CGAL_Kernel_cons
|
||||
# define CGAL_Kernel_cons(X, Y)
|
||||
#endif
|
||||
#ifndef CGAL_Kernel_cons1
|
||||
# define CGAL_Kernel_cons1(X, Y) CGAL_Kernel_cons(X, Y)
|
||||
#endif
|
||||
#ifndef CGAL_Kernel_cons2
|
||||
# define CGAL_Kernel_cons2(X, Y) CGAL_Kernel_cons(X, Y)
|
||||
#endif
|
||||
|
||||
#ifndef CGAL_Kernel_obj
|
||||
# define CGAL_Kernel_obj(X,Y)
|
||||
#endif
|
||||
#ifndef CGAL_Kernel_obj1
|
||||
# define CGAL_Kernel_obj1(X,Y) CGAL_Kernel_obj(X,Y)
|
||||
#endif
|
||||
#ifndef CGAL_Kernel_obj2
|
||||
# define CGAL_Kernel_obj2(X,Y) CGAL_Kernel_obj(X,Y)
|
||||
#endif
|
||||
#ifndef CGAL_Kernel_obj3
|
||||
# define CGAL_Kernel_obj3(X,Y) CGAL_Kernel_obj2(X,Y)
|
||||
#endif
|
||||
|
||||
//CGAL_Kernel_obj1(Vector,vector)
|
||||
//CGAL_Kernel_obj1(Point,point)
|
||||
CGAL_Kernel_obj2(Segment,segment)
|
||||
//CGAL_Kernel_obj2(Sphere,sphere)
|
||||
//CGAL_Kernel_obj3(Line,line)
|
||||
//CGAL_Kernel_obj3(Ray,ray)
|
||||
//CGAL_Kernel_obj3(Hyperplane,hyperplane)
|
||||
//CGAL_Kernel_obj3(Aff_transformation,aff_transformation)
|
||||
//CGAL_Kernel_obj3(Iso_box,iso_box)
|
||||
|
||||
//CGAL_Kernel_cons1(Construct_point_cartesian_const_iterator,
|
||||
// construct_point_cartesian_const_iterator_object)
|
||||
//CGAL_Kernel_cons1(Construct_vector_cartesian_const_iterator,
|
||||
// construct_vector_cartesian_const_iterator_object)
|
||||
//CGAL_Kernel_cons2(Sum_of_vectors,
|
||||
// sum_of_vectors_object)
|
||||
//CGAL_Kernel_cons2(Difference_of_vectors,
|
||||
// difference_of_vectors_object)
|
||||
//CGAL_Kernel_cons2(Translated_point,
|
||||
// translated_point_object)
|
||||
//CGAL_Kernel_cons2(Opposite_vector,
|
||||
// opposite_vector_object)
|
||||
//CGAL_Kernel_cons2(Scaled_vector,
|
||||
// scaled_vector_object)
|
||||
//CGAL_Kernel_cons2(Difference_of_points,
|
||||
// difference_of_points_object)
|
||||
//CGAL_Kernel_cons2(Vector_to_point,
|
||||
// vector_to_point_object)
|
||||
//CGAL_Kernel_cons2(Point_to_vector,
|
||||
// point_to_vector_object)
|
||||
//CGAL_Kernel_cons2(Midpoint,
|
||||
// midpoint_object)
|
||||
//CGAL_Kernel_cons2(Orthogonal_vector,
|
||||
// orthogonal_vector_object)
|
||||
//CGAL_Kernel_cons2(Hyperplane_translation,
|
||||
// hyperplane_translation_object)
|
||||
//CGAL_Kernel_cons2(Construct_segment,
|
||||
// construct_segment_object)
|
||||
CGAL_Kernel_cons2(Segment_extremity,
|
||||
segment_extremity_object)
|
||||
|
||||
//CGAL_Kernel_comp1(Compute_point_cartesian_coordinate,
|
||||
// compute_point_cartesian_coordinate_object)
|
||||
//CGAL_Kernel_comp1(Compute_vector_cartesian_coordinate,
|
||||
// compute_vector_cartesian_coordinate_object)
|
||||
//CGAL_Kernel_comp2(Squared_length,
|
||||
// squared_length_object)
|
||||
//CGAL_Kernel_comp2(Squared_distance,
|
||||
// squared_distance_object)
|
||||
//CGAL_Kernel_comp2(Squared_distance_to_origin,
|
||||
// squared_distance_to_origin_object)
|
||||
|
||||
#if 0
|
||||
CGAL_Kernel_pred(Orientation,
|
||||
orientation_object)
|
||||
#endif
|
||||
//CGAL_Kernel_pred(Orientation_of_points,
|
||||
// orientation_of_points_object)
|
||||
//CGAL_Kernel_pred(Orientation_of_vectors,
|
||||
// orientation_of_vectors_object)
|
||||
//CGAL_Kernel_pred(Side_of_oriented_sphere,
|
||||
// side_of_oriented_sphere_object)
|
||||
//CGAL_Kernel_pred(Less_point_cartesian_coordinate,
|
||||
// less_point_cartesian_coordinate_object)
|
||||
//CGAL_Kernel_pred(Compare_point_cartesian_coordinate,
|
||||
// compare_point_cartesian_coordinate_object)
|
||||
//CGAL_Kernel_pred(Compare_distance,
|
||||
// compare_distance_object)
|
||||
//CGAL_Kernel_pred(Compare_lexicographically,
|
||||
// compare_lexicographically_object)
|
||||
//CGAL_Kernel_pred(Less_lexicographically,
|
||||
// less_lexicographically_object)
|
||||
//CGAL_Kernel_pred(Equal_points,
|
||||
// equal_points_object)
|
||||
//CGAL_Kernel_pred(Less_or_equal_lexicographically,
|
||||
// less_or_equal_lexicographically_object)
|
||||
//CGAL_Kernel_pred(Contained_in_affine_hull,
|
||||
// contained_in_affine_hull_object)
|
||||
//CGAL_Kernel_pred(In_flat_orientation,
|
||||
// in_flat_orientation_object)
|
||||
//CGAL_Kernel_pred(In_flat_side_of_oriented_sphere,
|
||||
// in_flat_side_of_oriented_sphere_object)
|
||||
//CGAL_Kernel_pred(Construct_flat_orientation,
|
||||
// construct_flat_orientation_object)
|
||||
|
||||
#undef CGAL_Kernel_pred
|
||||
#undef CGAL_Kernel_comp
|
||||
#undef CGAL_Kernel_comp1
|
||||
#undef CGAL_Kernel_comp2
|
||||
#undef CGAL_Kernel_cons
|
||||
#undef CGAL_Kernel_cons1
|
||||
#undef CGAL_Kernel_cons2
|
||||
#undef CGAL_Kernel_obj
|
||||
#undef CGAL_Kernel_obj1
|
||||
#undef CGAL_Kernel_obj2
|
||||
#undef CGAL_Kernel_obj3
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
#ifndef CGAL_LA_EIGEN_H
|
||||
#define CGAL_LA_EIGEN_H
|
||||
|
||||
#ifndef CGAL_EIGEN3_ENABLED
|
||||
#error Requires Eigen
|
||||
#endif
|
||||
#include <boost/type_traits/is_arithmetic.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <Eigen/Dense>
|
||||
#include <CGAL/LA_eigen/constructors.h>
|
||||
#include <CGAL/iterator_from_indices.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
//FIXME: where could we use Matrix_base instead of Matrix?
|
||||
// Dim_ real dimension
|
||||
// Max_dim_ upper bound on the dimension
|
||||
template<class NT_,class Dim_,class Max_dim_=Dim_> struct LA_eigen {
|
||||
typedef NT_ NT;
|
||||
typedef Dim_ Dimension;
|
||||
typedef Max_dim_ Max_dimension;
|
||||
enum { dimension = Eigen_dimension<Dimension>::value };
|
||||
enum { max_dimension = Eigen_dimension<Max_dimension>::value };
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef LA_eigen< NT, D2, D3 > Other;
|
||||
};
|
||||
template<class,class=void> struct Property : boost::false_type {};
|
||||
template<class D> struct Property<Has_vector_plus_minus_tag,D> : boost::true_type {};
|
||||
template<class D> struct Property<Has_vector_scalar_ops_tag,D> : boost::true_type {};
|
||||
template<class D> struct Property<Has_dot_product_tag,D> : boost::true_type {};
|
||||
|
||||
typedef Eigen::Matrix<NT,Eigen_dimension<Dim_>::value,1,Eigen::ColMajor|Eigen::AutoAlign,Eigen_dimension<Max_dim_>::value,1> Vector;
|
||||
typedef Eigen::Matrix<NT,Eigen::Dynamic,1> Dynamic_vector;
|
||||
typedef Construct_eigen<Vector> Construct_vector;
|
||||
|
||||
#if (EIGEN_WORLD_VERSION>=3)
|
||||
typedef NT const* Vector_const_iterator;
|
||||
#else
|
||||
typedef Iterator_from_indices<const type,const NT
|
||||
#ifndef CGAL_CXX0X
|
||||
,NT
|
||||
#endif
|
||||
> Vector_const_iterator;
|
||||
#endif
|
||||
|
||||
template<class Vec_>static Vector_const_iterator vector_begin(Vec_ const&a){
|
||||
#if (EIGEN_WORLD_VERSION>=3)
|
||||
return &a[0];
|
||||
#else
|
||||
return Vector_const_iterator(a,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class Vec_>static Vector_const_iterator vector_end(Vec_ const&a){
|
||||
#if (EIGEN_WORLD_VERSION>=3)
|
||||
return &a[0]+a.size();
|
||||
#else
|
||||
return Vector_const_iterator(a,a.size());
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef Eigen::Matrix<NT,dimension,dimension,Eigen::ColMajor|Eigen::AutoAlign,max_dimension,max_dimension> Square_matrix;
|
||||
typedef Eigen::Matrix<NT,dimension,Eigen::Dynamic,Eigen::ColMajor|Eigen::AutoAlign,max_dimension,Eigen::Dynamic> Dynamic_matrix;
|
||||
//TODO: don't pass on the values of Max_* for an expensive NT
|
||||
// typedef ... Constructor
|
||||
// typedef ... Accessor
|
||||
#if 0
|
||||
private:
|
||||
template <class T> class Canonicalize_vector {
|
||||
typedef typename Dimension_eigen<T::SizeAtCompileTime>::type S1;
|
||||
typedef typename Dimension_eigen<T::MaxSizeAtCompileTime>::type S2;
|
||||
public:
|
||||
typedef typename Vector<S1,S2>::type type;
|
||||
};
|
||||
public:
|
||||
#endif
|
||||
|
||||
template<class Vec_>static int size_of_vector(Vec_ const&v){
|
||||
return v.size();
|
||||
}
|
||||
|
||||
template<class Vec_>static NT dot_product(Vec_ const&a,Vec_ const&b){
|
||||
return a.dot(b);
|
||||
}
|
||||
|
||||
template<class Mat_> static NT determinant(Mat_ const&m,bool=false){
|
||||
return m.determinant();
|
||||
}
|
||||
|
||||
template<class Mat_> static typename
|
||||
Same_uncertainty_nt<CGAL::Sign, NT>::type
|
||||
sign_of_determinant(Mat_ const&m,bool=false)
|
||||
{
|
||||
return CGAL::sign(m.determinant());
|
||||
}
|
||||
|
||||
template<class Vec1,class Vec2> static Vector homogeneous_add(Vec1 const&a,Vec2 const&b){
|
||||
//TODO: use compile-time size when available
|
||||
int d=a.size();
|
||||
Vector v(d);
|
||||
v << b[d-1]*a.topRows(d-1)+a[d-1]*b.topRows(d-1), a[d-1]*b[d-1];
|
||||
return v;
|
||||
}
|
||||
|
||||
template<class Vec1,class Vec2> static Vector homogeneous_sub(Vec1 const&a,Vec2 const&b){
|
||||
int d=a.size();
|
||||
Vector v(d);
|
||||
v << b[d-1]*a.topRows(d-1)-a[d-1]*b.topRows(d-1), a[d-1]*b[d-1];
|
||||
return v;
|
||||
}
|
||||
|
||||
template<class Vec1,class Vec2> static std::pair<NT,NT> homogeneous_dot_product(Vec1 const&a,Vec2 const&b){
|
||||
int d=a.size();
|
||||
return make_pair(a.topRows(d-1).dot(b.topRows(d-1)), a[d-1]*b[d-1]);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
#ifndef ecs_h
|
||||
#define ecs_h
|
||||
|
||||
#ifndef CGAL_EIGEN3_ENABLED
|
||||
#error Requires Eigen
|
||||
#endif
|
||||
#include <boost/type_traits/is_arithmetic.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <Eigen/Dense>
|
||||
#include <CGAL/iterator_from_indices.h>
|
||||
#include <CGAL/marcutils.h>
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
template <class Vector_> struct Construct_eigen {
|
||||
typedef Vector_ result_type;
|
||||
typedef typename Vector_::Scalar NT;
|
||||
|
||||
private:
|
||||
static void check_dim(int d){
|
||||
int m = result_type::MaxSizeAtCompileTime;
|
||||
CGAL_assertion((m == Eigen::Dynamic) || (d <= m));
|
||||
// could omit the first check since they use a big value for Dynamic.
|
||||
}
|
||||
public:
|
||||
|
||||
struct Dimension {
|
||||
// Initialize with NaN if possible?
|
||||
result_type operator()(int d) const {
|
||||
check_dim(d);
|
||||
return result_type(d);
|
||||
}
|
||||
};
|
||||
|
||||
struct Iterator {
|
||||
template<typename Iter>
|
||||
result_type operator()(int d,Iter const& f,Iter const& e) const {
|
||||
check_dim(d);
|
||||
CGAL_assertion(d==std::distance(f,e));
|
||||
result_type a(d);
|
||||
// TODO: check the right way to do this
|
||||
std::copy(f,e,&a[0]);
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
struct Iterator_add_one {
|
||||
template<typename Iter>
|
||||
result_type operator()(int d,Iter const& f,Iter const& e) const {
|
||||
check_dim(d);
|
||||
CGAL_assertion(d==std::distance(f,e)+1);
|
||||
result_type a(d);
|
||||
std::copy(f,e,&a[0]);
|
||||
a[d-1]=1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
struct Iterator_and_last {
|
||||
template<typename Iter,typename T>
|
||||
result_type operator()(int d,Iter const& f,Iter const& e,CGAL_FORWARDABLE(T) t) const {
|
||||
check_dim(d);
|
||||
CGAL_assertion(d==std::distance(f,e)+1);
|
||||
result_type a(d);
|
||||
std::copy(f,e,&a[0]);
|
||||
a[d-1]=CGAL_FORWARD(T,t);
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
struct Initializer_list {
|
||||
// Fix T==NT?
|
||||
template<class T>
|
||||
result_type operator()(std::initializer_list<T> l) const {
|
||||
return Iterator()(l.size(),l.begin(),l.end());
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
struct Values {
|
||||
#ifdef CGAL_CXX0X
|
||||
// TODO avoid going through Initializer_list which may cause extra copies. Possibly use forward_as_tuple.
|
||||
template<class...U>
|
||||
result_type operator()(U&&...u) const {
|
||||
check_dim(sizeof...(U)); // TODO: use static_assert
|
||||
return Initializer_list()({forward_safe<NT,U>(u)...});
|
||||
}
|
||||
#else
|
||||
|
||||
#define CODE(Z,N,_) result_type operator()(BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \
|
||||
check_dim(N); \
|
||||
result_type a(N); \
|
||||
a << BOOST_PP_ENUM_PARAMS(N,t); \
|
||||
return a; \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1, 11, CODE, _ )
|
||||
#undef CODE
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
struct Values_divide {
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class H,class...U>
|
||||
result_type operator()(H const&h,U&&...u) const {
|
||||
check_dim(sizeof...(U)); // TODO: use static_assert
|
||||
return Initializer_list()({Rational_traits<NT>().make_rational(std::forward<U>(u),h)...});
|
||||
}
|
||||
#else
|
||||
|
||||
#define VAR(Z,N,_) ( Rational_traits<NT>().make_rational( t##N ,h) )
|
||||
#define CODE(Z,N,_) template <class H> result_type \
|
||||
operator()(H const&h, BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \
|
||||
check_dim(N); \
|
||||
result_type a(N); \
|
||||
a << BOOST_PP_ENUM(N,VAR,); \
|
||||
return a; \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1, 11, CODE, _ )
|
||||
#undef CODE
|
||||
#undef VAR
|
||||
|
||||
#endif
|
||||
};
|
||||
};
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,146 @@
|
|||
#ifndef CGAL_VECTOR_ARRAY_H
|
||||
#define CGAL_VECTOR_ARRAY_H
|
||||
#include <boost/type_traits/is_arithmetic.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <CGAL/marcutils.h>
|
||||
#include <CGAL/array.h>
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
|
||||
#include <CGAL/Vector/determinant_of_points_from_vectors.h>
|
||||
#include <CGAL/Vector/determinant_of_vectors_small_dim.h>
|
||||
#include <CGAL/Vector/determinant_of_iterator_to_points_from_iterator_to_vectors.h>
|
||||
#include <CGAL/Vector/determinant_of_iterator_to_points_from_points.h>
|
||||
#include <CGAL/Vector/determinant_of_iterator_to_vectors_from_vectors.h>
|
||||
|
||||
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
// May not be safe to use with dim!=max_dim.
|
||||
// In that case, we should store the real dim next to the array.
|
||||
template<class NT_,class Dim_,class Max_dim_=Dim_> struct Array_vector {
|
||||
typedef NT_ NT;
|
||||
typedef Dim_ Dimension;
|
||||
typedef Max_dim_ Max_dimension;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef Array_vector< NT, D2, D3 > Other;
|
||||
};
|
||||
template<class> struct Property : boost::false_type {};
|
||||
|
||||
static const unsigned d_=Max_dim_::value;
|
||||
CGAL_static_assertion(d_ != (unsigned)UNKNOWN_DIMENSION);
|
||||
|
||||
typedef cpp0x::array<NT,d_> Vector;
|
||||
struct Construct_vector {
|
||||
struct Dimension {
|
||||
// Initialize with NaN if possible?
|
||||
Vector operator()(unsigned d) const {
|
||||
CGAL_assertion(d<=d_);
|
||||
return Vector();
|
||||
}
|
||||
};
|
||||
|
||||
struct Iterator {
|
||||
template<typename Iter>
|
||||
Vector operator()(unsigned CGAL_assertion_code(d),Iter const& f,Iter const& e) const {
|
||||
CGAL_assertion(d==std::distance(f,e));
|
||||
CGAL_assertion(d<=d_);
|
||||
//TODO: optimize for forward iterators
|
||||
Vector a;
|
||||
std::copy(f,e,a.begin());
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
struct Iterator_add_one {
|
||||
template<typename Iter>
|
||||
Vector operator()(unsigned d,Iter const& f,Iter const& e) const {
|
||||
CGAL_assertion(d==std::distance(f,e)+1);
|
||||
CGAL_assertion(d<=d_);
|
||||
//TODO: optimize
|
||||
Vector a;
|
||||
std::copy(f,e,a.begin());
|
||||
a.back()=1;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
struct Iterator_and_last {
|
||||
template<typename Iter,typename T>
|
||||
Vector operator()(unsigned d,Iter const& f,Iter const& e,CGAL_FORWARDABLE(T) t) const {
|
||||
CGAL_assertion(d==std::distance(f,e)+1);
|
||||
CGAL_assertion(d<=d_);
|
||||
//TODO: optimize for forward iterators
|
||||
Vector a;
|
||||
std::copy(f,e,a.begin());
|
||||
a.back()=CGAL_FORWARD(T,t);
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
struct Values {
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...U>
|
||||
Vector operator()(U&&...u) const {
|
||||
static_assert(sizeof...(U)<=d_,"too many arguments");
|
||||
Vector a={{forward_safe<NT,U>(u)...}};
|
||||
return a;
|
||||
}
|
||||
#else
|
||||
|
||||
#define CODE(Z,N,_) Vector operator()(BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \
|
||||
CGAL_assertion(N<=d_); \
|
||||
Vector a={{BOOST_PP_ENUM_PARAMS(N,t)}}; \
|
||||
return a; \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1, 11, CODE, _ )
|
||||
#undef CODE
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
struct Values_divide {
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class H,class...U>
|
||||
Vector operator()(H const& h,U&&...u) const {
|
||||
static_assert(sizeof...(U)<=d_,"too many arguments");
|
||||
Vector a={{Rational_traits<NT>().make_rational(std::forward<U>(u),h)...}};
|
||||
return a;
|
||||
}
|
||||
#else
|
||||
|
||||
#define VAR(Z,N,_) Rational_traits<NT>().make_rational( t##N , h)
|
||||
#define CODE(Z,N,_) template <class H> Vector \
|
||||
operator()(H const&h, BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \
|
||||
CGAL_assertion(N<=d_); \
|
||||
Vector a={{BOOST_PP_ENUM(N,VAR,_)}}; \
|
||||
return a; \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1, 11, CODE, _ )
|
||||
#undef CODE
|
||||
#undef VAR
|
||||
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
typedef NT const* Vector_const_iterator;
|
||||
static Vector_const_iterator vector_begin(Vector const&a){
|
||||
return &a[0];
|
||||
}
|
||||
static Vector_const_iterator vector_end(Vector const&a){
|
||||
return &a[0]+d_; // Don't know the real size
|
||||
}
|
||||
static unsigned size_of_vector(Vector const&){
|
||||
return d_; // Don't know the real size
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
#ifndef CGAL_VECTOR_AVX4_H
|
||||
#define CGAL_VECTOR_AVX4_H
|
||||
|
||||
#if !defined __AVX__ || (__GNUC__ * 100 + __GNUC_MINOR__ < 408)
|
||||
#error Requires AVX and gcc 4.8+
|
||||
#endif
|
||||
#include <x86intrin.h>
|
||||
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <CGAL/enum.h> // CGAL::Sign
|
||||
#include <CGAL/number_utils.h> // CGAL::sign
|
||||
|
||||
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
struct Avx_vector_4 {
|
||||
typedef double NT;
|
||||
typedef Dimension_tag<4> Dimension;
|
||||
typedef Dimension_tag<4> Max_dimension;
|
||||
// No Rebind_dimension, this is a building block
|
||||
template<class,bool=true> struct Property : boost::false_type {};
|
||||
template<bool b> struct Property<Has_vector_plus_minus_tag,b>
|
||||
: boost::true_type {};
|
||||
/* MAYBE?
|
||||
template<bool b> struct Property<Has_vector_scalar_ops_tag,b>
|
||||
: boost::true_type {};
|
||||
*/
|
||||
template<bool b> struct Property<Has_determinant_of_vectors_tag,b>
|
||||
: boost::true_type {};
|
||||
template<bool b> struct Property<Has_dot_product_tag,b>
|
||||
: boost::true_type {};
|
||||
template<bool b> struct Property<Has_determinant_of_vectors_omit_last_tag,b>
|
||||
: boost::true_type {};
|
||||
|
||||
typedef __m256d Vector;
|
||||
struct Construct_vector {
|
||||
struct Dimension {
|
||||
// Initialize with NaN?
|
||||
Vector operator()(unsigned d) const {
|
||||
CGAL_assertion(d==4);
|
||||
return Vector();
|
||||
}
|
||||
};
|
||||
|
||||
struct Iterator {
|
||||
template<typename Iter>
|
||||
Vector operator()(unsigned d,Iter const& f,Iter const& e) const {
|
||||
CGAL_assertion(d==4);
|
||||
double x0 = *f;
|
||||
double x1 = *++f;
|
||||
double x2 = *++f;
|
||||
double x3 = *++f;
|
||||
CGAL_assertion(++f==e);
|
||||
Vector a = { x0, x1, x2, x3 };
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
struct Iterator_and_last {
|
||||
template<typename Iter,typename T>
|
||||
Vector operator()(unsigned d,Iter const& f,Iter const& e,double t) const {
|
||||
CGAL_assertion(d==4);
|
||||
double x0 = *f;
|
||||
double x1 = *++f;
|
||||
double x2 = *++f;
|
||||
CGAL_assertion(++f==e);
|
||||
Vector a = { x0, x1, x2, t };
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
struct Values {
|
||||
Vector operator()(double a,double b,double c,double d) const {
|
||||
Vector r = { a, b, c, d };
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
struct Values_divide {
|
||||
Vector operator()(double h,double a,double b,double c,double d) const {
|
||||
// {a,b,c,d}/{h,h,h,h} should be roughly the same
|
||||
Vector r = { a/h, b/h, c/h, d/h };
|
||||
return r;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
public:
|
||||
typedef double const* Vector_const_iterator;
|
||||
static inline Vector_const_iterator vector_begin(Vector const&a){
|
||||
return (Vector_const_iterator)(&a);
|
||||
}
|
||||
static inline Vector_const_iterator vector_end(Vector const&a){
|
||||
return (Vector_const_iterator)(&a)+4;
|
||||
}
|
||||
static inline unsigned size_of_vector(Vector){
|
||||
return 4;
|
||||
}
|
||||
static inline double dot_product(__m256d x, __m256d y){
|
||||
__m256d p=x*y;
|
||||
__m256d z=_mm256_hadd_pd(p,p);
|
||||
return z[0]+z[2];
|
||||
}
|
||||
private:
|
||||
static inline __m256d avx_sym(__m256d x){
|
||||
#if 0
|
||||
return __builtin_shuffle(x,(__m256i){2,3,0,1});
|
||||
#else
|
||||
return _mm256_permute2f128_pd(x,x,1);
|
||||
#endif
|
||||
}
|
||||
static inline __m256d avx_left(__m256d x){
|
||||
#if 0
|
||||
return __builtin_shuffle(x,(__m256i){1,2,3,0});
|
||||
#else
|
||||
#ifdef __AVX2__
|
||||
return _mm256_permute4x64_pd(x,1+2*4+3*16+0*64);
|
||||
#else
|
||||
__m256d s = _mm256_permute2f128_pd(x,x,1);
|
||||
return _mm256_shuffle_pd(x,s,5);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
static inline __m256d avx_right(__m256d x){
|
||||
#if 0
|
||||
return __builtin_shuffle(x,(__m256i){3,0,1,2});
|
||||
#else
|
||||
#ifdef __AVX2__
|
||||
return _mm256_permute4x64_pd(x,3+0*4+1*16+2*64);
|
||||
#else
|
||||
__m256d s = _mm256_permute2f128_pd(x,x,1);
|
||||
return _mm256_shuffle_pd(s,x,5);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
static inline double avx_altprod(__m256d x, __m256d y){
|
||||
__m256d p=x*y;
|
||||
__m256d z=_mm256_hsub_pd(p,p);
|
||||
return z[0]+z[2];
|
||||
}
|
||||
public:
|
||||
static double
|
||||
determinant_of_vectors(Vector a, Vector b, Vector c, Vector d) {
|
||||
__m256d x=a*avx_left(b)-avx_left(a)*b;
|
||||
__m256d yy=a*avx_sym(b);
|
||||
__m256d y=yy-avx_sym(yy);
|
||||
__m256d z0=x*avx_sym(c);
|
||||
__m256d z1=avx_left(x)*c;
|
||||
__m256d z2=y*avx_left(c);
|
||||
__m256d z=z0+z1-z2;
|
||||
return avx_altprod(z,avx_right(d));
|
||||
}
|
||||
static CGAL::Sign
|
||||
sign_of_determinant_of_vectors(Vector a, Vector b, Vector c, Vector d) {
|
||||
return CGAL::sign(determinant_of_vectors(a,b,c,d));
|
||||
}
|
||||
|
||||
private:
|
||||
static inline __m256d avx3_right(__m256d x){
|
||||
#if 0
|
||||
return __builtin_shuffle(x,(__m256i){2,0,1,3}); // can replace 3 with anything
|
||||
#else
|
||||
#ifdef __AVX2__
|
||||
return _mm256_permute4x64_pd(x,2+0*4+1*16+3*64);
|
||||
#else
|
||||
__m256d s = _mm256_permute2f128_pd(x,x,1);
|
||||
return _mm256_shuffle_pd(s,x,12);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
public:
|
||||
static inline double dot_product_omit_last(__m256d x, __m256d y){
|
||||
__m256d p=x*y;
|
||||
__m128d q=_mm256_extractf128_pd(p,0);
|
||||
double z=_mm_hadd_pd(q,q)[0];
|
||||
return z+p[2];
|
||||
}
|
||||
// Note: without AVX2, is it faster than the scalar computation?
|
||||
static double
|
||||
determinant_of_vectors_omit_last(Vector a, Vector b, Vector c) {
|
||||
__m256d x=a*avx3_right(b)-avx3_right(a)*b;
|
||||
return dot_product_omit_last(c,avx3_right(x));
|
||||
}
|
||||
static CGAL::Sign
|
||||
sign_of_determinant_of_vectors_omit_last(Vector a, Vector b, Vector c) {
|
||||
return CGAL::sign(determinant_of_vectors_omit_last(a,b,c));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef CGAL_VECTOR_DET_ITER_PTS_ITER_VEC_H
|
||||
#define CGAL_VECTOR_DET_ITER_PTS_ITER_VEC_H
|
||||
#include <functional>
|
||||
#include <CGAL/transforming_iterator.h>
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class LA, class Dim_=typename LA::Dimension,
|
||||
class Max_dim_=typename LA::Max_dimension,
|
||||
bool = LA::template Property<Has_determinant_of_iterator_to_points_tag>::value,
|
||||
bool = LA::template Property<Has_determinant_of_iterator_to_vectors_tag>::value>
|
||||
struct Add_determinant_of_iterator_to_points_from_iterator_to_vectors : LA {
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_iterator_to_points_from_iterator_to_vectors<LA2> Other;
|
||||
};
|
||||
};
|
||||
|
||||
template <class LA, class Dim_,class Max_dim_>
|
||||
struct Add_determinant_of_iterator_to_points_from_iterator_to_vectors
|
||||
<LA, Dim_, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_iterator_to_points_from_iterator_to_vectors<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_iterator_to_points_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
// TODO: use std::minus, std::bind, etc
|
||||
template<class T> struct Minus_fixed {
|
||||
T const& a;
|
||||
Minus_fixed(T const&a_):a(a_){}
|
||||
T operator()(T const&b)const{return b-a;}
|
||||
};
|
||||
template<class Iter>
|
||||
static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Minus_fixed<Vector> f(a);
|
||||
return LA::determinant_of_iterator_to_vectors(make_transforming_iterator(first,f),make_transforming_iterator(end,f));
|
||||
}
|
||||
template<class Iter>
|
||||
static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Minus_fixed<Vector> f(a);
|
||||
return LA::sign_of_determinant_of_iterator_to_vectors(make_transforming_iterator(first,f),make_transforming_iterator(end,f));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
#ifndef CGAL_VECTOR_DET_ITER_PTS_PTS_H
|
||||
#define CGAL_VECTOR_DET_ITER_PTS_PTS_H
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class LA, class Dim_=typename LA::Dimension,
|
||||
class Max_dim_=typename LA::Max_dimension,
|
||||
bool = LA::template Property<Has_determinant_of_iterator_to_points_tag>::value,
|
||||
bool = LA::template Property<Has_determinant_of_points_tag>::value>
|
||||
struct Add_determinant_of_iterator_to_points_from_points : LA {
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_iterator_to_points_from_points<LA2> Other;
|
||||
};
|
||||
};
|
||||
|
||||
//FIXME: Use variadics and boost so it works in any dimension.
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_iterator_to_points_from_points
|
||||
<LA, Dimension_tag<2>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_iterator_to_points_from_points<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_iterator_to_points_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
template<class Iter>
|
||||
static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; CGAL_assertion(++first==end);
|
||||
return LA::determinant_of_points(a,b,c);
|
||||
}
|
||||
template<class Iter>
|
||||
static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; CGAL_assertion(++first==end);
|
||||
return LA::sign_of_determinant_of_points(a,b,c);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_iterator_to_points_from_points
|
||||
<LA, Dimension_tag<3>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_iterator_to_points_from_points<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_iterator_to_points_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
template<class Iter>
|
||||
static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; ++first;
|
||||
Vector const&d=*first; CGAL_assertion(++first==end);
|
||||
return LA::determinant_of_points(a,b,c,d);
|
||||
}
|
||||
template<class Iter>
|
||||
static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; ++first;
|
||||
Vector const&d=*first; CGAL_assertion(++first==end);
|
||||
return LA::sign_of_determinant_of_points(a,b,c,d);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_iterator_to_points_from_points
|
||||
<LA, Dimension_tag<4>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_iterator_to_points_from_points<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_iterator_to_points_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
template<class Iter>
|
||||
static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; ++first;
|
||||
Vector const&d=*first; ++first;
|
||||
Vector const&e=*first; CGAL_assertion(++first==end);
|
||||
return LA::determinant_of_points(a,b,c,d,e);
|
||||
}
|
||||
template<class Iter>
|
||||
static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; ++first;
|
||||
Vector const&d=*first; ++first;
|
||||
Vector const&e=*first; CGAL_assertion(++first==end);
|
||||
return LA::sign_of_determinant_of_points(a,b,c,d,e);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_iterator_to_points_from_points
|
||||
<LA, Dimension_tag<5>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_iterator_to_points_from_points<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_iterator_to_points_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
template<class Iter>
|
||||
static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; ++first;
|
||||
Vector const&d=*first; ++first;
|
||||
Vector const&e=*first; ++first;
|
||||
Vector const&f=*first; CGAL_assertion(++first==end);
|
||||
return LA::determinant_of_points(a,b,c,d,e,f);
|
||||
}
|
||||
template<class Iter>
|
||||
static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; ++first;
|
||||
Vector const&d=*first; ++first;
|
||||
Vector const&e=*first; ++first;
|
||||
Vector const&f=*first; CGAL_assertion(++first==end);
|
||||
return LA::sign_of_determinant_of_points(a,b,c,d,e,f);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_iterator_to_points_from_points
|
||||
<LA, Dimension_tag<6>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_iterator_to_points_from_points<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_iterator_to_points_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
template<class Iter>
|
||||
static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; ++first;
|
||||
Vector const&d=*first; ++first;
|
||||
Vector const&e=*first; ++first;
|
||||
Vector const&f=*first; ++first;
|
||||
Vector const&g=*first; CGAL_assertion(++first==end);
|
||||
return LA::determinant_of_points(a,b,c,d,e,f,g);
|
||||
}
|
||||
template<class Iter>
|
||||
static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; ++first;
|
||||
Vector const&d=*first; ++first;
|
||||
Vector const&e=*first; ++first;
|
||||
Vector const&f=*first; ++first;
|
||||
Vector const&g=*first; CGAL_assertion(++first==end);
|
||||
return LA::sign_of_determinant_of_points(a,b,c,d,e,f,g);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
#ifndef CGAL_VECTOR_DET_ITER_VEC_VEC_H
|
||||
#define CGAL_VECTOR_DET_ITER_VEC_VEC_H
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class LA, class Dim_=typename LA::Dimension,
|
||||
class Max_dim_=typename LA::Max_dimension,
|
||||
bool = LA::template Property<Has_determinant_of_iterator_to_vectors_tag>::value,
|
||||
bool = LA::template Property<Has_determinant_of_vectors_tag>::value>
|
||||
struct Add_determinant_of_iterator_to_vectors_from_vectors : LA {
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_iterator_to_vectors_from_vectors<LA2> Other;
|
||||
};
|
||||
};
|
||||
|
||||
//FIXME: Use variadics and boost so it works in any dimension.
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_iterator_to_vectors_from_vectors
|
||||
<LA, Dimension_tag<2>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_iterator_to_vectors_from_vectors<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_iterator_to_vectors_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
template<class Iter>
|
||||
static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; CGAL_assertion(++first==end);
|
||||
return LA::determinant_of_vectors(a,b);
|
||||
}
|
||||
template<class Iter>
|
||||
static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; CGAL_assertion(++first==end);
|
||||
return LA::sign_of_determinant_of_vectors(a,b);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_iterator_to_vectors_from_vectors
|
||||
<LA, Dimension_tag<3>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_iterator_to_vectors_from_vectors<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_iterator_to_vectors_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
template<class Iter>
|
||||
static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; CGAL_assertion(++first==end);
|
||||
return LA::determinant_of_vectors(a,b,c);
|
||||
}
|
||||
template<class Iter>
|
||||
static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; CGAL_assertion(++first==end);
|
||||
return LA::sign_of_determinant_of_vectors(a,b,c);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_iterator_to_vectors_from_vectors
|
||||
<LA, Dimension_tag<4>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_iterator_to_vectors_from_vectors<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_iterator_to_vectors_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
template<class Iter>
|
||||
static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; ++first;
|
||||
Vector const&d=*first; CGAL_assertion(++first==end);
|
||||
return LA::determinant_of_vectors(a,b,c,d);
|
||||
}
|
||||
template<class Iter>
|
||||
static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; ++first;
|
||||
Vector const&d=*first; CGAL_assertion(++first==end);
|
||||
return LA::sign_of_determinant_of_vectors(a,b,c,d);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_iterator_to_vectors_from_vectors
|
||||
<LA, Dimension_tag<5>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_iterator_to_vectors_from_vectors<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_iterator_to_vectors_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
template<class Iter>
|
||||
static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; ++first;
|
||||
Vector const&d=*first; ++first;
|
||||
Vector const&e=*first; CGAL_assertion(++first==end);
|
||||
return LA::determinant_of_vectors(a,b,c,d,e);
|
||||
}
|
||||
template<class Iter>
|
||||
static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; ++first;
|
||||
Vector const&d=*first; ++first;
|
||||
Vector const&e=*first; CGAL_assertion(++first==end);
|
||||
return LA::sign_of_determinant_of_vectors(a,b,c,d,e);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_iterator_to_vectors_from_vectors
|
||||
<LA, Dimension_tag<6>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_iterator_to_vectors_from_vectors<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_iterator_to_vectors_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
template<class Iter>
|
||||
static NT determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; ++first;
|
||||
Vector const&d=*first; ++first;
|
||||
Vector const&e=*first; ++first;
|
||||
Vector const&f=*first; CGAL_assertion(++first==end);
|
||||
return LA::determinant_of_vectors(a,b,c,d,e,f);
|
||||
}
|
||||
template<class Iter>
|
||||
static Sign sign_of_determinant_of_iterator_to_vectors(Iter const&first, Iter const&end){
|
||||
Vector const&a=*first; ++first;
|
||||
Vector const&b=*first; ++first;
|
||||
Vector const&c=*first; ++first;
|
||||
Vector const&d=*first; ++first;
|
||||
Vector const&e=*first; ++first;
|
||||
Vector const&f=*first; CGAL_assertion(++first==end);
|
||||
return LA::sign_of_determinant_of_vectors(a,b,c,d,e,f);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
#ifndef CGAL_VECTOR_DETPTS_H
|
||||
#define CGAL_VECTOR_DETPTS_H
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class LA, class Dim_=typename LA::Dimension,
|
||||
class Max_dim_=typename LA::Max_dimension,
|
||||
bool = LA::template Property<Has_determinant_of_points_tag>::value,
|
||||
bool = LA::template Property<Has_determinant_of_vectors_tag>::value
|
||||
&& LA::template Property<Has_vector_plus_minus_tag>::value>
|
||||
struct Add_determinant_of_points_from_vectors_and_minus : LA {
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_points_from_vectors_and_minus<LA2> Other;
|
||||
};
|
||||
};
|
||||
|
||||
//FIXME: Use variadics and boost so it works in any dimension.
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_points_from_vectors_and_minus
|
||||
<LA, Dimension_tag<2>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_points_from_vectors_and_minus<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_points_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
static NT determinant_of_points(Vector const&a, Vector const&b,
|
||||
Vector const&c){
|
||||
return LA::determinant_of_vectors(b-a,c-a);
|
||||
}
|
||||
static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b,
|
||||
Vector const&c){
|
||||
return LA::sign_of_determinant_of_vectors(b-a,c-a);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_points_from_vectors_and_minus
|
||||
<LA, Dimension_tag<3>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_points_from_vectors_and_minus<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_points_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
static NT determinant_of_points(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d){
|
||||
return LA::determinant_of_vectors(b-a,c-a,d-a);
|
||||
}
|
||||
static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d){
|
||||
return LA::sign_of_determinant_of_vectors(b-a,c-a,d-a);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_points_from_vectors_and_minus
|
||||
<LA, Dimension_tag<4>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_points_from_vectors_and_minus<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_points_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
static NT determinant_of_points(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d, Vector const&e){
|
||||
return LA::determinant_of_vectors(b-a,c-a,d-a,e-a);
|
||||
}
|
||||
static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d, Vector const&e){
|
||||
return LA::sign_of_determinant_of_vectors(b-a,c-a,d-a,e-a);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_points_from_vectors_and_minus
|
||||
<LA, Dimension_tag<5>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_points_from_vectors_and_minus<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_points_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
static NT determinant_of_points(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d, Vector const&e, Vector const&f){
|
||||
return LA::determinant_of_vectors(b-a,c-a,d-a,e-a,f-a);
|
||||
}
|
||||
static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d, Vector const&e, Vector const&f){
|
||||
return LA::sign_of_determinant_of_vectors(b-a,c-a,d-a,e-a,f-a);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct Add_determinant_of_points_from_vectors_and_minus
|
||||
<LA, Dimension_tag<6>, Max_dim_, false, true> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef Add_determinant_of_points_from_vectors_and_minus<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<Has_determinant_of_points_tag, D> :
|
||||
boost::true_type {};
|
||||
|
||||
static NT determinant_of_points(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d, Vector const&e, Vector const&f,
|
||||
Vector const&g){
|
||||
return LA::determinant_of_vectors(b-a,c-a,d-a,e-a,f-a,g-a);
|
||||
}
|
||||
static Sign sign_of_determinant_of_points(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d, Vector const&e, Vector const&f,
|
||||
Vector const&g){
|
||||
return LA::sign_of_determinant_of_vectors(b-a,c-a,d-a,e-a,f-a,g-a);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef CGAL_VECTOR_DETVEC_SMALL_H
|
||||
#define CGAL_VECTOR_DETVEC_SMALL_H
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <CGAL/determinant_of_vectors.h>
|
||||
|
||||
#define CGAL_ALLOWED_INCLUSION 1
|
||||
|
||||
#define CGAL_CLASS Add_determinant_of_vectors_small_dim
|
||||
#define CGAL_TAG Has_determinant_of_vectors_tag
|
||||
#define CGAL_FUNC determinant_of_vectors
|
||||
#define CGAL_SIGN_FUNC sign_of_determinant_of_vectors
|
||||
#define CGAL_SHIFT 0
|
||||
|
||||
#include <CGAL/Vector/determinant_of_vectors_small_dim_internal.h>
|
||||
|
||||
#undef CGAL_CLASS
|
||||
#undef CGAL_TAG
|
||||
#undef CGAL_FUNC
|
||||
#undef CGAL_SIGN_FUNC
|
||||
#undef CGAL_SHIFT
|
||||
|
||||
#define CGAL_CLASS Add_determinant_of_vectors_omit_last_small_dim
|
||||
#define CGAL_TAG Has_determinant_of_vectors_omit_last_tag
|
||||
#define CGAL_FUNC determinant_of_vectors_omit_last
|
||||
#define CGAL_SIGN_FUNC sign_of_determinant_of_vectors_omit_last
|
||||
#define CGAL_SHIFT 1
|
||||
|
||||
#include <CGAL/Vector/determinant_of_vectors_small_dim_internal.h>
|
||||
|
||||
#undef CGAL_CLASS
|
||||
#undef CGAL_TAG
|
||||
#undef CGAL_FUNC
|
||||
#undef CGAL_SIGN_FUNC
|
||||
#undef CGAL_SHIFT
|
||||
|
||||
#undef CGAL_ALLOWED_INCLUSION
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
#ifndef CGAL_ALLOWED_INCLUSION
|
||||
#error Must not include this header directly
|
||||
#endif
|
||||
#if !defined(CGAL_TAG) \
|
||||
|| ! defined(CGAL_CLASS) \
|
||||
|| ! defined(CGAL_FUNC) \
|
||||
|| ! defined(CGAL_SIGN_FUNC) \
|
||||
|| ! defined(CGAL_SHIFT)
|
||||
|
||||
#error Forgot one macro
|
||||
#endif
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <class LA, class Dim_=typename LA::Dimension,
|
||||
class Max_dim_=typename LA::Max_dimension,
|
||||
bool=LA::template Property<CGAL_TAG>::value>
|
||||
struct CGAL_CLASS : LA {
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef CGAL_CLASS<LA2> Other;
|
||||
};
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct CGAL_CLASS
|
||||
<LA, Dimension_tag<2+CGAL_SHIFT>, Max_dim_, false> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef CGAL_CLASS<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<CGAL_TAG, D> :
|
||||
boost::true_type {};
|
||||
|
||||
static NT CGAL_FUNC(Vector const&a, Vector const&b){
|
||||
return CGAL::determinant_of_vectors<NT>(a,b);
|
||||
}
|
||||
template <class V1, class V2>
|
||||
static Sign CGAL_SIGN_FUNC(V1 const&a, V2 const&b){
|
||||
return CGAL::sign_of_determinant_of_vectors<NT>(a,b);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct CGAL_CLASS
|
||||
<LA, Dimension_tag<3+CGAL_SHIFT>, Max_dim_, false> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef CGAL_CLASS<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<CGAL_TAG, D> :
|
||||
boost::true_type {};
|
||||
|
||||
static NT CGAL_FUNC(Vector const&a, Vector const&b,
|
||||
Vector const&c){
|
||||
return CGAL::determinant_of_vectors<NT>(a,b,c);
|
||||
}
|
||||
static Sign CGAL_SIGN_FUNC(Vector const&a, Vector const&b,
|
||||
Vector const&c){
|
||||
return CGAL::sign_of_determinant_of_vectors<NT>(a,b,c);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct CGAL_CLASS
|
||||
<LA, Dimension_tag<4+CGAL_SHIFT>, Max_dim_, false> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef CGAL_CLASS<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<CGAL_TAG, D> :
|
||||
boost::true_type {};
|
||||
|
||||
static NT CGAL_FUNC(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d){
|
||||
return CGAL::determinant_of_vectors<NT>(a,b,c,d);
|
||||
}
|
||||
static Sign CGAL_SIGN_FUNC(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d){
|
||||
return CGAL::sign_of_determinant_of_vectors<NT>(a,b,c,d);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct CGAL_CLASS
|
||||
<LA, Dimension_tag<5+CGAL_SHIFT>, Max_dim_, false> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef CGAL_CLASS<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<CGAL_TAG, D> :
|
||||
boost::true_type {};
|
||||
|
||||
static NT CGAL_FUNC(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d, Vector const&e){
|
||||
return CGAL::determinant_of_vectors<NT>(a,b,c,d,e);
|
||||
}
|
||||
static Sign CGAL_SIGN_FUNC(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d, Vector const&e){
|
||||
return CGAL::sign_of_determinant_of_vectors<NT>(a,b,c,d,e);
|
||||
}
|
||||
};
|
||||
|
||||
template <class LA, class Max_dim_>
|
||||
struct CGAL_CLASS
|
||||
<LA, Dimension_tag<6+CGAL_SHIFT>, Max_dim_, false> : LA {
|
||||
using typename LA::NT;
|
||||
using typename LA::Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef typename LA::template Rebind_dimension<D2,D3> LA2;
|
||||
typedef CGAL_CLASS<LA2> Other;
|
||||
};
|
||||
template<class P,class=void> struct Property : LA::template Property<P> {};
|
||||
template<class D> struct Property<CGAL_TAG, D> :
|
||||
boost::true_type {};
|
||||
|
||||
static NT CGAL_FUNC(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d, Vector const&e, Vector const&f){
|
||||
return CGAL::determinant_of_vectors<NT>(a,b,c,d,e,f);
|
||||
}
|
||||
static Sign CGAL_SIGN_FUNC(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d, Vector const&e, Vector const&f){
|
||||
return CGAL::sign_of_determinant_of_vectors<NT>(a,b,c,d,e,f);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
#ifndef CGAL_VECTOR_SSE2_H
|
||||
#define CGAL_VECTOR_SSE2_H
|
||||
|
||||
// Check what needs adapting for clang, intel and microsoft
|
||||
#if !defined __SSE2__ || (__GNUC__ * 100 + __GNUC_MINOR__ < 408)
|
||||
#error Requires SSE2 and gcc 4.8+
|
||||
#endif
|
||||
#include <x86intrin.h> // FIXME: other platforms call it differently
|
||||
|
||||
#include <CGAL/functor_tags.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <CGAL/enum.h> // CGAL::Sign
|
||||
#include <CGAL/number_utils.h> // CGAL::sign
|
||||
|
||||
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
struct Sse_vector_2 {
|
||||
typedef double NT;
|
||||
typedef Dimension_tag<2> Dimension;
|
||||
typedef Dimension_tag<2> Max_dimension;
|
||||
// No Rebind_dimension, this is a building block
|
||||
template<class,bool=true> struct Property : boost::false_type {};
|
||||
template<bool b> struct Property<Has_vector_plus_minus_tag,b>
|
||||
: boost::true_type {};
|
||||
/* MAYBE?
|
||||
template<bool b> struct Property<Has_vector_scalar_ops_tag,b>
|
||||
: boost::true_type {};
|
||||
*/
|
||||
template<bool b> struct Property<Has_determinant_of_vectors_tag,b>
|
||||
: boost::true_type {};
|
||||
template<bool b> struct Property<Has_dot_product_tag,b>
|
||||
: boost::true_type {};
|
||||
|
||||
typedef __m128d Vector;
|
||||
struct Construct_vector {
|
||||
struct Dimension {
|
||||
// Initialize with NaN?
|
||||
Vector operator()(unsigned d) const {
|
||||
CGAL_assertion(d==2);
|
||||
return Vector();
|
||||
}
|
||||
};
|
||||
|
||||
struct Iterator {
|
||||
template<typename Iter>
|
||||
Vector operator()(unsigned d,Iter const& f,Iter const& e) const {
|
||||
CGAL_assertion(d==2);
|
||||
double x0 = *f;
|
||||
double x1 = *++f;
|
||||
CGAL_assertion(++f==e);
|
||||
Vector a = { x0, x1 };
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
struct Iterator_and_last {
|
||||
template<typename Iter,typename T>
|
||||
Vector operator()(unsigned d,Iter const& f,Iter const& e,double t) const {
|
||||
CGAL_assertion(d==2);
|
||||
Vector a = { *f, t };
|
||||
CGAL_assertion(++f==e);
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
struct Values {
|
||||
Vector operator()(double a,double b) const {
|
||||
Vector r = { a, b };
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
struct Values_divide {
|
||||
Vector operator()(double h,double a,double b) const {
|
||||
// {a,b}/{h,h} is probably slower
|
||||
Vector r = { a/h, b/h };
|
||||
return r;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
typedef double const* Vector_const_iterator;
|
||||
static inline Vector_const_iterator vector_begin(Vector const&a){
|
||||
return (Vector_const_iterator)(&a);
|
||||
}
|
||||
static inline Vector_const_iterator vector_end(Vector const&a){
|
||||
return (Vector_const_iterator)(&a)+2;
|
||||
}
|
||||
static inline unsigned size_of_vector(Vector){
|
||||
return 2;
|
||||
}
|
||||
public:
|
||||
|
||||
static double determinant_of_vectors(Vector a, Vector b) {
|
||||
__m128d c = _mm_shuffle_pd (b, b, 1); // b1, b0
|
||||
__m128d d = a * c; // a0*b1, a1*b0
|
||||
#ifdef __SSE3__
|
||||
__m128d e = _mm_hsub_pd (d, d);
|
||||
return e[0];
|
||||
#else
|
||||
return d[0]-d[1];
|
||||
#endif
|
||||
}
|
||||
static CGAL::Sign sign_of_determinant_of_vectors(Vector a, Vector b) {
|
||||
return CGAL::sign(determinant_of_vectors(a,b));
|
||||
}
|
||||
|
||||
static double dot_product(Vector a,Vector b){
|
||||
#ifdef __SSE4_1__
|
||||
return _mm_dp_pd (a, b, 1+16+32)[0];
|
||||
#else
|
||||
__m128d p = a * b;
|
||||
#if defined __SSE3__
|
||||
__m128d s = _mm_hadd_pd (p, p);
|
||||
return s[0];
|
||||
#else
|
||||
return p[0]+p[1];
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
#ifndef CGAL_VECTOR_2INT_H
|
||||
#define CGAL_VECTOR_2INT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cmath>
|
||||
#include <CGAL/array.h>
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <CGAL/enum.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
#include <CGAL/NT_converter.h>
|
||||
#include <CGAL/transforming_iterator.h>
|
||||
#include <CGAL/determinant_of_vectors.h>
|
||||
#include <CGAL/functor_tags.h>
|
||||
|
||||
|
||||
// What are the pros and cons of having NT be int vs double?
|
||||
|
||||
namespace CGAL {
|
||||
struct Vector_2_int_prop1 {
|
||||
typedef double NT; // try lying a bit
|
||||
typedef int32_t NT1; // what is really stored
|
||||
typedef int32_t NT1b; // slightly longer
|
||||
typedef int_fast64_t NT2; // longer type for computations
|
||||
typedef int_fast64_t NT2b; // slightly longer
|
||||
bool check_limits(int32_t x){return std::abs(x)<(1<<30);}
|
||||
// TODO: find nice bounds
|
||||
};
|
||||
#ifdef __SIZEOF_INT128__
|
||||
struct Vector_2_int_prop2 {
|
||||
typedef double NT;
|
||||
typedef int32_t NT1;
|
||||
typedef int_fast64_t NT1b;
|
||||
typedef int_fast64_t NT2;
|
||||
typedef __int128 NT2b;
|
||||
bool check_limits(int32_t){return true;}
|
||||
// take a template/int64_t input and still check the limits?
|
||||
};
|
||||
struct Vector_2_int_prop3 {
|
||||
typedef long double NT;
|
||||
typedef int64_t NT1;
|
||||
typedef int64_t NT1b;
|
||||
typedef __int128 NT2;
|
||||
typedef __int128 NT2b;
|
||||
enum { has_limit=true };
|
||||
bool check_limits(int32_t x){return std::abs(x)<(1L<<62);}
|
||||
// TODO: find nice bounds
|
||||
};
|
||||
#endif
|
||||
|
||||
template<class Prop=Vector_2_int_prop1>
|
||||
struct Vector_2_int : Prop {
|
||||
using typename Prop::NT;
|
||||
using typename Prop::NT1;
|
||||
using typename Prop::NT1b;
|
||||
using typename Prop::NT2;
|
||||
using typename Prop::NT2b;
|
||||
using Prop::check_limits;
|
||||
|
||||
typedef Dimension_tag<2> Dimension;
|
||||
typedef Dimension_tag<2> Max_dimension;
|
||||
// No Rebind_dimension, this is a building block
|
||||
template<class,bool=true> struct Property : boost::false_type {};
|
||||
//template<bool b> struct Property<Has_vector_plus_minus_tag,b>
|
||||
// : boost::true_type {};
|
||||
template<bool b> struct Property<Has_determinant_of_vectors_tag,b>
|
||||
: boost::true_type {};
|
||||
//template<bool b> struct Property<Has_determinant_of_points_tag,b>
|
||||
// : boost::true_type {};
|
||||
// Advertise somehow that the sign_of_determinant* are exact?
|
||||
|
||||
typedef cpp0x::array<NT1,2> Vector;
|
||||
struct Construct_vector {
|
||||
struct Dimension {
|
||||
Vector operator()(unsigned d) const {
|
||||
CGAL_assertion(d==2);
|
||||
return Vector();
|
||||
}
|
||||
};
|
||||
|
||||
// TODO (for all constructors): check that input fits in NT1...
|
||||
struct Iterator {
|
||||
template<typename Iter>
|
||||
Vector operator()(unsigned d,Iter const& f,Iter const& e) const {
|
||||
CGAL_assertion(d==2);
|
||||
NT1 x0 = *f;
|
||||
NT1 x1 = *++f;
|
||||
CGAL_assertion (++f == e);
|
||||
CGAL_assertion (check_limits(x0) && check_limits(x1));
|
||||
Vector a = { x0, x1 };
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
struct Iterator_and_last {
|
||||
template<typename Iter,typename T>
|
||||
Vector operator()(unsigned d,Iter const& f,Iter const& e,double t) const {
|
||||
CGAL_assertion(d==2);
|
||||
NT1 x = *f;
|
||||
CGAL_assertion (++f == e);
|
||||
CGAL_assertion (check_limits(x) && check_limits(t));
|
||||
Vector a = { x, t };
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
struct Values {
|
||||
Vector operator()(NT1 a,NT1 b) const {
|
||||
CGAL_assertion (check_limits(a) && check_limits(b));
|
||||
Vector r = { a, b };
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
// Maybe safer not to provide it
|
||||
struct Values_divide {
|
||||
Vector operator()(double h,double a,double b) const {
|
||||
Vector r = { a/h, b/h };
|
||||
return r;
|
||||
}
|
||||
};
|
||||
*/
|
||||
};
|
||||
|
||||
// Since we lie about NT, be consistent about it
|
||||
typedef transforming_iterator<NT_converter<NT1,NT>,NT1 const*> Vector_const_iterator;
|
||||
static inline Vector_const_iterator vector_begin(Vector const&a){
|
||||
return Vector_const_iterator(a.begin());
|
||||
}
|
||||
static inline Vector_const_iterator vector_end(Vector const&a){
|
||||
return Vector_const_iterator(a.end());
|
||||
}
|
||||
static inline unsigned size_of_vector(Vector){
|
||||
return 2;
|
||||
}
|
||||
|
||||
// for unsigned NT1, check what changes to do.
|
||||
// return NT or NT2?
|
||||
static NT determinant_of_vectors(Vector a, Vector b) {
|
||||
return CGAL::determinant_of_vectors<NT2>(a,b);
|
||||
}
|
||||
static CGAL::Sign sign_of_determinant_of_vectors(Vector a, Vector b) {
|
||||
return CGAL::sign_of_determinant_of_vectors<NT2>(a,b);
|
||||
}
|
||||
|
||||
static NT determinant_of_points(Vector a, Vector b, Vector c) {
|
||||
// could be faster to convert to NT directly
|
||||
NT1b a0=a[0]; NT1b a1=a[1];
|
||||
NT1b x0=b[0]-a0; NT1b x1=b[1]-a1;
|
||||
NT1b y0=c[0]-a0; NT1b y1=c[1]-a1;
|
||||
return CGAL::determinant<NT>(x0,x1,y0,y1);
|
||||
}
|
||||
static CGAL::Sign sign_of_determinant_of_points(Vector a, Vector b, Vector c) {
|
||||
NT1b a0=a[0]; NT1b a1=a[1];
|
||||
NT1b x0=b[0]-a0; NT1b x1=b[1]-a1;
|
||||
NT2b y0=c[0]-a0; NT2b y1=c[1]-a1;
|
||||
return CGAL::compare(x0*y1,x1*y0);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
#ifndef CGAL_VECTOR_VECTOR_H
|
||||
#define CGAL_VECTOR_VECTOR_H
|
||||
#include <boost/type_traits/is_arithmetic.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <CGAL/Dimension.h>
|
||||
#include <CGAL/marcutils.h>
|
||||
#include <vector>
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
namespace CGAL {
|
||||
|
||||
//Derive from a class that doesn't depend on Dim, or still use Dim for checking?
|
||||
template<class NT_,class Dim_,class Max_dim_=Dim_> struct Vector_vector {
|
||||
typedef NT_ NT;
|
||||
typedef Dim_ Dimension;
|
||||
typedef Max_dim_ Max_dimension;
|
||||
typedef std::vector<NT> Vector;
|
||||
template< class D2, class D3=D2 >
|
||||
struct Rebind_dimension {
|
||||
typedef Vector_vector< NT, D2, D3 > Other;
|
||||
};
|
||||
template<class> struct Property : boost::false_type {};
|
||||
|
||||
struct Construct_vector {
|
||||
struct Dimension {
|
||||
Vector operator()(int d) const {
|
||||
return Vector(d);
|
||||
}
|
||||
};
|
||||
|
||||
struct Iterator {
|
||||
template<typename Iter>
|
||||
Vector operator()(int d,Iter const& f,Iter const& e) const {
|
||||
CGAL_assertion(d==std::distance(f,e));
|
||||
return Vector(f,e);
|
||||
}
|
||||
};
|
||||
|
||||
// unneeded thanks to Iterator_and_last?
|
||||
#if 0
|
||||
struct Iterator_add_one {
|
||||
template<typename Iter>
|
||||
Vector operator()(int d,Iter const& f,Iter const& e) const {
|
||||
CGAL_assertion(d==std::distance(f,e)+1);
|
||||
Vector a;
|
||||
a.reserve(d+1);
|
||||
a.insert(a.end(),f,e);
|
||||
a.push_back(1);
|
||||
return a;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
struct Iterator_and_last {
|
||||
template<typename Iter,typename T>
|
||||
Vector operator()(int d,Iter const& f,Iter const& e,CGAL_FORWARDABLE(T) t) const {
|
||||
CGAL_assertion(d==std::distance(f,e)+1);
|
||||
Vector a;
|
||||
a.reserve(d+1);
|
||||
a.insert(a.end(),f,e);
|
||||
a.push_back(CGAL_FORWARD(T,t));
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
// useless, use a transform_iterator?
|
||||
#if 0
|
||||
struct Iterator_and_last_divide {
|
||||
template<typename Iter,typename T>
|
||||
Vector operator()(int d,Iter f,Iter const& e,T const&t) const {
|
||||
CGAL_assertion(d==std::distance(f,e)+1);
|
||||
Vector a;
|
||||
a.reserve(d+1);
|
||||
for(;f!=e;++f){
|
||||
a.push_back(*f/t);
|
||||
}
|
||||
return a;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
struct Values {
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...U>
|
||||
Vector operator()(U&&...u) const {
|
||||
//TODO: check the right number of {}, g++ accepts one and two
|
||||
Vector a={forward_safe<NT,U>(u)...};
|
||||
return a;
|
||||
}
|
||||
#else
|
||||
|
||||
#define VAR(Z,N,_) a.push_back(t##N);
|
||||
#define CODE(Z,N,_) Vector operator()(BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \
|
||||
Vector a; \
|
||||
a.reserve(N); \
|
||||
BOOST_PP_REPEAT(N,VAR,) \
|
||||
return a; \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1, 11, CODE, _ )
|
||||
#undef CODE
|
||||
#undef VAR
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
struct Values_divide {
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class H,class...U>
|
||||
Vector operator()(H const&h,U&&...u) const {
|
||||
//TODO: do we want to cast at some point?
|
||||
//e.g. to avoid 1/2 in integers
|
||||
// ==> use Rational_traits<NT>().make_rational(x,y) ?
|
||||
Vector a={Rational_traits<NT>().make_rational(std::forward<U>(u),h)...};
|
||||
return a;
|
||||
}
|
||||
#else
|
||||
|
||||
#define VAR(Z,N,_) a.push_back(Rational_traits<NT>().make_rational( t##N ,h));
|
||||
#define CODE(Z,N,_) template<class H> Vector \
|
||||
operator()(H const&h, BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \
|
||||
Vector a; \
|
||||
a.reserve(N); \
|
||||
BOOST_PP_REPEAT(N,VAR,) \
|
||||
return a; \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1, 11, CODE, _ )
|
||||
#undef CODE
|
||||
#undef VAR
|
||||
|
||||
#endif
|
||||
};
|
||||
};
|
||||
typedef typename Vector::const_iterator Vector_const_iterator;
|
||||
static Vector_const_iterator vector_begin(Vector const&a){
|
||||
return a.begin();
|
||||
}
|
||||
static Vector_const_iterator vector_end(Vector const&a){
|
||||
return a.end();
|
||||
}
|
||||
static int size_of_vector(Vector const&a){
|
||||
return a.size();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
#ifndef CGAL_ARGUMENT_SWAPS_H
|
||||
#define CGAL_ARGUMENT_SWAPS_H
|
||||
|
||||
#include <CGAL/config.h>
|
||||
#include <utility>
|
||||
|
||||
#ifndef CGAL_CXX0X
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#endif
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<int,class...> struct Apply_to_last_then_rest_;
|
||||
|
||||
template<int d,class F,class T,class... U>
|
||||
struct Apply_to_last_then_rest_<d,F,T,U...> {
|
||||
typedef typename Apply_to_last_then_rest_<d-1,F,U...,T>::result_type result_type;
|
||||
inline result_type operator()(F&&f,T&&t,U&&...u)const{
|
||||
return Apply_to_last_then_rest_<d-1,F,U...,T>()(
|
||||
std::forward<F>(f),
|
||||
std::forward<U>(u)...,
|
||||
std::forward<T>(t));
|
||||
}
|
||||
};
|
||||
|
||||
template<class F,class T,class... U>
|
||||
struct Apply_to_last_then_rest_<0,F,T,U...> {
|
||||
typedef decltype(std::declval<F>()(std::declval<T>(), std::declval<U>()...)) result_type;
|
||||
inline result_type operator()(F&&f,T&&t,U&&...u)const{
|
||||
return std::forward<F>(f)(std::forward<T>(t), std::forward<U>(u)...);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
|
||||
struct Apply_to_last_then_rest {
|
||||
template<class F,class T,class...U> inline
|
||||
typename internal::Apply_to_last_then_rest_<sizeof...(U),F,T,U...>::result_type
|
||||
operator()(F&&f,T&&t,U&&...u)const{
|
||||
return internal::Apply_to_last_then_rest_<sizeof...(U),F,T,U...>()(
|
||||
std::forward<F>(f),
|
||||
std::forward<T>(t),
|
||||
std::forward<U>(u)...);
|
||||
}
|
||||
};
|
||||
|
||||
#else // CGAL_CXX0X
|
||||
|
||||
struct Apply_to_last_then_rest {
|
||||
#define CODE(Z,N,_) template<class F,class T,BOOST_PP_ENUM_PARAMS(N,class T)> \
|
||||
typename boost::result_of<F(T,BOOST_PP_ENUM_PARAMS(N,T))>::type \
|
||||
operator()(F const&f, BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t), T const&t) const { \
|
||||
return f(t,BOOST_PP_ENUM_PARAMS(N,t)); \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_)
|
||||
#undef CODE
|
||||
};
|
||||
|
||||
#endif // CGAL_CXX0X
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_ARGUMENT_SWAPS_H
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
#ifndef CGAL_DETVEC_H
|
||||
#define CGAL_DETVEC_H
|
||||
#include <CGAL/determinant.h>
|
||||
#include <CGAL/predicates/sign_of_determinant.h>
|
||||
|
||||
namespace CGAL {
|
||||
// TODO: determine whether it is better to pass them by lines or columns.
|
||||
|
||||
template <class NT, class Vector> inline
|
||||
NT determinant_of_vectors(Vector const&a, Vector const&b){
|
||||
return determinant<NT>(a[0],a[1],b[0],b[1]);
|
||||
}
|
||||
template <class NT, class Vector> inline
|
||||
typename Sgn<NT>::result_type
|
||||
sign_of_determinant_of_vectors(Vector const&a, Vector const&b){
|
||||
return sign_of_determinant<NT>(a[0],a[1],b[0],b[1]);
|
||||
}
|
||||
|
||||
template <class NT, class Vector>
|
||||
NT determinant_of_vectors(Vector const&a, Vector const&b,
|
||||
Vector const&c){
|
||||
return determinant<NT>(a[0],a[1],a[2],b[0],b[1],b[2],c[0],c[1],c[2]);
|
||||
}
|
||||
template <class NT, class Vector>
|
||||
typename Sgn<NT>::result_type
|
||||
sign_of_determinant_of_vectors(Vector const&a, Vector const&b,
|
||||
Vector const&c){
|
||||
return sign_of_determinant<NT>(a[0],a[1],a[2],b[0],b[1],b[2],c[0],c[1],c[2]);
|
||||
}
|
||||
|
||||
template <class NT, class Vector>
|
||||
NT determinant_of_vectors(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d){
|
||||
return determinant<NT>(
|
||||
a[0],a[1],a[2],a[3],
|
||||
b[0],b[1],b[2],b[3],
|
||||
c[0],c[1],c[2],c[3],
|
||||
d[0],d[1],d[2],d[3]);
|
||||
}
|
||||
template <class NT, class Vector>
|
||||
typename Sgn<NT>::result_type
|
||||
sign_of_determinant_of_vectors(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d){
|
||||
return sign_of_determinant<NT>(
|
||||
a[0],a[1],a[2],a[3],
|
||||
b[0],b[1],b[2],b[3],
|
||||
c[0],c[1],c[2],c[3],
|
||||
d[0],d[1],d[2],d[3]);
|
||||
}
|
||||
|
||||
template <class NT, class Vector>
|
||||
NT determinant_of_vectors(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d, Vector const&e){
|
||||
return determinant<NT>(
|
||||
a[0],a[1],a[2],a[3],a[4],
|
||||
b[0],b[1],b[2],b[3],b[4],
|
||||
c[0],c[1],c[2],c[3],c[4],
|
||||
d[0],d[1],d[2],d[3],d[4],
|
||||
e[0],e[1],e[2],e[3],e[4]);
|
||||
}
|
||||
template <class NT, class Vector>
|
||||
typename Sgn<NT>::result_type
|
||||
sign_of_determinant_of_vectors(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d, Vector const&e){
|
||||
return sign_of_determinant<NT>(
|
||||
a[0],a[1],a[2],a[3],a[4],
|
||||
b[0],b[1],b[2],b[3],b[4],
|
||||
c[0],c[1],c[2],c[3],c[4],
|
||||
d[0],d[1],d[2],d[3],d[4],
|
||||
e[0],e[1],e[2],e[3],e[4]);
|
||||
}
|
||||
|
||||
template <class NT, class Vector>
|
||||
NT determinant_of_vectors(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d, Vector const&e, Vector const&f){
|
||||
return determinant<NT>(
|
||||
a[0],a[1],a[2],a[3],a[4],a[5],
|
||||
b[0],b[1],b[2],b[3],b[4],b[5],
|
||||
c[0],c[1],c[2],c[3],c[4],c[5],
|
||||
d[0],d[1],d[2],d[3],d[4],d[5],
|
||||
e[0],e[1],e[2],e[3],e[4],e[5],
|
||||
f[0],f[1],f[2],f[3],f[4],f[5]);
|
||||
}
|
||||
template <class NT, class Vector>
|
||||
typename Sgn<NT>::result_type
|
||||
sign_of_determinant_of_vectors(Vector const&a, Vector const&b,
|
||||
Vector const&c, Vector const&d, Vector const&e, Vector const&f){
|
||||
return sign_of_determinant<NT>(
|
||||
a[0],a[1],a[2],a[3],a[4],a[5],
|
||||
b[0],b[1],b[2],b[3],b[4],b[5],
|
||||
c[0],c[1],c[2],c[3],c[4],c[5],
|
||||
d[0],d[1],d[2],d[3],d[4],d[5],
|
||||
e[0],e[1],e[2],e[3],e[4],e[5],
|
||||
f[0],f[1],f[2],f[3],f[4],f[5]);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef CGAL_EXACTNESS_H
|
||||
#define CGAL_EXACTNESS_H
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#include <CGAL/tags.h>
|
||||
namespace CGAL {
|
||||
|
||||
#define CGAL_STRAWBERRY(Is_pretty) \
|
||||
namespace internal { \
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(Is_pretty) \
|
||||
} \
|
||||
template<class T,bool=internal::has_##Is_pretty<T>::value> \
|
||||
struct Is_pretty : boost::false_type {}; \
|
||||
template<class T> \
|
||||
struct Is_pretty<T,true> : T::Is_pretty {}
|
||||
|
||||
CGAL_STRAWBERRY(Is_exact);
|
||||
CGAL_STRAWBERRY(Is_fast);
|
||||
CGAL_STRAWBERRY(Is_stored);
|
||||
#undef CGAL_STRAWBERRY
|
||||
}
|
||||
#endif // CGAL_EXACTNESS_H
|
||||
|
|
@ -0,0 +1,310 @@
|
|||
#ifndef CGAL_FUNCTOR_TAGS_H
|
||||
#define CGAL_FUNCTOR_TAGS_H
|
||||
#include <CGAL/tags.h> // for Null_tag
|
||||
#include <CGAL/marcutils.h>
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/empty.hpp>
|
||||
#include <boost/mpl/front.hpp>
|
||||
#include <boost/mpl/pop_front.hpp>
|
||||
namespace CGAL {
|
||||
|
||||
// Find a better place for this later
|
||||
|
||||
template <class K, class T, class=void> struct Get_type
|
||||
: K::template Type<T> {};
|
||||
template <class K, class F, class O=void, class=void> struct Get_functor
|
||||
: K::template Functor<F, O> {};
|
||||
#ifdef CGAL_CXX0X
|
||||
template <class K, class T> using Type = typename Get_type<K, T>::type;
|
||||
template <class K, class T> using Functor = typename Get_functor<K, T>::type;
|
||||
#endif
|
||||
|
||||
class Null_type {~Null_type();}; // no such object should be created
|
||||
|
||||
// To construct iterators
|
||||
struct Begin_tag {};
|
||||
struct End_tag {};
|
||||
|
||||
// Functor category
|
||||
struct Predicate_tag {};
|
||||
struct Construct_tag {};
|
||||
struct Construct_iterator_tag {};
|
||||
struct Compute_tag {};
|
||||
struct Misc_tag {};
|
||||
|
||||
struct No_filter_tag {};
|
||||
|
||||
template<class>struct Construct_ttag {};
|
||||
template<class>struct Convert_ttag {};
|
||||
|
||||
template <class K, class F, class=void, class=void> struct Get_functor_category { typedef Misc_tag type; };
|
||||
template<class Tg, class Obj, class Base> struct Typedef_tag_type;
|
||||
//template<class Kernel, class Tg> struct Read_tag_type {};
|
||||
|
||||
template<class Kernel, class Tg>
|
||||
struct Provides_type
|
||||
: Has_type_different_from<Get_type<Kernel, Tg>, Null_type> {};
|
||||
|
||||
template<class Kernel, class Tg, class O=void>
|
||||
struct Provides_functor
|
||||
: Has_type_different_from<Get_functor<Kernel, Tg, O>, Null_functor> {};
|
||||
|
||||
template<class K, class List, bool=boost::mpl::empty<List>::type::value>
|
||||
struct Provides_functors : boost::mpl::and_ <
|
||||
Provides_functor<K, typename boost::mpl::front<List>::type>,
|
||||
Provides_functors<K, typename boost::mpl::pop_front<List>::type> > {};
|
||||
template<class K, class List>
|
||||
struct Provides_functors<K, List, true> : boost::true_type {};
|
||||
|
||||
template<class K, class List, bool=boost::mpl::empty<List>::type::value>
|
||||
struct Provides_types : boost::mpl::and_ <
|
||||
Provides_type<K, typename boost::mpl::front<List>::type>,
|
||||
Provides_types<K, typename boost::mpl::pop_front<List>::type> > {};
|
||||
template<class K, class List>
|
||||
struct Provides_types<K, List, true> : boost::true_type {};
|
||||
|
||||
namespace internal { BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_Type,template Type<Null_tag>,false) }
|
||||
template<class Kernel, class Tg,
|
||||
bool = internal::has_Type<Kernel>::value /* false */>
|
||||
struct Provides_type_i : boost::false_type {};
|
||||
template<class Kernel, class Tg>
|
||||
struct Provides_type_i <Kernel, Tg, true>
|
||||
: Has_type_different_from<typename Kernel::template Type<Tg>, Null_type> {};
|
||||
|
||||
namespace internal { BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_Functor,template Functor<Null_tag>,false) }
|
||||
template<class Kernel, class Tg, class O=void,
|
||||
bool = internal::has_Functor<Kernel>::value /* false */>
|
||||
struct Provides_functor_i : boost::false_type {};
|
||||
template<class Kernel, class Tg, class O>
|
||||
struct Provides_functor_i <Kernel, Tg, O, true>
|
||||
: Has_type_different_from<typename Kernel::template Functor<Tg, O>, Null_functor> {};
|
||||
|
||||
// TODO: Refine this a bit.
|
||||
template <class K, class T, class D=void,
|
||||
//bool=Provides_functor<K,T>::value,
|
||||
//bool=Provides_functor_i<K,T>::value,
|
||||
bool=internal::has_Functor<K>::value>
|
||||
struct Inherit_functor : K::template Functor<T> {};
|
||||
template <class K, class T, class D>
|
||||
struct Inherit_functor <K, T, D, false> {};
|
||||
|
||||
template <class K, class T, bool=internal::has_Type<K>::value>
|
||||
struct Inherit_type : K::template Type<T> {};
|
||||
template <class K, class T>
|
||||
struct Inherit_type <K, T, false> {};
|
||||
|
||||
struct Number_tag {};
|
||||
struct Discrete_tag {};
|
||||
struct Object_tag {};
|
||||
template <class K, class T, class=void> struct Get_type_category {
|
||||
// The lazy kernel uses it too eagerly,
|
||||
// so it currently needs a default.
|
||||
typedef Null_tag type;
|
||||
};
|
||||
|
||||
#define DECL_OBJ_(X,Y) \
|
||||
template<class Obj,class Base> \
|
||||
struct Typedef_tag_type<X##_tag, Obj, Base> : Base { typedef Obj X; }; \
|
||||
template<class K, class D> \
|
||||
struct Get_type_category <K, X##_tag, D> { typedef Y##_tag type; }
|
||||
#define DECL_OBJ(X,Y) struct X##_tag {}; \
|
||||
DECL_OBJ_(X,Y)
|
||||
|
||||
//namespace has_object { BOOST_MPL_HAS_XXX_TRAIT_DEF(X) }
|
||||
//template<class Kernel>
|
||||
//struct Provides_tag_type<Kernel, X##_tag> : has_object::has_##X<Kernel> {};
|
||||
//template<class Kernel>
|
||||
//struct Read_tag_type<Kernel, X##_tag> { typedef typename Kernel::X type; }
|
||||
|
||||
// Not exactly objects, but the extras can't hurt.
|
||||
DECL_OBJ(FT, Number);
|
||||
DECL_OBJ(RT, Number);
|
||||
|
||||
DECL_OBJ(Bool, Discrete); // Boolean_tag is already taken, and is a template :-(
|
||||
DECL_OBJ(Comparison_result, Discrete);
|
||||
DECL_OBJ(Sign, Discrete);
|
||||
DECL_OBJ(Orientation, Discrete); // Note: duplicate with the functor tag!
|
||||
DECL_OBJ(Oriented_side, Discrete);
|
||||
DECL_OBJ(Bounded_side, Discrete);
|
||||
DECL_OBJ(Angle, Discrete);
|
||||
DECL_OBJ(Flat_orientation, Discrete);
|
||||
|
||||
DECL_OBJ(Vector, Object);
|
||||
DECL_OBJ(Point, Object);
|
||||
DECL_OBJ(Segment, Object);
|
||||
DECL_OBJ(Sphere, Object);
|
||||
DECL_OBJ(Line, Object);
|
||||
DECL_OBJ(Direction, Object);
|
||||
DECL_OBJ(Hyperplane, Object);
|
||||
DECL_OBJ(Ray, Object);
|
||||
DECL_OBJ(Iso_box, Object);
|
||||
DECL_OBJ(Bbox, Object);
|
||||
DECL_OBJ(Aff_transformation, Object);
|
||||
#undef DECL_OBJ_
|
||||
#undef DECL_OBJ
|
||||
|
||||
CGAL_KD_DEFAULT_TYPE(RT_tag,(typename Get_type<K, FT_tag>::type),(),());
|
||||
CGAL_KD_DEFAULT_TYPE(FT_tag,(CGAL::Quotient<typename Get_type<K, RT_tag>::type>),(),());
|
||||
|
||||
#define SMURF2(A,B) CGAL_KD_DEFAULT_TYPE(A##_tag,(typename Same_uncertainty_nt<B, typename Get_type<K,RT_tag>::type>::type),(RT_tag),())
|
||||
#define SMURF1(A) SMURF2(A,CGAL::A)
|
||||
SMURF2(Bool, bool);
|
||||
SMURF1(Sign);
|
||||
SMURF1(Comparison_result);
|
||||
SMURF1(Orientation);
|
||||
SMURF1(Oriented_side);
|
||||
SMURF1(Bounded_side);
|
||||
SMURF1(Angle);
|
||||
#undef SMURF1
|
||||
#undef SMURF2
|
||||
|
||||
// TODO: replace with Get_type_category
|
||||
template<class> struct is_NT_tag { enum { value = false }; };
|
||||
template<> struct is_NT_tag<FT_tag> { enum { value = true }; };
|
||||
template<> struct is_NT_tag<RT_tag> { enum { value = true }; };
|
||||
|
||||
template<class> struct iterator_tag_traits {
|
||||
enum { is_iterator = false, has_nth_element = false };
|
||||
typedef Null_tag value_tag;
|
||||
};
|
||||
|
||||
#define DECL_COMPUTE(X) struct X##_tag {}; \
|
||||
template<class A,class B,class C>struct Get_functor_category<A,X##_tag,B,C>{typedef Compute_tag type;}
|
||||
DECL_COMPUTE(Compute_point_cartesian_coordinate);
|
||||
DECL_COMPUTE(Compute_vector_cartesian_coordinate);
|
||||
DECL_COMPUTE(Compute_homogeneous_coordinate);
|
||||
DECL_COMPUTE(Squared_distance);
|
||||
DECL_COMPUTE(Squared_distance_to_origin);
|
||||
DECL_COMPUTE(Squared_length);
|
||||
DECL_COMPUTE(Squared_radius);
|
||||
DECL_COMPUTE(Scalar_product);
|
||||
DECL_COMPUTE(Hyperplane_translation);
|
||||
DECL_COMPUTE(Value_at);
|
||||
#undef DECL_COMPUTE
|
||||
|
||||
#define DECL_ITER_OBJ(X,Y,Z,C) struct X##_tag {}; \
|
||||
template<>struct iterator_tag_traits<X##_tag> { \
|
||||
enum { is_iterator = true, has_nth_element = true }; \
|
||||
typedef Y##_tag value_tag; \
|
||||
typedef Z##_tag nth_element; \
|
||||
typedef C##_tag container; \
|
||||
}; \
|
||||
template<class Obj,class Base> \
|
||||
struct Typedef_tag_type<X##_tag, Obj, Base> : Base { typedef Obj X; }
|
||||
|
||||
//namespace has_object { BOOST_MPL_HAS_XXX_TRAIT_DEF(X) }
|
||||
//template<class Kernel>
|
||||
//struct Provides_tag_type<Kernel, X##_tag> : has_object::has_##X<Kernel> {};
|
||||
//template<class Kernel>
|
||||
//struct Read_tag_type<Kernel, X##_tag> { typedef typename Kernel::X type; }
|
||||
|
||||
DECL_ITER_OBJ(Vector_cartesian_const_iterator, FT, Compute_vector_cartesian_coordinate, Vector);
|
||||
DECL_ITER_OBJ(Point_cartesian_const_iterator, FT, Compute_point_cartesian_coordinate, Point);
|
||||
#undef DECL_ITER_OBJ
|
||||
|
||||
template<class>struct map_result_tag{typedef Null_type type;};
|
||||
template<class T>struct map_result_tag<Construct_ttag<T> >{typedef T type;};
|
||||
|
||||
template<class A,class T,class B,class C>struct Get_functor_category<A,Construct_ttag<T>,B,C> :
|
||||
BOOSTD conditional<iterator_tag_traits<T>::is_iterator,
|
||||
Construct_iterator_tag,
|
||||
Construct_tag> {};
|
||||
|
||||
// Really?
|
||||
template<class A,class T,class B,class C>struct Get_functor_category<A,Convert_ttag<T>,B,C>{typedef Misc_tag type;};
|
||||
|
||||
#define DECL_CONSTRUCT(X,Y) struct X##_tag {}; \
|
||||
template<>struct map_result_tag<X##_tag>{typedef Y##_tag type;}; \
|
||||
template<class A,class B,class C>struct Get_functor_category<A,X##_tag,B,C>{typedef Construct_tag type;}
|
||||
DECL_CONSTRUCT(Midpoint,Point);
|
||||
DECL_CONSTRUCT(Center_of_sphere,Point);
|
||||
DECL_CONSTRUCT(Point_of_sphere,Point);
|
||||
DECL_CONSTRUCT(Segment_extremity,Point);
|
||||
DECL_CONSTRUCT(Sum_of_vectors,Vector);
|
||||
DECL_CONSTRUCT(Difference_of_vectors,Vector);
|
||||
DECL_CONSTRUCT(Opposite_vector,Vector);
|
||||
DECL_CONSTRUCT(Scaled_vector,Vector);
|
||||
DECL_CONSTRUCT(Orthogonal_vector,Vector);
|
||||
DECL_CONSTRUCT(Difference_of_points,Vector);
|
||||
DECL_CONSTRUCT(Translated_point,Point);
|
||||
DECL_CONSTRUCT(Point_to_vector,Vector);
|
||||
DECL_CONSTRUCT(Vector_to_point,Point);
|
||||
#undef DECL_CONSTRUCT
|
||||
#if 0
|
||||
#define DECL_ITER_CONSTRUCT(X,Y) struct X##_tag {}; \
|
||||
template<>struct map_result_tag<X##_tag>{typedef Y##_tag type;}; \
|
||||
template<>struct map_functor_type<X##_tag>{typedef Construct_iterator_tag type;}
|
||||
DECL_ITER_CONSTRUCT(Construct_point_cartesian_const_iterator,Point_cartesian_const_iterator);
|
||||
DECL_ITER_CONSTRUCT(Construct_vector_cartesian_const_iterator,Vector_cartesian_const_iterator);
|
||||
#undef DECL_ITER_CONSTRUCT
|
||||
#endif
|
||||
|
||||
//FIXME: choose a convention: prefix with Predicate_ ?
|
||||
#define DECL_PREDICATE_(X) \
|
||||
template<class A,class B,class C>struct Get_functor_category<A,X##_tag,B,C>{typedef Predicate_tag type;}
|
||||
#define DECL_PREDICATE(X) struct X##_tag {}; \
|
||||
DECL_PREDICATE_(X)
|
||||
DECL_PREDICATE(Less_point_cartesian_coordinate);
|
||||
DECL_PREDICATE(Compare_point_cartesian_coordinate);
|
||||
DECL_PREDICATE(Compare_distance);
|
||||
DECL_PREDICATE(Compare_lexicographically);
|
||||
DECL_PREDICATE(Less_lexicographically);
|
||||
DECL_PREDICATE(Less_or_equal_lexicographically);
|
||||
DECL_PREDICATE(Equal_points);
|
||||
DECL_PREDICATE(Has_on_positive_side);
|
||||
DECL_PREDICATE_(Orientation); // duplicate with the type
|
||||
DECL_PREDICATE_(Oriented_side); // duplicate with the type
|
||||
DECL_PREDICATE(Orientation_of_points);
|
||||
DECL_PREDICATE(Orientation_of_vectors);
|
||||
DECL_PREDICATE(Side_of_oriented_sphere);
|
||||
DECL_PREDICATE(Contained_in_affine_hull);
|
||||
DECL_PREDICATE(In_flat_orientation);
|
||||
DECL_PREDICATE(In_flat_side_of_oriented_sphere);
|
||||
DECL_PREDICATE(Construct_flat_orientation); // Making it a predicate is a questionable choice, it should be possible to let it be a construction for some implementations. Not sure how to do that... TODO
|
||||
#undef DECL_PREDICATE
|
||||
|
||||
#define DECL_MISC(X) struct X##_tag {}; \
|
||||
template<class A,class B,class C>struct Get_functor_category<A,X##_tag,B,C>{typedef Misc_tag type;}
|
||||
//TODO: split into _begin and _end ?
|
||||
//DECL_MISC(Construct_point_cartesian_const_iterator);
|
||||
//DECL_MISC(Construct_vector_cartesian_const_iterator);
|
||||
DECL_MISC(Point_dimension);
|
||||
DECL_MISC(Vector_dimension);
|
||||
#undef DECL_MISC
|
||||
|
||||
|
||||
// Properties for LA
|
||||
struct Has_extra_dimension_tag {};
|
||||
struct Has_vector_plus_minus_tag {};
|
||||
struct Has_vector_scalar_ops_tag {};
|
||||
struct Has_dot_product_tag {};
|
||||
struct Has_determinant_of_vectors_tag {};
|
||||
struct Has_determinant_of_points_tag {};
|
||||
struct Has_determinant_of_iterator_to_vectors_tag {};
|
||||
struct Has_determinant_of_iterator_to_points_tag {};
|
||||
struct Has_determinant_of_vectors_omit_last_tag {};
|
||||
struct Stores_squared_norm_tag {};
|
||||
|
||||
template<class> struct Preserved_by_non_linear_extra_coordinate
|
||||
: boost::false_type {};
|
||||
template<> struct Preserved_by_non_linear_extra_coordinate
|
||||
<Has_extra_dimension_tag> : boost::true_type {};
|
||||
template<> struct Preserved_by_non_linear_extra_coordinate
|
||||
<Has_determinant_of_vectors_tag> : boost::true_type {};
|
||||
template<> struct Preserved_by_non_linear_extra_coordinate
|
||||
<Has_determinant_of_points_tag> : boost::true_type {};
|
||||
template<> struct Preserved_by_non_linear_extra_coordinate
|
||||
<Has_determinant_of_iterator_to_vectors_tag> : boost::true_type {};
|
||||
template<> struct Preserved_by_non_linear_extra_coordinate
|
||||
<Has_determinant_of_iterator_to_points_tag> : boost::true_type {};
|
||||
template<> struct Preserved_by_non_linear_extra_coordinate
|
||||
<Has_determinant_of_vectors_omit_last_tag> : boost::true_type {};
|
||||
|
||||
// Kernel properties
|
||||
struct Point_stores_squared_distance_to_origin_tag {};
|
||||
|
||||
}
|
||||
#endif // CGAL_FUNCTOR_TAGS_H
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef CGAL_ITERATOR_FROM_INDICES_H
|
||||
#define CGAL_ITERATOR_FROM_INDICES_H
|
||||
#include <boost/iterator/iterator_facade.hpp>
|
||||
namespace CGAL {
|
||||
template <class Ref_>
|
||||
struct Default_coordinate_access {
|
||||
typedef Ref_ result_type;
|
||||
template<class T> Ref_ operator()(T const& t, int i)const{
|
||||
return t[i];
|
||||
}
|
||||
};
|
||||
|
||||
//TODO: default type for Value_: typename same_cv<Container_,typename remove_cv<Container_>::type::value_type>::type
|
||||
template <class Container_, class Value_, class Ref_=
|
||||
#ifdef CGAL_CXX0X
|
||||
decltype(std::declval<Container_>()[0])
|
||||
#else
|
||||
Value_&
|
||||
#endif
|
||||
, class Coord_access = Default_coordinate_access<Ref_>
|
||||
>
|
||||
class Iterator_from_indices
|
||||
: public boost::iterator_facade<Iterator_from_indices<Container_,Value_,Ref_,Coord_access>,
|
||||
Value_, std::bidirectional_iterator_tag, Ref_>
|
||||
{
|
||||
friend class boost::iterator_core_access;
|
||||
//FIXME: use int to save space
|
||||
//FIXME: use a signed type
|
||||
typedef std::size_t index_t;
|
||||
Container_* cont;
|
||||
index_t index;
|
||||
Coord_access ca;
|
||||
void increment(){ ++index; }
|
||||
void decrement(){ --index; }
|
||||
void advance(std::ptrdiff_t n){ index+=n; }
|
||||
ptrdiff_t distance_to(Iterator_from_indices const& other)const{
|
||||
return static_cast<ptrdiff_t>(other.index)
|
||||
-static_cast<ptrdiff_t>(index);
|
||||
}
|
||||
bool equal(Iterator_from_indices const& other)const{
|
||||
return index==other.index;
|
||||
}
|
||||
Ref_ dereference()const{
|
||||
//FIXME: use the functor properly
|
||||
//Uh, and what did I mean by that?
|
||||
return ca(*cont,index);
|
||||
}
|
||||
public:
|
||||
Iterator_from_indices(Container_& cont_,std::size_t n)
|
||||
: cont(&cont_), index(n) {}
|
||||
template<class T>
|
||||
Iterator_from_indices(Container_& cont_,std::size_t n,T const&t)
|
||||
: cont(&cont_), index(n), ca(t) {}
|
||||
};
|
||||
}
|
||||
#endif // CGAL_ITERATOR_FROM_INDICES_H
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
#ifndef marcutils
|
||||
#define marcutils
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#define CGAL_FORWARDABLE(T) T&&
|
||||
#define CGAL_FORWARD(T,t) std::forward<T>(t)
|
||||
#define CGAL_MOVE(t) std::move(t)
|
||||
#define CGAL_CONSTEXPR constexpr
|
||||
#else
|
||||
#define CGAL_FORWARDABLE(T) T const&
|
||||
#define CGAL_FORWARD(T,t) t
|
||||
#define CGAL_MOVE(t) t
|
||||
#define CGAL_CONSTEXPR
|
||||
#endif
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/preprocessor/repetition.hpp>
|
||||
#include <CGAL/Rational_traits.h>
|
||||
#include <CGAL/tuple.h>
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
#define BOOSTD std::
|
||||
#else
|
||||
#define BOOSTD boost::
|
||||
#endif
|
||||
|
||||
namespace CGAL {
|
||||
namespace internal {
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
|
||||
}
|
||||
|
||||
template <class T, class No, bool=internal::has_type<T>::value /*false*/>
|
||||
struct Has_type_different_from : boost::false_type {};
|
||||
template <class T, class No>
|
||||
struct Has_type_different_from <T, No, true>
|
||||
: boost::mpl::not_<boost::is_same<typename T::type, No> > {};
|
||||
|
||||
|
||||
template <class T> struct Wrap_type { typedef T type; };
|
||||
|
||||
// tell a function f(a,b,c) that its real argument is a(b,c)
|
||||
struct Eval_functor {};
|
||||
|
||||
// forget the first argument. Useful to make something dependant
|
||||
// (and thus usable in SFINAE), although that's not a great design.
|
||||
template<class A,class B> struct Second_arg {
|
||||
typedef B type;
|
||||
};
|
||||
|
||||
// like std::forward, except for basic types where it does a cast, to
|
||||
// avoid issues with narrowing conversions
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class T,class U,class V> inline
|
||||
typename std::conditional<std::is_arithmetic<T>::value&&std::is_arithmetic<typename std::remove_reference<U>::type>::value,T,U&&>::type
|
||||
forward_safe(V&& u) { return std::forward<U>(u); }
|
||||
#else
|
||||
template<class T,class U> inline U const& forward_safe(U const& u) {
|
||||
return u;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...> struct Constructible_from_each;
|
||||
template<class To,class From1,class...From> struct Constructible_from_each<To,From1,From...>{
|
||||
enum { value=std::is_convertible<From1,To>::value&&Constructible_from_each<To,From...>::value };
|
||||
};
|
||||
template<class To> struct Constructible_from_each<To>{
|
||||
enum { value=true };
|
||||
};
|
||||
#else
|
||||
// currently only used in C++0X code
|
||||
#endif
|
||||
|
||||
template<class T> struct Scale {
|
||||
T const& scale;
|
||||
Scale(T const& t):scale(t){}
|
||||
template<class FT>
|
||||
#ifdef CGAL_CXX0X
|
||||
auto operator()(FT&& x)const->decltype(scale*std::forward<FT>(x))
|
||||
#else
|
||||
FT operator()(FT const& x)const
|
||||
#endif
|
||||
{
|
||||
return scale*CGAL_FORWARD(FT,x);
|
||||
}
|
||||
};
|
||||
template<class NT,class T> struct Divide {
|
||||
#if !defined(CGAL_CXX0X) || !defined(BOOST_RESULT_OF_USE_DECLTYPE)
|
||||
// requires boost > 1.44
|
||||
// shouldn't be needed with C++0X
|
||||
//template<class> struct result;
|
||||
//template<class FT> struct result<Divide(FT)> {
|
||||
// typedef FT type;
|
||||
//};
|
||||
typedef NT result_type;
|
||||
#endif
|
||||
T const& scale;
|
||||
Divide(T const& t):scale(t){}
|
||||
template<class FT>
|
||||
#ifdef CGAL_CXX0X
|
||||
//FIXME: gcc complains for Gmpq
|
||||
//auto operator()(FT&& x)const->decltype(Rational_traits<NT>().make_rational(std::forward<FT>(x),scale))
|
||||
NT operator()(FT&& x)const
|
||||
#else
|
||||
NT operator()(FT const& x)const
|
||||
#endif
|
||||
{
|
||||
return Rational_traits<NT>().
|
||||
make_rational(CGAL_FORWARD(FT,x),scale);
|
||||
}
|
||||
};
|
||||
|
||||
template <class NT> struct has_cheap_constructor : boost::is_arithmetic<NT>{};
|
||||
template <bool p> struct has_cheap_constructor<Interval_nt<p> > {
|
||||
enum { value=true };
|
||||
};
|
||||
|
||||
// like std::multiplies but allows mixing types
|
||||
// in C++0x in doesn't need to be a template
|
||||
template < class Ret >
|
||||
struct multiplies {
|
||||
template<class A,class B>
|
||||
#ifdef CGAL_CXX0X
|
||||
auto operator()(A&&a,B&&b)const->decltype(std::forward<A>(a)*std::forward<B>(b))
|
||||
#else
|
||||
Ret operator()(A const& a, B const& b)const
|
||||
#endif
|
||||
{
|
||||
return CGAL_FORWARD(A,a)*CGAL_FORWARD(B,b);
|
||||
}
|
||||
};
|
||||
template < class Ret >
|
||||
struct division {
|
||||
template<class A,class B>
|
||||
#ifdef CGAL_CXX0X
|
||||
auto operator()(A&&a,B&&b)const->decltype(std::forward<A>(a)/std::forward<B>(b))
|
||||
#else
|
||||
Ret operator()(A const& a, B const& b)const
|
||||
#endif
|
||||
{
|
||||
return CGAL_FORWARD(A,a)/CGAL_FORWARD(B,b);
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
using std::decay;
|
||||
#else
|
||||
template<class T> struct decay : boost::remove_cv<typename boost::decay<T>::type> {};
|
||||
#endif
|
||||
|
||||
template<class T,class U> struct Type_copy_ref { typedef U type; };
|
||||
template<class T,class U> struct Type_copy_ref<T&,U> { typedef U& type; };
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class T,class U> struct Type_copy_ref<T&&,U> { typedef U&& type; };
|
||||
#endif
|
||||
template<class T,class U> struct Type_copy_cv { typedef U type; };
|
||||
template<class T,class U> struct Type_copy_cv<T const,U> { typedef U const type; };
|
||||
template<class T,class U> struct Type_copy_cv<T volatile,U> { typedef U volatile type; };
|
||||
template<class T,class U> struct Type_copy_cv<T const volatile,U> { typedef U const volatile type; };
|
||||
|
||||
template<class T,class U> struct Type_copy_cvref :
|
||||
Type_copy_ref<T,typename Type_copy_cv<typename boost::remove_reference<T>::type,U>::type> {};
|
||||
|
||||
struct Dereference_functor {
|
||||
template<class> struct result{};
|
||||
template<class It> struct result<Dereference_functor(It)> {
|
||||
typedef typename std::iterator_traits<It>::reference type;
|
||||
};
|
||||
template<class It> typename result<Dereference_functor(It)>::type
|
||||
operator()(It const&i)const{
|
||||
return *i;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
template<int...> struct Indices{};
|
||||
template<class> struct Next_increasing_indices;
|
||||
template<int...I> struct Next_increasing_indices<Indices<I...> > {
|
||||
typedef Indices<I...,sizeof...(I)> type;
|
||||
};
|
||||
template<int N> struct N_increasing_indices {
|
||||
typedef typename Next_increasing_indices<typename N_increasing_indices<N-1>::type>::type type;
|
||||
};
|
||||
template<> struct N_increasing_indices<0> { typedef Indices<> type; };
|
||||
namespace internal {
|
||||
template<class F,class...U,int...I> inline typename std::result_of<F&&(U...)>::type
|
||||
do_call_on_tuple_elements(F&&f, std::tuple<U...>&&t, Indices<I...>&&) {
|
||||
return f(std::get<I>(std::move(t))...);
|
||||
}
|
||||
} // internal
|
||||
template<class/*result type, ignored*/,class F,class...U>
|
||||
inline typename std::result_of<F&&(U...)>::type
|
||||
call_on_tuple_elements(F&&f, std::tuple<U...>&&t) {
|
||||
return internal::do_call_on_tuple_elements(std::forward<F>(f),std::move(t),
|
||||
typename N_increasing_indices<sizeof...(U)>::type());
|
||||
}
|
||||
#else
|
||||
#define VAR(Z,N,_) cpp0x::get<N>(t)
|
||||
#define CODE(Z,N,_) template<class Res, class F BOOST_PP_COMMA_IF(N) BOOST_PP_ENUM_PARAMS(N,class U)> \
|
||||
inline Res call_on_tuple_elements(F const&f, \
|
||||
cpp0x::tuple<BOOST_PP_ENUM_PARAMS(N,U)> const&t) { \
|
||||
return f(BOOST_PP_ENUM(N,VAR,)); \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(0, 8, CODE, _ )
|
||||
#undef CODE
|
||||
#undef VAR
|
||||
#endif
|
||||
|
||||
template<class A> struct Factory {
|
||||
typedef A result_type;
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...U> result_type operator()(U&&...u)const{
|
||||
return A(std::forward<U>(u)...);
|
||||
}
|
||||
#else
|
||||
result_type operator()()const{
|
||||
return A();
|
||||
}
|
||||
#define CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class U)> \
|
||||
result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \
|
||||
return A(BOOST_PP_ENUM_PARAMS(N,u)); \
|
||||
}
|
||||
BOOST_PP_REPEAT_FROM_TO(1, 8, CODE, _ )
|
||||
#undef CODE
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: make a Cartesian-only variant
|
||||
// WARNING: do not use the Req* parameters too much, they can cause circular instanciations and are only useful for dispatching.
|
||||
#define CGAL_STRIP_PAREN_(...) __VA_ARGS__
|
||||
#define CGAL_STRIP_PAREN(...) CGAL_STRIP_PAREN_ __VA_ARGS__
|
||||
// What to do with O? pass it down to other functors or drop it?
|
||||
#define CGAL_KD_DEFAULT_FUNCTOR(Tg,Name,ReqTyp,ReqFun) \
|
||||
template <class K, class O> \
|
||||
struct Get_functor<K, Tg, O, \
|
||||
typename boost::mpl::if_c< \
|
||||
Provides_functor_i<K, Tg, O>::value \
|
||||
|| !Provides_types<K, boost::mpl::vector<CGAL_STRIP_PAREN_ ReqTyp> >::value \
|
||||
|| !Provides_functors<K, boost::mpl::vector<CGAL_STRIP_PAREN_ ReqFun> >::value \
|
||||
, int, void>::type> \
|
||||
{ \
|
||||
typedef CGAL_STRIP_PAREN_ Name type; \
|
||||
typedef K Bound_kernel; \
|
||||
}
|
||||
|
||||
// Not used yet, may need some changes.
|
||||
#define CGAL_KD_DEFAULT_TYPE(Tg,Name,ReqTyp,ReqFun) \
|
||||
template <class K> \
|
||||
struct Get_type<K, Tg, \
|
||||
typename boost::mpl::if_c< \
|
||||
Provides_type_i<K, Tg>::value \
|
||||
|| !Provides_types<K, boost::mpl::vector<CGAL_STRIP_PAREN_ ReqTyp> >::value \
|
||||
|| !Provides_functors<K, boost::mpl::vector<CGAL_STRIP_PAREN_ ReqFun> >::value \
|
||||
, int, void>::type> \
|
||||
{ \
|
||||
typedef CGAL_STRIP_PAREN_ Name type; \
|
||||
typedef K Bound_kernel; \
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef CGAL_STATIC_INT_H
|
||||
#define CGAL_STATIC_INT_H
|
||||
#include <CGAL/constant.h>
|
||||
|
||||
namespace CGAL {
|
||||
template <class NT> struct static_zero {
|
||||
operator NT() const { return constant<NT,0>(); }
|
||||
};
|
||||
template <class NT> struct static_one {
|
||||
operator NT() const { return constant<NT,1>(); }
|
||||
};
|
||||
|
||||
template <class NT> static_zero<NT> operator-(static_zero<NT>) { return static_zero<NT>(); }
|
||||
|
||||
template <class NT> NT operator+(NT const& x, static_zero<NT>) { return x; }
|
||||
template <class NT> NT operator+(static_zero<NT>, NT const& x) { return x; }
|
||||
template <class NT> static_zero<NT> operator+(static_zero<NT>, static_zero<NT>) { return static_zero<NT>(); }
|
||||
template <class NT> static_one<NT> operator+(static_zero<NT>, static_one<NT>) { return static_one<NT>(); }
|
||||
template <class NT> static_one<NT> operator+(static_one<NT>, static_zero<NT>) { return static_one<NT>(); }
|
||||
|
||||
template <class NT> NT operator-(NT const& x, static_zero<NT>) { return x; }
|
||||
template <class NT> NT operator-(static_zero<NT>, NT const& x) { return -x; }
|
||||
template <class NT> static_zero<NT> operator-(static_zero<NT>, static_zero<NT>) { return static_zero<NT>(); }
|
||||
template <class NT> static_zero<NT> operator-(static_one<NT>, static_one<NT>) { return static_zero<NT>(); }
|
||||
template <class NT> static_one<NT> operator-(static_one<NT>, static_zero<NT>) { return static_one<NT>(); }
|
||||
|
||||
template <class NT> NT operator*(NT const& x, static_one<NT>) { return x; }
|
||||
template <class NT> NT operator*(static_one<NT>, NT const& x) { return x; }
|
||||
template <class NT> static_zero<NT> operator*(NT const&, static_zero<NT>) { return static_zero<NT>(); }
|
||||
template <class NT> static_zero<NT> operator*(static_zero<NT>, NT const&) { return static_zero<NT>(); }
|
||||
template <class NT> static_zero<NT> operator*(static_zero<NT>, static_zero<NT>) { return static_zero<NT>(); }
|
||||
template <class NT> static_one<NT> operator*(static_one<NT>, static_one<NT>) { return static_one<NT>(); }
|
||||
template <class NT> static_zero<NT> operator*(static_zero<NT>, static_one<NT>) { return static_zero<NT>(); }
|
||||
template <class NT> static_zero<NT> operator*(static_one<NT>, static_zero<NT>) { return static_zero<NT>(); }
|
||||
|
||||
template <class NT> NT operator/(NT const& x, static_one<NT>) { return x; }
|
||||
template <class NT> static_zero<NT> operator/(static_zero<NT>, NT const&) { return static_zero<NT>(); }
|
||||
template <class NT> static_zero<NT> operator/(static_zero<NT>, static_one<NT>) { return static_zero<NT>(); }
|
||||
template <class NT> static_one<NT> operator/(static_one<NT>, static_one<NT>) { return static_one<NT>(); }
|
||||
|
||||
}
|
||||
#endif // CGAL_STATIC_INT_H
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
#ifndef CGAL_STORE_KERNEL_H
|
||||
#define CGAL_STORE_KERNEL_H
|
||||
|
||||
#include <CGAL/assertions.h>
|
||||
#include <boost/type_traits/is_empty.hpp>
|
||||
|
||||
namespace CGAL {
|
||||
namespace internal {
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(Do_not_store_kernel)
|
||||
template<class T,bool=has_Do_not_store_kernel<T>::value> struct Do_not_store_kernel {
|
||||
enum { value=false };
|
||||
typedef Tag_false type;
|
||||
};
|
||||
template<class T> struct Do_not_store_kernel<T,true> {
|
||||
typedef typename T::Do_not_store_kernel type;
|
||||
enum { value=type::value };
|
||||
};
|
||||
}
|
||||
|
||||
template<class R_,bool=boost::is_empty<R_>::value||internal::Do_not_store_kernel<R_>::value>
|
||||
struct Store_kernel {
|
||||
Store_kernel(){}
|
||||
Store_kernel(R_ const&){}
|
||||
enum { kernel_is_stored = false };
|
||||
R_ kernel()const{return R_();}
|
||||
typedef R_ reference_type;
|
||||
void set_kernel(R_ const&){}
|
||||
};
|
||||
template<class R_>
|
||||
struct Store_kernel<R_,false> {
|
||||
Store_kernel():rp(0){
|
||||
CGAL_warning_msg(true,"I should know my kernel");
|
||||
}
|
||||
Store_kernel(R_ const& r):rp(&r){}
|
||||
enum { kernel_is_stored = true };
|
||||
R_ const& kernel()const{
|
||||
CGAL_warning_msg(rp!=0,"I should know my kernel");
|
||||
return *rp;
|
||||
}
|
||||
typedef R_ const& reference_type;
|
||||
void set_kernel(R_ const&r){rp=&r;}
|
||||
private:
|
||||
R_ const* rp;
|
||||
};
|
||||
|
||||
//For a second kernel. TODO: find something more elegant
|
||||
template<class R_,bool=boost::is_empty<R_>::value||internal::Do_not_store_kernel<R_>::value>
|
||||
struct Store_kernel2 {
|
||||
Store_kernel2(){}
|
||||
Store_kernel2(R_ const&){}
|
||||
enum { kernel2_is_stored = false };
|
||||
R_ kernel2()const{return R_();}
|
||||
typedef R_ reference2_type;
|
||||
void set_kernel2(R_ const&){}
|
||||
};
|
||||
template<class R_>
|
||||
struct Store_kernel2<R_,false> {
|
||||
Store_kernel2(){
|
||||
//CGAL_warning_msg(true,"I should know my kernel");
|
||||
}
|
||||
Store_kernel2(R_ const& r):rp(&r){}
|
||||
enum { kernel2_is_stored = true };
|
||||
R_ const& kernel2()const{
|
||||
CGAL_warning_msg(rp==0,"I should know my kernel");
|
||||
return *rp;
|
||||
}
|
||||
typedef R_ const& reference2_type;
|
||||
void set_kernel2(R_ const&r){rp=&r;}
|
||||
private:
|
||||
R_ const* rp;
|
||||
};
|
||||
}
|
||||
#define CGAL_BASE_INIT(X,Y) \
|
||||
X():Y(){} \
|
||||
X(R_ const&r):Y(r){}
|
||||
#define CGAL_FUNCTOR_INIT_STORE(X) CGAL_BASE_INIT(X,Store_kernel<R_>)
|
||||
#define CGAL_FUNCTOR_INIT_IGNORE(X) \
|
||||
X(){} \
|
||||
X(R_ const&){}
|
||||
|
||||
#endif // CGAL_STORE_KERNEL_H
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
#ifndef CGAL_TRANSFORMING_ITERATOR_H
|
||||
#define CGAL_TRANSFORMING_ITERATOR_H
|
||||
#include <boost/iterator/iterator_adaptor.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
#include <boost/type_traits/is_empty.hpp>
|
||||
#include <CGAL/Default.h>
|
||||
#include <utility>
|
||||
|
||||
// Inspired by the boost version, but more compact and
|
||||
// without any iterator_category games.
|
||||
|
||||
namespace CGAL {
|
||||
namespace internal {
|
||||
|
||||
// non-empty case
|
||||
template<class T,bool=boost::is_empty<T>::value> struct Functor_as_base {
|
||||
Functor_as_base(){}
|
||||
Functor_as_base(T const& t):f(t){}
|
||||
//template<class T2> Functor_as_base(Functor_as_base<T2> const&g):f(g.functor()){}
|
||||
T const& functor()const{return f;}
|
||||
T & functor() {return f;}
|
||||
private:
|
||||
T f;
|
||||
};
|
||||
|
||||
// empty case
|
||||
template<class T> struct Functor_as_base<T,true> : public T {
|
||||
Functor_as_base(){}
|
||||
Functor_as_base(T const& t):T(t){}
|
||||
//template<class T2> Functor_as_base(Functor_as_base<T2> const&g):T(g.functor()){}
|
||||
T const& functor()const{return *this;}
|
||||
T & functor() {return *this;}
|
||||
};
|
||||
|
||||
template <typename Derived, typename F, typename Iter, typename Ref, typename Val>
|
||||
class transforming_iterator_helper
|
||||
{
|
||||
typedef typename Default::Get<Ref,
|
||||
#ifndef CGAL_CFG_NO_CPP0X_DECLTYPE
|
||||
decltype(std::declval<F>()(std::declval<typename std::iterator_traits<Iter>::reference>()))
|
||||
#else
|
||||
typename boost::result_of<F(typename std::iterator_traits<Iter>::value_type)>::type
|
||||
// should be reference instead of value_type
|
||||
#endif
|
||||
>::type reference;
|
||||
|
||||
typedef typename Default::Get<Val,typename boost::remove_cv<typename boost::remove_reference<reference>::type>::type>::type value_type;
|
||||
|
||||
public:
|
||||
typedef boost::iterator_adaptor<
|
||||
Derived,
|
||||
Iter,
|
||||
value_type,
|
||||
typename std::iterator_traits<Iter>::iterator_category,
|
||||
reference
|
||||
> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename F, typename Iter, typename Ref=Default, typename Val=Default>
|
||||
class transforming_iterator
|
||||
: public internal::transforming_iterator_helper<transforming_iterator<F,Iter,Ref,Val>,F,Iter,Ref,Val>::type,
|
||||
private internal::Functor_as_base<F>
|
||||
{
|
||||
friend class boost::iterator_core_access;
|
||||
typedef typename internal::transforming_iterator_helper<transforming_iterator,F,Iter,Ref,Val>::type Base;
|
||||
typedef internal::Functor_as_base<F> Functor_base;
|
||||
typename Base::reference dereference()const{
|
||||
return functor()(*this->base_reference());
|
||||
}
|
||||
public:
|
||||
using Functor_base::functor;
|
||||
transforming_iterator(){}
|
||||
explicit transforming_iterator(Iter i,F const& f=F())
|
||||
:Base(i),Functor_base(f){}
|
||||
template<class F2,class I2,class R2,class V2>
|
||||
transforming_iterator(
|
||||
transforming_iterator<F2,I2,R2,V2> const&i,
|
||||
typename boost::enable_if_convertible<I2, Iter>::type* = 0,
|
||||
typename boost::enable_if_convertible<F2, F>::type* = 0)
|
||||
: Base(i.base()),Functor_base(i.functor()) {}
|
||||
|
||||
};
|
||||
|
||||
template <typename F, typename Iter> inline
|
||||
transforming_iterator<F,Iter> make_transforming_iterator(Iter i, F const&f=F()) {
|
||||
return transforming_iterator<F,Iter>(i,f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // CGAL_TRANSFORMING_ITERATOR_H
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
#ifndef CGAL_TRANSFORMING_PAIR_ITERATOR_H
|
||||
#define CGAL_TRANSFORMING_PAIR_ITERATOR_H
|
||||
// Should be a combination of transform_iterator and zip_iterator,
|
||||
// but boost's iterator_category games are a pain.
|
||||
|
||||
#include <CGAL/transforming_iterator.h>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
|
||||
|
||||
namespace CGAL {
|
||||
namespace internal {
|
||||
template <class Cat1, class Cat2, bool=boost::is_convertible<Cat1,Cat2>::value>
|
||||
struct Min_category {
|
||||
BOOST_STATIC_ASSERT((boost::is_convertible<Cat2,Cat1>::value));
|
||||
typedef Cat1 type;
|
||||
};
|
||||
|
||||
template <class Cat1, class Cat2>
|
||||
struct Min_category<Cat1,Cat2,true> {
|
||||
typedef Cat2 type;
|
||||
};
|
||||
|
||||
|
||||
template <typename Derived, typename F, typename It1, typename It2, typename Ref, typename Val>
|
||||
class transforming_pair_iterator_helper
|
||||
{
|
||||
typedef typename Min_category<
|
||||
typename std::iterator_traits<It1>::iterator_category,
|
||||
typename std::iterator_traits<It1>::iterator_category>
|
||||
::type iterator_category;
|
||||
|
||||
typedef typename Default::Get<Ref,
|
||||
#ifndef CGAL_CFG_NO_CPP0X_DECLTYPE
|
||||
decltype(std::declval<F>()(std::declval<typename std::iterator_traits<It1>::reference>(),std::declval<typename std::iterator_traits<It2>::reference>()))
|
||||
#else
|
||||
typename boost::result_of<F(typename std::iterator_traits<It1>::value_type,typename std::iterator_traits<It2>::value_type)>::type
|
||||
// should be reference instead of value_type
|
||||
#endif
|
||||
>::type reference;
|
||||
|
||||
typedef typename Default::Get<Val,typename boost::remove_cv<typename boost::remove_reference<reference>::type>::type>::type value_type;
|
||||
|
||||
public:
|
||||
typedef boost::iterator_facade<
|
||||
Derived,
|
||||
value_type,
|
||||
iterator_category,
|
||||
reference
|
||||
// expect ptrdiff_t is good enough for difference
|
||||
> type;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename F, typename It1, typename It2, typename Ref=Default, typename Val=Default>
|
||||
class transforming_pair_iterator
|
||||
: public internal::transforming_pair_iterator_helper<transforming_pair_iterator<F,It1,It2,Ref,Val>,F,It1,It2,Ref,Val>::type,
|
||||
private internal::Functor_as_base<F>
|
||||
{
|
||||
It1 iter1; It2 iter2;
|
||||
friend class boost::iterator_core_access;
|
||||
typedef typename internal::transforming_pair_iterator_helper<transforming_pair_iterator,F,It1,It2,Ref,Val>::type Base;
|
||||
typedef internal::Functor_as_base<F> Functor_base;
|
||||
typename Base::reference dereference()const{
|
||||
return functor()(*iter1,*iter2);
|
||||
}
|
||||
bool equal(transforming_pair_iterator const&i)const{
|
||||
bool b=(iter1==i.iter1);
|
||||
CGAL_assertion(b==(iter2==i.iter2));
|
||||
//FIXME: or do we want only one driving iterator
|
||||
return b;
|
||||
}
|
||||
void increment(){ ++iter1; ++iter2; }
|
||||
void decrement(){ --iter1; --iter2; }
|
||||
void advance(std::ptrdiff_t n){
|
||||
std::advance(iter1,n);
|
||||
std::advance(iter2,n);
|
||||
}
|
||||
std::ptrdiff_t distance_to(transforming_pair_iterator const&i)const{
|
||||
std::ptrdiff_t dist=std::distance(iter1,i.iter1);
|
||||
CGAL_assertion(dist==std::distance(iter2,i.iter2));
|
||||
return dist;
|
||||
}
|
||||
public:
|
||||
using Functor_base::functor;
|
||||
transforming_pair_iterator(){}
|
||||
explicit transforming_pair_iterator(It1 i1,It2 i2,F const& f=F())
|
||||
:Functor_base(f),iter1(i1),iter2(i2){}
|
||||
template<class F2,class J1,class J2,class R2,class V2>
|
||||
transforming_pair_iterator(
|
||||
transforming_pair_iterator<F2,J1,J2,R2,V2> const&i,
|
||||
typename boost::enable_if_convertible<J1, It1>::type* = 0,
|
||||
typename boost::enable_if_convertible<J2, It2>::type* = 0,
|
||||
typename boost::enable_if_convertible<F2, F>::type* = 0)
|
||||
: Functor_base(i.functor()),iter1(i.iter1),iter2(i.iter2) {}
|
||||
|
||||
};
|
||||
|
||||
template <typename F, typename It1, typename It2> inline
|
||||
transforming_pair_iterator<F,It1,It2> make_transforming_pair_iterator(It1 i1, It2 i2, F const&f=F()) {
|
||||
return transforming_pair_iterator<F,It1,It2>(i1,i2,f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // CGAL_TRANSFORMING_PAIR_ITERATOR_H
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
#ifndef CGAL_TYPESET_H
|
||||
#define CGAL_TYPESET_H
|
||||
#ifdef CGAL_CXX0X
|
||||
#include <type_traits>
|
||||
#else
|
||||
#include <boost/type_traits.hpp>
|
||||
#endif
|
||||
|
||||
// Sometimes using tuple just to list types is overkill (takes forever to
|
||||
// instantiate).
|
||||
|
||||
namespace CGAL {
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class...> struct typeset;
|
||||
template<class H,class...U> struct typeset<H,U...> {
|
||||
typedef H head;
|
||||
typedef typeset<U...> tail;
|
||||
typedef typeset type;
|
||||
template<class X> using contains = typename
|
||||
std::conditional<
|
||||
std::is_same<H,X>::value,
|
||||
std::true_type,
|
||||
typename tail::template contains<X>
|
||||
>::type;
|
||||
template<class X> using add = typename
|
||||
std::conditional<
|
||||
contains<X>::value,
|
||||
typeset<H,U...>,
|
||||
typeset<H,U...,X>
|
||||
>::type;
|
||||
};
|
||||
template<> struct typeset<> {
|
||||
typedef typeset type;
|
||||
template<class X> using contains = std::false_type;
|
||||
template<class X> using add = typeset<X>;
|
||||
};
|
||||
#else
|
||||
template<class,class> struct typeset;
|
||||
template<class H=void, class T=typename
|
||||
boost::mpl::if_<boost::is_same<H,void>, void, typeset<void, void> >::type >
|
||||
struct typeset {
|
||||
typedef typeset type;
|
||||
typedef H head;
|
||||
typedef T tail;
|
||||
template<class X> struct contains :
|
||||
boost::mpl::if_<boost::is_same<H,X>,boost::true_type,typename tail::template contains<X> >::type
|
||||
{};
|
||||
template<class X,class=void> struct add;
|
||||
//boost::mpl::if_<boost::is_same<H,X>,typeset,typeset<X,typeset> >::type
|
||||
};
|
||||
template<> struct typeset<> {
|
||||
typedef typeset type;
|
||||
template<class X> struct contains : boost::false_type {};
|
||||
template<class X> struct add : typeset<X> {};
|
||||
};
|
||||
|
||||
template<class H,class T>
|
||||
template<class X,class>
|
||||
struct typeset<H,T>::add : typeset<H,typename T::template add<X>::type> {};
|
||||
template<class H,class T>
|
||||
template<class V>
|
||||
struct typeset<H,T>::add<H,V> : typeset<H,T> {};
|
||||
#endif
|
||||
|
||||
template<class T1, class T2> struct typeset_union_ :
|
||||
typeset_union_<typename T1::template add<typename T2::head>::type, typename T2::tail>
|
||||
{};
|
||||
template<class T> struct typeset_union_ <T, typeset<> > : T {};
|
||||
|
||||
template<class T1, class T2>
|
||||
struct typeset_intersection_ {
|
||||
typedef typename T1::head H;
|
||||
typedef typename typeset_intersection_<typename T1::tail,T2>::type U;
|
||||
typedef typename
|
||||
#ifdef CGAL_CXX0X
|
||||
std::conditional<T2::template contains<H>::value,
|
||||
#else
|
||||
boost::mpl::if_<typename T2::template contains<H>,
|
||||
#endif
|
||||
typename U::template add<H>::type, U>::type type;
|
||||
};
|
||||
template<class T>
|
||||
struct typeset_intersection_<typeset<>,T> : typeset<> {};
|
||||
|
||||
#ifdef CGAL_CXX0X
|
||||
template<class T1, class T2>
|
||||
using typeset_union = typename typeset_union_<T1,T2>::type;
|
||||
template<class T1, class T2>
|
||||
using typeset_intersection = typename typeset_intersection_<T1,T2>::type;
|
||||
#else
|
||||
template<class T1, class T2>
|
||||
struct typeset_union : typeset_union_<T1,T2>::type {};
|
||||
template<class T1, class T2>
|
||||
struct typeset_intersection : typeset_intersection_<T1,T2>::type {};
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
@ -0,0 +1 @@
|
|||
d-dimensional Geometry Kernel
|
||||
|
|
@ -0,0 +1 @@
|
|||
Marc Glisse <marc.glisse@inria.fr>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
all: normal cxx0x
|
||||
|
||||
CGAL_INC = -I../../../Algebraic_foundations/include -I../../../STL_Extension/include -I../../../Number_types/include -I../../../Kernel_23/include -DCGAL_DISABLE_ROUNDING_MATH_CHECK
|
||||
|
||||
EIGEN_INC = `pkg-config --cflags eigen3|sed -e 's/-I/-isystem/g'` -DCGAL_EIGEN3_ENABLED
|
||||
|
||||
normal:
|
||||
g++ test.cpp -O2 -lCGAL -lboost_thread -frounding-math -Wall -Wextra -I. -lmpfr -lgmp -I../../include ${EIGEN_INC} ${CGAL_INC} -DCGAL_CFG_NO_CPP0X_COPY_N -DCGAL_CFG_NO_CPP0X_NEXT_PREV
|
||||
./a.out
|
||||
|
||||
cxx0x:
|
||||
g++ -std=c++0x -O2 test.cpp -lCGAL -lboost_thread -frounding-math -Wall -Wextra -I. -lmpfr -lgmp -DCGAL_CXX0X -I../../include ${EIGEN_INC} ${CGAL_INC} -o b.out
|
||||
./b.out
|
||||
|
||||
#-DBOOST_RESULT_OF_USE_DECLTYPE
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
//#define BOOST_RESULT_OF_USE_DECLTYPE 1
|
||||
#include <CGAL/Epick_d.h>
|
||||
#include <typeinfo>
|
||||
#include <CGAL/Kernel_d/Cartesian_base.h>
|
||||
#include <CGAL/Kernel_d/Cartesian_static_filters.h>
|
||||
#include <CGAL/Kernel_d/Cartesian_filter_NT.h>
|
||||
#include <CGAL/Kernel_d/Cartesian_filter_K.h>
|
||||
#include <CGAL/Kernel_d/Lazy_cartesian.h>
|
||||
#include <CGAL/Kernel_d/Wrapper/Cartesian_wrap.h>
|
||||
#include <CGAL/Kernel_d/Kernel_d_interface.h>
|
||||
#include <CGAL/Gmpq.h>
|
||||
#include <CGAL/Interval_nt.h>
|
||||
#include <iostream>
|
||||
|
||||
template<class>void marc_use(){}
|
||||
#define USE_TYPE(T) marc_use<T>()
|
||||
|
||||
//typedef CGAL::Cartesian_base_d<double,CGAL::Dimension_tag<2> > K0;
|
||||
//typedef CGAL::Cartesian_base_d<CGAL::Interval_nt_advanced,CGAL::Dimension_tag<2> > KA;
|
||||
struct KA : CGAL::Cartesian_static_filters<CGAL::Dimension_tag<2>, CGAL::Cartesian_base_d<CGAL::Interval_nt_advanced,CGAL::Dimension_tag<2>, KA>, KA> {};
|
||||
typedef CGAL::Cartesian_base_d<CGAL::Gmpq,CGAL::Dimension_tag<2> > KE;
|
||||
|
||||
struct RC: public
|
||||
CGAL::Cartesian_static_filters<CGAL::Dimension_tag<2>, // Yes, it is silly to put it there.
|
||||
CGAL::Cartesian_refcount<
|
||||
CGAL::Cartesian_LA_base_d<double,CGAL::Dimension_tag<2> >
|
||||
>, RC
|
||||
>
|
||||
{
|
||||
RC(){}
|
||||
RC(int){}
|
||||
};
|
||||
|
||||
struct K0 : RC {};
|
||||
|
||||
|
||||
#if 0
|
||||
typedef K0 K2;
|
||||
#elif 0
|
||||
typedef CGAL::Cartesian_filter_NT<K0> K2;
|
||||
#elif 0
|
||||
typedef CGAL::Cartesian_filter_K<K0,KA,KE> K2;
|
||||
#elif 1
|
||||
typedef CGAL::Lazy_cartesian<KE,KA,CGAL::KernelD_converter<KE,KA> > K2;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
typedef K2 KK;
|
||||
#elif 1
|
||||
typedef CGAL::Cartesian_wrap<K2> KK;
|
||||
#elif 1
|
||||
typedef CGAL::Cartesian_wrap<K2> K3;
|
||||
typedef CGAL::Cartesian_wrap<K3> KK;
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#define Kinit(f) =k.f()
|
||||
#else
|
||||
#define Kinit(f)
|
||||
#endif
|
||||
|
||||
template<class Ker>
|
||||
void test2(){
|
||||
typedef Ker K1;
|
||||
typedef typename K1::Point_d P;
|
||||
typedef typename K1::Cartesian_const_iterator_d CI;
|
||||
typedef typename K1::Vector_d V;
|
||||
typedef typename K1::Segment_d S;
|
||||
typedef typename K1::Flat_orientation_d FO;
|
||||
|
||||
//typedef K1::Construct_point CP;
|
||||
typedef typename K1::Construct_point_d CP;
|
||||
typedef typename K1::Construct_vector_d CV;
|
||||
typedef typename K1::Construct_segment_d CS;
|
||||
typedef typename CGAL::Get_functor<K1, CGAL::Segment_extremity_tag>::type CSE;
|
||||
typedef typename K1::Construct_cartesian_const_iterator_d CCI;
|
||||
typedef typename K1::Orientation_d PO;
|
||||
typedef typename K1::Side_of_oriented_sphere_d SOS;
|
||||
typedef typename K1::Compute_coordinate_d CC;
|
||||
typedef typename K1::Construct_flat_orientation_d CFO;
|
||||
typedef typename K1::In_flat_orientation_d IFO;
|
||||
typedef typename K1::In_flat_side_of_oriented_sphere_d IFSOS;
|
||||
typedef typename K1::Contained_in_affine_hull_d CAH;
|
||||
typedef typename K1::Compare_lexicographically_d CL;
|
||||
|
||||
USE_TYPE(V);
|
||||
USE_TYPE(CV);
|
||||
USE_TYPE(FO);
|
||||
USE_TYPE(CL);
|
||||
Ker k
|
||||
#if 0
|
||||
(2)
|
||||
#endif
|
||||
;
|
||||
CP cp Kinit(construct_point_d_object);
|
||||
CCI ci Kinit(construct_cartesian_const_iterator_d_object);
|
||||
CC cc Kinit(compute_coordinate_d_object);
|
||||
PO po Kinit(orientation_d_object);
|
||||
CS cs Kinit(construct_segment_d_object);
|
||||
CSE cse (k);
|
||||
SOS sos Kinit(side_of_oriented_sphere_d_object);
|
||||
CFO cfo Kinit(construct_flat_orientation_d_object);
|
||||
IFO ifo Kinit(in_flat_orientation_d_object);
|
||||
IFSOS ifsos Kinit(in_flat_side_of_oriented_sphere_d_object);
|
||||
CAH cah Kinit(contained_in_affine_hull_d_object);
|
||||
P a=cp(3,4);
|
||||
P b=cp(5,6,7);
|
||||
int rr[]={3,5,2};
|
||||
int* r=rr;
|
||||
P c=cp(r,r+2);
|
||||
P d=cp(r,r+3,CGAL::Homogeneous_tag());
|
||||
S s=cs(c,d);
|
||||
std::cout << cc(a,1) << std::endl;
|
||||
std::cout << cc(b,1) << std::endl;
|
||||
std::cout << cc(cse(s,0),1) << std::endl;
|
||||
std::cout << cc(cse(s,1),1) << std::endl;
|
||||
for(CI i=ci(a);i!=ci(a,0);++i)
|
||||
std::cout << *i << ' ';
|
||||
std::cout << '\n';
|
||||
P tab[]={a,b,c,d};
|
||||
std::cout << po (&tab[0],tab+3) << std::endl;
|
||||
std::cout << sos(&tab[0],tab+4) << std::endl;
|
||||
P x1=cp(0,1);
|
||||
P x2=cp(-1,-1);
|
||||
P x3=cp(1,-1);
|
||||
P x4=cp(0,0);
|
||||
P x5=cp(0,-1);
|
||||
P tab2[]={x1,x2,x3,x4};
|
||||
assert(po(tab2+0,tab2+3)==CGAL::COUNTERCLOCKWISE);
|
||||
assert(sos(tab2+0,tab2+3,x4)==CGAL::ON_POSITIVE_SIDE);
|
||||
#if 0
|
||||
// Doesn't compile with Lazy yet.
|
||||
FO fo=cfo(tab2+1,tab2+3);
|
||||
assert(ifo(fo,tab2+1,tab2+3)==CGAL::POSITIVE);
|
||||
assert(ifsos(fo,tab2+1,tab2+3,x5)==CGAL::ON_POSITIVE_SIDE);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<class CP> struct Construct_point3_helper {
|
||||
CP const& cp;
|
||||
Construct_point3_helper(CP const& x) : cp(x) {}
|
||||
template<class T1,class T2,class T3>
|
||||
typename CP::result_type operator()(T1 const&t1, T2 const&t2, T3 const&t3)const{
|
||||
double tab[]={(double)t1,(double)t2,(double)t3};
|
||||
return cp(tab+0,tab+3);
|
||||
}
|
||||
template<class T1,class T2,class T3,class T4>
|
||||
typename CP::result_type operator()(T1 const&t1, T2 const&t2, T3 const&t3, T4 const&t4)const{
|
||||
double tab[]={(double)t1,(double)t2,(double)t3};
|
||||
return cp(tab+0,tab+3,t4);
|
||||
}
|
||||
};
|
||||
|
||||
template<class Ker>
|
||||
void test3(){
|
||||
typedef Ker K1;
|
||||
typedef typename K1::Point_d P;
|
||||
typedef typename K1::Cartesian_const_iterator_d CI;
|
||||
typedef typename K1::Vector_d V;
|
||||
typedef typename K1::Segment_d S;
|
||||
typedef typename K1::Flat_orientation_d FO;
|
||||
|
||||
//typedef K1::Construct_point CP;
|
||||
typedef typename K1::Construct_point_d CP_;
|
||||
typedef typename K1::Construct_vector_d CV;
|
||||
typedef typename K1::Construct_segment_d CS;
|
||||
typedef typename CGAL::Get_functor<K1, CGAL::Segment_extremity_tag>::type CSE;
|
||||
typedef typename K1::Construct_cartesian_const_iterator_d CCI;
|
||||
typedef typename K1::Orientation_d PO;
|
||||
typedef typename K1::Side_of_oriented_sphere_d SOS;
|
||||
typedef typename K1::Compute_coordinate_d CC;
|
||||
typedef typename K1::Construct_flat_orientation_d CFO;
|
||||
typedef typename K1::In_flat_orientation_d IFO;
|
||||
typedef typename K1::In_flat_side_of_oriented_sphere_d IFSOS;
|
||||
typedef typename K1::Contained_in_affine_hull_d CAH;
|
||||
typedef typename K1::Compare_lexicographically_d CL;
|
||||
|
||||
USE_TYPE(V);
|
||||
USE_TYPE(CV);
|
||||
USE_TYPE(FO);
|
||||
Ker k
|
||||
#if 1
|
||||
(3)
|
||||
#endif
|
||||
;
|
||||
CP_ cp_ Kinit(construct_point_d_object);
|
||||
typename boost::conditional<boost::is_same<typename Ker::Default_ambient_dimension,CGAL::Dynamic_dimension_tag>::value,Construct_point3_helper<CP_>,CP_>::type cp(cp_);
|
||||
CCI ci Kinit(construct_cartesian_const_iterator_d_object);
|
||||
CC cc Kinit(compute_coordinate_d_object);
|
||||
CL cl Kinit(compare_lexicographically_d_object);
|
||||
PO po Kinit(orientation_d_object);
|
||||
CS cs Kinit(construct_segment_d_object);
|
||||
CSE cse (k);
|
||||
SOS sos Kinit(side_of_oriented_sphere_d_object);
|
||||
CFO cfo Kinit(construct_flat_orientation_d_object);
|
||||
IFO ifo Kinit(in_flat_orientation_d_object);
|
||||
IFSOS ifsos Kinit(in_flat_side_of_oriented_sphere_d_object);
|
||||
CAH cah Kinit(contained_in_affine_hull_d_object);
|
||||
P a=cp(2,3,4);
|
||||
P b=cp(5,6,7,8);
|
||||
int rr[]={3,5,2,3};
|
||||
int* r=rr;
|
||||
P c=cp_(3,r,r+3);
|
||||
P d=cp_(r,r+4,CGAL::Homogeneous_tag());
|
||||
S s=cs(c,d);
|
||||
std::cout << cc(a,1) << std::endl;
|
||||
std::cout << cc(b,2) << std::endl;
|
||||
std::cout << cc(cse(s,0),1) << std::endl;
|
||||
std::cout << cc(cse(s,1),2) << std::endl;
|
||||
for(CI i=ci(a);i!=ci(a,0);++i)
|
||||
std::cout << *i << ' ';
|
||||
std::cout << '\n';
|
||||
P e=cp(-2,3,0);
|
||||
P tab[]={a,b,c,d,e};
|
||||
std::cout << po (&tab[0],tab+4) << std::endl;
|
||||
std::cout << sos(&tab[0],tab+5) << std::endl;
|
||||
FO fo=cfo(&tab[0],tab+3);
|
||||
std::cout << fo;
|
||||
P x[]={cp(2,2,3),cp(2,2,0),cp(1,2,1)};
|
||||
FO fo2=cfo(&x[0],x+3);
|
||||
std::cout << fo2;
|
||||
P y[]={cp(0,2,4),cp(3,1,2),cp(3,3,6),cp(0,4,8)};
|
||||
FO fo3=cfo(&y[0],y+3);
|
||||
assert(fo3.rest.size()==1 && fo3.rest[0]!=3);
|
||||
std::cout << fo3;
|
||||
CGAL::Orientation base=ifo(fo3,&y[0],y+3);
|
||||
assert(ifo(fo3,y+1,y+4)==base);
|
||||
P yy[]={y[1],y[3],y[0],y[2]};
|
||||
assert(ifo(fo3,yy+0,yy+3)==base);
|
||||
assert(ifo(fo3,yy+1,yy+4)==base);
|
||||
std::cout << ifsos(fo3,y+0,y+3,y[3]) << ' ';
|
||||
std::cout << ifsos(fo3,y+1,y+4,y[0]) << ' ';
|
||||
std::cout << ifsos(fo3,yy+0,yy+3,yy[3]) << ' ';
|
||||
std::cout << ifsos(fo3,yy+1,yy+4,yy[0]) << '\n';
|
||||
P buf[]={cp(100,900,0),y[0],y[1],y[2],y[3]};
|
||||
std::cout << sos(buf+0,buf+5) << ' ';
|
||||
buf[1]=y[1];buf[2]=y[2];buf[3]=y[3];buf[4]=y[0];
|
||||
std::cout << sos(buf+0,buf+5) << ' ';
|
||||
buf[1]=yy[0];buf[2]=yy[1];buf[3]=yy[2];buf[4]=yy[3];
|
||||
std::cout << sos(buf+0,buf+5) << ' ';
|
||||
buf[1]=yy[1];buf[2]=yy[2];buf[3]=yy[3];buf[4]=yy[0];
|
||||
std::cout << sos(buf+0,buf+5) << '\n';
|
||||
assert(cah(y+0,y+3,y[3]));
|
||||
assert(!cah(y+0,y+3,buf[0]));
|
||||
assert(cl(a,a)==CGAL::EQUAL);
|
||||
assert(cl(a,b)==CGAL::LARGER);
|
||||
P x1=cp(0,1,-1);
|
||||
P x2=cp(-1,-1,-1);
|
||||
P x3=cp(1,-1,-1);
|
||||
P x4=cp(0,0,1);
|
||||
P x5=cp(0,0,0);
|
||||
P x6=cp(0,0,-1);
|
||||
P tab2[]={x1,x2,x3,x4,x5};
|
||||
assert(po(tab2+0,tab2+4)==CGAL::POSITIVE);
|
||||
assert(sos(tab2+0,tab2+4,x5)==CGAL::ON_POSITIVE_SIDE);
|
||||
FO fo4=cfo(tab2+0,tab2+3);
|
||||
assert(ifo(fo4,tab2+0,tab2+3)==CGAL::POSITIVE);
|
||||
assert(ifsos(fo4,tab2+0,tab2+3,x6)==CGAL::ON_POSITIVE_SIDE);
|
||||
}
|
||||
|
||||
int main(){
|
||||
test2<CGAL::Kernel_d_interface<KK> >();
|
||||
test2<CGAL::Epick_d<CGAL::Dimension_tag<2> > >();
|
||||
test3<CGAL::Epick_d<CGAL::Dimension_tag<3> > >();
|
||||
test3<CGAL::Epick_d<CGAL::Dynamic_dimension_tag> >();
|
||||
}
|
||||
|
|
@ -88,6 +88,50 @@ template <> class Real_embeddable_traits< unsigned long long >
|
|||
};
|
||||
};
|
||||
|
||||
#ifdef __SIZEOF_INT128__
|
||||
// __int128
|
||||
template<> class Algebraic_structure_traits< __int128 >
|
||||
: public Algebraic_structure_traits_base< __int128,
|
||||
Euclidean_ring_tag > {
|
||||
|
||||
public:
|
||||
typedef Tag_true Is_exact;
|
||||
typedef Tag_false Is_numerical_sensitive;
|
||||
|
||||
typedef INTERN_AST::Div_per_operator< Type > Div;
|
||||
typedef INTERN_AST::Mod_per_operator< Type > Mod;
|
||||
|
||||
};
|
||||
|
||||
template <> class Real_embeddable_traits< __int128 >
|
||||
: public INTERN_RET::Real_embeddable_traits_base< __int128 , CGAL::Tag_true > {
|
||||
public:
|
||||
|
||||
class To_interval
|
||||
: public std::unary_function< Type, std::pair< double, double > > {
|
||||
public:
|
||||
std::pair<double, double> operator()( const Type& x ) const {
|
||||
return (Interval_nt<>((double)x)+Interval_nt<>::smallest()).pair();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// unsigned __int128
|
||||
template <> class Real_embeddable_traits< unsigned __int128 >
|
||||
: public INTERN_RET::Real_embeddable_traits_base< unsigned __int128 , CGAL::Tag_true > {
|
||||
public:
|
||||
|
||||
class To_interval
|
||||
: public std::unary_function< Type, std::pair< double, double > > {
|
||||
public:
|
||||
std::pair<double, double> operator()( const Type& x ) const {
|
||||
return (Interval_nt<>((double)x)+Interval_nt<>::smallest()).pair();
|
||||
}
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#include <CGAL/Interval_nt.h>
|
||||
|
|
|
|||
|
|
@ -68,6 +68,13 @@ template <class T> struct is_iterator :
|
|||
template <class T,class Tag> struct is_iterator_type :
|
||||
internal::is_iterator_type_<typename boost::remove_cv<typename boost::remove_reference<T>::type>::type,Tag> {};
|
||||
|
||||
template <class T,class U,bool=is_iterator<T>::value> struct is_iterator_to {
|
||||
enum { value=false };
|
||||
};
|
||||
template <class T,class U> struct is_iterator_to<T,U,true> :
|
||||
boost::is_convertible<typename std::iterator_traits<T>::value_type,U>
|
||||
{ };
|
||||
|
||||
}
|
||||
|
||||
#endif // CGAL_IS_ITERATOR_H
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue