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:
Marc Glisse 2013-11-23 12:34:18 +01:00
commit 8ddf8255d5
102 changed files with 10957 additions and 27 deletions

View File

@ -23,9 +23,33 @@
#include <CGAL/basic.h> #include <CGAL/basic.h>
#include <CGAL/Kernel_traits.h> #include <CGAL/Kernel_traits.h>
#include <climits> #include <climits>
#include <limits>
#ifdef CGAL_EIGEN3_ENABLED
#include <Eigen/Core>
#endif
namespace CGAL { 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. // These tag classes help dispatching functions based on a geometric dimension.
template < int dim > template < int dim >
@ -34,7 +58,9 @@ struct Dimension_tag
static const int value = dim; static const int value = dim;
}; };
struct Dynamic_dimension_tag {}; struct Dynamic_dimension_tag {
static const int value = UNKNOWN_DIMENSION;
};
namespace internal { namespace internal {
@ -69,6 +95,39 @@ struct Feature_dimension
typedef typename K::template Feature_dimension<T>::type type; 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 } //namespace CGAL
#endif // CGAL_DIMENSION_H #endif // CGAL_DIMENSION_H

View File

@ -4,7 +4,7 @@ namespace CGAL {
/*! /*!
\ingroup PkgKernelDKernels \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 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>, 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` 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 field (such as the built-in type `double`), then the geometry provided by
the kernel is only an approximation of Euclidean geometry. the kernel is only an approximation of Euclidean geometry.
\cgalModels `Kernel_d` \cgalModels `KernelWithLifting_d`
\sa `CGAL::Homogeneous_d<RingNumberType>` \sa `CGAL::Homogeneous_d<RingNumberType>`

View File

@ -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 */

View File

@ -4,7 +4,7 @@ namespace CGAL {
/*! /*!
\ingroup PkgKernelDKernels \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 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>, 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` 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 ring (such as the built-in type `double`), then the geometry provided by
the kernel is only an approximation of Euclidean geometry. the kernel is only an approximation of Euclidean geometry.
\cgalModels `Kernel_d` \cgalModels `KernelWithLifting_d`
\sa `CGAL::Cartesian_d<FieldNumberType>` \sa `CGAL::Cartesian_d<FieldNumberType>`

View File

@ -5,7 +5,7 @@
*/ */
class Kernel_d::Lift_to_paraboloid_d { class KernelWithLifting_d::Lift_to_paraboloid_d {
public: public:
/// \name Operations /// \name Operations
@ -14,13 +14,13 @@ public:
/*! /*!
returns \f$ p = (x_0,\ldots,x_{d-1})\f$ lifted to the paraboloid of 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 < revolution which is the point \f$ (x_0, \ldots,x_{d-1},\sum_{0 \le i <
d}p_i^2)\f$ in \f$ (d+1)\f$-space. d}x_i^2)\f$ in \f$ (d+1)\f$-space.
*/ */
Kernel_d::Point_d operator()(const Kernel_d::Point_d& Kernel_d::Point_d operator()(const Kernel_d::Point_d&
p); p);
/// @} /// @}
}; /* end Kernel_d::Lift_to_paraboloid_d */ }; /* end KernelWithLifting_d::Lift_to_paraboloid_d */

View File

@ -5,7 +5,7 @@
*/ */
class Kernel_d::Project_along_d_axis_d { class KernelWithLifting_d::Project_along_d_axis_d {
public: public:
/// \name Operations /// \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 */

View File

@ -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 */

View File

@ -20,6 +20,7 @@ replacing operators, especially for equality testing.
\cgalHasModel `CGAL::Cartesian_d<FieldNumberType>` \cgalHasModel `CGAL::Cartesian_d<FieldNumberType>`
\cgalHasModel `CGAL::Homogeneous_d<RingNumberType>` \cgalHasModel `CGAL::Homogeneous_d<RingNumberType>`
\cgalHasModel `CGAL::Epick_d<DimensionTag>`
*/ */
class Kernel_d { class Kernel_d {
public: public:

View File

@ -67,7 +67,7 @@ unordered set of elements of the corresponding tuple.
This extends the syntax of random access iterators to input iterators. This extends the syntax of random access iterators to input iterators.
If we index the tuple as above then we require that 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 \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 syntax and semantics. The list of requirements defines an abstract
kernel concept. In \cgal such a kernel concept is often also called a kernel concept. In \cgal such a kernel concept is often also called a
<I>representation class</I> and denoted by `R`. A representation <I>representation class</I> and denoted by `R`. A representation
class provides the actual implementations of the kernel objects. For class provides the actual implementations of the kernel objects.
all kernel objects `Kernel_object`, the types For all kernel objects `Kernel_object` of a representation class `R` based
`CGAL::Kernel_object<R>` and `R::Kernel_object` are identical. 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 and one based on the homogeneous
representation of points. The interface of the kernel objects is representation of points. The interface of the kernel objects is
designed such that it works well with both 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 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 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 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 <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 `R::RT` is a type for which operations \f$ +\f$, \f$ -\f$, \f$ *\f$ are
defined with semantics (approximately) corresponding to those of a 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 `Homogeneous_d<RingNumberType,LinearAlgebra>::%LA` is mapped to the
type `LinearAlgebra`. 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 \subsection Kernel_dNamingconventions Naming conventions
The use of representation classes not only avoids problems, it also 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> <OL>
<LI>The <I>capitalized base name</I> of the geometric object, such as <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>Followed by `_d`.
<LI>A <I>representation class</I> as parameter, which itself is <LI>A <I>representation class</I>, which itself may be parameterized with a
parameterized with a number type, such as number type, such as `Cartesian_d<double>` or `Homogeneous_d<leda_integer>`,
`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> </OL>
\subsection Kernel_dKernelasaTraitsClass Kernel as a Traits Class \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 you even do not have to specify the kernel; it is detected
automatically using the types of the geometric objects passed to the automatically using the types of the geometric objects passed to the
algorithm. In some other cases, the algorithms or data structures 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. not be used as a traits class.
\subsection Kernel_dChoosingaKernel Choosing a Kernel \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 algorithms that, from time to time, crash or compute incorrect results
due to accumulated rounding errors. 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 \subsection Kernel_dInclusionofHeaderFiles Inclusion of Header Files
You need just to include a representation class to obtain the 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 This work was supported by ESPRIT IV Long Term Research Projects
No. 21957 (CGAL) and No. 28155 (GALIA). 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 */ } /* namespace CGAL */

View File

@ -47,7 +47,8 @@
## Kernels ## ## Kernels ##
- `CGAL::Cartesian_d<FieldNumberType>` - `CGAL::Cartesian_d<FieldNumberType>`
- `CGAL::Homogeneous<RingNumberType>` - `CGAL::Homogeneous_d<RingNumberType>`
- `CGAL::Epick_d<DimensionTag>`
## %Kernel Objects ## ## %Kernel Objects ##
- `CGAL::Point_d<Kernel>` - `CGAL::Point_d<Kernel>`

View File

@ -132,6 +132,12 @@ circumvented. With \ccc{Homogeneous_d<RingNumberType>},
\ccc{Homogeneous_d<RingNumberType,LinearAlgebra>::LA} is mapped to the \ccc{Homogeneous_d<RingNumberType,LinearAlgebra>::LA} is mapped to the
type \ccc{LinearAlgebra}. 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} \subsection{Naming conventions}
The use of representation classes not only avoids problems, it also The use of representation classes not only avoids problems, it also

View File

@ -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}

View File

@ -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}

View File

@ -1,4 +1,4 @@
\begin{ccRefClass}{Homogeneous<RingNumberType>} \begin{ccRefClass}{Homogeneous_d<RingNumberType>}
\ccInclude{CGAL/Homogeneous_d.h} \ccInclude{CGAL/Homogeneous_d.h}
\ccDefinition \ccDefinition
@ -16,6 +16,6 @@ the kernel is only an approximation of Euclidean geometry.
\ccRefConceptPage{Kernel_d} \ccRefConceptPage{Kernel_d}
\ccSeeAlso \ccSeeAlso
\ccRefIdfierPage{CGAL::Cartesian_d<FieldumberType>} \ccRefIdfierPage{CGAL::Cartesian_d<FieldNumberType>}
\end{ccRefClass} \end{ccRefClass}

View File

@ -170,6 +170,6 @@ corresponding functions are:
\ccHasModels \ccHasModels
\ccc{Cartesian_d<FieldNumberType>}, \ccc{Homogeneous_d<RingNumberType>} \ccc{Cartesian_d<FieldNumberType>}, \ccc{Homogeneous_d<RingNumberType>}, \ccc{Epick_d<dimension>}
\end{ccRefConcept} \end{ccRefConcept}

View File

@ -20,6 +20,7 @@
\input{Kernel_d_ref/Cartesian_d.tex} \input{Kernel_d_ref/Cartesian_d.tex}
\gdef\ccRefPageBreak{\ccTrue} \gdef\ccRefPageBreak{\ccTrue}
\input{Kernel_d_ref/Homogeneous_d.tex} \input{Kernel_d_ref/Homogeneous_d.tex}
\input{Kernel_d_ref/Epick_d.tex}
\clearpage \clearpage
\section{Kernel Objects} \section{Kernel Objects}
@ -36,6 +37,7 @@
\input{Kernel_d_ref/Sphere_d.tex} \input{Kernel_d_ref/Sphere_d.tex}
\input{Kernel_d_ref/Iso_box_d.tex} \input{Kernel_d_ref/Iso_box_d.tex}
\input{Kernel_d_ref/Aff_transformation_d.tex} \input{Kernel_d_ref/Aff_transformation_d.tex}
\input{Kernel_d_ref/Epick_d_Point_d.tex}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -0,0 +1,8 @@
\begin{ccPkgDescription}{dD Kernel}
\ccPkgSummary{
A new d-dimensional kernel.
}
\ccPkgIntroducedInCGAL{42.0}
\ccPkgLicense{\ccLicenseLGPL}
\end{ccPkgDescription}

View File

@ -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}

View File

@ -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
% +------------------------------------------------------------------------+

View File

@ -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}

View File

@ -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

View File

@ -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}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}
};
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
d-dimensional Geometry Kernel

View File

@ -0,0 +1 @@
Marc Glisse <marc.glisse@inria.fr>

View File

@ -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

View File

@ -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> >();
}

View File

@ -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 } //namespace CGAL
#include <CGAL/Interval_nt.h> #include <CGAL/Interval_nt.h>

View File

@ -68,6 +68,13 @@ template <class T> struct is_iterator :
template <class T,class Tag> struct is_iterator_type : 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> {}; 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 #endif // CGAL_IS_ITERATOR_H

Some files were not shown because too many files have changed in this diff Show More