diff --git a/Kernel_23/include/CGAL/Dimension.h b/Kernel_23/include/CGAL/Dimension.h index aab513f36ae..3070af031e3 100644 --- a/Kernel_23/include/CGAL/Dimension.h +++ b/Kernel_23/include/CGAL/Dimension.h @@ -23,9 +23,33 @@ #include #include #include +#include +#ifdef CGAL_EIGEN3_ENABLED +#include +#endif namespace CGAL { +#ifdef CGAL_EIGEN3_ENABLED +const int UNKNOWN_DIMENSION=Eigen::Dynamic; +#else +const int UNKNOWN_DIMENSION=std::numeric_limits::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 @@ -34,7 +58,9 @@ struct Dimension_tag static const int value = dim; }; -struct Dynamic_dimension_tag {}; +struct Dynamic_dimension_tag { + static const int value = UNKNOWN_DIMENSION; +}; namespace internal { @@ -69,6 +95,39 @@ struct Feature_dimension typedef typename K::template Feature_dimension::type type; }; +// Change the dimension +templatestruct Increment_dimension { + typedef Dynamic_dimension_tag type; +}; +templatestruct Increment_dimension,i> { + typedef Dimension_tag type; +}; + +templatestruct Product_dimension { + typedef Dynamic_dimension_tag type; +}; +templatestruct Product_dimension,Dimension_tag > { + typedef Dimension_tag type; +}; + +#ifdef CGAL_EIGEN3_ENABLED +// Convert to Eigen's notion of dimension +template struct Eigen_dimension { + enum { value=Eigen::Dynamic }; +}; +template struct Eigen_dimension > { + enum { value=d }; +}; + +// and convert back +template struct Dimension_eigen { + typedef Dimension_tag type; +}; +template <> struct Dimension_eigen { + typedef Dynamic_dimension_tag type; +}; +#endif + } //namespace CGAL #endif // CGAL_DIMENSION_H diff --git a/Kernel_d/doc/Kernel_d/CGAL/Cartesian_d.h b/Kernel_d/doc/Kernel_d/CGAL/Cartesian_d.h index a9136ed3072..dc5a473b70c 100644 --- a/Kernel_d/doc/Kernel_d/CGAL/Cartesian_d.h +++ b/Kernel_d/doc/Kernel_d/CGAL/Cartesian_d.h @@ -4,7 +4,7 @@ namespace CGAL { /*! \ingroup PkgKernelDKernels -A model for `Kernel_d` that uses %Cartesian coordinates to represent the +A model for `Kernel_d` (and even `KernelWithLifting_d`) that uses %Cartesian coordinates to represent the geometric objects. In order for `Cartesian_d` to model Euclidean geometry in \f$ E^d\f$ , for some mathematical field \f$ E\f$ (e.g., the rationals \f$\mathbb{Q}\f$ or the reals \f$\mathbb{R}\f$), the template parameter `FieldNumberType` @@ -14,7 +14,7 @@ type provided as a model for `FieldNumberType` is only an approximation of a field (such as the built-in type `double`), then the geometry provided by the kernel is only an approximation of Euclidean geometry. -\cgalModels `Kernel_d` +\cgalModels `KernelWithLifting_d` \sa `CGAL::Homogeneous_d` diff --git a/Kernel_d/doc/Kernel_d/CGAL/Epick_d.h b/Kernel_d/doc/Kernel_d/CGAL/Epick_d.h new file mode 100644 index 00000000000..57eb9284c8e --- /dev/null +++ b/Kernel_d/doc/Kernel_d/CGAL/Epick_d.h @@ -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` \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` +\sa `CGAL::Homogeneous_d` + +*/ +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 +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 */ diff --git a/Kernel_d/doc/Kernel_d/CGAL/Homogeneous_d.h b/Kernel_d/doc/Kernel_d/CGAL/Homogeneous_d.h index ef224f2df35..71d57228738 100644 --- a/Kernel_d/doc/Kernel_d/CGAL/Homogeneous_d.h +++ b/Kernel_d/doc/Kernel_d/CGAL/Homogeneous_d.h @@ -4,7 +4,7 @@ namespace CGAL { /*! \ingroup PkgKernelDKernels -A model for a `Kernel_d` using homogeneous coordinates to represent the +A model for a `Kernel_d` (and even `KernelWithLifting_d`) using homogeneous coordinates to represent the geometric objects. In order for `Homogeneous` to model Euclidean geometry in \f$ E^d\f$, for some mathematical ring \f$ E\f$ (e.g., the integers \f$\mathbb{Z}\f$ or the rationals \f$\mathbb{Q}\f$), the template parameter `RT` @@ -14,7 +14,7 @@ type provided as a model for `RingNumberType` is only an approximation of a ring (such as the built-in type `double`), then the geometry provided by the kernel is only an approximation of Euclidean geometry. -\cgalModels `Kernel_d` +\cgalModels `KernelWithLifting_d` \sa `CGAL::Cartesian_d` diff --git a/Kernel_d/doc/Kernel_d/Concepts/Kernel--Lift_to_paraboloid_d.h b/Kernel_d/doc/Kernel_d/Concepts/Kernel--Lift_to_paraboloid_d.h index b1402af0763..69e02b8d07c 100644 --- a/Kernel_d/doc/Kernel_d/Concepts/Kernel--Lift_to_paraboloid_d.h +++ b/Kernel_d/doc/Kernel_d/Concepts/Kernel--Lift_to_paraboloid_d.h @@ -5,7 +5,7 @@ */ -class Kernel_d::Lift_to_paraboloid_d { +class KernelWithLifting_d::Lift_to_paraboloid_d { public: /// \name Operations @@ -14,13 +14,13 @@ public: /*! returns \f$ p = (x_0,\ldots,x_{d-1})\f$ lifted to the paraboloid of -revolution which is the point \f$ (p_0, \ldots,p_{d-1},\sum_{0 \le i < -d}p_i^2)\f$ in \f$ (d+1)\f$-space. +revolution which is the point \f$ (x_0, \ldots,x_{d-1},\sum_{0 \le i < +d}x_i^2)\f$ in \f$ (d+1)\f$-space. */ Kernel_d::Point_d operator()(const Kernel_d::Point_d& p); /// @} -}; /* end Kernel_d::Lift_to_paraboloid_d */ +}; /* end KernelWithLifting_d::Lift_to_paraboloid_d */ diff --git a/Kernel_d/doc/Kernel_d/Concepts/Kernel--Project_along_d_axis_d.h b/Kernel_d/doc/Kernel_d/Concepts/Kernel--Project_along_d_axis_d.h index 09bfeada680..fee63ba10ea 100644 --- a/Kernel_d/doc/Kernel_d/Concepts/Kernel--Project_along_d_axis_d.h +++ b/Kernel_d/doc/Kernel_d/Concepts/Kernel--Project_along_d_axis_d.h @@ -5,7 +5,7 @@ */ -class Kernel_d::Project_along_d_axis_d { +class KernelWithLifting_d::Project_along_d_axis_d { public: /// \name Operations @@ -20,5 +20,5 @@ Kernel_d::Point_d operator()(const Kernel_d::Point_d& p); /// @} -}; /* end Kernel_d::Project_along_d_axis_d */ +}; /* end KernelWithLifting_d::Project_along_d_axis_d */ diff --git a/Kernel_d/doc/Kernel_d/Concepts/KernelWithLifting_d.h b/Kernel_d/doc/Kernel_d/Concepts/KernelWithLifting_d.h new file mode 100644 index 00000000000..65a6fe54a3f --- /dev/null +++ b/Kernel_d/doc/Kernel_d/Concepts/KernelWithLifting_d.h @@ -0,0 +1,50 @@ + +/*! +\ingroup PkgKernelDKernelConcept +\cgalConcept + +The concept of a kernel with lifting 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` +\cgalHasModel `CGAL::Homogeneous_d` +*/ +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 */ + diff --git a/Kernel_d/doc/Kernel_d/Concepts/Kernel_d.h b/Kernel_d/doc/Kernel_d/Concepts/Kernel_d.h index 9c2a9476348..2f793674081 100644 --- a/Kernel_d/doc/Kernel_d/Concepts/Kernel_d.h +++ b/Kernel_d/doc/Kernel_d/Concepts/Kernel_d.h @@ -20,6 +20,7 @@ replacing operators, especially for equality testing. \cgalHasModel `CGAL::Cartesian_d` \cgalHasModel `CGAL::Homogeneous_d` +\cgalHasModel `CGAL::Epick_d` */ class Kernel_d { public: diff --git a/Kernel_d/doc/Kernel_d/Kernel_d.txt b/Kernel_d/doc/Kernel_d/Kernel_d.txt index 2baf8840b35..a73c7dd85d0 100644 --- a/Kernel_d/doc/Kernel_d/Kernel_d.txt +++ b/Kernel_d/doc/Kernel_d/Kernel_d.txt @@ -67,7 +67,7 @@ unordered set of elements of the corresponding tuple. This extends the syntax of random access iterators to input iterators. If we index the tuple as above then we require that -\f$ ++^{(d+1)}\mathit{first} = \mathit{last}\f$. +\f$ ++^{(d)}\mathit{first} = \mathit{last}\f$. \section Kernel_dKernel Kernel Representations @@ -109,12 +109,14 @@ argument for this parameter must fulfill certain requirements on syntax and semantics. The list of requirements defines an abstract kernel concept. In \cgal such a kernel concept is often also called a representation class and denoted by `R`. A representation -class provides the actual implementations of the kernel objects. For -all kernel objects `Kernel_object`, the types -`CGAL::Kernel_object` and `R::Kernel_object` are identical. +class provides the actual implementations of the kernel objects. +For all kernel objects `Kernel_object` of a representation class `R` based +on `Cartesian_d` or `Homogeneous_d`, the types `CGAL::Kernel_object` and +`R::Kernel_object` are identical. -\cgal offers two families of concrete models for the concept -representation class, one based on the %Cartesian + +\cgal offers three families of concrete models for the concept +representation class, two based on the %Cartesian representation of points and one based on the homogeneous representation of points. The interface of the kernel objects is designed such that it works well with both @@ -140,7 +142,7 @@ strictly speaking, the built-in type `int` does not fulfill the requirements on a field type, since `int`s correspond to elements of a ring rather than a field, especially operation \f$ /\f$ is not the inverse of \f$ *\f$. The requirements on the type `R::RT` are -weaker. This type must fulfill the requirements on what is called an +weaker. This type must fulfill the requirements on what is called a Euclidean ring type in \cgal. This roughly means that `R::RT` is a type for which operations \f$ +\f$, \f$ -\f$, \f$ *\f$ are defined with semantics (approximately) corresponding to those of a @@ -205,10 +207,29 @@ circumvented. With `Homogeneous_d`, `Homogeneous_d::%LA` is mapped to the type `LinearAlgebra`. +\subsection Kernel_dEpickKernel Epick_d Kernel + +The kernel `Epick_d`, 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` 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::Point_d`, not `Point_d>`. + + \subsection Kernel_dNamingconventions Naming conventions The use of representation classes not only avoids problems, it also -makes all \cgal classes very uniform. They always consist of: +makes all \cgal classes very uniform. Like `Cartesian_d::Point_d`, +they always consist of:
  1. The capitalized base name of the geometric object, such as @@ -216,9 +237,10 @@ makes all \cgal classes very uniform. They always consist of:
  2. Followed by `_d`. -
  3. A representation class as parameter, which itself is -parameterized with a number type, such as -`Cartesian_d` or `Homogeneous_d`. +
  4. A representation class, which itself may be parameterized with a +number type, such as `Cartesian_d` or `Homogeneous_d`, +where the type can be found, \cgalModifBegin except for `Epick_d` where the +number type is implicitly `double`\cgalModifEnd .
\subsection Kernel_dKernelasaTraitsClass Kernel as a Traits Class @@ -231,7 +253,7 @@ library you can use a kernel as a traits class. For some algorithms you even do not have to specify the kernel; it is detected automatically using the types of the geometric objects passed to the algorithm. In some other cases, the algorithms or data structures -needs more than is provided by a kernel. In these cases, a kernel can +need more than is provided by a kernel. In these cases, a kernel can not be used as a traits class. \subsection Kernel_dChoosingaKernel Choosing a Kernel @@ -266,6 +288,11 @@ they need speed and can live with approximate results, or even algorithms that, from time to time, crash or compute incorrect results due to accumulated rounding errors. +The `Epick_d` kernel provides a compromise using `double` coordinates. It +evaluates predicates exactly, which is slower than plain `double` +computations, but still faster than using an exact number type thanks to +filtering techniques. Constructions are inexact, computed with `double`. + \subsection Kernel_dInclusionofHeaderFiles Inclusion of Header Files You need just to include a representation class to obtain the @@ -516,6 +543,10 @@ Stefan Schirra. This work was supported by ESPRIT IV Long Term Research Projects No. 21957 (CGAL) and No. 28155 (GALIA). +The Epick_d kernel was partially supported by the IST Programme of the EU +(FET Open) Project under Contract No IST-25582 – (CGL - Computational +Geometric Learning). + */ } /* namespace CGAL */ diff --git a/Kernel_d/doc/Kernel_d/PackageDescription.txt b/Kernel_d/doc/Kernel_d/PackageDescription.txt index 9ec3f820ce0..fac0bbea0cb 100644 --- a/Kernel_d/doc/Kernel_d/PackageDescription.txt +++ b/Kernel_d/doc/Kernel_d/PackageDescription.txt @@ -47,7 +47,8 @@ ## Kernels ## - `CGAL::Cartesian_d` -- `CGAL::Homogeneous` +- `CGAL::Homogeneous_d` +- `CGAL::Epick_d` ## %Kernel Objects ## - `CGAL::Point_d` diff --git a/Kernel_d/doc_tex/Kernel_d/kernel_representation_d.tex b/Kernel_d/doc_tex/Kernel_d/kernel_representation_d.tex index bd0daf32851..f1aec33956e 100644 --- a/Kernel_d/doc_tex/Kernel_d/kernel_representation_d.tex +++ b/Kernel_d/doc_tex/Kernel_d/kernel_representation_d.tex @@ -132,6 +132,12 @@ circumvented. With \ccc{Homogeneous_d}, \ccc{Homogeneous_d::LA} is mapped to the type \ccc{LinearAlgebra}. +\subsection{Epick Kernel} + +The kernel \ccc{Epick_d}, 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::Point_d}, {\bf not} \ccc{Point_d>}. + \subsection{Naming conventions} The use of representation classes not only avoids problems, it also diff --git a/Kernel_d/doc_tex/Kernel_d_ref/Epick_d.tex b/Kernel_d/doc_tex/Kernel_d_ref/Epick_d.tex new file mode 100644 index 00000000000..a4c6a600aea --- /dev/null +++ b/Kernel_d/doc_tex/Kernel_d_ref/Epick_d.tex @@ -0,0 +1,36 @@ +\begin{ccRefClass}{Epick_d} + +\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::Point_d} + +\ccRefIdfierPage{CGAL::Cartesian_d} + +\ccRefIdfierPage{CGAL::Homogeneous_d} + + +\end{ccRefClass} diff --git a/Kernel_d/doc_tex/Kernel_d_ref/Epick_d_Point_d.tex b/Kernel_d/doc_tex/Kernel_d_ref/Epick_d_Point_d.tex new file mode 100644 index 00000000000..b246ac76f42 --- /dev/null +++ b/Kernel_d/doc_tex/Kernel_d_ref/Epick_d_Point_d.tex @@ -0,0 +1,18 @@ +\begin{ccRefClass} {Epick_d::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} diff --git a/Kernel_d/doc_tex/Kernel_d_ref/Homogeneous_d.tex b/Kernel_d/doc_tex/Kernel_d_ref/Homogeneous_d.tex index a1bf9bb9ce3..fd43aa8eade 100644 --- a/Kernel_d/doc_tex/Kernel_d_ref/Homogeneous_d.tex +++ b/Kernel_d/doc_tex/Kernel_d_ref/Homogeneous_d.tex @@ -1,4 +1,4 @@ -\begin{ccRefClass}{Homogeneous} +\begin{ccRefClass}{Homogeneous_d} \ccInclude{CGAL/Homogeneous_d.h} \ccDefinition @@ -16,6 +16,6 @@ the kernel is only an approximation of Euclidean geometry. \ccRefConceptPage{Kernel_d} \ccSeeAlso -\ccRefIdfierPage{CGAL::Cartesian_d} +\ccRefIdfierPage{CGAL::Cartesian_d} \end{ccRefClass} diff --git a/Kernel_d/doc_tex/Kernel_d_ref/Kernel.tex b/Kernel_d/doc_tex/Kernel_d_ref/Kernel.tex index b2274b7871a..fe4765f1cb7 100644 --- a/Kernel_d/doc_tex/Kernel_d_ref/Kernel.tex +++ b/Kernel_d/doc_tex/Kernel_d_ref/Kernel.tex @@ -170,6 +170,6 @@ corresponding functions are: \ccHasModels -\ccc{Cartesian_d}, \ccc{Homogeneous_d} +\ccc{Cartesian_d}, \ccc{Homogeneous_d}, \ccc{Epick_d} \end{ccRefConcept} diff --git a/Kernel_d/doc_tex/Kernel_d_ref/main.tex b/Kernel_d/doc_tex/Kernel_d_ref/main.tex index 9ad0cc9a3d7..182519caf6b 100644 --- a/Kernel_d/doc_tex/Kernel_d_ref/main.tex +++ b/Kernel_d/doc_tex/Kernel_d_ref/main.tex @@ -20,6 +20,7 @@ \input{Kernel_d_ref/Cartesian_d.tex} \gdef\ccRefPageBreak{\ccTrue} \input{Kernel_d_ref/Homogeneous_d.tex} +\input{Kernel_d_ref/Epick_d.tex} \clearpage \section{Kernel Objects} @@ -36,6 +37,7 @@ \input{Kernel_d_ref/Sphere_d.tex} \input{Kernel_d_ref/Iso_box_d.tex} \input{Kernel_d_ref/Aff_transformation_d.tex} +\input{Kernel_d_ref/Epick_d_Point_d.tex} diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/Cartesian_complete.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/Cartesian_complete.tex new file mode 100644 index 00000000000..02fa294a347 --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/Cartesian_complete.tex @@ -0,0 +1,25 @@ +\begin{ccRefClass}{Cartesian_complete} +\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} diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/Cartesian_filter_K.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/Cartesian_filter_K.tex new file mode 100644 index 00000000000..28c1fdc9d16 --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/Cartesian_filter_K.tex @@ -0,0 +1,25 @@ +\begin{ccRefClass}{Cartesian_filter_K} +\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::Is_exact::value} is true, don't filter. + \item \ccc{Functor::type} is taken from Base. +\end{itemize} + +\ccImplementation +The implementation uses \ccc{CGAL::Filtered_predicate} and +\ccc{CGAL::KernelD_converter}. + +\end{ccRefClass} diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/Cartesian_mini_d.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/Cartesian_mini_d.tex new file mode 100644 index 00000000000..806109d70c8 --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/Cartesian_mini_d.tex @@ -0,0 +1,16 @@ +\begin{ccRefClass}{Cartesian_mini_d} +\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} diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/Cartesian_wrap.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/Cartesian_wrap.tex new file mode 100644 index 00000000000..6d8644789af --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/Cartesian_wrap.tex @@ -0,0 +1,27 @@ +\begin{ccRefClass}{Cartesian_wrap} +\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>::type}, +\ccc{Point::operator[]} forwards to +\ccc{Functor::type}, +\ccc{operator+(Vector,Vector)} forwards to +\ccc{Functor::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} diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/Define_segment.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/Define_segment.tex new file mode 100644 index 00000000000..107671ddc2a --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/Define_segment.tex @@ -0,0 +1,18 @@ +\begin{ccRefClass}{Define_segment} +\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} diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/KernelD_converter.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/KernelD_converter.tex new file mode 100644 index 00000000000..bceafc65cab --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/KernelD_converter.tex @@ -0,0 +1,14 @@ +\begin{ccRefFunctionObjectClass}{KernelD_converter} +\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::type} for \ccc{K1::Type::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} diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/Kernel_2_interface.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/Kernel_2_interface.tex new file mode 100644 index 00000000000..f04d1ffd1f0 --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/Kernel_2_interface.tex @@ -0,0 +1,16 @@ +\begin{ccRefClass}{Kernel_2_interface} +\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::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} diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/Kernel_3_interface.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/Kernel_3_interface.tex new file mode 100644 index 00000000000..99ccf619b17 --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/Kernel_3_interface.tex @@ -0,0 +1,16 @@ +\begin{ccRefClass}{Kernel_3_interface} +\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::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} diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/Kernel_d_interface.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/Kernel_d_interface.tex new file mode 100644 index 00000000000..a75b6045e3e --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/Kernel_d_interface.tex @@ -0,0 +1,19 @@ +\begin{ccRefClass}{Kernel_d_interface} +\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::type Point_d}\\ +\ccc{typedef Functor::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} diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/Kernel_functor.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/Kernel_functor.tex new file mode 100644 index 00000000000..ad84ab0d69e --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/Kernel_functor.tex @@ -0,0 +1,19 @@ +\begin{ccRefConcept}[Kernel::]{Functor} +Functors have a constructor that takes a \ccc{Kernel} as argument. If the kernel is stateless (as tested with \ccc{boost::is_empty}), 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}. It contains member functions \ccc{Kernel::Type::type operator()(Args...) const}. + \item A converter is a functor represented by a tag \ccc{Convert_ttag}. It contains a member function \ccc{template K2::Type::type operator()(K2 const&, Converter, Kernel::Type::type) const}. As an example, a segment converter could first extract its extremities with \ccc{Kernel::Functor}, then convert them to \ccc{K2::Type} using \ccc{Converter} and finally build a \ccc{K2::Type} with \ccc{K2::Functor}. + %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::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::type>::type} where \ccc{map_result_tag} is specialized to specify the tag of the result. All others are miscellaneous. + + +\end{ccRefConcept} + diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/Lazy_kernel.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/Lazy_kernel.tex new file mode 100644 index 00000000000..4b6f7c0ad64 --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/Lazy_kernel.tex @@ -0,0 +1,17 @@ +\begin{ccRefClass}{Lazy_kernel>} +\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} diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/PkgDescription.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/PkgDescription.tex new file mode 100644 index 00000000000..369d0eff79f --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/PkgDescription.tex @@ -0,0 +1,8 @@ +\begin{ccPkgDescription}{dD Kernel} +\ccPkgSummary{ +A new d-dimensional kernel. +} +\ccPkgIntroducedInCGAL{42.0} +\ccPkgLicense{\ccLicenseLGPL} +\end{ccPkgDescription} + diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/Point.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/Point.tex new file mode 100644 index 00000000000..d405de6c2c7 --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/Point.tex @@ -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::type}{shall be CopyConstructible.} +\ccNestedType{Type::type}{shall be a forward iterator (except that it may return an rvalue) whose \ccc{value_type} is \ccc{Kernel::Type::type}.} + +\ccNestedType{Functor>::type}{[Optional] A default converter it available to \ccc{Kernel_converter}, but may be unsuitable if your Point type is too original.} +\ccNestedType{Functor>::type}{shall provide \ccc{Type::type operator()(Type::type const&, Extremity_tag)const} where \ccc{Extemity_tag} is \ccc{Begin_tag} or \ccc{End_tag}.} +\ccNestedType{Functor::type}{shall provide \ccc{FT operator()(Type::type,int k)const} which returns the $k$th Cartesian coordinate of the point.} +\ccNestedType{Functor::type}{shall provide \ccc{int operator()(Type::type)const} which returns the dimension of a point.} +\ccNestedType{Functor>::type}{shall provide:\\ + \ccc{Type::type operator()(int dim)const} which constructs a point at the origin;\\ + \ccc{Type::type operator()()const} the same, when \ccc{Default_ambient_dimension} is known;\\ + \ccc{Type::type operator()(Type::type)const} which copies (???);\\ + \ccc{Type::type operator()(Iter, Iter, Cartesian_tag)const} which reads the Cartesian coordinates from the iterators;\\ + \ccc{Type::type operator()(Iter, Iter)const} same as above;\\ + \ccc{Type::type operator()(FT...)const} which reads the Cartesian coordinates from the arguments, when \ccc{Default_ambient_dimension} is known. +} + +\end{ccRefConcept} + diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/PreKernel.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/PreKernel.tex new file mode 100644 index 00000000000..3370fdc5fc4 --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/PreKernel.tex @@ -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}, and the conversion functor by +\ccc{Convert_ttag}. + +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} 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} 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} or similar. + +\ccNestedType{Boolean}{\ccc{bool} or \ccc{Uncertain}} +\ccGlue +\ccNestedType{Sign}{\ccc{CGAL::Sign} or \ccc{Uncertain}} +\ccGlue +\ccNestedType{Comparison_result}{\ccc{CGAL::Comparison_result} or \ccc{Uncertain}} +\ccGlue +\ccNestedType{Orientation}{\ccc{CGAL::Orientation} or \ccc{Uncertain}} +\ccGlue +\ccNestedType{Oriented_side}{\ccc{CGAL::Oriented_side} or \ccc{Uncertain}} +\ccGlue +\ccNestedType{Bounded_side}{\ccc{CGAL::Bounded_side} or \ccc{Uncertain}} +\ccGlue +\ccNestedType{Angle}{\ccc{CGAL::Angle} or \ccc{Uncertain}} + +\ccHeading{Geometric Objects} + +%\ccNestedType{template struct Type}{This nested template class defines an object type \ccc{type}. For instance, \ccc{Type::type} is the type of points.} +\ccNestedType{Point, \ldots}{Geometric object type} + +\ccNestedType{Object_list}{A typedef for \ccc{typeset} +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} with the list of +tags corresponding to the provided iterators.} + + +\ccHeading{Function objects} + +\ccNestedType{template struct Functor}{This nested template class defines a functor type \ccc{type}. For instance, \ccc{Functor::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 +% +------------------------------------------------------------------------+ diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/Segment.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/Segment.tex new file mode 100644 index 00000000000..e6b6230582f --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/Segment.tex @@ -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::type}{shall be CopyConstructible.} + +\ccNestedType{Functor>::type}{[Optional] A default converter it available to \ccc{Kernel_converter}, but may be unsuitable if your Segment type is too original.} +\ccNestedType{Functor::type}{shall +provide \ccc{Type::type operator()(Type::type, +int k)const} which returns the $k$th ($0$ or $1$) extremity of the segment.} +\ccNestedType{Functor>::type}{shall provide:\\ + \ccc{Type::type + operator()(Type::type,Type::type)const} which + constructs a segment from its extremities;\\ + \ccc{Type::type operator()(piecewise_construct_t, + tuple u, tuple v)const} which calls + \ccc{Functor>::type} on the content of each + tuple to create the extremities. +} + +\end{ccRefConcept} + diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/main.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/main.tex new file mode 100644 index 00000000000..8366d2fa080 --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/main.tex @@ -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 diff --git a/NewKernel_d/doc_tex/NewKernel_d_ref/typeset.tex b/NewKernel_d/doc_tex/NewKernel_d_ref/typeset.tex new file mode 100644 index 00000000000..5c07a3591de --- /dev/null +++ b/NewKernel_d/doc_tex/NewKernel_d_ref/typeset.tex @@ -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::type}{A typeset with \ccc{X} added to the list.} +\ccNestedType{contains::value}{A boolean that says whether \ccc{X} is in the list.} + +In C++11, \ccc{add} is already a typeset so one can omit \ccc{::type}, and \ccc{contains} derives from \ccc{true_type} or \ccc{false_type}. + +\ccImplementation +In C++11, the list looks like \ccc{typeset} whereas in C++03 it looks like \ccc{typeset > > >} (an alternative would have been \ccc{typeset}, as in \ccc{boost::tuple}). + +\end{ccRefClass} diff --git a/NewKernel_d/include/CGAL/Epick_d.h b/NewKernel_d/include/CGAL/Epick_d.h new file mode 100644 index 00000000000..38b20bafc1a --- /dev/null +++ b/NewKernel_d/include/CGAL/Epick_d.h @@ -0,0 +1,51 @@ +#ifndef CGAL_EPICK_D_H +#define CGAL_EPICK_D_H +#include +#include +#include +#include +#include +#include +#include + + +namespace CGAL { +#define CGAL_BASE \ + Cartesian_filter_K< \ + Cartesian_base_d, \ + Cartesian_base_d, \ + Cartesian_base_d \ + > +template +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,Epick_d_help2 > +template +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, \ + Epick_d > > +template +struct Epick_d +: CGAL_BASE +{ + CGAL_CONSTEXPR Epick_d(){} + CGAL_CONSTEXPR Epick_d(int d):CGAL_BASE(d){} +}; +#undef CGAL_BASE +} +#endif diff --git a/NewKernel_d/include/CGAL/Filtered_predicate2.h b/NewKernel_d/include/CGAL/Filtered_predicate2.h new file mode 100644 index 00000000000..06e13ca42f1 --- /dev/null +++ b/NewKernel_d/include/CGAL/Filtered_predicate2.h @@ -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 +#include +#include +#include +#include +#include +#include + +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 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 + 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 + 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 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 p(CGAL_FE_TONEAREST); + return ep(c2e(std::forward(args))...); + } +#else + +#define VAR(Z,N,C) C(a##N) +#define CODE(Z,N,_) \ + template \ + 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 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 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 diff --git a/NewKernel_d/include/CGAL/Handle_for.h b/NewKernel_d/include/CGAL/Handle_for.h new file mode 100644 index 00000000000..63a3fc39683 --- /dev/null +++ b/NewKernel_d/include/CGAL/Handle_for.h @@ -0,0 +1,323 @@ +// Copyright (c) 1999,2001,2003 Utrecht University (The Netherlands), +// ETH Zurich (Switzerland), Freie Universitaet Berlin (Germany), +// INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg +// (Germany), Max-Planck-Institute Saarbruecken (Germany), RISC Linz (Austria), +// and Tel-Aviv University (Israel). All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Stefan Schirra, Sylvain Pion + +#ifndef CGAL_HANDLE_FOR_H +#define CGAL_HANDLE_FOR_H + +#include +#include +#include +#include +#include +#include + +#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 Handle_for +{ + // Wrapper that adds the reference counter. + struct RefCounted { + T t; + unsigned int count; + }; + + typedef typename Alloc::template rebind::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), std::forward(t2), std::forward(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)(std::forward(args)...)); + ptr_->count = 1; + } +#else +#define CODE(Z,N,_) template \ + 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 \ + 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 + 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(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 +typename Handle_for::Allocator +Handle_for::allocator; + +template +inline +void +swap(Handle_for &h1, Handle_for &h2) +{ + h1.swap(h2); +} + +template +inline +bool +identical(const Handle_for &h1, + const Handle_for &h2) +{ + return h1.identical(h2); +} + +template inline bool identical(const T &t1, const T &t2) { return &t1 == &t2; } + +template +inline +const T& +get(const Handle_for &h) +{ + return *(h.Ptr()); +} + +template +inline +const T& +get(const T &t) +{ + return t; +} + +} //namespace CGAL + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // CGAL_HANDLE_FOR_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/Cartesian_LA_base.h b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_LA_base.h new file mode 100644 index 00000000000..73ea8612bd9 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_LA_base.h @@ -0,0 +1,135 @@ +#ifndef CGAL_KERNEL_D_CARTESIAN_LA_BASE_H +#define CGAL_KERNEL_D_CARTESIAN_LA_BASE_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#ifdef CGAL_EIGEN3_ENABLED +#include +#else +#include +#endif + +namespace CGAL { + +template < typename FT_, typename Dim_, +#if 0 + typename Vec_=Array_vector, +#else + typename Vec_=LA_eigen, +#endif + typename LA_=LA_eigen > + /* Default LA to Vec or to LA_eigen? */ +struct Cartesian_LA_base_d : public Dimension_base +{ + typedef Cartesian_LA_base_d 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 struct Type {}; + template struct Type< Point_tag, D> { typedef Vector_ type; }; + template struct Type { typedef Vector_ type; }; + template struct Type< FT_tag, D> { typedef FT_ type; }; + template struct Type< RT_tag, D> { typedef FT_ type; }; + + typedef typeset + ::add::type + // FIXME: Segment has nothing to do here. + ::add::type + Object_list; + + typedef typeset< Point_cartesian_const_iterator_tag>::type + ::add::type + Iterator_list; + + template struct Functor { + typedef Null_functor type; + }; + template struct Functor,D> { + typedef CartesianDVectorBase::Construct_LA_vector type; + }; + template struct Functor,D> { + typedef CartesianDVectorBase::Construct_LA_vector type; + }; + template struct Functor,D> { + typedef CartesianDVectorBase::Construct_cartesian_const_iterator type; + }; + template struct Functor,D> { + typedef CartesianDVectorBase::Construct_cartesian_const_iterator type; + }; + template struct Functor::value> { + typedef CartesianDVectorBase::Sum_of_vectors type; + }; + template struct Functor::value> { + typedef CartesianDVectorBase::Difference_of_vectors type; + }; + template struct Functor::value> { + typedef CartesianDVectorBase::Opposite_vector type; + }; + template struct Functor::value && + LA_vector::template Property::value> { + typedef CartesianDVectorBase::Midpoint type; + }; + template struct Functor { + typedef CartesianDVectorBase::Compute_cartesian_coordinate type; + }; + template struct Functor { + typedef CartesianDVectorBase::Compute_cartesian_coordinate type; + }; + template struct Functor { + typedef CartesianDVectorBase::PV_dimension type; + }; + template struct Functor { + typedef CartesianDVectorBase::PV_dimension type; + }; + template struct Functor::value> { + typedef CartesianDVectorBase::Orientation_of_vectors type; + }; + template struct Functor::value> { + typedef CartesianDVectorBase::Orientation_of_points type; + }; + template struct Functor::value> { + typedef CartesianDVectorBase::Scalar_product type; + }; + template struct Functor::value> { + typedef CartesianDVectorBase::Squared_distance_to_origin_stored type; + }; + template struct Functor::value && + LA_vector::template Property::value> { + typedef CartesianDVectorBase::Squared_distance_to_origin_via_dotprod type; + }; + + CGAL_CONSTEXPR Cartesian_LA_base_d(){} + CGAL_CONSTEXPR Cartesian_LA_base_d(int d):Dimension_base(d){} +}; + +} //namespace CGAL + +#endif // CGAL_KERNEL_D_CARTESIAN_LA_BASE_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/Cartesian_LA_functors.h b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_LA_functors.h new file mode 100644 index 00000000000..01756c203f4 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_LA_functors.h @@ -0,0 +1,313 @@ +#ifndef CGAL_CARTESIAN_LA_FUNCTORS_H +#define CGAL_CARTESIAN_LA_FUNCTORS_H + +#include +#include +#include +#include +#include +#include + +namespace CGAL { +namespace CartesianDVectorBase { +#ifndef CGAL_CXX0X +namespace internal { +template struct Construct_LA_vector_ { + struct Never_use {}; + void operator()(Never_use)const; +}; +#define CODE(Z,N,_) template struct Construct_LA_vector_ { \ + typedef typename R::Constructor Constructor; \ + typedef typename Get_type::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 struct Construct_LA_vector +: private Store_kernel +#ifndef CGAL_CXX0X +, public internal::Construct_LA_vector_ +#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::type RT; + typedef typename Get_type::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 + typename std::enable_if::value && + (sizeof...(U)==static_dim), result_type>::type + operator()(U&&...u)const{ + return typename Constructor::Values()(std::forward(u)...); + } + //template::value>::type,class=typename std::enable_if<(sizeof...(U)==static_dim+1)>::type,class=void> + template + typename std::enable_if::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)...); + } +#else + using internal::Construct_LA_vector_::operator(); +#endif + template inline + typename boost::enable_if,result_type>::type operator() + (Iter f,Iter g,Cartesian_tag t)const + { + return this->operator()(std::distance(f,g),f,g,t); + } + template inline + typename boost::enable_if,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 inline + typename boost::enable_if,result_type>::type operator() + (Iter f,Iter g,Homogeneous_tag)const + { + --g; + return this->operator()(std::distance(f,g),f,g,*g); + } + template inline + typename boost::enable_if,result_type>::type operator() + (int d,Iter f,Iter g,Homogeneous_tag)const + { + --g; + return this->operator()(d,f,g,*g); + } + template inline + typename boost::enable_if,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 inline + typename boost::enable_if,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 inline + typename boost::enable_if,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(l)),CGAL::make_transforming_iterator(g,Divide(l))); + } + template inline + typename boost::enable_if,result_type>::type operator() + (Iter f,Iter g,NT const&l)const + { + return this->operator()(std::distance(f,g),f,g,l); + } +}; + +template struct Compute_cartesian_coordinate { + CGAL_FUNCTOR_INIT_IGNORE(Compute_cartesian_coordinate) + typedef R_ R; + typedef typename Get_type::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()[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 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 struct Midpoint { + CGAL_FUNCTOR_INIT_IGNORE(Midpoint) + typedef R_ R; + typedef typename Get_type::type first_argument_type; + typedef typename Get_type::type second_argument_type; + typedef typename Get_type::type result_type; + + result_type operator()(result_type const& a, result_type const& b)const{ + return (a+b)/2; + } +}; + +template struct Sum_of_vectors { + CGAL_FUNCTOR_INIT_IGNORE(Sum_of_vectors) + typedef R_ R; + typedef typename Get_type::type first_argument_type; + typedef typename Get_type::type second_argument_type; + typedef typename Get_type::type result_type; + + result_type operator()(result_type const& a, result_type const& b)const{ + return a+b; + } +}; + +template struct Difference_of_vectors { + CGAL_FUNCTOR_INIT_IGNORE(Difference_of_vectors) + typedef R_ R; + typedef typename Get_type::type first_argument_type; + typedef typename Get_type::type second_argument_type; + typedef typename Get_type::type result_type; + + result_type operator()(result_type const& a, result_type const& b)const{ + return a-b; + } +}; + +template struct Opposite_vector { + CGAL_FUNCTOR_INIT_IGNORE(Opposite_vector) + typedef R_ R; + typedef typename Get_type::type result_type; + typedef typename Get_type::type argument_type; + + result_type operator()(result_type const& v)const{ + return -v; + } +}; + +template struct Scalar_product { + CGAL_FUNCTOR_INIT_IGNORE(Scalar_product) + typedef R_ R; + typedef typename R::LA_vector LA; + typedef typename Get_type::type result_type; + typedef typename Get_type::type first_argument_type; + typedef typename Get_type::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 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::type result_type; + typedef typename Get_type::type argument_type; + + result_type operator()(argument_type const& a)const{ + return LA::squared_norm(a); + } +}; + +template 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::type result_type; + typedef typename Get_type::type argument_type; + + result_type operator()(argument_type const& a)const{ + return LA::dot_product(a,a); + } +}; + +template 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::type result_type; + typedef typename R::LA_vector LA; + + template + result_type operator()(Iter const& f, Iter const& e) const { + return LA::determinant_of_iterators_to_vectors(f,e); + } +}; + +template 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::type result_type; + typedef typename R::LA_vector LA; + + template + result_type operator()(Iter const& f, Iter const& e) const { + return LA::determinant_of_iterators_to_points(f,e); + } +}; + +template 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 + result_type operator()(T const& v) const { + return LA::size_of_vector(v); + } +}; + + +} +} // namespace CGAL +#endif // CGAL_CARTESIAN_LA_FUNCTORS_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/Cartesian_base.h b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_base.h new file mode 100644 index 00000000000..f5ef884ac76 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_base.h @@ -0,0 +1,21 @@ +#ifndef CGAL_KERNEL_D_CARTESIAN_BASE_H +#define CGAL_KERNEL_D_CARTESIAN_BASE_H + +#include +#include +#include + +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 diff --git a/NewKernel_d/include/CGAL/Kernel_d/Cartesian_change_FT.h b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_change_FT.h new file mode 100644 index 00000000000..ba2d44dc904 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_change_FT.h @@ -0,0 +1,98 @@ +#ifndef CGAL_KERNEL_D_CARTESIAN_CHANGE_FT_H +#define CGAL_KERNEL_D_CARTESIAN_CHANGE_FT_H + +#include +#include +#include +#include + +namespace CGAL { + +template < typename Base_, typename FT_, typename LA_=CGAL::LA_eigen > +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 struct Type : Inherit_type {}; + template struct Type { typedef FT_ type; }; + template struct Type { typedef FT_ type; }; + + typedef NT_converter::type,FT_> FT_converter; + typedef transforming_iterator Point_cartesian_const_iterator; + typedef transforming_iterator Vector_cartesian_const_iterator; + //FIXME: use Iterator_list! + /* + template::value_tag,FT_tag>::value> + struct Iterator : Get_type {}; + template struct Iterator { + typedef transforming_iterator::type> type; + }; + */ + + template + struct Construct_cartesian_const_iterator_ { + typedef typename Get_functor::type Functor_base; + Construct_cartesian_const_iterator_(){} + Construct_cartesian_const_iterator_(Self const&r):f(r){} + Functor_base f; + typedef Type_ result_type; + template + result_type operator()(T const& v, Begin_tag)const{ + return make_transforming_iterator(f(v,Begin_tag()),FT_converter()); + } + template + result_type operator()(T const& v, End_tag)const{ + return make_transforming_iterator(f(v,End_tag()),FT_converter()); + } + }; + typedef Construct_cartesian_const_iterator_,Point_cartesian_const_iterator> Construct_point_cartesian_const_iterator; + typedef Construct_cartesian_const_iterator_,Vector_cartesian_const_iterator> Construct_vector_cartesian_const_iterator; + + template + struct Compute_cartesian_coordinate { + typedef typename Get_functor::type Functor_base; + Compute_cartesian_coordinate(){} + Compute_cartesian_coordinate(Self const&r):f(r){} + Functor_base f; + typedef FT_ result_type; + template + result_type operator()(Obj_ const& v,int i)const{ + return FT_converter()(f(v,i)); + } + }; + + template::type> struct Functor : + Inherit_functor { }; + template struct Functor { }; + template struct Functor { }; + template struct Functor { + typedef Compute_cartesian_coordinate type; + }; + template struct Functor { + typedef Compute_cartesian_coordinate type; + }; + template struct Functor,D,Construct_iterator_tag> { + typedef Construct_point_cartesian_const_iterator type; + }; + template struct Functor,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 +{ + CGAL_CONSTEXPR Cartesian_change_FT(){} + CGAL_CONSTEXPR Cartesian_change_FT(int d):Cartesian_change_FT_base(d){} +}; + +} //namespace CGAL + +#endif // CGAL_KERNEL_D_CARTESIAN_CHANGE_FT_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/Cartesian_complete.h b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_complete.h new file mode 100644 index 00000000000..b78a96a0e7c --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_complete.h @@ -0,0 +1,14 @@ +#ifndef CGAL_KERNEL_D_CARTESIAN_COMPLETE_H +#define CGAL_KERNEL_D_CARTESIAN_COMPLETE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // CGAL_KERNEL_D_CARTESIAN_COMPLETE_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/Cartesian_filter_K.h b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_filter_K.h new file mode 100644 index 00000000000..4e08e39d4ff --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_filter_K.h @@ -0,0 +1,49 @@ +#ifndef CGAL_KERNEL_D_CARTESIAN_FILTER_K_H +#define CGAL_KERNEL_D_CARTESIAN_FILTER_K_H + +#include +#include +#include +#include + +namespace CGAL { + +template < typename Base_, typename AK_, typename EK_ > +struct Cartesian_filter_K : public Base_, + private Store_kernel, private Store_kernel2 +{ + 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(a),Store_kernel2(b){} + CGAL_CONSTEXPR Cartesian_filter_K(int d,AK_ const&a,EK_ const&b):Base_(d),Store_kernel(a),Store_kernel2(b){} + typedef Base_ Kernel_base; + typedef AK_ AK; + typedef EK_ EK; + typedef typename Store_kernel::reference_type AK_rt; + AK_rt approximate_kernel()const{return this->kernel();} + typedef typename Store_kernel2::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 C2A; + typedef KernelD_converter C2E; + + template::type> struct Functor : + Inherit_functor {}; + template struct Functor { + typedef typename Get_functor::type AP; + typedef typename Get_functor::type EP; + typedef Filtered_predicate2 type; + }; +// TODO: +// template struct Functor : +// Kernel_base::template Functor {}; +// TODO: +// detect when Less_cartesian_coordinate doesn't need filtering +}; + +} //namespace CGAL + +#endif // CGAL_KERNEL_D_CARTESIAN_FILTER_K_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/Cartesian_filter_NT.h b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_filter_NT.h new file mode 100644 index 00000000000..33b136a5385 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_filter_NT.h @@ -0,0 +1,74 @@ +#ifndef CGAL_KERNEL_D_CARTESIAN_FILTER_NT_H +#define CGAL_KERNEL_D_CARTESIAN_FILTER_NT_H + +#include +#include +#include + +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 K1; + typedef typename internal::Exact_field_selector::type>::Type Exact_nt; + typedef Cartesian_change_FT K2; + + template::type> struct Functor : + Inherit_functor {}; + template struct Functor { + struct type { + //TODO: use compression (derive from a compressed_pair?) + typedef typename Get_functor::type P1; P1 p1; + typedef typename Get_functor::type P2; P2 p2; + typedef typename P2::result_type result_type; + type(){} + type(Cartesian_filter_NT const&k):p1(reinterpret_cast(k)),p2(reinterpret_cast(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 result_type operator()(U&&...u)const{ + { + Protect_FPU_rounding 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)...); + } +#else + result_type operator()()const{ // does it make sense to have 0 argument? + { + Protect_FPU_rounding 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 result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t))const{ \ + { \ + Protect_FPU_rounding 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 diff --git a/NewKernel_d/include/CGAL/Kernel_d/Cartesian_per_dimension.h b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_per_dimension.h new file mode 100644 index 00000000000..b67e680350e --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_per_dimension.h @@ -0,0 +1,14 @@ +#ifndef CGAL_KD_CARTESIAN_PER_DIM_H +#define CGAL_KD_CARTESIAN_PER_DIM_H +#include +#include +#include + +// Should probably disappear. + +namespace CGAL { +template +struct Cartesian_per_dimension : public R_ {}; +} + +#endif diff --git a/NewKernel_d/include/CGAL/Kernel_d/Cartesian_static_filters.h b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_static_filters.h new file mode 100644 index 00000000000..d33820cd844 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Cartesian_static_filters.h @@ -0,0 +1,76 @@ +#ifndef CGAL_KD_CARTESIAN_STATIC_FILTERS_H +#define CGAL_KD_CARTESIAN_STATIC_FILTERS_H +#include +#include +#include // bug, should be included by the next one +#include +#include + +namespace CGAL { +namespace SFA { // static filter adapter +// Note that this would be quite a bit simpler without stateful kernels +template struct Orientation_of_points_2 : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Orientation_of_points_2); + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Get_type::type FT; + typedef typename Get_functor::type CC; + typedef typename Get_functor::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(t+0),make_transforming_iterator(t+3)); + } + }; + }; + template 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()(P(this->kernel(),c,A),P(this->kernel(),c,B),P(this->kernel(),c,C)); + } +}; +} + +template +struct Cartesian_static_filters : public R_ { + CGAL_CONSTEXPR Cartesian_static_filters(){} + CGAL_CONSTEXPR Cartesian_static_filters(int d):R_(d){} +}; + +template +struct Cartesian_static_filters, R_, Derived_> : public R_ { + CGAL_CONSTEXPR Cartesian_static_filters(){} + CGAL_CONSTEXPR Cartesian_static_filters(int d):R_(d){} + typedef Cartesian_static_filters, R_, Derived_> Self; + typedef typename Default::Get::type Derived; + template struct Functor : Inherit_functor {}; + template struct Functor { + typedef + //typename boost::conditional< + //boost::is_same::value, + //typename Get_functor::type, + SFA::Orientation_of_points_2 + // >::type + type; + }; +}; + +} + +#endif diff --git a/NewKernel_d/include/CGAL/Kernel_d/Coaffine.h b/NewKernel_d/include/CGAL/Kernel_d/Coaffine.h new file mode 100644 index 00000000000..ffc81ae6ecc --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Coaffine.h @@ -0,0 +1,248 @@ +#ifndef CGAL_KD_COAFFINE_H +#define CGAL_KD_COAFFINE_H +#include +#include +#include +#include +#include + +namespace CGAL { +namespace CartesianDKernelFunctors { +struct Flat_orientation { + std::vector proj; + std::vector rest; +}; + +// For debugging purposes +inline std::ostream& operator<< (std::ostream& o, Flat_orientation const& f) { + o << "Proj: "; + for(std::vector::const_iterator i=f.proj.begin(); + i!=f.proj.end(); ++i) + o << *i << ' '; + o << "\nRest: "; + for(std::vector::const_iterator i=f.rest.begin(); + i!=f.rest.end(); ++i) + o << *i << ' '; + return o << '\n'; +} + +namespace internal { +namespace coaffine { +template +inline void debug_matrix(std::ostream& o, Mat const&mat) { + for(int i=0;i struct Construct_flat_orientation : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Construct_flat_orientation) + typedef R_ R; + typedef typename Get_type::type FT; + typedef typename Get_type::type Point; + typedef typename Increment_dimension::type Dplusone; + typedef typename R::LA::template Rebind_dimension::Other LA; + typedef typename LA::Square_matrix Matrix; + typedef typename Get_functor::type CCC; + typedef typename Get_functor::type PD; + typedef Flat_orientation result_type; + + // This implementation is going to suck. Maybe we should push the + // functionality into LA. + template + 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& proj=o.proj; + std::vector& rest=o.rest; rest.reserve(dim+1); + for(int i=0; i::iterator it=rest.begin();;++it) { + CGAL_assertion(it!=rest.end()); + for(int i=0; i struct Contained_in_affine_hull : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Contained_in_affine_hull) + typedef R_ R; + typedef typename Get_type::type FT; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Get_functor::type CCC; + typedef typename Get_functor::type PD; + //typedef typename Increment_dimension::type D1; + //typedef typename Increment_dimension::type D2; + //typedef typename R::LA::template Rebind_dimension::Other LA; + typedef typename Increment_dimension::type Dplusone; + typedef typename R::LA::template Rebind_dimension::Other LA; + typedef typename LA::Square_matrix Matrix; + + // mostly copied from Construct_flat_orientation. TODO: dedup this code. + template + 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 proj; + std::vector rest; rest.reserve(dim+1); + for(int i=0; i::iterator it=rest.begin();it!=rest.end();++it) { + for(int i=0; i::iterator it=rest.begin();it!=rest.end();++it) { + for(int i=0; i struct In_flat_orientation : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(In_flat_orientation) + typedef R_ R; + typedef typename Get_type::type FT; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Increment_dimension::type D1; + typedef typename Increment_dimension::type D2; + typedef typename R::LA::template Rebind_dimension::Other LA; + typedef typename LA::Square_matrix Matrix; + + template + 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::type c(this->kernel()); + typename Get_functor::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::const_iterator it = o.rest.begin(); it != o.rest.end() /* i struct In_flat_side_of_oriented_sphere : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(In_flat_side_of_oriented_sphere) + typedef R_ R; + typedef typename Get_type::type FT; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Increment_dimension::type D1; + typedef typename Increment_dimension::type D2; + typedef typename R::LA::template Rebind_dimension::Other LA; + typedef typename LA::Square_matrix Matrix; + + template + 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::type c(this->kernel()); + typename Get_functor::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::const_iterator it = o.rest.begin(); it != o.rest.end() /* i),(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),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag)); +CGAL_KD_DEFAULT_FUNCTOR(Construct_flat_orientation_tag,(CartesianDKernelFunctors::Construct_flat_orientation),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag)); +CGAL_KD_DEFAULT_FUNCTOR(Contained_in_affine_hull_tag,(CartesianDKernelFunctors::Contained_in_affine_hull),(Point_tag),(Compute_point_cartesian_coordinate_tag,Point_dimension_tag)); +} +#endif diff --git a/NewKernel_d/include/CGAL/Kernel_d/Define_kernel_types.h b/NewKernel_d/include/CGAL/Kernel_d/Define_kernel_types.h new file mode 100644 index 00000000000..bbf981b8848 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Define_kernel_types.h @@ -0,0 +1,30 @@ +#ifndef CGAL_DEFINE_KERNEL_TYPES_H +#define CGAL_DEFINE_KERNEL_TYPES_H +#include +#include +#ifdef CGAL_CXX0X +#include +#else +#include +#endif + +namespace CGAL { + namespace internal { + template::is_iterator> + struct Type_or_iter : K::template Type {}; + template + struct Type_or_iter : K::template Iterator {}; + } + template::type> struct Define_kernel_types; + template + struct Define_kernel_types > : Base {}; + template + struct Define_kernel_types > {}; + template + struct Define_kernel_types : + Typedef_tag_type::type, + Define_kernel_types + > {}; +} +#endif diff --git a/NewKernel_d/include/CGAL/Kernel_d/Dimension_base.h b/NewKernel_d/include/CGAL/Kernel_d/Dimension_base.h new file mode 100644 index 00000000000..98e64f0c99d --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Dimension_base.h @@ -0,0 +1,30 @@ +#ifndef bd_h +#define db_h +#include +#include +#include +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 +struct Dimension_base { + Dimension_base(int = UNKNOWN_DIMENSION){} + int dimension() const { return UNKNOWN_DIMENSION; } + void set_dimension(int) {} +}; +template +struct Dimension_base > { + 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 + diff --git a/NewKernel_d/include/CGAL/Kernel_d/KernelD_converter.h b/NewKernel_d/include/CGAL/Kernel_d/KernelD_converter.h new file mode 100644 index 00000000000..7028ea68899 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/KernelD_converter.h @@ -0,0 +1,175 @@ +#ifndef CGAL_KERNEL_D_CARTESIAN_CONVERTER_H +#define CGAL_KERNEL_D_CARTESIAN_CONVERTER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { +namespace internal { +// Reverses order, but that shouldn't matter. +template struct Map_taglist_to_typelist : + Map_taglist_to_typelist::type + ::template add::type> +{}; +template struct Map_taglist_to_typelist > : typeset<> {}; +} + +template > +struct Object_converter { + typedef Object result_type; + template + result_type operator()(Object const& o, F const& f) const { + typedef typename List::head H; + if (H const* ptr = object_cast(&o)) + return make_object(f(*ptr)); + else + return Object_converter()(o,f); + } +}; +template<> +struct Object_converter > { + typedef Object result_type; + template + 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 KernelD_converter_ +: public KernelD_converter_ +{ + typedef typename List::head Tag_; + typedef typename List::tail Rest; + typedef KernelD_converter_ Base; + typedef typename Get_type::type K1_Obj; + typedef typename Get_type::type K2_Obj; + typedef typename Get_functor >::type K1_Conv; + typedef KO_converter KOC; + typedef BOOSTD is_same no_converter; + typedef typename internal::Map_taglist_to_typelist::type::template contains 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::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 struct result:Base::template result{}; + template struct result {typedef K2_Obj type;}; +}; + +template +class KernelD_converter_ > { + public: + struct Do_not_use{}; + void operator()(Do_not_use)const{} + template struct result; + Final_& myself(){return *static_cast(this);} + Final_ const& myself()const{return *static_cast(this);} +}; + + +// TODO: use the intersection of Kn::Object_list. +template::type +//typeset::add::type/*::add::type*/ +> class KernelD_converter + : public Store_kernel, public Store_kernel2, + public KernelD_converter_,K1,K2,List_> +{ + typedef KernelD_converter Self; + typedef Self Final_; + typedef KernelD_converter_ Base; + typedef typename Get_type::type FT1; + typedef typename Get_type::type FT2; + typedef NT_converter 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(a),Store_kernel2(b){} + + // For boost::result_of, used in transforming_iterator + template::value?42:0> struct result:Base::template result{}; + template struct result { + typedef transforming_iterator type; + }; + template struct result{typedef K2 type;}; + template struct result{typedef int type;}; + // Ideally the next 2 would come with Point_tag and Vector_tag, but that's hard... + template struct result{typedef Origin type;}; + template struct result{typedef Null_vector type;}; + template struct result{typedef Object type;}; + template struct result{typedef FT2 type;}; + + using Base::operator(); + typename Store_kernel2::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::Type const&x)const{return cr(x);} + + typename Get_type::type const& + operator()(typename Get_type::type const&o)const + { return o; } // Both kernels should have the same, returning a reference should warn if not. + + template + transforming_iterator,It>::type> + operator()(It const& it) const { + return make_transforming_iterator(it,*this); + } + + template + //TODO: use decltype in C++11 instead of result + std::vector::type> + operator()(const std::vector& v) const { + return std::vector::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::type Possibilities; + //TODO: add Empty, vector, etc to the list. + return Object_converter()(obj,*this); + } + + //TODO: convert boost::variant + +}; + +} //namespace CGAL + +#endif // CGAL_KERNEL_D_CARTESIAN_CONVERTER_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/Kernel_2_interface.h b/NewKernel_d/include/CGAL/Kernel_d/Kernel_2_interface.h new file mode 100644 index 00000000000..aed4ebbc645 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Kernel_2_interface.h @@ -0,0 +1,85 @@ +#ifndef CGAL_KD_KERNEL_2_INTERFACE_H +#define CGAL_KD_KERNEL_2_INTERFACE_H + +#include +#include +#include +#include + + +namespace CGAL { +template struct Kernel_2_interface : public Base_ { + typedef Base_ Base; + typedef Kernel_2_interface Kernel; + typedef typename Get_type::type RT; + typedef typename Get_type::type FT; + typedef typename Get_type::type Boolean; + typedef typename Get_type::type Sign; + typedef typename Get_type::type Comparison_result; + typedef typename Get_type::type Orientation; + typedef typename Get_type::type Oriented_side; + typedef typename Get_type::type Bounded_side; + typedef typename Get_type::type Angle; + typedef typename Get_type::type Point_2; + typedef typename Get_type::type Vector_2; + typedef typename Get_type::type Segment_2; + typedef cpp0x::tuple Triangle_2; // triangulation insists... + template struct Help_2p_i { + typedef typename Get_functor::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_x_2; + typedef Help_2p_i Less_y_2; + typedef Help_2p_i Compare_x_2; + typedef Help_2p_i Compare_y_2; + struct Compare_distance_2 { + typedef typename Get_functor::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::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(t+0),make_transforming_iterator(t+3)); + + } + }; + struct Side_of_oriented_circle_2 { + typedef typename Get_functor::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(t+0),make_transforming_iterator(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 diff --git a/NewKernel_d/include/CGAL/Kernel_d/Kernel_3_interface.h b/NewKernel_d/include/CGAL/Kernel_d/Kernel_3_interface.h new file mode 100644 index 00000000000..1a523ee2213 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Kernel_3_interface.h @@ -0,0 +1,83 @@ +#ifndef CGAL_KD_KERNEL_3_INTERFACE_H +#define CGAL_KD_KERNEL_3_INTERFACE_H + +#include +#include +#include +#include + + +namespace CGAL { +template struct Kernel_3_interface : public Base_ { + typedef Base_ Base; + typedef Kernel_3_interface Kernel; + typedef typename Get_type::type RT; + typedef typename Get_type::type FT; + typedef typename Get_type::type Boolean; + typedef typename Get_type::type Sign; + typedef typename Get_type::type Comparison_result; + typedef typename Get_type::type Orientation; + typedef typename Get_type::type Oriented_side; + typedef typename Get_type::type Bounded_side; + typedef typename Get_type::type Angle; + typedef typename Get_type::type Point_3; + typedef typename Get_type::type Vector_3; + typedef typename Get_type::type Segment_3; + typedef cpp0x::tuple Triangle_3; // placeholder + typedef cpp0x::tuple Tetrahedron_3; // placeholder + struct Compare_xyz_3 { + typedef typename Get_functor::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::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::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(t+0),make_transforming_iterator(t+4)); + + } + }; + struct Side_of_oriented_sphere_3 { + typedef typename Get_functor::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(t+0),make_transforming_iterator(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 diff --git a/NewKernel_d/include/CGAL/Kernel_d/Kernel_d_interface.h b/NewKernel_d/include/CGAL/Kernel_d/Kernel_d_interface.h new file mode 100644 index 00000000000..ffc102e1a25 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Kernel_d_interface.h @@ -0,0 +1,173 @@ +#ifndef CGAL_KD_KERNEL_D_INTERFACE_H +#define CGAL_KD_KERNEL_D_INTERFACE_H + +#include +#include +#include +#include + + +namespace CGAL { +template 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 Kernel; + typedef Base_ R_; // for the macros + typedef typename Get_type::type RT; + typedef typename Get_type::type FT; + typedef typename Get_type::type Boolean; + typedef typename Get_type::type Sign; + typedef typename Get_type::type Comparison_result; + typedef typename Get_type::type Orientation; + typedef typename Get_type::type Oriented_side; + typedef typename Get_type::type Bounded_side; + typedef typename Get_type::type Angle; + typedef typename Get_type::type Flat_orientation_d; + typedef typename Get_type::type Point_d; + typedef typename Get_type::type Vector_d; + typedef typename Get_type::type Segment_d; + typedef typename Get_type::type Sphere_d; + typedef typename Get_type::type Hyperplane_d; + typedef Vector_d Direction_d; + typedef typename Get_type::type Line_d; + typedef typename Get_type::type Ray_d; + typedef typename Get_type::type Iso_box_d; + typedef typename Get_type::type Aff_transformation_d; + typedef typename Get_functor::type Compute_coordinate_d; + typedef typename Get_functor::type Compare_lexicographically_d; + typedef typename Get_functor::type Equal_d; + typedef typename Get_functor::type Less_lexicographically_d; + typedef typename Get_functor::type Less_or_equal_lexicographically_d; + // FIXME: and vectors? + typedef typename Get_functor::type Orientation_d; + typedef typename Get_functor::type Less_coordinate_d; + typedef typename Get_functor::type Point_dimension_d; + typedef typename Get_functor::type Side_of_oriented_sphere_d; + typedef typename Get_functor::type Contained_in_affine_hull_d; + typedef typename Get_functor::type Construct_flat_orientation_d; + typedef typename Get_functor::type In_flat_orientation_d; + typedef typename Get_functor::type In_flat_side_of_oriented_sphere_d; + typedef typename Get_functor::type Point_to_vector_d; + typedef typename Get_functor::type Vector_to_point_d; + typedef typename Get_functor >::type Construct_point_d; + typedef typename Get_functor >::type Construct_vector_d; + typedef typename Get_functor >::type Construct_segment_d; + typedef typename Get_functor >::type Construct_sphere_d; + typedef typename Get_functor >::type Construct_hyperplane_d; + typedef Construct_vector_d Construct_direction_d; + typedef typename Get_functor >::type Construct_line_d; + typedef typename Get_functor >::type Construct_ray_d; + typedef typename Get_functor >::type Construct_iso_box_d; + typedef typename Get_functor >::type Construct_aff_transformation_d; + typedef typename Get_functor::type Midpoint_d; + struct Component_accessor_d : private Store_kernel { + 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 { + CGAL_FUNCTOR_INIT_STORE(Construct_cartesian_const_iterator_d) + typedef typename Get_functor >::type CPI; + typedef typename Get_functor >::type CVI; + typedef typename CGAL::decay::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::type>::type, result_type>::value)); + template + result_type operator()(Point_d const&p, Tag_ t)const{ + return CPI(this->kernel())(p,t); + } + template + result_type operator()(typename First_if_different::Type const&v, Tag_ t)const{ + return CVI(this->kernel())(v,t); + } + + template + 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::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::type Squared_distance_d; + //typedef typename Get_functor::type Affine_rank_d; + //typedef typename Get_functor::type Affinely_independent_d; + //typedef typename Get_functor::type Contained_in_linear_hull_d; + //typedef typename Get_functor::type Contained_in_simplex_d; + typedef typename Get_functor::type Has_on_positive_side_d; + //typedef typename Get_functor::type Linear_rank_d; + //typedef typename Get_functor::type Linearly_independent_d; + typedef typename Get_functor::type Oriented_side_d; + //typedef typename Get_functor::type Side_of_bounded_sphere_d; + + typedef typename Get_functor::type Center_of_sphere_d; + typedef typename Get_functor::type Value_at_d; + typedef typename Get_functor::type Point_of_sphere_d; + typedef typename Get_functor::type Orthogonal_vector_d; + //typedef typename Get_functor::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 diff --git a/NewKernel_d/include/CGAL/Kernel_d/Kernel_object_converter.h b/NewKernel_d/include/CGAL/Kernel_d/Kernel_object_converter.h new file mode 100644 index 00000000000..ba233fea139 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Kernel_object_converter.h @@ -0,0 +1,78 @@ +#ifndef CGAL_KD_KO_CONVERTER_H +#define CGAL_KD_KO_CONVERTER_H +#include +#include +#include // First_if_different +namespace CGAL { +template 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 +struct Point_converter_help { + typedef typename Get_type::type argument_type; + typedef typename Get_type::type result_type; + template + result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& p) const { + typename Get_functor >::type i(k1); + typename Get_functor >::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 +struct Point_converter_help,K1,K2> { + typedef typename Get_type::type argument_type; + typedef typename Get_type::type result_type; + template + result_type help(Indices, K1 const& k1, K2 const& k2, C const& conv, argument_type const& p) const { + typename Get_functor::type cc(k1); + typename Get_functor >::type cp(k2); + return cp(conv(cc(p,I))...); + } + template + result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& p) const { + return help(typename N_increasing_indices::type(),k1,k2,conv,p); + } +}; +#endif +} +template struct KO_converter +: internal::Point_converter_help +{}; + +template struct KO_converter{ + typedef typename Get_type::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::Type argument_type; + + typedef K1_Vector argument_type; + typedef typename Get_type::type result_type; + template + result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& v) const { + typename Get_functor >::type i(k1); + typename Get_functor >::type cp(k2); + return cp(conv(i(v,Begin_tag())),conv(i(v,End_tag()))); + } +}; + +template struct KO_converter{ + typedef typename Get_type::type argument_type; + typedef typename Get_type::type result_type; + template + result_type operator()(K1 const& k1, K2 const& k2, C const& conv, argument_type const& s) const { + typename Get_functor::type f(k1); + typename Get_functor >::type cs(k2); + return cs(conv(f(s,0)),conv(f(s,1))); + } +}; + +} +#endif diff --git a/NewKernel_d/include/CGAL/Kernel_d/Lazy_cartesian.h b/NewKernel_d/include/CGAL/Kernel_d/Lazy_cartesian.h new file mode 100644 index 00000000000..059e2a74fe5 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Lazy_cartesian.h @@ -0,0 +1,169 @@ +#ifndef CGAL_KERNEL_D_LAZY_CARTESIAN_H +#define CGAL_KERNEL_D_LAZY_CARTESIAN_H + +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { + +template +struct Nth_iterator_element : private Store_kernel { + Nth_iterator_element(){} + Nth_iterator_element(K const&k):Store_kernel(k){} + typedef typename Get_type::value_tag>::type result_type; + template result_type operator()(CGAL_FORWARDABLE(U) u, int i) const { + typename Get_functor >::type ci(this->kernel()); + return *cpp0x::next(ci(CGAL_FORWARD(U,u),Begin_tag()),i); + } +}; + //typedef typename Functor::nth_element>::type nth_elem; +template::has_nth_element> +struct Select_nth_element_functor { + typedef Nth_iterator_element type; +}; +template +struct Select_nth_element_functor : + Get_functor::nth_element> {}; + +namespace internal { + template + struct Lazy_construction_maybe_nt { + typedef Lazy_construction type; + }; + template + struct Lazy_construction_maybe_nt { + typedef Lazy_construction_nt type; + }; +} + +template +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 ::type> struct Type {}; + template struct Type { + typedef Lazy< + typename Get_type::type, + typename Get_type::type, + typename Get_type::type, + E2A_> type; + }; + template struct Type { + typedef CGAL::Lazy_exact_nt::type> type; + }; + + template struct Iterator { + typedef typename iterator_tag_traits::value_tag Vt; + typedef typename Type::type V; + typedef typename Select_nth_element_functor::type AF; + typedef typename Select_nth_element_functor::type EF; + + typedef typename internal::Lazy_construction_maybe_nt< + Kernel_, AF, EF, is_NT_tag::value + >::type nth_elem; + + typedef Iterator_from_indices< + const typename Type::container>::type, + const V, V, nth_elem + > type; + }; +}; + +template +struct Lazy_cartesian : Dimension_base, + Lazy_cartesian_types > +{ + //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 Base; + //typedef typename Default::Get::type Kernel; + typedef Self Kernel; + typedef AK_ Approximate_kernel; + typedef EK_ Exact_kernel; + typedef E2A_ E2A; + typedef Approx_converter C2A; + typedef Exact_converter 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::type> struct Functor { + typedef Null_functor type; + }; + //FIXME: what do we do with D here? + template struct Functor { + typedef typename Get_functor::type FA; + typedef typename Get_functor::type FE; + typedef Filtered_predicate2 type; + }; + template struct Functor { + typedef typename Get_functor::type FA; + typedef typename Get_functor::type FE; + typedef Lazy_construction_nt type; + }; + template struct Functor { + typedef typename Get_functor::type FA; + typedef typename Get_functor::type FE; + typedef Lazy_construction type; + }; + + //typedef typename Iterator::type Point_cartesian_const_iterator; + //typedef typename Iterator::type Vector_cartesian_const_iterator; + + template + struct Construct_iter : private Store_kernel { + Construct_iter(){} + Construct_iter(Kernel const&k):Store_kernel(k){} + //FIXME: pass the kernel to the functor in the iterator + typedef U result_type; + template + result_type operator()(T const& t,Begin_tag)const{ + return result_type(t,0,this->kernel()); + } + template + result_type operator()(T const& t,End_tag)const{ + return result_type(t,Self().dimension(),this->kernel()); + } + }; + template struct Functor { + typedef Construct_iter::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 diff --git a/NewKernel_d/include/CGAL/Kernel_d/Types/Aff_transformation.h b/NewKernel_d/include/CGAL/Kernel_d/Types/Aff_transformation.h new file mode 100644 index 00000000000..27f01671e2b --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Types/Aff_transformation.h @@ -0,0 +1,39 @@ +#ifndef CGAL_KD_TYPE_AFF_TRANSFORMATION_H +#define CGAL_KD_TYPE_AFF_TRANSFORMATION_H +#include +#include + +// Dummy, that's all the Kernel_d concept requires, so a useful class will wait. + +namespace CGAL { +template +struct Aff_transformation { + typedef R_ R; +}; +namespace CartesianDKernelFunctors { +template struct Construct_aff_transformation { + CGAL_FUNCTOR_INIT_IGNORE(Construct_aff_transformation) + typedef R_ R; + typedef typename Get_type::type result_type; +#ifdef CGAL_CXX0X + template + result_type operator()(T&&...)const{return result_type();} +#else + result_type operator()()const{ + return result_type(); + } +#define CODE(Z,N,_) template \ + 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),(),()); +CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag,(CartesianDKernelFunctors::Construct_aff_transformation),(Aff_transformation_tag),()); + +} +#endif diff --git a/NewKernel_d/include/CGAL/Kernel_d/Types/Hyperplane.h b/NewKernel_d/include/CGAL/Kernel_d/Types/Hyperplane.h new file mode 100644 index 00000000000..b35c9f91abc --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Types/Hyperplane.h @@ -0,0 +1,79 @@ +#ifndef CGAL_KD_TYPE_HYPERPLANE_H +#define CGAL_KD_TYPE_HYPERPLANE_H +#include +namespace CGAL { +template class Hyperplane { + typedef typename Get_type::type FT_; + typedef typename Get_type::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 struct Construct_hyperplane : Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Construct_hyperplane) + typedef typename Get_type::type result_type; + typedef typename Get_type::type Vector; + typedef typename Get_type::type FT; + typedef typename R_::LA LA; + result_type operator()(Vector const&a, FT const&b)const{ + return result_type(a,b); + } + template + result_type operator()(Iter f, Iter e)const{ + throw "not implemented yet!"; + } +}; +template struct Orthogonal_vector { + CGAL_FUNCTOR_INIT_IGNORE(Orthogonal_vector) + typedef typename Get_type::type Hyperplane; + typedef typename Get_type::type result_type; + result_type operator()(Hyperplane const&s)const{ + return s.orthogonal_vector(); + } +}; +template struct Hyperplane_translation { + CGAL_FUNCTOR_INIT_IGNORE(Hyperplane_translation) + typedef typename Get_type::type Hyperplane; + typedef typename Get_type::type result_type; + // TODO: Is_exact? + result_type operator()(Hyperplane const&s)const{ + return s.translation(); + } +}; +template struct Value_at : Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Value_at) + typedef typename Get_type::type Hyperplane; + typedef typename Get_type::type Vector; + typedef typename Get_type::type Point; + typedef typename Get_type::type FT; + typedef FT result_type; + typedef typename Get_functor::type Dot; + typedef typename Get_functor::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 + 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),(Vector_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag,(CartesianDKernelFunctors::Construct_hyperplane),(Vector_tag,Hyperplane_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Orthogonal_vector_tag,(CartesianDKernelFunctors::Orthogonal_vector),(Vector_tag,Hyperplane_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Hyperplane_translation_tag,(CartesianDKernelFunctors::Hyperplane_translation),(Hyperplane_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Value_at_tag,(CartesianDKernelFunctors::Value_at),(Point_tag,Vector_tag,Hyperplane_tag),(Scalar_product_tag,Point_to_vector_tag)); +} // namespace CGAL +#endif diff --git a/NewKernel_d/include/CGAL/Kernel_d/Types/Iso_box.h b/NewKernel_d/include/CGAL/Kernel_d/Types/Iso_box.h new file mode 100644 index 00000000000..8559ed39af8 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Types/Iso_box.h @@ -0,0 +1,49 @@ +#ifndef CGAL_KERNELD_TYPES_ISO_BOX_H +#define CGAL_KERNELD_TYPES_ISO_BOX_H +#include +#include +#include +#include +#include +namespace CGAL { +template class Iso_box { + typedef typename Get_type::type FT_; + typedef typename Get_type::type Point_; + typedef std::pair 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 struct Construct_iso_box : Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Construct_iso_box) + typedef typename Get_type::type result_type; + typedef typename Get_type::type RT; + typedef typename Get_type::type Point; + typedef typename Get_functor >::type Cp_; + typedef typename Get_functor >::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()), + make_transforming_pair_iterator(ci(a,End_tag()), ci(b,End_tag()), Min())), + cp( + make_transforming_pair_iterator(ci(a,Begin_tag()), ci(b,Begin_tag()), Max()), + make_transforming_pair_iterator(ci(a,End_tag()), ci(b,End_tag()), Max()))); + } + }; +} +CGAL_KD_DEFAULT_TYPE(Iso_box_tag,(CGAL::Iso_box),(Point_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag,(CartesianDKernelFunctors::Construct_iso_box),(Iso_box_tag,Point_tag),(Construct_ttag,Construct_ttag)); + +} // namespace CGAL + +#endif // CGAL_KERNELD_TYPES_ISO_BOX_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/Types/Line.h b/NewKernel_d/include/CGAL/Kernel_d/Types/Line.h new file mode 100644 index 00000000000..338bdd00b46 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Types/Line.h @@ -0,0 +1,47 @@ +#ifndef CGAL_KERNELD_TYPES_LINE_H +#define CGAL_KERNELD_TYPES_LINE_H +#include +#include +#include +namespace CGAL { +template class Line { + typedef typename Get_type::type FT_; + typedef typename Get_type::type Point_; + typedef std::pair 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 struct Construct_line : Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Construct_line) + typedef typename Get_type::type result_type; + typedef typename Get_type::type Point; + typedef typename Get_type::type Vector; + typedef typename Get_functor::type Tp_; + //typedef typename Get_functor::type Dp_; + //typedef typename Get_functor::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::Type const&b)const{ + Tp_ tp(this->kernel()); + return result_type(a,tp(a,b)); + } + }; +} +CGAL_KD_DEFAULT_TYPE(Line_tag,(CGAL::Line),(Point_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag,(CartesianDKernelFunctors::Construct_line),(Line_tag,Point_tag,Vector_tag),(Translated_point_tag)); + +} // namespace CGAL + +#endif // CGAL_KERNELD_TYPES_LINE_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/Types/Ray.h b/NewKernel_d/include/CGAL/Kernel_d/Types/Ray.h new file mode 100644 index 00000000000..2dfcf2b2ba4 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Types/Ray.h @@ -0,0 +1,47 @@ +#ifndef CGAL_KERNELD_TYPES_RAY_H +#define CGAL_KERNELD_TYPES_RAY_H +#include +#include +#include +namespace CGAL { +template class Ray { + typedef typename Get_type::type FT_; + typedef typename Get_type::type Point_; + typedef typename Get_type::type Vector_; + typedef std::pair 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 struct Construct_ray : Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Construct_ray) + typedef typename Get_type::type result_type; + typedef typename Get_type::type Point; + typedef typename Get_type::type Vector; + typedef typename Get_functor::type Dp_; + //typedef typename Get_functor::type Tp_; + //typedef typename Get_functor::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::Type const&b)const{ + Dp_ dp(this->kernel()); + return result_type(a,dp(b,a)); + } + }; +} +CGAL_KD_DEFAULT_TYPE(Ray_tag,(CGAL::Ray),(Point_tag,Vector_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag,(CartesianDKernelFunctors::Construct_ray),(Point_tag,Ray_tag,Vector_tag),(Difference_of_points_tag)); + +} // namespace CGAL + +#endif // CGAL_KERNELD_TYPES_RAY_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/Types/Segment.h b/NewKernel_d/include/CGAL/Kernel_d/Types/Segment.h new file mode 100644 index 00000000000..0f617ed4494 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Types/Segment.h @@ -0,0 +1,96 @@ +#ifndef CGAL_KERNELD_SEGMENTD_H +#define CGAL_KERNELD_SEGMENTD_H +#include +#include +namespace CGAL { +template class Segment { + typedef typename Get_type::type FT_; + typedef typename Get_type::type Point_; + //typedef typename R_::Vector Vector_; + //typedef typename Get_functor >::type Cv_; +// typedef typename R_::Squared_distance Csd_; + typedef std::pair Data_; + Data_ data; + public: + //typedef Segmentd Segment; +#ifdef CGAL_CXX0X + //FIXME: don't forward directly, piecewise_constuct should call the point construction functor (I guess? or is it unnecessary?) + template::type...>,std::tuple>::value>::type> + Segment(U&&...u):data(std::forward(u)...){} +#else + Segment(){} + Segment(Point_ const&a, Point_ const&b): data(a,b) {} + //template + //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 struct Construct_segment { + CGAL_FUNCTOR_INIT_IGNORE(Construct_segment) + typedef R_ R; + typedef typename Get_type::type Point; + typedef typename Get_type::type Segment; + typedef typename Get_functor >::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 + 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(cp, CGAL_FORWARD(U,u)), + call_on_tuple_elements(cp, CGAL_FORWARD(V,v)) }}; + return r; + } +}; + +// This should be part of Construct_point, according to Kernel_23 conventions +template struct Segment_extremity { + CGAL_FUNCTOR_INIT_IGNORE(Segment_extremity) + typedef R_ R; + typedef typename Get_type::type Point; + typedef typename Get_type::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),(Point_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag,(CartesianDKernelFunctors::Construct_segment),(Segment_tag,Point_tag),(Construct_ttag)); +CGAL_KD_DEFAULT_FUNCTOR(Segment_extremity_tag,(CartesianDKernelFunctors::Segment_extremity),(Segment_tag,Point_tag),()); + +} // namespace CGAL + +#endif // CGAL_KERNELD_SEGMENTD_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/Types/Sphere.h b/NewKernel_d/include/CGAL/Kernel_d/Types/Sphere.h new file mode 100644 index 00000000000..dabae71f8cb --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Types/Sphere.h @@ -0,0 +1,90 @@ +#ifndef CGAL_KD_TYPE_SPHERE_H +#define CGAL_KD_TYPE_SPHERE_H +#include +#include +namespace CGAL { +template class Sphere { + typedef typename Get_type::type FT_; + typedef typename Get_type::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 struct Construct_sphere : Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Construct_sphere) + typedef typename Get_type::type result_type; + typedef typename Get_type::type Point; + typedef typename Get_type::type FT; + typedef typename R_::LA LA; + result_type operator()(Point const&a, FT const&b)const{ + return result_type(a,b); + } + template + result_type operator()(Iter f, Iter e)const{ + throw "not implemented yet!"; + } +}; +template struct Center_of_sphere { + CGAL_FUNCTOR_INIT_IGNORE(Center_of_sphere) + typedef typename Get_type::type Sphere; + typedef typename Get_type::type const& result_type; + result_type operator()(Sphere const&s)const{ + return s.center(); + } +}; +template struct Squared_radius { + CGAL_FUNCTOR_INIT_IGNORE(Squared_radius) + typedef typename Get_type::type Sphere; + typedef typename Get_type::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 struct Point_of_sphere : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Point_of_sphere) + typedef R_ R; + typedef typename Get_type::type FT; + typedef typename Get_type::type RT; + typedef typename Get_type::type Point; + typedef typename Get_type::type Sphere; + typedef typename Get_functor >::type CP; + typedef typename Get_functor >::type CI; + typedef typename Get_functor::type PD; + typedef Point result_type; + typedef Sphere first_argument_type; + typedef int second_argument_type; + struct Trans : std::binary_function { + 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 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),(Point_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Construct_ttag,(CartesianDKernelFunctors::Construct_sphere),(Sphere_tag,Point_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Center_of_sphere_tag,(CartesianDKernelFunctors::Center_of_sphere),(Sphere_tag,Point_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Squared_radius_tag,(CartesianDKernelFunctors::Squared_radius),(Sphere_tag),()); +CGAL_KD_DEFAULT_FUNCTOR(Point_of_sphere_tag,(CartesianDKernelFunctors::Point_of_sphere),(Sphere_tag,Point_tag),(Construct_ttag, Construct_ttag)); +} // namespace CGAL +#endif diff --git a/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Cartesian_wrap.h b/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Cartesian_wrap.h new file mode 100644 index 00000000000..daeb376495e --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Cartesian_wrap.h @@ -0,0 +1,262 @@ +#ifndef CGAL_KERNEL_D_CARTESIAN_WRAP_H +#define CGAL_KERNEL_D_CARTESIAN_WRAP_H + +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +//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::value> struct Is_wrapper { + enum { value=false }; + typedef Tag_false type; +}; +template struct Is_wrapper { + typedef typename T::Is_wrapper type; + enum { value=type::value }; +}; + +template::value> struct Is_wrapper_iterator { + enum { value=false }; + typedef Tag_false type; +}; +template struct Is_wrapper_iterator : + Is_wrapper::value_type> +{ }; + +struct Forward_rep { +//TODO: make a good C++0X version with perfect forwarding +//#ifdef CGAL_CXX0X +//template ::type>::value&&!Is_wrapper_iterator::type>::value>::type> +//T&& operator()(typename std::remove_reference::type&& t) const {return static_cast(t);}; +//template ::type>::value&&!Is_wrapper_iterator::type>::value>::type> +//T&& operator()(typename std::remove_reference::type& t) const {return static_cast(t);}; +// +//template ::type>::value>::type> +//typename Type_copy_cvref::type::Rep>::type&& +//operator()(T&& t) const { +// return static_cast::type::Rep>::type&&>(t.rep()); +//}; +// +//template ::type>::value>::type> +//transforming_iterator::type> +//operator()(T&& t) const { +// return make_transforming_iterator(std::forward(t),Forward_rep()); +//}; +//#else +template ::value,bool=Is_wrapper_iterator::value> struct result_; +template struct result_{typedef T const& type;}; +template struct result_{typedef typename decay::type::Rep const& type;}; +template struct result_{typedef transforming_iterator::type> type;}; +template struct result; +template struct result : result_ {}; + +template typename boost::disable_if,Is_wrapper_iterator >,T>::type const& operator()(T const& t) const {return t;} + +template typename boost::enable_if,T>::type::Rep const& operator()(T const& t) const {return t.rep();} + +template transforming_iterator,T>::type> operator()(T const& t) const {return make_transforming_iterator(t,Forward_rep());} +//#endif +}; +} + +template ::value> +struct Map_wrapping_type : Get_type {}; +#define CGAL_REGISTER_OBJECT_WRAPPER(X) \ + template \ + struct Map_wrapping_type { \ + typedef X##_d 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::type Derived; + // FIXME: The list doesn't belong here. + typedef boost::mpl::vector Wrapped_list; + + template + struct Type : Map_wrapping_type {}; + + //Translate the arguments + template ::type, + bool=Provides_functor::value, + bool=boost::mpl::contains::type>::type::value> + struct Functor { + typedef typename Get_functor::type B; + struct type { + B b; + type(){} + type(Self const&k):b(k){} + typedef typename B::result_type result_type; +#ifdef CGAL_CXX0X + template 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 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 + struct Functor + : Get_functor {}; + + //Translate both the arguments and the result + //TODO: Check Is_wrapper instead of relying on map_result_tag? + template struct Functor { + typedef typename Get_functor::type B; + struct type { + B b; + type(){} + type(Self const&k):b(k){} + typedef typename map_result_tag::type result_tag; + // FIXME: Self or Derived? + typedef typename Get_type::type result_type; +#ifdef CGAL_CXX0X + template 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 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 struct Type : Get_type {}; +#define CGAL_Kernel_obj(X,Y) \ + template struct Type { typedef Ref_count_obj type; }; + + CGAL_Kernel_obj(Point,point) + CGAL_Kernel_obj(Vector,vector) +#undef CGAL_Kernel_obj + + template struct Dispatch { + //typedef typename map_functor_type::type f_t; + typedef typename map_result_tag::type r_t; + enum { + is_nul = boost::is_same::type,Null_functor>::value, + ret_rcobj = boost::is_same::value || boost::is_same::value + }; + }; + + //Translate the arguments + template::is_nul,bool=Dispatch::ret_rcobj> struct Functor { + typedef typename Get_functor::type B; + struct type { + B b; + type(){} + type(Self const&k):b(k){} + typedef typename B::result_type result_type; +#ifdef CGAL_CXX0X + template 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 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 struct Functor { + typedef Null_functor type; + }; + + template struct Functor { + typedef typename Get_functor::type B; + struct type { + B b; + type(){} + type(Self const&k):b(k){} + typedef typename map_result_tag::type result_tag; + typedef typename Get_type::type result_type; +#ifdef CGAL_CXX0X + template 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 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 diff --git a/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Point_d.h b/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Point_d.h new file mode 100644 index 00000000000..7a1adc87fa0 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Point_d.h @@ -0,0 +1,248 @@ +#ifndef CGAL_WRAPPER_POINT_D_H +#define CGAL_WRAPPER_POINT_D_H + +#include +#include +#include +#include +#include +#include +#include +#ifndef CGAL_CXX0X +#include +#endif +#include + +namespace CGAL { + +template +class Point_d : public Get_type::type + // Deriving won't work if the point is just a __m256d. + // Test boost/std::is_class for instance +{ + typedef typename Get_type::type RT_; + typedef typename Get_type::type FT_; + typedef typename R_::Kernel_base Kbase; + typedef typename Get_type::type Vector_; + typedef typename Get_functor >::type CPBase; + typedef typename Get_functor::type CCBase; + + typedef Point_d Self; + BOOST_STATIC_ASSERT((boost::is_same::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::type Rep; + + const Rep& rep() const + { + return *this; + } + + Rep& rep() + { + return *this; + } + + typedef R_ R; + +#ifdef CGAL_CXX0X + template::type...>,std::tuple >::value>::type> explicit Point_d(U&&...u) + : Rep(CPBase()(std::forward(u)...)){} + +// // called from Construct_point_d +// template explicit Point_d(Eval_functor&&,U&&...u) +// : Rep(Eval_functor(), std::forward(u)...){} + template explicit Point_d(Eval_functor&&,F&&f,U&&...u) + : Rep(std::forward(f)(std::forward(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(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 \ + explicit Point_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(CPBase()( \ + BOOST_PP_ENUM_PARAMS(N,t))) {} \ + \ + template \ + 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 \ + 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::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::Type & c) const + { + return R().construct_divided_vector_d_object()(*this,c); + } + + typename Qualified_result_of::type + x() const + { + return R().compute_x_3_object()(*this); + } + + typename Qualified_result_of::type + y() const + { + return R().compute_y_3_object()(*this); + } + + typename Qualified_result_of::type + z() const + { + return R().compute_z_3_object()(*this); + } + + typename Qualified_result_of::type + hx() const + { + return R().compute_hx_3_object()(*this); + } + + typename Qualified_result_of::type + hy() const + { + return R().compute_hy_3_object()(*this); + } + + typename Qualified_result_of::type + hz() const + { + return R().compute_hz_3_object()(*this); + } + + typename Qualified_result_of::type + hw() const + { + return R().compute_hw_3_object()(*this); + } + + typename Qualified_result_of::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::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::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::type + squared_length() const + { + return R().compute_squared_length_3_object()(*this); + } +*/ +}; +#if 0 +template Point_d::Point_d(Point_d &)=default; +#endif + +//TODO: IO + +//template +//Vector_d operator+(const Vector_d& v,const Vector_d& w) const +//{ +// return typename R::template Construct::type()(v,w); +//} +// +//template +//Vector_d operator-(const Vector_d& v,const Vector_d& w) const +//{ +// return typename R::template Construct::type()(v,w); +//} + +} //namespace CGAL + +#endif // CGAL_WRAPPER_POINT_D_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Ref_count_obj.h b/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Ref_count_obj.h new file mode 100644 index 00000000000..ec87fffed54 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Ref_count_obj.h @@ -0,0 +1,101 @@ +#ifndef CGAL_WRAPPER_REF_COUNT_OBJ_H +#define CGAL_WRAPPER_REF_COUNT_OBJ_H + +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef CGAL_CXX0X +#include +#endif +#include + +// no need for a fancy interface here, people can use the Point_d wrapper on +// top. + +namespace CGAL { + +template +class Ref_count_obj +{ + typedef typename R_::Kernel_base Kbase; + typedef typename Get_functor >::type CBase; + + typedef Ref_count_obj Self; + BOOST_STATIC_ASSERT((boost::is_same::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::type Rep; + typedef Handle_for Data; + +private: + Data data; +public: + + const Rep& rep() const + { + return CGAL::get(data); + } + +#ifdef CGAL_CXX0X + template::type...>,std::tuple >::value>::type> explicit Ref_count_obj(U&&...u) + : data(Eval_functor(),CBase(),std::forward(u)...){} + + template explicit Ref_count_obj(Eval_functor&&,F&&f,U&&...u) + : data(Eval_functor(),std::forward(f),std::forward(u)...){} + + // try not to use these + Ref_count_obj(Rep const& v) : data(v) {} + Ref_count_obj(Rep& v) : data(static_cast(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 \ + explicit Ref_count_obj(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : data(Eval_functor(),CBase(),BOOST_PP_ENUM_PARAMS(N,t)) {} \ + \ + template \ + 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 + 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 diff --git a/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Segment_d.h b/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Segment_d.h new file mode 100644 index 00000000000..45834171060 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Segment_d.h @@ -0,0 +1,112 @@ +#ifndef CGAL_WRAPPER_SEGMENT_D_H +#define CGAL_WRAPPER_SEGMENT_D_H + +#include +#include +#include +#include +#include +#include +#include +#ifndef CGAL_CXX0X +#include +#endif +#include + +namespace CGAL { + +template +class Segment_d : public Get_type::type +{ + typedef typename Get_type::type RT_; + typedef typename Get_type::type FT_; + typedef typename R_::Kernel_base Kbase; + typedef typename Get_type::type Point_; + typedef typename Get_functor >::type CPBase; + typedef typename Get_functor >::type CSBase; + typedef typename Get_functor::type CSEBase; + + typedef Segment_d Self; + BOOST_STATIC_ASSERT((boost::is_same::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::type Rep; + + const Rep& rep() const + { + return *this; + } + + Rep& rep() + { + return *this; + } + + typedef R_ R; + +#ifdef CGAL_CXX0X + template::type...>,std::tuple >::value>::type> explicit Segment_d(U&&...u) + : Rep(CSBase()(std::forward(u)...)){} + +// // called from Construct_point_d +// template explicit Point_d(Eval_functor&&,U&&...u) +// : Rep(Eval_functor(), std::forward(u)...){} + template explicit Segment_d(Eval_functor&&,F&&f,U&&...u) + : Rep(std::forward(f)(std::forward(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(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 \ + explicit Segment_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(CSBase()( \ + BOOST_PP_ENUM_PARAMS(N,t))) {} \ + \ + template \ + 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 \ + 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 diff --git a/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Sphere_d.h b/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Sphere_d.h new file mode 100644 index 00000000000..43af2a834bd --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Sphere_d.h @@ -0,0 +1,109 @@ +#ifndef CGAL_WRAPPER_SPHERE_D_H +#define CGAL_WRAPPER_SPHERE_D_H + +#include +#include +#include +#include +#include +#ifndef CGAL_CXX0X +#include +#endif +#include + +namespace CGAL { + +template +class Sphere_d : public Get_type::type +{ + typedef typename Get_type::type FT_; + typedef typename R_::Kernel_base Kbase; + typedef typename Get_type::type Point_; + typedef typename Get_functor >::type CSBase; + typedef typename Get_functor::type COSBase; + typedef typename Get_functor::type SRBase; + + typedef Sphere_d Self; + BOOST_STATIC_ASSERT((boost::is_same::type>::value)); + +public: + + typedef Tag_true Is_wrapper; + typedef typename R_::Default_ambient_dimension Ambient_dimension; + typedef typename Increment_dimension::type Feature_dimension; + + typedef typename Get_type::type Rep; + + const Rep& rep() const + { + return *this; + } + + Rep& rep() + { + return *this; + } + + typedef R_ R; + +#ifdef CGAL_CXX0X + template::type...>,std::tuple >::value>::type> explicit Sphere_d(U&&...u) + : Rep(CSBase()(std::forward(u)...)){} + +// // called from Construct_point_d +// template explicit Point_d(Eval_functor&&,U&&...u) +// : Rep(Eval_functor(), std::forward(u)...){} + template explicit Sphere_d(Eval_functor&&,F&&f,U&&...u) + : Rep(std::forward(f)(std::forward(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(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 \ + explicit Sphere_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(CSBase()( \ + BOOST_PP_ENUM_PARAMS(N,t))) {} \ + \ + template \ + 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 \ + 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 diff --git a/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Vector_d.h b/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Vector_d.h new file mode 100644 index 00000000000..bced5b751a8 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/Wrapper/Vector_d.h @@ -0,0 +1,250 @@ +#ifndef CGAL_WRAPPER_VECTOR_D_H +#define CGAL_WRAPPER_VECTOR_D_H + +#include +#include +#include +#include +#include +#include +#include +#ifndef CGAL_CXX0X +#include +#endif +#include + +namespace CGAL { + +template +class Vector_d : public Get_type::type +{ + typedef typename Get_type::type RT_; + typedef typename Get_type::type FT_; + typedef typename R_::Kernel_base Kbase; + typedef typename Get_type::type Point_; + typedef typename Get_functor >::type CVBase; + typedef typename Get_functor::type CCBase; + + typedef Vector_d Self; + BOOST_STATIC_ASSERT((boost::is_same::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::type Rep; + + const Rep& rep() const + { + return *this; + } + + Rep& rep() + { + return *this; + } + + typedef R_ R; + +#ifdef CGAL_CXX0X + template::type...>,std::tuple >::value>::type> explicit Vector_d(U&&...u) + : Rep(CVBase()(std::forward(u)...)){} + +// // called from Construct_vector_d +// template explicit Vector_d(Eval_functor&&,U&&...u) +// : Rep(Eval_functor(), std::forward(u)...){} + template explicit Vector_d(Eval_functor&&,F&&f,U&&...u) + : Rep(std::forward(f)(std::forward(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(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 \ + explicit Vector_d(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t)) \ + : Rep(CVBase()( \ + BOOST_PP_ENUM_PARAMS(N,t))) {} \ + \ + template \ + 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 \ + 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::type cartesian(int i)const{ + return CCBase()(rep(),i); + } + + Vector_d operator-() const + { + return typename Get_functor::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::Type & c) const + { + return R().construct_divided_vector_d_object()(*this,c); + } + + typename Qualified_result_of::type + x() const + { + return R().compute_x_3_object()(*this); + } + + typename Qualified_result_of::type + y() const + { + return R().compute_y_3_object()(*this); + } + + typename Qualified_result_of::type + z() const + { + return R().compute_z_3_object()(*this); + } + + typename Qualified_result_of::type + hx() const + { + return R().compute_hx_3_object()(*this); + } + + typename Qualified_result_of::type + hy() const + { + return R().compute_hy_3_object()(*this); + } + + typename Qualified_result_of::type + hz() const + { + return R().compute_hz_3_object()(*this); + } + + typename Qualified_result_of::type + hw() const + { + return R().compute_hw_3_object()(*this); + } + + typename Qualified_result_of::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::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::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::type + squared_length() const + { + return R().compute_squared_length_3_object()(*this); + } +*/ +}; +#if 0 +template Vector_d::Vector_d(Vector_d &)=default; +#endif + +//TODO: IO + +template +Vector_d operator+(const Vector_d& v,const Vector_d& w) +{ + return typename Get_functor::type()(v,w); +} + +template +Vector_d operator-(const Vector_d& v,const Vector_d& w) +{ + return typename Get_functor::type()(v,w); +} + +} //namespace CGAL + +#endif // CGAL_WRAPPER_VECTOR_D_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/function_objects_cartesian.h b/NewKernel_d/include/CGAL/Kernel_d/function_objects_cartesian.h new file mode 100644 index 00000000000..ce10ca8b10c --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/function_objects_cartesian.h @@ -0,0 +1,796 @@ +#ifndef CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H +#define CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CGAL_CXX0X +#include +#endif + +namespace CGAL { +namespace CartesianDKernelFunctors { +namespace internal { +template struct Dimension_at_most { enum { value = false }; }; +template struct Dimension_at_most,b> { + enum { value = (a <= b) }; +}; +} + +template::value> struct Orientation_of_points : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Orientation_of_points) + typedef R_ R; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename R::LA::Square_matrix Matrix; + + template + result_type operator()(Iter f, Iter e)const{ + typename Get_functor::type c(this->kernel()); + typename Get_functor::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,typename R::Default_ambient_dimension>::value>::type> + template =3)>::type> + result_type operator()(U&&...u) const { + return operator()({std::forward(u)...}); + } + + template + result_type operator()(std::initializer_list

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::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 struct Orientation_of_points,true> : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Orientation_of_points) + typedef R_ R; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + templatestruct Help; + templatestruct Help > { + template result_type operator()(C const&c,P const&x,T&&t)const{ + return sign_of_determinant(c(std::get(t),I%d)-c(x,I%d)...); + } + }; + template result_type operator()(P0 const&x,P&&...p)const{ + static_assert(d==sizeof...(P),"Wrong number of arguments"); + typename Get_functor::type c(this->kernel()); + return Help::type>()(c,x,std::forward_as_tuple(std::forward

(p)...)); + } + + + template result_type help2(Dimension_tag, Iter f, Iter const&e, U&&...u)const{ + auto const&p=*f; + return help2(Dimension_tag(),++f,e,std::forward(u)...,p); + } + template 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)...); + } + template + result_type operator()(Iter f, Iter e)const{ + return help2(Dimension_tag(),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 struct Orientation_of_points,true> : private Store_kernel { \ + CGAL_FUNCTOR_INIT_STORE(Orientation_of_points) \ + typedef R_ R; \ + typedef typename Get_type::type RT; \ + typedef typename Get_type::type Point; \ + typedef typename Get_type::type result_type; \ + result_type operator()(Point const&x, BOOST_PP_ENUM_PARAMS(N,Point const&p)) const { \ + typename Get_functor::type c(this->kernel()); \ + BOOST_PP_REPEAT(N,VAR4,) \ + return sign_of_determinant(BOOST_PP_ENUM(N,VAR2,N)); \ + } \ + template \ + 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),(Point_tag),(Point_dimension_tag,Compute_point_cartesian_coordinate_tag)); + +namespace CartesianDKernelFunctors { +template struct Orientation_of_vectors : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Orientation_of_vectors) + typedef R_ R; + typedef typename Get_type::type Vector; + typedef typename Get_type::type result_type; + typedef typename R::LA::Square_matrix Matrix; + + template + result_type operator()(Iter f, Iter e)const{ + typename Get_functor::type c(this->kernel()); + typename Get_functor::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=3)>::type> + result_type operator()(U&&...u) const { + return operator()({std::forward(u)...}); + } + + template + result_type operator()(std::initializer_list l) const { + return operator()(l.begin(),l.end()); + } +#else + //TODO +#endif +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Orientation_of_vectors_tag,(CartesianDKernelFunctors::Orientation_of_vectors),(Vector_tag),(Point_dimension_tag,Compute_vector_cartesian_coordinate_tag)); + +namespace CartesianDKernelFunctors { +#if 0 +template::value> struct Orientation : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Orientation) + typedef R_ R; + typedef typename Get_type::type Vector; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Get_functor::type OP; + typedef typename Get_functor::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 + result_type operator()(Iter const&f, Iter const& e)const{ + typename Get_functor::type pd(this->kernel()); + typename std::iterator_traits::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 struct Orientation : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Orientation) + typedef R_ R; + typedef typename Get_type::type Vector; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Get_functor::type OP; + typedef typename Get_functor::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 + typename boost::enable_if,result_type>::type + operator()(Iter const&f, Iter const& e)const{ + return OP(this->kernel())(f,e); + } + template + typename boost::enable_if,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 struct Side_of_oriented_sphere : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Side_of_oriented_sphere) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Point; + typedef typename Get_type::type result_type; + typedef typename Increment_dimension::type D1; + typedef typename Increment_dimension::type D2; + typedef typename R::LA::template Rebind_dimension::Other LA; + typedef typename LA::Square_matrix Matrix; + + template + result_type operator()(Iter f, Iter const& e)const{ + Point const& p0=*f++; // *--e ? + return this->operator()(f,e,p0); + } + + template + result_type operator()(Iter f, Iter const& e, Point const& p0) const { + typedef typename Get_functor::type Sqdo; + typename Get_functor::type c(this->kernel()); + typename Get_functor::type pd(this->kernel()); + + int d=pd(p0); + Matrix m(d+1,d+1); + if(CGAL::Is_stored::value) { + Sqdo sqdo(this->kernel()); + for(int i=0;f!=e;++f,++i) { + Point const& p=*f; + for(int j=0;j=4)>::type> + result_type operator()(U&&...u) const { + return operator()({std::forward(u)...}); + } + + template + result_type operator()(std::initializer_list

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),(Point_tag),(Point_dimension_tag,Squared_distance_to_origin_tag,Compute_point_cartesian_coordinate_tag)); + +namespace CartesianDKernelFunctors { +template struct Point_to_vector : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Point_to_vector) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_type::type Point; + typedef typename Get_functor >::type CV; + typedef typename Get_functor >::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),(Point_tag,Vector_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Vector_to_point : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Vector_to_point) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_type::type Point; + typedef typename Get_functor >::type CV; + typedef typename Get_functor >::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),(Point_tag,Vector_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Opposite_vector : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Opposite_vector) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_functor >::type CV; + typedef typename Get_functor >::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()),make_transforming_iterator(ci(v,End_tag()),std::negate())); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Opposite_vector_tag,(CartesianDKernelFunctors::Opposite_vector),(Vector_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Scaled_vector : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Scaled_vector) + typedef R_ R; + typedef typename Get_type::type FT; + typedef typename Get_type::type Vector; + typedef typename Get_functor >::type CV; + typedef typename Get_functor >::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(s)),make_transforming_iterator(ci(v,End_tag()),Scale(s))); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Scaled_vector_tag,(CartesianDKernelFunctors::Scaled_vector),(Vector_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Sum_of_vectors : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Sum_of_vectors) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_functor >::type CV; + typedef typename Get_functor >::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()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),std::plus())); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Sum_of_vectors_tag,(CartesianDKernelFunctors::Sum_of_vectors),(Vector_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Difference_of_vectors : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Difference_of_vectors) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_functor >::type CV; + typedef typename Get_functor >::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()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),std::minus())); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Difference_of_vectors_tag,(CartesianDKernelFunctors::Difference_of_vectors),(Vector_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Translated_point : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Translated_point) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_type::type Point; + typedef typename Get_functor >::type CP; + typedef typename Get_functor >::type CVI; + typedef typename Get_functor >::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()),make_transforming_pair_iterator(cpi(a,End_tag()),cvi(b,End_tag()),std::plus())); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Translated_point_tag,(CartesianDKernelFunctors::Translated_point),(Point_tag, Vector_tag),(Construct_ttag, Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Difference_of_points : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Difference_of_points) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Point; + typedef typename Get_type::type Vector; + typedef typename Get_functor >::type CV; + typedef typename Get_functor >::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()),make_transforming_pair_iterator(ci(a,End_tag()),ci(b,End_tag()),std::minus())); + } +}; +} + +CGAL_KD_DEFAULT_FUNCTOR(Difference_of_points_tag,(CartesianDKernelFunctors::Difference_of_points),(Point_tag, Vector_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Midpoint : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Midpoint) + typedef R_ R; + typedef typename Get_type::type FT; + typedef typename Get_type::type RT; + typedef typename Get_type::type Point; + typedef typename Get_functor >::type CP; + typedef typename Get_functor >::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 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 half(2); + //return CP(this->kernel())(make_transforming_iterator(make_transforming_pair_iterator(ci.begin(a),ci.begin(b),std::plus()),half),make_transforming_iterator(make_transforming_pair_iterator(ci.end(a),ci.end(b),std::plus()),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),(Point_tag),(Construct_ttag, Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Squared_length : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Squared_length) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Vector; + typedef typename Get_functor >::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::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),(Vector_tag),(Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Squared_distance_to_origin : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Squared_distance_to_origin) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Point; + typedef typename Get_functor >::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::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),(Point_tag),(Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Squared_distance : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Squared_distance) + typedef R_ R; + typedef typename Get_type::type RT; + typedef typename Get_type::type Point; + typedef typename Get_functor >::type CI; + typedef RT result_type; + typedef Point first_argument_type; + typedef Point second_argument_type; + struct Sq_diff : std::binary_function { + 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),(Point_tag),(Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Compare_distance : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Compare_distance) + typedef R_ R; + typedef typename Get_type::type Point; + typedef typename Get_functor::type CSD; + typedef typename Get_type::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),(Point_tag),(Squared_distance_tag)); + +namespace CartesianDKernelFunctors { +template struct Less_point_cartesian_coordinate : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Less_point_cartesian_coordinate) + typedef R_ R; + typedef typename Get_type::type result_type; + typedef typename Get_functor::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 Is_exact; + + template + result_type operator()(V const&a, W const&b, I i)const{ + Cc c(this->kernel()); + return c(a,i)),(),(Compute_point_cartesian_coordinate_tag)); + +namespace CartesianDKernelFunctors { +template struct Compare_point_cartesian_coordinate : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Compare_point_cartesian_coordinate) + typedef R_ R; + typedef typename Get_type::type result_type; + typedef typename Get_functor::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 Is_exact; + + template + 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),(),(Compute_point_cartesian_coordinate_tag)); + +namespace CartesianDKernelFunctors { +template struct Compare_lexicographically : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Compare_lexicographically) + typedef R_ R; + typedef typename Get_type::type result_type; + typedef typename Get_functor >::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 Is_exact; + + template + 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(); + 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),(),(Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Less_lexicographically : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Less_lexicographically) + typedef R_ R; + typedef typename Get_type::type result_type; + typedef typename Get_functor::type CL; + typedef typename CGAL::Is_exact Is_exact; + + template + 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),(),(Compare_lexicographically_tag)); + +namespace CartesianDKernelFunctors { +template struct Less_or_equal_lexicographically : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Less_or_equal_lexicographically) + typedef R_ R; + typedef typename Get_type::type result_type; + typedef typename Get_functor::type CL; + typedef typename CGAL::Is_exact Is_exact; + + template + 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),(),(Compare_lexicographically_tag)); + +namespace CartesianDKernelFunctors { +template struct Equal_points : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Equal_points) + typedef R_ R; + typedef typename Get_type::type result_type; + typedef typename Get_functor >::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 Is_exact; + + template + 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),(),(Construct_ttag)); + +namespace CartesianDKernelFunctors { +template struct Oriented_side : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Oriented_side) + typedef R_ R; + typedef typename Get_type::type result_type; + typedef typename Get_type::type Point; + typedef typename Get_type::type Hyperplane; + typedef typename Get_type::type Sphere; + typedef typename Get_functor::type VA; + typedef typename Get_functor::type HT; + typedef typename Get_functor::type SD; + typedef typename Get_functor::type SR; + typedef typename Get_functor::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),(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 struct Has_on_positive_side : private Store_kernel { + CGAL_FUNCTOR_INIT_STORE(Has_on_positive_side) + typedef R_ R; + typedef typename Get_type::type result_type; + typedef typename Get_functor::type OS; + + template + 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),(),(Oriented_side_tag)); + +} +#include +#endif // CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H diff --git a/NewKernel_d/include/CGAL/Kernel_d/interface_macros.h b/NewKernel_d/include/CGAL/Kernel_d/interface_macros.h new file mode 100644 index 00000000000..4760e400c97 --- /dev/null +++ b/NewKernel_d/include/CGAL/Kernel_d/interface_macros.h @@ -0,0 +1,133 @@ +#ifndef CGAL_Kernel_pred +# define CGAL_Kernel_pred(X, Y) +#endif + +#ifndef CGAL_Kernel_comp +# define CGAL_Kernel_comp(X, Y) +#endif +#ifndef CGAL_Kernel_comp1 +# define CGAL_Kernel_comp1(X, Y) CGAL_Kernel_comp(X, Y) +#endif +#ifndef CGAL_Kernel_comp2 +# define CGAL_Kernel_comp2(X, Y) CGAL_Kernel_comp(X, Y) +#endif + +#ifndef CGAL_Kernel_cons +# define CGAL_Kernel_cons(X, Y) +#endif +#ifndef CGAL_Kernel_cons1 +# define CGAL_Kernel_cons1(X, Y) CGAL_Kernel_cons(X, Y) +#endif +#ifndef CGAL_Kernel_cons2 +# define CGAL_Kernel_cons2(X, Y) CGAL_Kernel_cons(X, Y) +#endif + +#ifndef CGAL_Kernel_obj +# define CGAL_Kernel_obj(X,Y) +#endif +#ifndef CGAL_Kernel_obj1 +# define CGAL_Kernel_obj1(X,Y) CGAL_Kernel_obj(X,Y) +#endif +#ifndef CGAL_Kernel_obj2 +# define CGAL_Kernel_obj2(X,Y) CGAL_Kernel_obj(X,Y) +#endif +#ifndef CGAL_Kernel_obj3 +# define CGAL_Kernel_obj3(X,Y) CGAL_Kernel_obj2(X,Y) +#endif + +//CGAL_Kernel_obj1(Vector,vector) +//CGAL_Kernel_obj1(Point,point) +CGAL_Kernel_obj2(Segment,segment) +//CGAL_Kernel_obj2(Sphere,sphere) +//CGAL_Kernel_obj3(Line,line) +//CGAL_Kernel_obj3(Ray,ray) +//CGAL_Kernel_obj3(Hyperplane,hyperplane) +//CGAL_Kernel_obj3(Aff_transformation,aff_transformation) +//CGAL_Kernel_obj3(Iso_box,iso_box) + +//CGAL_Kernel_cons1(Construct_point_cartesian_const_iterator, +// construct_point_cartesian_const_iterator_object) +//CGAL_Kernel_cons1(Construct_vector_cartesian_const_iterator, +// construct_vector_cartesian_const_iterator_object) +//CGAL_Kernel_cons2(Sum_of_vectors, +// sum_of_vectors_object) +//CGAL_Kernel_cons2(Difference_of_vectors, +// difference_of_vectors_object) +//CGAL_Kernel_cons2(Translated_point, +// translated_point_object) +//CGAL_Kernel_cons2(Opposite_vector, +// opposite_vector_object) +//CGAL_Kernel_cons2(Scaled_vector, +// scaled_vector_object) +//CGAL_Kernel_cons2(Difference_of_points, +// difference_of_points_object) +//CGAL_Kernel_cons2(Vector_to_point, +// vector_to_point_object) +//CGAL_Kernel_cons2(Point_to_vector, +// point_to_vector_object) +//CGAL_Kernel_cons2(Midpoint, +// midpoint_object) +//CGAL_Kernel_cons2(Orthogonal_vector, +// orthogonal_vector_object) +//CGAL_Kernel_cons2(Hyperplane_translation, +// hyperplane_translation_object) +//CGAL_Kernel_cons2(Construct_segment, +// construct_segment_object) +CGAL_Kernel_cons2(Segment_extremity, + segment_extremity_object) + +//CGAL_Kernel_comp1(Compute_point_cartesian_coordinate, +// compute_point_cartesian_coordinate_object) +//CGAL_Kernel_comp1(Compute_vector_cartesian_coordinate, +// compute_vector_cartesian_coordinate_object) +//CGAL_Kernel_comp2(Squared_length, +// squared_length_object) +//CGAL_Kernel_comp2(Squared_distance, +// squared_distance_object) +//CGAL_Kernel_comp2(Squared_distance_to_origin, +// squared_distance_to_origin_object) + +#if 0 +CGAL_Kernel_pred(Orientation, + orientation_object) +#endif +//CGAL_Kernel_pred(Orientation_of_points, +// orientation_of_points_object) +//CGAL_Kernel_pred(Orientation_of_vectors, +// orientation_of_vectors_object) +//CGAL_Kernel_pred(Side_of_oriented_sphere, +// side_of_oriented_sphere_object) +//CGAL_Kernel_pred(Less_point_cartesian_coordinate, +// less_point_cartesian_coordinate_object) +//CGAL_Kernel_pred(Compare_point_cartesian_coordinate, +// compare_point_cartesian_coordinate_object) +//CGAL_Kernel_pred(Compare_distance, +// compare_distance_object) +//CGAL_Kernel_pred(Compare_lexicographically, +// compare_lexicographically_object) +//CGAL_Kernel_pred(Less_lexicographically, +// less_lexicographically_object) +//CGAL_Kernel_pred(Equal_points, +// equal_points_object) +//CGAL_Kernel_pred(Less_or_equal_lexicographically, +// less_or_equal_lexicographically_object) +//CGAL_Kernel_pred(Contained_in_affine_hull, +// contained_in_affine_hull_object) +//CGAL_Kernel_pred(In_flat_orientation, +// in_flat_orientation_object) +//CGAL_Kernel_pred(In_flat_side_of_oriented_sphere, +// in_flat_side_of_oriented_sphere_object) +//CGAL_Kernel_pred(Construct_flat_orientation, +// construct_flat_orientation_object) + +#undef CGAL_Kernel_pred +#undef CGAL_Kernel_comp +#undef CGAL_Kernel_comp1 +#undef CGAL_Kernel_comp2 +#undef CGAL_Kernel_cons +#undef CGAL_Kernel_cons1 +#undef CGAL_Kernel_cons2 +#undef CGAL_Kernel_obj +#undef CGAL_Kernel_obj1 +#undef CGAL_Kernel_obj2 +#undef CGAL_Kernel_obj3 diff --git a/NewKernel_d/include/CGAL/LA_eigen/LA.h b/NewKernel_d/include/CGAL/LA_eigen/LA.h new file mode 100644 index 00000000000..4eaffd6db75 --- /dev/null +++ b/NewKernel_d/include/CGAL/LA_eigen/LA.h @@ -0,0 +1,121 @@ +#ifndef CGAL_LA_EIGEN_H +#define CGAL_LA_EIGEN_H + +#ifndef CGAL_EIGEN3_ENABLED +#error Requires Eigen +#endif +#include +#include +#include +#include +#include +#include + +namespace CGAL { + +//FIXME: where could we use Matrix_base instead of Matrix? +// Dim_ real dimension +// Max_dim_ upper bound on the dimension +template struct LA_eigen { + typedef NT_ NT; + typedef Dim_ Dimension; + typedef Max_dim_ Max_dimension; + enum { dimension = Eigen_dimension::value }; + enum { max_dimension = Eigen_dimension::value }; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef LA_eigen< NT, D2, D3 > Other; + }; + template struct Property : boost::false_type {}; + template struct Property : boost::true_type {}; + template struct Property : boost::true_type {}; + template struct Property : boost::true_type {}; + + typedef Eigen::Matrix::value,1,Eigen::ColMajor|Eigen::AutoAlign,Eigen_dimension::value,1> Vector; + typedef Eigen::Matrix Dynamic_vector; + typedef Construct_eigen Construct_vector; + +#if (EIGEN_WORLD_VERSION>=3) + typedef NT const* Vector_const_iterator; +#else + typedef Iterator_from_indices Vector_const_iterator; +#endif + + templatestatic Vector_const_iterator vector_begin(Vec_ const&a){ +#if (EIGEN_WORLD_VERSION>=3) + return &a[0]; +#else + return Vector_const_iterator(a,0); +#endif + } + + templatestatic 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 Square_matrix; + typedef Eigen::Matrix Dynamic_matrix; + //TODO: don't pass on the values of Max_* for an expensive NT + // typedef ... Constructor + // typedef ... Accessor +#if 0 + private: + template class Canonicalize_vector { + typedef typename Dimension_eigen::type S1; + typedef typename Dimension_eigen::type S2; + public: + typedef typename Vector::type type; + }; + public: +#endif + + templatestatic int size_of_vector(Vec_ const&v){ + return v.size(); + } + + templatestatic NT dot_product(Vec_ const&a,Vec_ const&b){ + return a.dot(b); + } + + template static NT determinant(Mat_ const&m,bool=false){ + return m.determinant(); + } + + template static typename + Same_uncertainty_nt::type + sign_of_determinant(Mat_ const&m,bool=false) + { + return CGAL::sign(m.determinant()); + } + + template 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 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 static std::pair 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 diff --git a/NewKernel_d/include/CGAL/LA_eigen/constructors.h b/NewKernel_d/include/CGAL/LA_eigen/constructors.h new file mode 100644 index 00000000000..97492a68fa6 --- /dev/null +++ b/NewKernel_d/include/CGAL/LA_eigen/constructors.h @@ -0,0 +1,133 @@ +#ifndef ecs_h +#define ecs_h + +#ifndef CGAL_EIGEN3_ENABLED +#error Requires Eigen +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { + template 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 + 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 + 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 + 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 + result_type operator()(std::initializer_list 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 + result_type operator()(U&&...u) const { + check_dim(sizeof...(U)); // TODO: use static_assert + return Initializer_list()({forward_safe(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 + result_type operator()(H const&h,U&&...u) const { + check_dim(sizeof...(U)); // TODO: use static_assert + return Initializer_list()({Rational_traits().make_rational(std::forward(u),h)...}); + } +#else + +#define VAR(Z,N,_) ( Rational_traits().make_rational( t##N ,h) ) +#define CODE(Z,N,_) template 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 diff --git a/NewKernel_d/include/CGAL/Lazy.h b/NewKernel_d/include/CGAL/Lazy.h new file mode 100644 index 00000000000..e62d45917f6 --- /dev/null +++ b/NewKernel_d/include/CGAL/Lazy.h @@ -0,0 +1,1971 @@ +// Copyright (c) 2005,2006 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; either version 3 of the License, +// or (at your option) any later version. +// +// 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) : Andreas Fabri, Sylvain Pion + +#ifndef CGAL_LAZY_H +#define CGAL_LAZY_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CGAL_HAS_THREADS +# include +#endif + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace CGAL { +namespace internal { + BOOST_MPL_HAS_XXX_TRAIT_DEF(AT) + BOOST_MPL_HAS_XXX_TRAIT_DEF(ET) +} + + +template class Lazy; + +template +class Lazy_exact_nt; + +template +inline +const AT& +approx(const Lazy& l) +{ + return l.approx(); +} + +// Where is this one (non-const) needed ? Is it ? +template +inline +AT& +approx(Lazy& l) +{ + return l.approx(); +} + + +template +inline +const ET& +exact(const Lazy& l) +{ + return l.exact(); +} + + +template +inline +unsigned +depth(const Lazy& l) +{ + return l.depth(); +} + + +template +inline T const & approx(T const& d) { return d; }; +template +inline T const & exact (T const& d) { return d; }; +template +inline unsigned depth (T const& ) { return 0; }; +/* +#define CGAL_LAZY_FORWARD(T) \ + inline const T & approx(const T& d) { return d; } \ + inline const T & exact (const T& d) { return d; } \ + inline unsigned depth (const T& ) { return 0; } + + +CGAL_LAZY_FORWARD(long double) +CGAL_LAZY_FORWARD(double) +CGAL_LAZY_FORWARD(float) +CGAL_LAZY_FORWARD(int) +CGAL_LAZY_FORWARD(unsigned int) +CGAL_LAZY_FORWARD(long) +CGAL_LAZY_FORWARD(unsigned long) +#ifdef CGAL_USE_LONG_LONG +CGAL_LAZY_FORWARD(long long) +CGAL_LAZY_FORWARD(unsigned long long) +#endif +CGAL_LAZY_FORWARD(Return_base_tag) +CGAL_LAZY_FORWARD(Null_vector) +CGAL_LAZY_FORWARD(Origin) +CGAL_LAZY_FORWARD(Orientation) +CGAL_LAZY_FORWARD(Bbox_2) +CGAL_LAZY_FORWARD(Bbox_3) +*/ +#undef CGAL_LAZY_FORWARD + +#ifdef CGAL_LAZY_KERNEL_DEBUG +template +void +print_at(std::ostream& os, const T& at) +{ + os << at; +} + +template +void +print_at(std::ostream& os, const std::vector& at) +{ + os << "std::vector"; +} + +template <> +void +print_at(std::ostream& os, const Object& o) +{ + os << "Object"; +} + +template +void +print_at(std::ostream& os, const std::pair & at) +{ + os << "[ " << at.first << " | " << at.second << " ]" << std::endl ; +} + + +template +inline +void +print_dag(const Lazy& l, std::ostream& os, int level = 0) +{ + l.print_dag(os, level); +} + +inline +void +print_dag(double d, std::ostream& os, int level) +{ + for(int i = 0; i < level; i++) + os << " "; + os << d << std::endl; +} + +inline +void +msg(std::ostream& os, int level, const char* s) +{ + for(int i = 0; i < level; i++) + os << " "; + os << s << std::endl; +} + +inline +void +print_dag(const Null_vector&, std::ostream& os, int level) +{ + for(int i = 0; i < level; i++) + os << " "; + os << "Null_vector" << std::endl; +} + +inline +void +print_dag(const Origin&, std::ostream& os, int level) +{ + for(int i = 0; i < level; i++) + os << " "; + os << "Origin" << std::endl; +} + +inline +void +print_dag(const Return_base_tag&, std::ostream& os, int level) +{ + for(int i = 0; i < level; i++) + os << " "; + os << "Return_base_tag" << std::endl; +} +#endif + + +struct Depth_base { +#ifdef CGAL_PROFILE + unsigned depth_; + Depth_base() { set_depth(0); } + unsigned depth() const { return depth_; } + void set_depth(unsigned i) + { + depth_ = i; + CGAL_HISTOGRAM_PROFILER(std::string("[Lazy_kernel DAG depths]"), i); + //(unsigned) ::log2(double(i))); + } +#else + unsigned depth() const { return 0; } + void set_depth(unsigned) {} +#endif +}; + + +// Abstract base class for lazy numbers and lazy objects +template +class Lazy_rep : public Rep, public Depth_base +{ + Lazy_rep (const Lazy_rep&); // cannot be copied. + +public: + + typedef AT_ AT; + + mutable AT at; + mutable ET *et; + + Lazy_rep () + : at(), et(NULL){} + + Lazy_rep (const AT& a) + : at(a), et(NULL){} + + Lazy_rep (const AT& a, const ET& e) + : at(a), et(new ET(e)) {} + + const AT& approx() const + { + return at; + } + + AT& approx() + { + return at; + } + + const ET & exact() const + { + if (et==NULL) + update_exact(); + return *et; + } + + ET & exact() + { + if (et==NULL) + update_exact(); + return *et; + } + +#ifdef CGAL_LAZY_KERNEL_DEBUG + void print_at_et(std::ostream& os, int level) const + { + for(int i = 0; i < level; i++){ + os << " "; + } + os << "Approximation: "; + print_at(os, at); + os << std::endl; + if(! is_lazy()){ + for(int i = 0; i < level; i++){ + os << " "; + } + os << "Exact: "; + print_at(os, *et); + os << std::endl; +#ifdef CGAL_LAZY_KERNEL_DEBUG_SHOW_TYPEID + for(int i = 0; i < level; i++){ + os << " "; + } + os << " (type: " << typeid(*et).name() << ")" << std::endl; +#endif // CGAL_LAZY_KERNEL_DEBUG_SHOW_TYPEID + } + } + + virtual void print_dag(std::ostream& os, int level) const {} +#endif + + bool is_lazy() const { return et == NULL; } + virtual void update_exact() const = 0; + virtual ~Lazy_rep() { delete et; } +}; + + +//____________________________________________________________ +// The rep for the leaf node +// FIXME TODO : Factorize all the Lazy_rep_[0-8] !!! + +template +class Lazy_rep_0 : public Lazy_rep +{ + + typedef Lazy_rep Base; +public: + + void + update_exact() const + { + this->et = new ET(); + } + + Lazy_rep_0() + : Lazy_rep() {} + + Lazy_rep_0(const AT& a, const ET& e) + : Lazy_rep(a, e) {} + + Lazy_rep_0(const AT& a, void*) + : Lazy_rep(a) {} + + Lazy_rep_0(const ET& e) + : Lazy_rep(E2A()(e), e) {} + + void + print_dag(std::ostream& os, int level) const + { + this->print_at_et(os, level); + } +}; + + +//____________________________________________________________ + +template +class Lazy_rep_1 + : public Lazy_rep::type, typename decay::type, E2A> + , private EC +{ + typedef typename decay::type AT; + typedef typename decay::type ET; + typedef Lazy_rep Base; + + mutable L1 l1_; + + const EC& ec() const { return *this; } + +public: + + void + update_exact() const + { + this->et = new ET(ec()(CGAL::exact(l1_))); + this->at = E2A()(*(this->et)); + // Prune lazy tree + l1_ = L1(); + } + + Lazy_rep_1(const AC& ac, const EC& ec, const L1& l1) + : Lazy_rep(ac(CGAL::approx(l1))), EC(ec), l1_(l1) + { + this->set_depth(CGAL::depth(l1_) + 1); + } + +#ifdef CGAL_LAZY_KERNEL_DEBUG_SHOW_TYPEID +# define CGAL_LAZY_PRINT_TYPEID CGAL::msg(os, level, typeid(AC).name()); +#else // not CGAL_LAZY_KERNEL_DEBUG_SHOW_TYPEID +# define CGAL_LAZY_PRINT_TYPEID +#endif // not CGAL_LAZY_KERNEL_DEBUG_SHOW_TYPEID + +#ifdef CGAL_LAZY_KERNEL_DEBUG + void + print_dag(std::ostream& os, int level) const + { + this->print_at_et(os, level); + if(this->is_lazy()){ + CGAL_LAZY_PRINT_TYPEID + CGAL::msg(os, level, "DAG with one child node:"); + CGAL::print_dag(l1_, os, level+1); + } + } +#endif +}; + + + +//____________________________________________________________ + +template +class Lazy_rep_2 + : public Lazy_rep::type, typename decay::type, E2A> + , private EC +{ + typedef typename decay::type AT; + typedef typename decay::type ET; + typedef Lazy_rep Base; + + mutable L1 l1_; + mutable L2 l2_; + + const EC& ec() const { return *this; } + +public: + + void + update_exact() const + { + this->et = new ET(ec()(CGAL::exact(l1_), CGAL::exact(l2_))); + this->at = E2A()(*(this->et)); + // Prune lazy tree + l1_ = L1(); + l2_ = L2(); + } + + Lazy_rep_2(const AC& ac, const EC& /*ec*/, const L1& l1, const L2& l2) + : Lazy_rep(ac(CGAL::approx(l1), CGAL::approx(l2))), + l1_(l1), l2_(l2) + { + this->set_depth(max_n(CGAL::depth(l1_), CGAL::depth(l2_)) + 1); + } + +#ifdef CGAL_LAZY_KERNEL_DEBUG + void + print_dag(std::ostream& os, int level) const + { + this->print_at_et(os, level); + if(this->is_lazy()){ + CGAL::msg(os, level, "DAG with two child nodes:"); + CGAL::print_dag(l1_, os, level+1); + CGAL::print_dag(l2_, os, level+1); + } + } +#endif +}; + + +//____________________________________________________________ + +template +class Lazy_rep_3 + : public Lazy_rep::type, typename decay::type, E2A> + , private EC +{ + typedef typename decay::type AT; + typedef typename decay::type ET; + typedef Lazy_rep Base; + + mutable L1 l1_; + mutable L2 l2_; + mutable L3 l3_; + + const EC& ec() const { return *this; } + +public: + + void + update_exact() const + { + this->et = new ET(ec()(CGAL::exact(l1_), CGAL::exact(l2_), + CGAL::exact(l3_))); + this->at = E2A()(*(this->et)); + // Prune lazy tree + l1_ = L1(); + l2_ = L2(); + l3_ = L3(); + } + + Lazy_rep_3(const AC& ac, const EC& /*ec*/, + const L1& l1, const L2& l2, const L3& l3) + : Lazy_rep(ac(CGAL::approx(l1), CGAL::approx(l2), + CGAL::approx(l3))), + l1_(l1), l2_(l2), l3_(l3) + { + this->set_depth(max_n(CGAL::depth(l1_), + CGAL::depth(l2_), + CGAL::depth(l3_)) + 1); + } + +#ifdef CGAL_LAZY_KERNEL_DEBUG + void + print_dag(std::ostream& os, int level) const + { + this->print_at_et(os, level); + if(this->is_lazy()){ + CGAL::msg(os, level, "DAG with three child nodes:"); + CGAL::print_dag(l1_, os, level+1); + CGAL::print_dag(l2_, os, level+1); + CGAL::print_dag(l3_, os, level+1); + } + } +#endif +}; + + +//____________________________________________________________ + +template +class Lazy_rep_4 + : public Lazy_rep + , private EC +{ + typedef typename AC::result_type AT; + typedef typename EC::result_type ET; + typedef Lazy_rep Base; + + mutable L1 l1_; + mutable L2 l2_; + mutable L3 l3_; + mutable L4 l4_; + + const EC& ec() const { return *this; } + +public: + + void + update_exact() const + { + this->et = new ET(ec()(CGAL::exact(l1_), CGAL::exact(l2_), + CGAL::exact(l3_), CGAL::exact(l4_))); + this->at = E2A()(*(this->et)); + // Prune lazy tree + l1_ = L1(); + l2_ = L2(); + l3_ = L3(); + l4_ = L4(); + } + + Lazy_rep_4(const AC& ac, const EC& /*ec*/, + const L1& l1, const L2& l2, const L3& l3, const L4& l4) + : Lazy_rep(ac(CGAL::approx(l1), CGAL::approx(l2), + CGAL::approx(l3), CGAL::approx(l4))), + l1_(l1), l2_(l2), l3_(l3), l4_(l4) + { + this->set_depth(max_n(CGAL::depth(l1_), + CGAL::depth(l2_), + CGAL::depth(l3_), + CGAL::depth(l4_)) + 1); + } + +#ifdef CGAL_LAZY_KERNEL_DEBUG + void + print_dag(std::ostream& os, int level) const + { + this->print_at_et(os, level); + + if(this->is_lazy()){ + CGAL::msg(os, level, "DAG with four child nodes:"); + CGAL::print_dag(l1_, os, level+1); + CGAL::print_dag(l2_, os, level+1); + CGAL::print_dag(l3_, os, level+1); + CGAL::print_dag(l4_, os, level+1); + } + } +#endif +}; + +//____________________________________________________________ + + +template +class Lazy_rep_5 + : public Lazy_rep + , private EC +{ + typedef typename AC::result_type AT; + typedef typename EC::result_type ET; + typedef Lazy_rep Base; + + mutable L1 l1_; + mutable L2 l2_; + mutable L3 l3_; + mutable L4 l4_; + mutable L5 l5_; + + const EC& ec() const { return *this; } + +public: + + void + update_exact() const + { + this->et = new ET(ec()(CGAL::exact(l1_), CGAL::exact(l2_), + CGAL::exact(l3_), CGAL::exact(l4_), + CGAL::exact(l5_))); + this->at = E2A()(*(this->et)); + // Prune lazy tree + l1_ = L1(); + l2_ = L2(); + l3_ = L3(); + l4_ = L4(); + l5_ = L5(); + } + + Lazy_rep_5(const AC& ac, const EC& /*ec*/, + const L1& l1, const L2& l2, const L3& l3, const L4& l4, + const L5& l5) + : Lazy_rep(ac(CGAL::approx(l1), CGAL::approx(l2), + CGAL::approx(l3), CGAL::approx(l4), + CGAL::approx(l5))), + l1_(l1), l2_(l2), l3_(l3), l4_(l4), l5_(l5) + { + this->set_depth(max_n(CGAL::depth(l1_), + CGAL::depth(l2_), + CGAL::depth(l3_), + CGAL::depth(l4_), + CGAL::depth(l5_)) + 1); + } + +#ifdef CGAL_LAZY_KERNEL_DEBUG + void + print_dag(std::ostream& os, int level) const + { + this->print_at_et(os, level); + + if(this->is_lazy()){ + CGAL::msg(os, level, "DAG with five child nodes:"); + CGAL::print_dag(l1_, os, level+1); + CGAL::print_dag(l2_, os, level+1); + CGAL::print_dag(l3_, os, level+1); + CGAL::print_dag(l4_, os, level+1); + CGAL::print_dag(l5_, os, level+1); + } + } +#endif +}; + +template +class Lazy_rep_6 + : public Lazy_rep + , private EC +{ + typedef typename AC::result_type AT; + typedef typename EC::result_type ET; + typedef Lazy_rep Base; + + mutable L1 l1_; + mutable L2 l2_; + mutable L3 l3_; + mutable L4 l4_; + mutable L5 l5_; + mutable L6 l6_; + + const EC& ec() const { return *this; } + +public: + + void + update_exact() const + { + this->et = new ET(ec()(CGAL::exact(l1_), CGAL::exact(l2_), + CGAL::exact(l3_), CGAL::exact(l4_), + CGAL::exact(l5_), CGAL::exact(l6_))); + this->at = E2A()(*(this->et)); + // Prune lazy tree + l1_ = L1(); + l2_ = L2(); + l3_ = L3(); + l4_ = L4(); + l5_ = L5(); + l6_ = L6(); + } + + Lazy_rep_6(const AC& ac, const EC& /*ec*/, + const L1& l1, const L2& l2, const L3& l3, const L4& l4, + const L5& l5, const L6& l6) + : Lazy_rep(ac(CGAL::approx(l1), CGAL::approx(l2), + CGAL::approx(l3), CGAL::approx(l4), + CGAL::approx(l5), CGAL::approx(l6))), + l1_(l1), l2_(l2), l3_(l3), l4_(l4), l5_(l5), l6_(l6) + { + this->set_depth(max_n(CGAL::depth(l1_), + CGAL::depth(l2_), + CGAL::depth(l3_), + CGAL::depth(l4_), + CGAL::depth(l5_), + CGAL::depth(l6_)) + 1); + } + +#ifdef CGAL_LAZY_KERNEL_DEBUG + void + print_dag(std::ostream& os, int level) const + { + this->print_at_et(os, level); + + if(this->is_lazy()){ + CGAL::msg(os, level, "DAG with 6 child nodes:"); + CGAL::print_dag(l1_, os, level+1); + CGAL::print_dag(l2_, os, level+1); + CGAL::print_dag(l3_, os, level+1); + CGAL::print_dag(l4_, os, level+1); + CGAL::print_dag(l5_, os, level+1); + CGAL::print_dag(l6_, os, level+1); + } + } +#endif +}; + +template +class Lazy_rep_7 + : public Lazy_rep + , private EC +{ + typedef typename AC::result_type AT; + typedef typename EC::result_type ET; + typedef Lazy_rep Base; + + mutable L1 l1_; + mutable L2 l2_; + mutable L3 l3_; + mutable L4 l4_; + mutable L5 l5_; + mutable L6 l6_; + mutable L7 l7_; + + const EC& ec() const { return *this; } + +public: + + void + update_exact() const + { + this->et = new ET(ec()(CGAL::exact(l1_), CGAL::exact(l2_), + CGAL::exact(l3_), CGAL::exact(l4_), + CGAL::exact(l5_), CGAL::exact(l6_), + CGAL::exact(l7_))); + this->at = E2A()(*(this->et)); + // Prune lazy tree + l1_ = L1(); + l2_ = L2(); + l3_ = L3(); + l4_ = L4(); + l5_ = L5(); + l6_ = L6(); + l7_ = L7(); + } + + Lazy_rep_7(const AC& ac, const EC& /*ec*/, + const L1& l1, const L2& l2, const L3& l3, const L4& l4, + const L5& l5, const L6& l6, const L7& l7) + : Lazy_rep(ac(CGAL::approx(l1), CGAL::approx(l2), + CGAL::approx(l3), CGAL::approx(l4), + CGAL::approx(l5), CGAL::approx(l6), + CGAL::approx(l7))), + l1_(l1), l2_(l2), l3_(l3), l4_(l4), l5_(l5), l6_(l6), l7_(l7) + { + this->set_depth(max_n(CGAL::depth(l1_), + CGAL::depth(l2_), + CGAL::depth(l3_), + CGAL::depth(l4_), + CGAL::depth(l5_), + CGAL::depth(l6_), + CGAL::depth(l7_)) + 1); + } + +#ifdef CGAL_LAZY_KERNEL_DEBUG + void + print_dag(std::ostream& os, int level) const + { + this->print_at_et(os, level); + + if(this->is_lazy()){ + CGAL::msg(os, level, "DAG with 7 child nodes:"); + CGAL::print_dag(l1_, os, level+1); + CGAL::print_dag(l2_, os, level+1); + CGAL::print_dag(l3_, os, level+1); + CGAL::print_dag(l4_, os, level+1); + CGAL::print_dag(l5_, os, level+1); + CGAL::print_dag(l6_, os, level+1); + CGAL::print_dag(l7_, os, level+1); + } + } +#endif +}; + +template +class Lazy_rep_8 + : public Lazy_rep + , private EC +{ + typedef typename AC::result_type AT; + typedef typename EC::result_type ET; + typedef Lazy_rep Base; + + mutable L1 l1_; + mutable L2 l2_; + mutable L3 l3_; + mutable L4 l4_; + mutable L5 l5_; + mutable L6 l6_; + mutable L7 l7_; + mutable L8 l8_; + + const EC& ec() const { return *this; } + +public: + + void + update_exact() const + { + this->et = new ET(ec()(CGAL::exact(l1_), CGAL::exact(l2_), + CGAL::exact(l3_), CGAL::exact(l4_), + CGAL::exact(l5_), CGAL::exact(l6_), + CGAL::exact(l7_), CGAL::exact(l8_))); + this->at = E2A()(*(this->et)); + // Prune lazy tree + l1_ = L1(); + l2_ = L2(); + l3_ = L3(); + l4_ = L4(); + l5_ = L5(); + l6_ = L6(); + l7_ = L7(); + l8_ = L8(); + } + + Lazy_rep_8(const AC& ac, const EC& /*ec*/, + const L1& l1, const L2& l2, const L3& l3, const L4& l4, + const L5& l5, const L6& l6, const L7& l7, const L8& l8) + : Lazy_rep(ac(CGAL::approx(l1), CGAL::approx(l2), + CGAL::approx(l3), CGAL::approx(l4), + CGAL::approx(l5), CGAL::approx(l6), + CGAL::approx(l7), CGAL::approx(l8))), + l1_(l1), l2_(l2), l3_(l3), l4_(l4), l5_(l5), l6_(l6), l7_(l7), l8_(l8) + { + this->set_depth(max_n(CGAL::depth(l1_), + CGAL::depth(l2_), + CGAL::depth(l3_), + CGAL::depth(l4_), + CGAL::depth(l5_), + CGAL::depth(l6_), + CGAL::depth(l7_), + CGAL::depth(l8_)) + 1); + } + +#ifdef CGAL_LAZY_KERNEL_DEBUG + void + print_dag(std::ostream& os, int level) const + { + this->print_at_et(os, level); + + if(this->is_lazy()){ + CGAL::msg(os, level, "DAG with 8 child nodes:"); + CGAL::print_dag(l1_, os, level+1); + CGAL::print_dag(l2_, os, level+1); + CGAL::print_dag(l3_, os, level+1); + CGAL::print_dag(l4_, os, level+1); + CGAL::print_dag(l5_, os, level+1); + CGAL::print_dag(l6_, os, level+1); + CGAL::print_dag(l7_, os, level+1); + CGAL::print_dag(l8_, os, level+1); + } + } +#endif +}; + + +template < typename K1, typename K2 > +struct Approx_converter +{ + typedef Approx_converter Self; + typedef K1 Source_kernel; + typedef K2 Target_kernel; + //typedef Converter Number_type_converter; + Approx_converter(){} + Approx_converter(K1 const&,K2 const&){} + //TODO: check that it is normal that we never need k1 or k2 here + + template struct result_; + template struct result_ { + typedef typename T::AT const& type; + }; + template struct result_ { + typedef transforming_iterator type; + }; + + template struct result; + template struct result : result_::value,is_iterator::value>{}; + template struct result{typedef Null_vector type;}; + template struct result{typedef Bbox_2 type;}; + template struct result{typedef Bbox_3 type;}; + + template < typename T > + const typename T::AT& + operator()(const T&t) const + { return t.approx(); } + + template + transforming_iterator,It>::type> + operator()(const It& i) const + { + return make_transforming_iterator(i,*this); + } + + const Null_vector& + operator()(const Null_vector& n) const + { return n; } + + const Bbox_2& + operator()(const Bbox_2& b) const + { return b; } + + const Bbox_3& + operator()(const Bbox_3& b) const + { return b; } +}; + +template < typename K1, typename K2 > +struct Exact_converter +{ + typedef Exact_converter Self; + typedef K1 Source_kernel; + typedef K2 Target_kernel; + //typedef Converter Number_type_converter; + Exact_converter(){} + Exact_converter(K1 const&,K2 const&){} + //TODO: check that it is normal that we never need k1 or k2 here + + template struct result_; + template struct result_ { + typedef typename T::ET const& type; + }; + template struct result_ { + typedef transforming_iterator type; + }; + + template struct result; + template struct result : result_::value,is_iterator::value>{}; + template struct result{typedef Null_vector type;}; + template struct result{typedef Bbox_2 type;}; + template struct result{typedef Bbox_3 type;}; + + template < typename T > + const typename T::ET& + operator()(const T&t) const + { return t.exact(); } + + template + transforming_iterator,It>::type> + operator()(const It& i) const + { + return make_transforming_iterator(i,*this); + } + + const Null_vector& + operator()(const Null_vector& n) const + { return n; } + + const Bbox_2& + operator()(const Bbox_2& b) const + { return b; } + + const Bbox_3& + operator()(const Bbox_3& b) const + { return b; } +}; + +//____________________________________________________________ + + + +template +class Lazy_rep_with_vector_1 + : public Lazy_rep, std::vector, E2A> + , private EC +{ + typedef std::vector AT; + typedef std::vector ET; + typedef Lazy_rep Base; + + mutable L1 l1_; + + const EC& ec() const { return *this; } + +public: + + void + update_exact() const + { +// TODO : This looks really unfinished... + std::vector vec; + this->et = new ET(); + //this->et->reserve(this->at.size()); + ec()(CGAL::exact(l1_), std::back_inserter(*(this->et))); + if(this->et==NULL) + E2A()(*(this->et)); + this->at = E2A()(*(this->et)); + // Prune lazy tree + l1_ = L1(); + } + + Lazy_rep_with_vector_1(const AC& ac, const EC& /*ec*/, const L1& l1) + : l1_(l1) + { + ac(CGAL::approx(l1), std::back_inserter(this->at)); + } + +#ifdef CGAL_LAZY_KERNEL_DEBUG + void + print_dag(std::ostream& os, int level) const + { + this->print_at_et(os, level); + os << "A Lazy_rep_with_vector_1 of size " << this->at.size() << std::endl; + if(this->is_lazy()){ + CGAL::msg(os, level, "DAG with one child node:"); + CGAL::print_dag(l1_, os, level+1); + + } + } +#endif +}; + + +template +class Lazy_rep_with_vector_2 + : public Lazy_rep, std::vector, E2A> + , private EC +{ + typedef std::vector AT; + typedef std::vector ET; + typedef Lazy_rep Base; + + mutable L1 l1_; + mutable L2 l2_; + + const EC& ec() const { return *this; } + +public: + + void + update_exact() const + { + this->et = new ET(); + this->et->reserve(this->at.size()); + ec()(CGAL::exact(l1_), CGAL::exact(l2_), std::back_inserter(*(this->et))); + this->at = E2A()(*(this->et)); + // Prune lazy tree + l1_ = L1(); + l2_ = L2(); + } + + Lazy_rep_with_vector_2(const AC& ac, const EC& /*ec*/, const L1& l1, const L2& l2) + : l1_(l1), l2_(l2) + { + ac(CGAL::approx(l1), CGAL::approx(l2), std::back_inserter(this->at)); + } + +#ifdef CGAL_LAZY_KERNEL_DEBUG + void + print_dag(std::ostream& os, int level) const + { + this->print_at_et(os, level); + os << "A Lazy_rep_with_vector_2 of size " << this->at.size() << std::endl; + if(this->is_lazy()){ + CGAL::msg(os, level, "DAG with two child nodes:"); + CGAL::print_dag(l1_, os, level+1); + CGAL::print_dag(l2_, os, level+1); + } + } +#endif +}; + + +template +class Lazy_rep_2_1 + : public Lazy_rep + , private EC +{ + typedef typename R1::AT AT; + typedef typename R1::ET ET; + typedef Lazy_rep Base; + + mutable L1 l1_; + mutable L2 l2_; + + const EC& ec() const { return *this; } + +public: + + void + update_exact() const + { + this->et = new ET(); + ec()(CGAL::exact(l1_), CGAL::exact(l2_), *(this->et)); + this->at = E2A()(*(this->et)); + // Prune lazy tree + l1_ = L1(); + l2_ = L2(); + } + + Lazy_rep_2_1(const AC& ac, const EC& /*ec*/, const L1& l1, const L2& l2) + : Lazy_rep(), l1_(l1), l2_(l2) + { + ac(CGAL::approx(l1), CGAL::approx(l2), this->at); + } + +#ifdef CGAL_LAZY_KERNEL_DEBUG + void + print_dag(std::ostream& os, int level) const + { + this->print_at_et(os, level); + os << "A Lazy_rep_2_1" << std::endl; + if(this->is_lazy()){ + CGAL::msg(os, level, "DAG with two child nodes:"); + CGAL::print_dag(l1_, os, level+1); + CGAL::print_dag(l2_, os, level+1); + } + } +#endif +}; + + +//____________________________________________________________________________________ +// The following rep class stores two non-const reference parameters of type R1 and R2 + +template +class Lazy_rep_2_2 + : public Lazy_rep, std::pair, E2A> + , private EC +{ + typedef std::pair AT; + typedef std::pair ET; + typedef Lazy_rep Base; + + mutable L1 l1_; + mutable L2 l2_; + + const EC& ec() const { return *this; } + +public: + + void + update_exact() const + { + this->et = new ET(); + ec()(CGAL::exact(l1_), CGAL::exact(l2_), this->et->first, this->et->second ); + this->at = E2A()(*(this->et)); + // Prune lazy tree + l1_ = L1(); + l2_ = L2(); + } + + Lazy_rep_2_2(const AC& ac, const EC& /*ec*/, const L1& l1, const L2& l2) + : Lazy_rep(), l1_(l1), l2_(l2) + { + ac(CGAL::approx(l1), CGAL::approx(l2), this->at.first, this->at.second); + } + +#ifdef CGAL_LAZY_KERNEL_DEBUG + void + print_dag(std::ostream& os, int level) const + { + this->print_at_et(os, level); + os << "A Lazy_rep_2_2" << std::endl; + if(this->is_lazy()){ + CGAL::msg(os, level, "DAG with two child nodes:"); + CGAL::print_dag(l1_, os, level+1); + CGAL::print_dag(l2_, os, level+1); + } + } +#endif +}; + + +//____________________________________________________________ +// The handle class +template +class Lazy : public Handle +{ +public : + + typedef Lazy Self; + typedef Lazy_rep Self_rep; + + typedef AT_ AT; // undocumented + typedef ET_ ET; // undocumented + + typedef AT Approximate_type; + typedef ET Exact_type; + +/* + typedef Self Rep; + + const Rep& rep() const + { + return *this; + } + + Rep& rep() + { + return *this; + } +*/ + + Lazy() + : Handle(zero()) {} + + // Before Lazy::zero() used Boost.Thread, the definition of Lazy() was: + // Lazy() + // #ifndef CGAL_HAS_THREAD + // : Handle(zero()) {} + // #else + // { + // PTR = new Lazy_rep_0(); + // } + // #endif + + Lazy(Self_rep *r) + { + PTR = r; + } + + Lazy(const ET& e) + { + PTR = new Lazy_rep_0(e); + } + + const AT& approx() const + { return ptr()->approx(); } + + const ET& exact() const + { return ptr()->exact(); } + + AT& approx() + { return ptr()->approx(); } + + ET& exact() + { return ptr()->exact(); } + + unsigned depth() const + { + return ptr()->depth(); + } + + void print_dag(std::ostream& os, int level) const + { + ptr()->print_dag(os, level); + } + +private: + + // We have a static variable for optimizing the default constructor, + // which is in particular heavily used for pruning DAGs. + static const Self & zero() + { +#ifdef CGAL_HAS_THREADS + static boost::thread_specific_ptr z; + if (z.get() == NULL) { + z.reset(new Self(new Lazy_rep_0())); + } + return * z.get(); +#else + static const Self z = new Lazy_rep_0(); + return z; +#endif + } + + Self_rep * ptr() const { return (Self_rep*) PTR; } +}; + + + + + +// The magic functor for Construct_bbox_[2,3], as there is no Lazy + +template +struct Lazy_construction_bbox +{ + static const bool Protection = true; + typedef typename LK::Approximate_kernel AK; + typedef typename LK::Exact_kernel EK; + typedef typename AC::result_type result_type; + + AC ac; + EC ec; + + template + result_type operator()(const L1& l1) 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 P; + try { + return ac(CGAL::approx(l1)); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return ec(CGAL::exact(l1)); + } + } +}; + +template +struct Lazy_construction_nt { + + static const bool Protection = true; + + typedef typename LK::Approximate_kernel AK; + typedef typename LK::Exact_kernel EK; + typedef typename LK::E2A E2A; + typedef typename decay::type AT; + typedef typename decay::type ET; + typedef Lazy_exact_nt result_type; + + AC ac; + EC ec; + Lazy_construction_nt(){} + Lazy_construction_nt(LK const&k):ac(k.approximate_kernel()),ec(k.exact_kernel()){} + + template + result_type operator()(const L1& l1) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + return new Lazy_rep_1, L1>(ac, ec, l1); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return new Lazy_rep_0 >(ec(CGAL::exact(l1))); + } + } + + template + result_type operator()(const L1& l1, const L2& l2) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + return new Lazy_rep_2, L1,L2>(ac, ec, l1,l2); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return new Lazy_rep_0 >(ec(CGAL::exact(l1), CGAL::exact(l2))); + } + } + + template + result_type operator()(const L1& l1, const L2& l2, const L3& l3) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + return new Lazy_rep_3, L1,L2,L3>(ac, ec, l1,l2,l3); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return new Lazy_rep_0 >(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3))); + } + } + + template + result_type operator()(const L1& l1, const L2& l2, const L3& l3, const L4& l4) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + return new Lazy_rep_4, L1,L2,L3,L4>(ac, ec, l1,l2,l3,l4); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return new Lazy_rep_0 >(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3), CGAL::exact(l4))); + } + } + + template + result_type operator()(const L1& l1, const L2& l2, const L3& l3, const L4& l4, const L5& l5) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + return new Lazy_rep_5, L1,L2,L3,L4,L5>(ac, ec, l1,l2,l3,l4,l5); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return new Lazy_rep_0 >(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3), CGAL::exact(l4), CGAL::exact(l5))); + } + } +}; + + +template +Object +make_lazy(const Object& eto) +{ + typedef typename LK::Approximate_kernel AK; + typedef typename LK::Exact_kernel EK; + typedef typename LK::E2A E2A; + + if (eto.is_empty()) + return Object(); + +#define CGAL_Kernel_obj(X) \ + if (const typename EK::X* ptr = object_cast(&eto)) \ + return make_object(typename LK::X(new Lazy_rep_0(*ptr))); + +#include + + std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#2)" << std::endl; + std::cerr << "dynamic type of the Object : " << eto.type().name() << std::endl; + + return Object(); +} + + +// This functor selects the i'th element in a vector of Object's +// and casts it to what is in the Object + +template +struct Ith { + typedef T2 result_type; + + // We keep a Sign member object + // for future utilisation, in case + // we have pairs of 2 T2 objects e.g. + // for a numeric_point vector returned + // from a construction of a possible + // lazy algebraic kernel + + int i; + Sign sgn; + + Ith(int i_) + : i(i_) + {sgn=NEGATIVE;} + + Ith(int i_, bool b_) + : i(i_) + { sgn= (b_) ? POSITIVE : ZERO;} + + const T2& + operator()(const std::vector& v) const + { + if(sgn==NEGATIVE) + return *object_cast(&v[i]); + + typedef std::pair Pair_type_1; + typedef std::pair > Pair_type_2; + + if(const Pair_type_1 *p1 = object_cast(&v[i])) + return p1->first; + else if(const Pair_type_2 *p2 = object_cast(&v[i])) + return p2->first; + + CGAL_error_msg( " Unexpected encapsulated type "); + } +}; + + +template +struct Lazy_cartesian_const_iterator_2 +{ + typedef typename LK::Approximate_kernel AK; + typedef typename LK::Exact_kernel EK; + typedef typename LK::Cartesian_const_iterator_2 result_type; + + AC ac; + EC ec; + +public: + + template < typename L1> + result_type + operator()(const L1& l1) const + { + return result_type(&l1); + } + + template < typename L1> + result_type + operator()(const L1& l1, int i) const + { + return result_type(&l1,i); + } + +}; + + +template +struct Lazy_cartesian_const_iterator_3 +{ + typedef typename LK::Approximate_kernel AK; + typedef typename LK::Exact_kernel EK; + typedef typename LK::Cartesian_const_iterator_3 result_type; + + AC ac; + EC ec; + +public: + + template < typename L1> + result_type + operator()(const L1& l1) const + { + return result_type(&l1); + } + + template < typename L1> + result_type + operator()(const L1& l1, int i) const + { + return result_type(&l1,i); + } + +}; + + +// This is the magic functor for functors that write their result in a reference argument +// In a first version we assume that the references are of type Lazy, +// and that the result type is void + +template +struct Lazy_functor_2_1 +{ + static const bool Protection = true; + typedef void result_type; + + AC ac; + EC ec; + +public: + + template + void + operator()(const L1& l1, const L2& l2, R1& r1) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + // we suppose that R1 is a Lazy + r1 = R1(new Lazy_rep_2_1(ac, ec, l1, l2)); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + typename R1::ET et; + ec(CGAL::exact(l1), CGAL::exact(l2), et); + r1 = R1(new Lazy_rep_0(et)); + } + } +}; + + +template +struct First +{ + typedef typename T::first_type result_type; + + const typename T::first_type& + operator()(const T& p) const + { + return p.first; + } + }; + +template +struct Second +{ + typedef typename T::second_type result_type; + + const typename T::second_type& + operator()(const T& p) const + { + return p.second; + } +}; + +// This is the magic functor for functors that write their result in a reference argument +// In a first version we assume that the references are of type Lazy, +// and that the result type is void + +//template +template +struct Lazy_functor_2_2 +{ + static const bool Protection = true; + + typedef void result_type; + typedef typename LK::Approximate_kernel AK; + typedef typename LK::Exact_kernel EK; + typedef typename Get_type::type EFT; + typedef typename LK::E2A E2A; + + AC ac; + EC ec; + +public: + + template + void + operator()(const L1& l1, const L2& l2, R1& r1, R2& r2) const + { + typedef Lazy Handle_1; + typedef Lazy Handle_2; + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + typedef Lazy, std::pair, EFT, E2A> Lazy_pair; + Lazy_pair lv(new Lazy_rep_2_2(ac, ec, l1, l2)); + // lv->approx() is a std::pair; + r1 = R1(Handle_1(new Lazy_rep_1 >, First >, E2A, Lazy_pair>(First >(), First >(), lv))); + r2 = R2(Handle_2(new Lazy_rep_1 >, Second >, E2A, Lazy_pair>(Second >(), Second >(), lv))); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + typename R1::ET et1, et2; + ec(CGAL::exact(l1), CGAL::exact(l2), et1, et2); + r1 = R1(Handle_1(new Lazy_rep_0(et1))); + r2 = R2(Handle_2(new Lazy_rep_0(et2))); + } + } +}; + + +// This is the magic functor for functors that write their result as Objects into an output iterator + +template +struct Lazy_intersect_with_iterators +{ + static const bool Protection = true; + typedef typename LK::Approximate_kernel AK; + typedef typename LK::Exact_kernel EK; + typedef typename Get_type::type EFT; + typedef typename LK::E2A E2A; + typedef void result_type; + typedef Lazy Lazy_object; + typedef Lazy, std::vector, EFT, E2A> Lazy_vector; + + AC ac; + EC ec; + +public: + + // In the example we intersect two Lazys + // and write into a back_inserter(list,Lazy]) >) + template + OutputIterator + operator()(const L1& l1, const L2& l2, OutputIterator it) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + Lazy_vector lv(new Lazy_rep_with_vector_2(ac, ec, l1, l2)); + // lv.approx() is a std::vector + // that is, when we get here we have constructed all approximate results + for (unsigned int i = 0; i < lv.approx().size(); i++) { +// FIXME : I'm not sure how this work... +#define CGAL_Kernel_obj(X) if (object_cast(& (lv.approx()[i]))) { \ + *it++ = make_object(typename LK::X(new Lazy_rep_1, \ + Ith, E2A, Lazy_vector> \ + (Ith(i), Ith(i), lv))); \ + continue; \ + } + +#include + + std::cerr << "we need more casts" << std::endl; + } + + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + // TODO: Instead of using a vector, write an iterator adapter + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + std::vector exact_objects; + ec(CGAL::exact(l1), CGAL::exact(l2), std::back_inserter(exact_objects)); + for (std::vector::const_iterator oit = exact_objects.begin(); + oit != exact_objects.end(); + ++oit){ + *it++ = make_lazy(*oit); + } + } + return it; + } +}; + + +template +struct Object_cast +{ + typedef T result_type; + + const T& + operator()(const Object& o) const + { + return *object_cast(&o); + } +}; + +// The following functor returns an Object with a Lazy inside +// As the nested kernels return Objects of AK::Something and EK::Something +// we have to unwrap them from the Object, and wrap them in a Lazy +// +// TODO: write operators for other than two arguments. For the current kernel we only need two for Intersect_2 + +template +struct Lazy_construction_object +{ + static const bool Protection = true; + + typedef typename LK::Approximate_kernel AK; + typedef typename LK::Exact_kernel EK; + typedef typename Get_type::type EFT; + typedef typename LK::E2A E2A; + typedef typename AC::result_type AT; + typedef typename EC::result_type ET; + typedef Object result_type; + + typedef Lazy Lazy_object; + + AC ac; + EC ec; + +public: + + template + result_type + operator()(const L1& l1) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + Lazy_object lo(new Lazy_rep_1(ac, ec, l1)); + + if(lo.approx().is_empty()) + return Object(); + +#define CGAL_Kernel_obj(X) \ + if (object_cast(& (lo.approx()))) { \ + typedef Lazy_rep_1, Object_cast, E2A, Lazy_object> Lcr; \ + Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); \ + return make_object(typename LK::X(lcr)); \ + } + +#include + + std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl; + std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl; + + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + ET eto = ec(CGAL::exact(l1)); + return make_lazy(eto); + } + return Object(); + } + + template + result_type + operator()(const L1& l1, const L2& l2) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + Lazy_object lo(new Lazy_rep_2(ac, ec, l1, l2)); + + if(lo.approx().is_empty()) + return Object(); + +#define CGAL_Kernel_obj(X) \ + if (object_cast(& (lo.approx()))) { \ + typedef Lazy_rep_1, Object_cast, E2A, Lazy_object> Lcr; \ + Lcr * lcr = new Lcr(Object_cast(), Object_cast(), lo); \ + return make_object(typename LK::X(lcr)); \ + } + +#include + + std::cerr << "object_cast inside Lazy_construction_rep::operator() failed. It needs more else if's (#1)" << std::endl; + std::cerr << "dynamic type of the Object : " << lo.approx().type().name() << std::endl; + + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + ET eto = ec(CGAL::exact(l1), CGAL::exact(l2)); + return make_lazy(eto); + } + return Object(); + } + +}; + + + +//____________________________________________________________ +// The magic functor that has Lazy as result type + +template +struct Lazy_construction +{ + static const bool Protection = true; + + typedef typename LK::Approximate_kernel AK; + typedef typename LK::Exact_kernel EK; + typedef typename Get_type::type EFT; + typedef typename Default::Get::type E2A; + typedef typename decay::type AT; + typedef typename decay::type ET; + typedef Lazy Handle; + //typedef typename Type_mapper::type result_type; + typedef Handle result_type; + + AC ac; + EC ec; + Lazy_construction(){} + Lazy_construction(LK const&k):ac(k.approximate_kernel()),ec(k.exact_kernel()){} + +public: + + result_type + operator()() const + { + return result_type( Handle(new Lazy_rep_0()) ); + } + + template + result_type + operator()(const L1& l1) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + return result_type( Handle(new Lazy_rep_1(ac, ec, l1)) ); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return result_type( Handle(new Lazy_rep_0(ec(CGAL::exact(l1)))) ); + } + } + + template + result_type + operator()(const L1& l1, const L2& l2) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + return result_type( Handle(new Lazy_rep_2(ac, ec, l1, l2)) ); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return result_type( Handle(new Lazy_rep_0(ec(CGAL::exact(l1), CGAL::exact(l2)))) ); + } + } + + template + result_type + operator()(const L1& l1, const L2& l2, const L3& l3) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + return result_type( Handle(new Lazy_rep_3(ac, ec, l1, l2, l3)) ); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return result_type( Handle(new Lazy_rep_0(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3)))) ); + } + } + + template + result_type + operator()(const L1& l1, const L2& l2, const L3& l3, const L4& l4) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + return result_type( Handle(new Lazy_rep_4(ac, ec, l1, l2, l3, l4)) ); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return result_type( Handle(new Lazy_rep_0(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3), CGAL::exact(l4)))) ); + } + } + + template + result_type + operator()(const L1& l1, const L2& l2, const L3& l3, const L4& l4, const L5& l5) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + return result_type( Handle(new Lazy_rep_5(ac, ec, l1, l2, l3, l4, l5)) ); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return result_type( Handle(new Lazy_rep_0(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3), CGAL::exact(l4), CGAL::exact(l5)))) ); + } + } + + template + result_type + operator()(const L1& l1, const L2& l2, const L3& l3, const L4& l4, const L5& l5, const L6& l6) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + return result_type( Handle(new Lazy_rep_6(ac, ec, l1, l2, l3, l4, l5, l6)) ); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return result_type( Handle(new Lazy_rep_0(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3), CGAL::exact(l4), CGAL::exact(l5), CGAL::exact(l6)))) ); + } + } + + template + result_type + operator()(const L1& l1, const L2& l2, const L3& l3, const L4& l4, const L5& l5, const L6& l6, const L7& l7) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + return result_type( Handle(new Lazy_rep_7(ac, ec, l1, l2, l3, l4, l5, l6, l7)) ); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return result_type( Handle(new Lazy_rep_0(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3), CGAL::exact(l4), CGAL::exact(l5), CGAL::exact(l6), CGAL::exact(l7)))) ); + } + } + + template + result_type + operator()(const L1& l1, const L2& l2, const L3& l3, const L4& l4, const L5& l5, const L6& l6, const L7& l7, const L8& l8) const + { + CGAL_BRANCH_PROFILER(std::string(" failures/calls to : ") + std::string(CGAL_PRETTY_FUNCTION), tmp); + Protect_FPU_rounding P; + try { + return result_type( Handle(new Lazy_rep_8(ac, ec, l1, l2, l3, l4, l5, l6, l7, l8)) ); + } catch (Uncertain_conversion_exception) { + CGAL_BRANCH_PROFILER_BRANCH(tmp); + Protect_FPU_rounding P2(CGAL_FE_TONEAREST); + return result_type( Handle(new Lazy_rep_0(ec(CGAL::exact(l1), CGAL::exact(l2), CGAL::exact(l3), CGAL::exact(l4), CGAL::exact(l5), CGAL::exact(l6), CGAL::exact(l7), CGAL::exact(l8)))) ); + } + } + +}; + +} //namespace CGAL + +#endif // CGAL_LAZY_H diff --git a/NewKernel_d/include/CGAL/Vector/array.h b/NewKernel_d/include/CGAL/Vector/array.h new file mode 100644 index 00000000000..6f32da9eda6 --- /dev/null +++ b/NewKernel_d/include/CGAL/Vector/array.h @@ -0,0 +1,146 @@ +#ifndef CGAL_VECTOR_ARRAY_H +#define CGAL_VECTOR_ARRAY_H +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + + +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 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 struct Property : boost::false_type {}; + + static const unsigned d_=Max_dim_::value; + CGAL_static_assertion(d_ != (unsigned)UNKNOWN_DIMENSION); + + typedef cpp0x::array 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 + 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 + 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 + 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 + Vector operator()(U&&...u) const { + static_assert(sizeof...(U)<=d_,"too many arguments"); + Vector a={{forward_safe(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 + Vector operator()(H const& h,U&&...u) const { + static_assert(sizeof...(U)<=d_,"too many arguments"); + Vector a={{Rational_traits().make_rational(std::forward(u),h)...}}; + return a; + } +#else + +#define VAR(Z,N,_) Rational_traits().make_rational( t##N , h) +#define CODE(Z,N,_) template 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 diff --git a/NewKernel_d/include/CGAL/Vector/avx4.h b/NewKernel_d/include/CGAL/Vector/avx4.h new file mode 100644 index 00000000000..9f05a449502 --- /dev/null +++ b/NewKernel_d/include/CGAL/Vector/avx4.h @@ -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 + +#include +#include +#include // CGAL::Sign +#include // 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 struct Property : boost::false_type {}; + template struct Property + : boost::true_type {}; + /* MAYBE? + template struct Property + : boost::true_type {}; + */ + template struct Property + : boost::true_type {}; + template struct Property + : boost::true_type {}; + template struct Property + : 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 + 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 + 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 diff --git a/NewKernel_d/include/CGAL/Vector/determinant_of_iterator_to_points_from_iterator_to_vectors.h b/NewKernel_d/include/CGAL/Vector/determinant_of_iterator_to_points_from_iterator_to_vectors.h new file mode 100644 index 00000000000..9bca268abf8 --- /dev/null +++ b/NewKernel_d/include/CGAL/Vector/determinant_of_iterator_to_points_from_iterator_to_vectors.h @@ -0,0 +1,57 @@ +#ifndef CGAL_VECTOR_DET_ITER_PTS_ITER_VEC_H +#define CGAL_VECTOR_DET_ITER_PTS_ITER_VEC_H +#include +#include +#include +#include + +namespace CGAL { + +template ::value, + bool = LA::template Property::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 LA2; + typedef Add_determinant_of_iterator_to_points_from_iterator_to_vectors Other; + }; +}; + +template +struct Add_determinant_of_iterator_to_points_from_iterator_to_vectors + : LA { + using typename LA::NT; + using typename LA::Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef Add_determinant_of_iterator_to_points_from_iterator_to_vectors Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + // TODO: use std::minus, std::bind, etc + template struct Minus_fixed { + T const& a; + Minus_fixed(T const&a_):a(a_){} + T operator()(T const&b)const{return b-a;} + }; + template + static NT determinant_of_iterator_to_points(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Minus_fixed f(a); + return LA::determinant_of_iterator_to_vectors(make_transforming_iterator(first,f),make_transforming_iterator(end,f)); + } + template + static Sign sign_of_determinant_of_iterator_to_points(Iter const&first, Iter const&end){ + Vector const&a=*first; ++first; + Minus_fixed f(a); + return LA::sign_of_determinant_of_iterator_to_vectors(make_transforming_iterator(first,f),make_transforming_iterator(end,f)); + } +}; + +} +#endif diff --git a/NewKernel_d/include/CGAL/Vector/determinant_of_iterator_to_points_from_points.h b/NewKernel_d/include/CGAL/Vector/determinant_of_iterator_to_points_from_points.h new file mode 100644 index 00000000000..39f7dcf6545 --- /dev/null +++ b/NewKernel_d/include/CGAL/Vector/determinant_of_iterator_to_points_from_points.h @@ -0,0 +1,192 @@ +#ifndef CGAL_VECTOR_DET_ITER_PTS_PTS_H +#define CGAL_VECTOR_DET_ITER_PTS_PTS_H +#include +#include + +namespace CGAL { + +template ::value, + bool = LA::template Property::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 LA2; + typedef Add_determinant_of_iterator_to_points_from_points Other; + }; +}; + +//FIXME: Use variadics and boost so it works in any dimension. +template +struct Add_determinant_of_iterator_to_points_from_points +, 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 LA2; + typedef Add_determinant_of_iterator_to_points_from_points Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + 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 + 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 +struct Add_determinant_of_iterator_to_points_from_points +, 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 LA2; + typedef Add_determinant_of_iterator_to_points_from_points Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + 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 + 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 +struct Add_determinant_of_iterator_to_points_from_points +, 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 LA2; + typedef Add_determinant_of_iterator_to_points_from_points Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + 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 + 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 +struct Add_determinant_of_iterator_to_points_from_points +, 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 LA2; + typedef Add_determinant_of_iterator_to_points_from_points Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + 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 + 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 +struct Add_determinant_of_iterator_to_points_from_points +, 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 LA2; + typedef Add_determinant_of_iterator_to_points_from_points Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + 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 + 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 diff --git a/NewKernel_d/include/CGAL/Vector/determinant_of_iterator_to_vectors_from_vectors.h b/NewKernel_d/include/CGAL/Vector/determinant_of_iterator_to_vectors_from_vectors.h new file mode 100644 index 00000000000..3032bcab345 --- /dev/null +++ b/NewKernel_d/include/CGAL/Vector/determinant_of_iterator_to_vectors_from_vectors.h @@ -0,0 +1,182 @@ +#ifndef CGAL_VECTOR_DET_ITER_VEC_VEC_H +#define CGAL_VECTOR_DET_ITER_VEC_VEC_H +#include +#include + +namespace CGAL { + +template ::value, + bool = LA::template Property::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 LA2; + typedef Add_determinant_of_iterator_to_vectors_from_vectors Other; + }; +}; + +//FIXME: Use variadics and boost so it works in any dimension. +template +struct Add_determinant_of_iterator_to_vectors_from_vectors +, 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 LA2; + typedef Add_determinant_of_iterator_to_vectors_from_vectors Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + 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 + 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 +struct Add_determinant_of_iterator_to_vectors_from_vectors +, 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 LA2; + typedef Add_determinant_of_iterator_to_vectors_from_vectors Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + 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 + 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 +struct Add_determinant_of_iterator_to_vectors_from_vectors +, 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 LA2; + typedef Add_determinant_of_iterator_to_vectors_from_vectors Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + 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 + 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 +struct Add_determinant_of_iterator_to_vectors_from_vectors +, 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 LA2; + typedef Add_determinant_of_iterator_to_vectors_from_vectors Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + 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 + 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 +struct Add_determinant_of_iterator_to_vectors_from_vectors +, 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 LA2; + typedef Add_determinant_of_iterator_to_vectors_from_vectors Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + template + 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 + 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 diff --git a/NewKernel_d/include/CGAL/Vector/determinant_of_points_from_vectors.h b/NewKernel_d/include/CGAL/Vector/determinant_of_points_from_vectors.h new file mode 100644 index 00000000000..a9520e17c27 --- /dev/null +++ b/NewKernel_d/include/CGAL/Vector/determinant_of_points_from_vectors.h @@ -0,0 +1,145 @@ +#ifndef CGAL_VECTOR_DETPTS_H +#define CGAL_VECTOR_DETPTS_H +#include +#include + +namespace CGAL { + +template ::value, + bool = LA::template Property::value + && LA::template Property::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 LA2; + typedef Add_determinant_of_points_from_vectors_and_minus Other; + }; +}; + +//FIXME: Use variadics and boost so it works in any dimension. +template +struct Add_determinant_of_points_from_vectors_and_minus +, 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 LA2; + typedef Add_determinant_of_points_from_vectors_and_minus Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + 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 +struct Add_determinant_of_points_from_vectors_and_minus +, 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 LA2; + typedef Add_determinant_of_points_from_vectors_and_minus Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + 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 +struct Add_determinant_of_points_from_vectors_and_minus +, 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 LA2; + typedef Add_determinant_of_points_from_vectors_and_minus Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + 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 +struct Add_determinant_of_points_from_vectors_and_minus +, 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 LA2; + typedef Add_determinant_of_points_from_vectors_and_minus Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + 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 +struct Add_determinant_of_points_from_vectors_and_minus +, 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 LA2; + typedef Add_determinant_of_points_from_vectors_and_minus Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + 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 diff --git a/NewKernel_d/include/CGAL/Vector/determinant_of_vectors_small_dim.h b/NewKernel_d/include/CGAL/Vector/determinant_of_vectors_small_dim.h new file mode 100644 index 00000000000..5f004cf168d --- /dev/null +++ b/NewKernel_d/include/CGAL/Vector/determinant_of_vectors_small_dim.h @@ -0,0 +1,39 @@ +#ifndef CGAL_VECTOR_DETVEC_SMALL_H +#define CGAL_VECTOR_DETVEC_SMALL_H +#include +#include +#include + +#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 + +#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 + +#undef CGAL_CLASS +#undef CGAL_TAG +#undef CGAL_FUNC +#undef CGAL_SIGN_FUNC +#undef CGAL_SHIFT + +#undef CGAL_ALLOWED_INCLUSION + +#endif diff --git a/NewKernel_d/include/CGAL/Vector/determinant_of_vectors_small_dim_internal.h b/NewKernel_d/include/CGAL/Vector/determinant_of_vectors_small_dim_internal.h new file mode 100644 index 00000000000..19d7995dfcb --- /dev/null +++ b/NewKernel_d/include/CGAL/Vector/determinant_of_vectors_small_dim_internal.h @@ -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 ::value> +struct CGAL_CLASS : LA { + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef typename LA::template Rebind_dimension LA2; + typedef CGAL_CLASS Other; + }; +}; + +template +struct CGAL_CLASS +, 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 LA2; + typedef CGAL_CLASS Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + static NT CGAL_FUNC(Vector const&a, Vector const&b){ + return CGAL::determinant_of_vectors(a,b); + } + template + static Sign CGAL_SIGN_FUNC(V1 const&a, V2 const&b){ + return CGAL::sign_of_determinant_of_vectors(a,b); + } +}; + +template +struct CGAL_CLASS +, 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 LA2; + typedef CGAL_CLASS Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + static NT CGAL_FUNC(Vector const&a, Vector const&b, + Vector const&c){ + return CGAL::determinant_of_vectors(a,b,c); + } + static Sign CGAL_SIGN_FUNC(Vector const&a, Vector const&b, + Vector const&c){ + return CGAL::sign_of_determinant_of_vectors(a,b,c); + } +}; + +template +struct CGAL_CLASS +, 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 LA2; + typedef CGAL_CLASS Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + boost::true_type {}; + + static NT CGAL_FUNC(Vector const&a, Vector const&b, + Vector const&c, Vector const&d){ + return CGAL::determinant_of_vectors(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(a,b,c,d); + } +}; + +template +struct CGAL_CLASS +, 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 LA2; + typedef CGAL_CLASS Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + 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(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(a,b,c,d,e); + } +}; + +template +struct CGAL_CLASS +, 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 LA2; + typedef CGAL_CLASS Other; + }; + template struct Property : LA::template Property

{}; + template struct Property : + 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(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(a,b,c,d,e,f); + } +}; + +} diff --git a/NewKernel_d/include/CGAL/Vector/sse2.h b/NewKernel_d/include/CGAL/Vector/sse2.h new file mode 100644 index 00000000000..80cc96f24f7 --- /dev/null +++ b/NewKernel_d/include/CGAL/Vector/sse2.h @@ -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 // FIXME: other platforms call it differently + +#include +#include +#include // CGAL::Sign +#include // 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 struct Property : boost::false_type {}; + template struct Property + : boost::true_type {}; + /* MAYBE? + template struct Property + : boost::true_type {}; + */ + template struct Property + : boost::true_type {}; + template struct Property + : 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 + 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 + 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 diff --git a/NewKernel_d/include/CGAL/Vector/v2int.h b/NewKernel_d/include/CGAL/Vector/v2int.h new file mode 100644 index 00000000000..7a6be6163a8 --- /dev/null +++ b/NewKernel_d/include/CGAL/Vector/v2int.h @@ -0,0 +1,162 @@ +#ifndef CGAL_VECTOR_2INT_H +#define CGAL_VECTOR_2INT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// 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 + 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 struct Property : boost::false_type {}; + //template struct Property + // : boost::true_type {}; + template struct Property + : boost::true_type {}; + //template struct Property + // : boost::true_type {}; + // Advertise somehow that the sign_of_determinant* are exact? + + typedef cpp0x::array 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 + 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 + 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,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(a,b); + } + static CGAL::Sign sign_of_determinant_of_vectors(Vector a, Vector b) { + return CGAL::sign_of_determinant_of_vectors(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(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 diff --git a/NewKernel_d/include/CGAL/Vector/vector.h b/NewKernel_d/include/CGAL/Vector/vector.h new file mode 100644 index 00000000000..9db230b1b7d --- /dev/null +++ b/NewKernel_d/include/CGAL/Vector/vector.h @@ -0,0 +1,148 @@ +#ifndef CGAL_VECTOR_VECTOR_H +#define CGAL_VECTOR_VECTOR_H +#include +#include +#include +#include +#include +#include +#include +namespace CGAL { + +//Derive from a class that doesn't depend on Dim, or still use Dim for checking? +template struct Vector_vector { + typedef NT_ NT; + typedef Dim_ Dimension; + typedef Max_dim_ Max_dimension; + typedef std::vector Vector; + template< class D2, class D3=D2 > + struct Rebind_dimension { + typedef Vector_vector< NT, D2, D3 > Other; + }; + template struct Property : boost::false_type {}; + + struct Construct_vector { + struct Dimension { + Vector operator()(int d) const { + return Vector(d); + } + }; + + struct Iterator { + template + 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 + 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 + 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 + 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 + Vector operator()(U&&...u) const { + //TODO: check the right number of {}, g++ accepts one and two + Vector a={forward_safe(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 + 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().make_rational(x,y) ? + Vector a={Rational_traits().make_rational(std::forward(u),h)...}; + return a; + } +#else + +#define VAR(Z,N,_) a.push_back(Rational_traits().make_rational( t##N ,h)); +#define CODE(Z,N,_) template 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 + diff --git a/NewKernel_d/include/CGAL/argument_swaps.h b/NewKernel_d/include/CGAL/argument_swaps.h new file mode 100644 index 00000000000..66192f0ec9f --- /dev/null +++ b/NewKernel_d/include/CGAL/argument_swaps.h @@ -0,0 +1,69 @@ +#ifndef CGAL_ARGUMENT_SWAPS_H +#define CGAL_ARGUMENT_SWAPS_H + +#include +#include + +#ifndef CGAL_CXX0X +#include +#include +#endif + +namespace CGAL { + +#ifdef CGAL_CXX0X + +namespace internal { + +template struct Apply_to_last_then_rest_; + +template +struct Apply_to_last_then_rest_ { + typedef typename Apply_to_last_then_rest_::result_type result_type; + inline result_type operator()(F&&f,T&&t,U&&...u)const{ + return Apply_to_last_then_rest_()( + std::forward(f), + std::forward(u)..., + std::forward(t)); + } +}; + +template +struct Apply_to_last_then_rest_<0,F,T,U...> { + typedef decltype(std::declval()(std::declval(), std::declval()...)) result_type; + inline result_type operator()(F&&f,T&&t,U&&...u)const{ + return std::forward(f)(std::forward(t), std::forward(u)...); + } +}; + +} // namespace internal + + +struct Apply_to_last_then_rest { + template inline + typename internal::Apply_to_last_then_rest_::result_type + operator()(F&&f,T&&t,U&&...u)const{ + return internal::Apply_to_last_then_rest_()( + std::forward(f), + std::forward(t), + std::forward(u)...); + } +}; + +#else // CGAL_CXX0X + +struct Apply_to_last_then_rest { +#define CODE(Z,N,_) template \ + typename boost::result_of::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 diff --git a/NewKernel_d/include/CGAL/determinant_of_vectors.h b/NewKernel_d/include/CGAL/determinant_of_vectors.h new file mode 100644 index 00000000000..e0af0a62365 --- /dev/null +++ b/NewKernel_d/include/CGAL/determinant_of_vectors.h @@ -0,0 +1,98 @@ +#ifndef CGAL_DETVEC_H +#define CGAL_DETVEC_H +#include +#include + +namespace CGAL { + // TODO: determine whether it is better to pass them by lines or columns. + + template inline + NT determinant_of_vectors(Vector const&a, Vector const&b){ + return determinant(a[0],a[1],b[0],b[1]); + } + template inline + typename Sgn::result_type + sign_of_determinant_of_vectors(Vector const&a, Vector const&b){ + return sign_of_determinant(a[0],a[1],b[0],b[1]); + } + + template + NT determinant_of_vectors(Vector const&a, Vector const&b, + Vector const&c){ + return determinant(a[0],a[1],a[2],b[0],b[1],b[2],c[0],c[1],c[2]); + } + template + typename Sgn::result_type + sign_of_determinant_of_vectors(Vector const&a, Vector const&b, + Vector const&c){ + return sign_of_determinant(a[0],a[1],a[2],b[0],b[1],b[2],c[0],c[1],c[2]); + } + + template + NT determinant_of_vectors(Vector const&a, Vector const&b, + Vector const&c, Vector const&d){ + return determinant( + 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 + typename Sgn::result_type + sign_of_determinant_of_vectors(Vector const&a, Vector const&b, + Vector const&c, Vector const&d){ + return sign_of_determinant( + 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 + NT determinant_of_vectors(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e){ + return determinant( + 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 + typename Sgn::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( + 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 + NT determinant_of_vectors(Vector const&a, Vector const&b, + Vector const&c, Vector const&d, Vector const&e, Vector const&f){ + return determinant( + 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 + typename Sgn::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( + 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 diff --git a/NewKernel_d/include/CGAL/functor_properties.h b/NewKernel_d/include/CGAL/functor_properties.h new file mode 100644 index 00000000000..c849509b07d --- /dev/null +++ b/NewKernel_d/include/CGAL/functor_properties.h @@ -0,0 +1,21 @@ +#ifndef CGAL_EXACTNESS_H +#define CGAL_EXACTNESS_H +#include +#include +namespace CGAL { + +#define CGAL_STRAWBERRY(Is_pretty) \ + namespace internal { \ + BOOST_MPL_HAS_XXX_TRAIT_DEF(Is_pretty) \ + } \ + template::value> \ + struct Is_pretty : boost::false_type {}; \ + template \ + struct Is_pretty : T::Is_pretty {} + +CGAL_STRAWBERRY(Is_exact); +CGAL_STRAWBERRY(Is_fast); +CGAL_STRAWBERRY(Is_stored); +#undef CGAL_STRAWBERRY +} +#endif // CGAL_EXACTNESS_H diff --git a/NewKernel_d/include/CGAL/functor_tags.h b/NewKernel_d/include/CGAL/functor_tags.h new file mode 100644 index 00000000000..5fb34472835 --- /dev/null +++ b/NewKernel_d/include/CGAL/functor_tags.h @@ -0,0 +1,310 @@ +#ifndef CGAL_FUNCTOR_TAGS_H +#define CGAL_FUNCTOR_TAGS_H +#include // for Null_tag +#include +#include +#include +#include +#include +#include +#include +#include +namespace CGAL { + + // Find a better place for this later + + template struct Get_type + : K::template Type {}; + template struct Get_functor + : K::template Functor {}; +#ifdef CGAL_CXX0X + template using Type = typename Get_type::type; + template using Functor = typename Get_functor::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 {}; + + templatestruct Construct_ttag {}; + templatestruct Convert_ttag {}; + + template struct Get_functor_category { typedef Misc_tag type; }; + template struct Typedef_tag_type; + //template struct Read_tag_type {}; + + template + struct Provides_type + : Has_type_different_from, Null_type> {}; + + template + struct Provides_functor + : Has_type_different_from, Null_functor> {}; + + template::type::value> + struct Provides_functors : boost::mpl::and_ < + Provides_functor::type>, + Provides_functors::type> > {}; + template + struct Provides_functors : boost::true_type {}; + + template::type::value> + struct Provides_types : boost::mpl::and_ < + Provides_type::type>, + Provides_types::type> > {}; + template + struct Provides_types : boost::true_type {}; + + namespace internal { BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_Type,template Type,false) } + template::value /* false */> + struct Provides_type_i : boost::false_type {}; + template + struct Provides_type_i + : Has_type_different_from, Null_type> {}; + + namespace internal { BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_Functor,template Functor,false) } + template::value /* false */> + struct Provides_functor_i : boost::false_type {}; + template + struct Provides_functor_i + : Has_type_different_from, Null_functor> {}; + + // TODO: Refine this a bit. + template ::value, + //bool=Provides_functor_i::value, + bool=internal::has_Functor::value> + struct Inherit_functor : K::template Functor {}; + template + struct Inherit_functor {}; + + template ::value> + struct Inherit_type : K::template Type {}; + template + struct Inherit_type {}; + + struct Number_tag {}; + struct Discrete_tag {}; + struct Object_tag {}; + template 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 \ + struct Typedef_tag_type : Base { typedef Obj X; }; \ + template \ + struct Get_type_category { 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 + //struct Provides_tag_type : has_object::has_##X {}; + //template + //struct Read_tag_type { 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::type),(),()); + CGAL_KD_DEFAULT_TYPE(FT_tag,(CGAL::Quotient::type>),(),()); + +#define SMURF2(A,B) CGAL_KD_DEFAULT_TYPE(A##_tag,(typename Same_uncertainty_nt::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 struct is_NT_tag { enum { value = false }; }; + template<> struct is_NT_tag { enum { value = true }; }; + template<> struct is_NT_tag { enum { value = true }; }; + + template struct iterator_tag_traits { + enum { is_iterator = false, has_nth_element = false }; + typedef Null_tag value_tag; + }; + +#define DECL_COMPUTE(X) struct X##_tag {}; \ + templatestruct Get_functor_category{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 { \ + enum { is_iterator = true, has_nth_element = true }; \ + typedef Y##_tag value_tag; \ + typedef Z##_tag nth_element; \ + typedef C##_tag container; \ + }; \ + template \ + struct Typedef_tag_type : Base { typedef Obj X; } + + //namespace has_object { BOOST_MPL_HAS_XXX_TRAIT_DEF(X) } + //template + //struct Provides_tag_type : has_object::has_##X {}; + //template + //struct Read_tag_type { 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 + + templatestruct map_result_tag{typedef Null_type type;}; + templatestruct map_result_tag >{typedef T type;}; + + templatestruct Get_functor_category,B,C> : + BOOSTD conditional::is_iterator, + Construct_iterator_tag, + Construct_tag> {}; + + // Really? + templatestruct Get_functor_category,B,C>{typedef Misc_tag type;}; + +#define DECL_CONSTRUCT(X,Y) struct X##_tag {}; \ + template<>struct map_result_tag{typedef Y##_tag type;}; \ + templatestruct Get_functor_category{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{typedef Y##_tag type;}; \ + template<>struct map_functor_type{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) \ + templatestruct Get_functor_category{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 {}; \ + templatestruct Get_functor_category{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 struct Preserved_by_non_linear_extra_coordinate + : boost::false_type {}; + template<> struct Preserved_by_non_linear_extra_coordinate + : boost::true_type {}; + template<> struct Preserved_by_non_linear_extra_coordinate + : boost::true_type {}; + template<> struct Preserved_by_non_linear_extra_coordinate + : boost::true_type {}; + template<> struct Preserved_by_non_linear_extra_coordinate + : boost::true_type {}; + template<> struct Preserved_by_non_linear_extra_coordinate + : boost::true_type {}; + template<> struct Preserved_by_non_linear_extra_coordinate + : boost::true_type {}; + + // Kernel properties + struct Point_stores_squared_distance_to_origin_tag {}; + +} +#endif // CGAL_FUNCTOR_TAGS_H diff --git a/NewKernel_d/include/CGAL/iterator_from_indices.h b/NewKernel_d/include/CGAL/iterator_from_indices.h new file mode 100644 index 00000000000..d83c263b98a --- /dev/null +++ b/NewKernel_d/include/CGAL/iterator_from_indices.h @@ -0,0 +1,56 @@ +#ifndef CGAL_ITERATOR_FROM_INDICES_H +#define CGAL_ITERATOR_FROM_INDICES_H +#include +namespace CGAL { +template +struct Default_coordinate_access { + typedef Ref_ result_type; + template Ref_ operator()(T const& t, int i)const{ + return t[i]; + } +}; + +//TODO: default type for Value_: typename same_cv::type::value_type>::type +template ()[0]) +#else + Value_& +#endif + , class Coord_access = Default_coordinate_access + > +class Iterator_from_indices +: public boost::iterator_facade, + 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(other.index) + -static_cast(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 + Iterator_from_indices(Container_& cont_,std::size_t n,T const&t) + : cont(&cont_), index(n), ca(t) {} +}; +} +#endif // CGAL_ITERATOR_FROM_INDICES_H diff --git a/NewKernel_d/include/CGAL/marcutils.h b/NewKernel_d/include/CGAL/marcutils.h new file mode 100644 index 00000000000..90ea434792a --- /dev/null +++ b/NewKernel_d/include/CGAL/marcutils.h @@ -0,0 +1,266 @@ +#ifndef marcutils +#define marcutils + +#ifdef CGAL_CXX0X +#include +#include +#define CGAL_FORWARDABLE(T) T&& +#define CGAL_FORWARD(T,t) std::forward(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 +#include +#include +#include +#include +#include +#include + +#ifdef CGAL_CXX0X +#define BOOSTD std:: +#else +#define BOOSTD boost:: +#endif + +namespace CGAL { +namespace internal { + BOOST_MPL_HAS_XXX_TRAIT_DEF(type) +} + +template ::value /*false*/> +struct Has_type_different_from : boost::false_type {}; +template +struct Has_type_different_from +: boost::mpl::not_ > {}; + + + template 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 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 inline + typename std::conditional::value&&std::is_arithmetic::type>::value,T,U&&>::type + forward_safe(V&& u) { return std::forward(u); } +#else + template inline U const& forward_safe(U const& u) { + return u; + } +#endif + +#ifdef CGAL_CXX0X + template struct Constructible_from_each; + template struct Constructible_from_each{ + enum { value=std::is_convertible::value&&Constructible_from_each::value }; + }; + template struct Constructible_from_each{ + enum { value=true }; + }; +#else +// currently only used in C++0X code +#endif + + template struct Scale { + T const& scale; + Scale(T const& t):scale(t){} + template +#ifdef CGAL_CXX0X + auto operator()(FT&& x)const->decltype(scale*std::forward(x)) +#else + FT operator()(FT const& x)const +#endif + { + return scale*CGAL_FORWARD(FT,x); + } + }; + template struct Divide { +#if !defined(CGAL_CXX0X) || !defined(BOOST_RESULT_OF_USE_DECLTYPE) + // requires boost > 1.44 + // shouldn't be needed with C++0X + //template struct result; + //template struct result { + // typedef FT type; + //}; + typedef NT result_type; +#endif + T const& scale; + Divide(T const& t):scale(t){} + template +#ifdef CGAL_CXX0X + //FIXME: gcc complains for Gmpq + //auto operator()(FT&& x)const->decltype(Rational_traits().make_rational(std::forward(x),scale)) + NT operator()(FT&& x)const +#else + NT operator()(FT const& x)const +#endif + { + return Rational_traits(). + make_rational(CGAL_FORWARD(FT,x),scale); + } + }; + + template struct has_cheap_constructor : boost::is_arithmetic{}; + template struct has_cheap_constructor > { + 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 +#ifdef CGAL_CXX0X + auto operator()(A&&a,B&&b)const->decltype(std::forward(a)*std::forward(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 +#ifdef CGAL_CXX0X + auto operator()(A&&a,B&&b)const->decltype(std::forward(a)/std::forward(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 struct decay : boost::remove_cv::type> {}; +#endif + + template struct Type_copy_ref { typedef U type; }; + template struct Type_copy_ref { typedef U& type; }; +#ifdef CGAL_CXX0X + template struct Type_copy_ref { typedef U&& type; }; +#endif + template struct Type_copy_cv { typedef U type; }; + template struct Type_copy_cv { typedef U const type; }; + template struct Type_copy_cv { typedef U volatile type; }; + template struct Type_copy_cv { typedef U const volatile type; }; + + template struct Type_copy_cvref : + Type_copy_ref::type,U>::type> {}; + + struct Dereference_functor { + template struct result{}; + template struct result { + typedef typename std::iterator_traits::reference type; + }; + template typename result::type + operator()(It const&i)const{ + return *i; + } + }; + +#ifdef CGAL_CXX0X + template struct Indices{}; + template struct Next_increasing_indices; + template struct Next_increasing_indices > { + typedef Indices type; + }; + template struct N_increasing_indices { + typedef typename Next_increasing_indices::type>::type type; + }; + template<> struct N_increasing_indices<0> { typedef Indices<> type; }; + namespace internal { + template inline typename std::result_of::type + do_call_on_tuple_elements(F&&f, std::tuple&&t, Indices&&) { + return f(std::get(std::move(t))...); + } + } // internal + template + inline typename std::result_of::type + call_on_tuple_elements(F&&f, std::tuple&&t) { + return internal::do_call_on_tuple_elements(std::forward(f),std::move(t), + typename N_increasing_indices::type()); + } +#else +#define VAR(Z,N,_) cpp0x::get(t) +#define CODE(Z,N,_) template \ + inline Res call_on_tuple_elements(F const&f, \ + cpp0x::tuple const&t) { \ + return f(BOOST_PP_ENUM(N,VAR,)); \ + } +BOOST_PP_REPEAT_FROM_TO(0, 8, CODE, _ ) +#undef CODE +#undef VAR +#endif + + template struct Factory { + typedef A result_type; +#ifdef CGAL_CXX0X + template result_type operator()(U&&...u)const{ + return A(std::forward(u)...); + } +#else + result_type operator()()const{ + return A(); + } +#define CODE(Z,N,_) template \ + 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 \ + struct Get_functor::value \ + || !Provides_types >::value \ + || !Provides_functors >::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 \ + struct Get_type::value \ + || !Provides_types >::value \ + || !Provides_functors >::value \ + , int, void>::type> \ + { \ + typedef CGAL_STRIP_PAREN_ Name type; \ + typedef K Bound_kernel; \ + } + + +#endif diff --git a/NewKernel_d/include/CGAL/static_int.h b/NewKernel_d/include/CGAL/static_int.h new file mode 100644 index 00000000000..16a8f174c9d --- /dev/null +++ b/NewKernel_d/include/CGAL/static_int.h @@ -0,0 +1,42 @@ +#ifndef CGAL_STATIC_INT_H +#define CGAL_STATIC_INT_H +#include + +namespace CGAL { +template struct static_zero { + operator NT() const { return constant(); } +}; +template struct static_one { + operator NT() const { return constant(); } +}; + +template static_zero operator-(static_zero) { return static_zero(); } + +template NT operator+(NT const& x, static_zero) { return x; } +template NT operator+(static_zero, NT const& x) { return x; } +template static_zero operator+(static_zero, static_zero) { return static_zero(); } +template static_one operator+(static_zero, static_one) { return static_one(); } +template static_one operator+(static_one, static_zero) { return static_one(); } + +template NT operator-(NT const& x, static_zero) { return x; } +template NT operator-(static_zero, NT const& x) { return -x; } +template static_zero operator-(static_zero, static_zero) { return static_zero(); } +template static_zero operator-(static_one, static_one) { return static_zero(); } +template static_one operator-(static_one, static_zero) { return static_one(); } + +template NT operator*(NT const& x, static_one) { return x; } +template NT operator*(static_one, NT const& x) { return x; } +template static_zero operator*(NT const&, static_zero) { return static_zero(); } +template static_zero operator*(static_zero, NT const&) { return static_zero(); } +template static_zero operator*(static_zero, static_zero) { return static_zero(); } +template static_one operator*(static_one, static_one) { return static_one(); } +template static_zero operator*(static_zero, static_one) { return static_zero(); } +template static_zero operator*(static_one, static_zero) { return static_zero(); } + +template NT operator/(NT const& x, static_one) { return x; } +template static_zero operator/(static_zero, NT const&) { return static_zero(); } +template static_zero operator/(static_zero, static_one) { return static_zero(); } +template static_one operator/(static_one, static_one) { return static_one(); } + +} +#endif // CGAL_STATIC_INT_H diff --git a/NewKernel_d/include/CGAL/store_kernel.h b/NewKernel_d/include/CGAL/store_kernel.h new file mode 100644 index 00000000000..669bcb56ce6 --- /dev/null +++ b/NewKernel_d/include/CGAL/store_kernel.h @@ -0,0 +1,81 @@ +#ifndef CGAL_STORE_KERNEL_H +#define CGAL_STORE_KERNEL_H + +#include +#include + +namespace CGAL { +namespace internal { +BOOST_MPL_HAS_XXX_TRAIT_DEF(Do_not_store_kernel) +template::value> struct Do_not_store_kernel { + enum { value=false }; + typedef Tag_false type; +}; +template struct Do_not_store_kernel { + typedef typename T::Do_not_store_kernel type; + enum { value=type::value }; +}; +} + +template::value||internal::Do_not_store_kernel::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 +struct Store_kernel { + 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::value||internal::Do_not_store_kernel::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 +struct Store_kernel2 { + 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) +#define CGAL_FUNCTOR_INIT_IGNORE(X) \ + X(){} \ + X(R_ const&){} + +#endif // CGAL_STORE_KERNEL_H diff --git a/NewKernel_d/include/CGAL/transforming_iterator.h b/NewKernel_d/include/CGAL/transforming_iterator.h new file mode 100644 index 00000000000..b4d398c5951 --- /dev/null +++ b/NewKernel_d/include/CGAL/transforming_iterator.h @@ -0,0 +1,92 @@ +#ifndef CGAL_TRANSFORMING_ITERATOR_H +#define CGAL_TRANSFORMING_ITERATOR_H +#include +#include +#include +#include +#include + +// Inspired by the boost version, but more compact and +// without any iterator_category games. + +namespace CGAL { +namespace internal { + +// non-empty case +template::value> struct Functor_as_base { + Functor_as_base(){} + Functor_as_base(T const& t):f(t){} + //template Functor_as_base(Functor_as_base const&g):f(g.functor()){} + T const& functor()const{return f;} + T & functor() {return f;} + private: + T f; +}; + +// empty case +template struct Functor_as_base : public T { + Functor_as_base(){} + Functor_as_base(T const& t):T(t){} + //template Functor_as_base(Functor_as_base const&g):T(g.functor()){} + T const& functor()const{return *this;} + T & functor() {return *this;} +}; + +template +class transforming_iterator_helper +{ + typedef typename Default::Get()(std::declval::reference>())) +#else + typename boost::result_of::value_type)>::type + // should be reference instead of value_type +#endif + >::type reference; + + typedef typename Default::Get::type>::type>::type value_type; + + public: + typedef boost::iterator_adaptor< + Derived, + Iter, + value_type, + typename std::iterator_traits::iterator_category, + reference + > type; +}; +} + +template +class transforming_iterator +: public internal::transforming_iterator_helper,F,Iter,Ref,Val>::type, +private internal::Functor_as_base +{ + friend class boost::iterator_core_access; + typedef typename internal::transforming_iterator_helper::type Base; + typedef internal::Functor_as_base 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 + transforming_iterator( + transforming_iterator const&i, + typename boost::enable_if_convertible::type* = 0, + typename boost::enable_if_convertible::type* = 0) + : Base(i.base()),Functor_base(i.functor()) {} + +}; + +template inline +transforming_iterator make_transforming_iterator(Iter i, F const&f=F()) { + return transforming_iterator(i,f); +} + +} + +#endif // CGAL_TRANSFORMING_ITERATOR_H diff --git a/NewKernel_d/include/CGAL/transforming_pair_iterator.h b/NewKernel_d/include/CGAL/transforming_pair_iterator.h new file mode 100644 index 00000000000..9df4b61c4e9 --- /dev/null +++ b/NewKernel_d/include/CGAL/transforming_pair_iterator.h @@ -0,0 +1,107 @@ +#ifndef CGAL_TRANSFORMING_PAIR_ITERATOR_H +#define CGAL_TRANSFORMING_PAIR_ITERATOR_H +// Should be a combination of transform_iterator and zip_iterator, +// but boost's iterator_category games are a pain. + +#include +#include +#include + + + +namespace CGAL { +namespace internal { +template ::value> +struct Min_category { + BOOST_STATIC_ASSERT((boost::is_convertible::value)); + typedef Cat1 type; +}; + +template +struct Min_category { + typedef Cat2 type; +}; + + +template +class transforming_pair_iterator_helper +{ + typedef typename Min_category< + typename std::iterator_traits::iterator_category, + typename std::iterator_traits::iterator_category> + ::type iterator_category; + + typedef typename Default::Get()(std::declval::reference>(),std::declval::reference>())) +#else + typename boost::result_of::value_type,typename std::iterator_traits::value_type)>::type + // should be reference instead of value_type +#endif + >::type reference; + + typedef typename Default::Get::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 +class transforming_pair_iterator +: public internal::transforming_pair_iterator_helper,F,It1,It2,Ref,Val>::type, +private internal::Functor_as_base +{ + It1 iter1; It2 iter2; + friend class boost::iterator_core_access; + typedef typename internal::transforming_pair_iterator_helper::type Base; + typedef internal::Functor_as_base 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 + transforming_pair_iterator( + transforming_pair_iterator const&i, + typename boost::enable_if_convertible::type* = 0, + typename boost::enable_if_convertible::type* = 0, + typename boost::enable_if_convertible::type* = 0) + : Functor_base(i.functor()),iter1(i.iter1),iter2(i.iter2) {} + +}; + +template inline +transforming_pair_iterator make_transforming_pair_iterator(It1 i1, It2 i2, F const&f=F()) { + return transforming_pair_iterator(i1,i2,f); +} + +} + +#endif // CGAL_TRANSFORMING_PAIR_ITERATOR_H diff --git a/NewKernel_d/include/CGAL/typeset.h b/NewKernel_d/include/CGAL/typeset.h new file mode 100644 index 00000000000..422a768a18d --- /dev/null +++ b/NewKernel_d/include/CGAL/typeset.h @@ -0,0 +1,97 @@ +#ifndef CGAL_TYPESET_H +#define CGAL_TYPESET_H +#ifdef CGAL_CXX0X +#include +#else +#include +#endif + +// Sometimes using tuple just to list types is overkill (takes forever to +// instantiate). + +namespace CGAL { +#ifdef CGAL_CXX0X + template struct typeset; + template struct typeset { + typedef H head; + typedef typeset tail; + typedef typeset type; + template using contains = typename + std::conditional< + std::is_same::value, + std::true_type, + typename tail::template contains + >::type; + template using add = typename + std::conditional< + contains::value, + typeset, + typeset + >::type; + }; + template<> struct typeset<> { + typedef typeset type; + template using contains = std::false_type; + template using add = typeset; + }; +#else + template struct typeset; + template, void, typeset >::type > + struct typeset { + typedef typeset type; + typedef H head; + typedef T tail; + template struct contains : + boost::mpl::if_,boost::true_type,typename tail::template contains >::type + {}; + template struct add; + //boost::mpl::if_,typeset,typeset >::type + }; + template<> struct typeset<> { + typedef typeset type; + template struct contains : boost::false_type {}; + template struct add : typeset {}; + }; + + template + template + struct typeset::add : typeset::type> {}; + template + template + struct typeset::add : typeset {}; +#endif + + template struct typeset_union_ : + typeset_union_::type, typename T2::tail> + {}; + template struct typeset_union_ > : T {}; + + template + struct typeset_intersection_ { + typedef typename T1::head H; + typedef typename typeset_intersection_::type U; + typedef typename +#ifdef CGAL_CXX0X + std::conditional::value, +#else + boost::mpl::if_, +#endif + typename U::template add::type, U>::type type; + }; + template + struct typeset_intersection_,T> : typeset<> {}; + +#ifdef CGAL_CXX0X + template + using typeset_union = typename typeset_union_::type; + template + using typeset_intersection = typename typeset_intersection_::type; +#else + template + struct typeset_union : typeset_union_::type {}; + template + struct typeset_intersection : typeset_intersection_::type {}; +#endif +} +#endif diff --git a/NewKernel_d/package_info/Kernel_d/description.txt b/NewKernel_d/package_info/Kernel_d/description.txt new file mode 100644 index 00000000000..ad14cf1d649 --- /dev/null +++ b/NewKernel_d/package_info/Kernel_d/description.txt @@ -0,0 +1 @@ +d-dimensional Geometry Kernel diff --git a/NewKernel_d/package_info/Kernel_d/maintainer b/NewKernel_d/package_info/Kernel_d/maintainer new file mode 100644 index 00000000000..a9ff63ce1ce --- /dev/null +++ b/NewKernel_d/package_info/Kernel_d/maintainer @@ -0,0 +1 @@ +Marc Glisse diff --git a/NewKernel_d/test/NewKernel_d/Makefile b/NewKernel_d/test/NewKernel_d/Makefile new file mode 100644 index 00000000000..0a6cbe80189 --- /dev/null +++ b/NewKernel_d/test/NewKernel_d/Makefile @@ -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 diff --git a/NewKernel_d/test/NewKernel_d/test.cpp b/NewKernel_d/test/NewKernel_d/test.cpp new file mode 100644 index 00000000000..74042308c19 --- /dev/null +++ b/NewKernel_d/test/NewKernel_d/test.cpp @@ -0,0 +1,266 @@ +//#define BOOST_RESULT_OF_USE_DECLTYPE 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +templatevoid marc_use(){} +#define USE_TYPE(T) marc_use() + +//typedef CGAL::Cartesian_base_d > K0; +//typedef CGAL::Cartesian_base_d > KA; +struct KA : CGAL::Cartesian_static_filters, CGAL::Cartesian_base_d, KA>, KA> {}; +typedef CGAL::Cartesian_base_d > KE; + +struct RC: public +CGAL::Cartesian_static_filters, // Yes, it is silly to put it there. + CGAL::Cartesian_refcount< + CGAL::Cartesian_LA_base_d > + >, RC +> +{ + RC(){} + RC(int){} +}; + +struct K0 : RC {}; + + +#if 0 +typedef K0 K2; +#elif 0 +typedef CGAL::Cartesian_filter_NT K2; +#elif 0 +typedef CGAL::Cartesian_filter_K K2; +#elif 1 +typedef CGAL::Lazy_cartesian > K2; +#endif + +#if 0 +typedef K2 KK; +#elif 1 +typedef CGAL::Cartesian_wrap KK; +#elif 1 +typedef CGAL::Cartesian_wrap K3; +typedef CGAL::Cartesian_wrap KK; +#endif + +#if 1 +#define Kinit(f) =k.f() +#else +#define Kinit(f) +#endif + +template +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::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 struct Construct_point3_helper { + CP const& cp; + Construct_point3_helper(CP const& x) : cp(x) {} + template + 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 + 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 +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::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::value,Construct_point3_helper,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 >(); + test2 > >(); + test3 > >(); + test3 >(); +} diff --git a/Number_types/include/CGAL/long_long.h b/Number_types/include/CGAL/long_long.h index 6f6c9001292..6135f76323b 100644 --- a/Number_types/include/CGAL/long_long.h +++ b/Number_types/include/CGAL/long_long.h @@ -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 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 operator()( const Type& x ) const { + return (Interval_nt<>((double)x)+Interval_nt<>::smallest()).pair(); + } + }; +}; +#endif + + } //namespace CGAL #include diff --git a/STL_Extension/include/CGAL/is_iterator.h b/STL_Extension/include/CGAL/is_iterator.h index 35f0b5fc54c..91cf0439aa3 100644 --- a/STL_Extension/include/CGAL/is_iterator.h +++ b/STL_Extension/include/CGAL/is_iterator.h @@ -68,6 +68,13 @@ template struct is_iterator : template struct is_iterator_type : internal::is_iterator_type_::type>::type,Tag> {}; +template ::value> struct is_iterator_to { + enum { value=false }; +}; +template struct is_iterator_to : + boost::is_convertible::value_type,U> +{ }; + } #endif // CGAL_IS_ITERATOR_H diff --git a/STL_Extension/include/CGAL/tags.h b/STL_Extension/include/CGAL/tags.h index 8bf81c78a83..9e5c943d0a2 100644 --- a/STL_Extension/include/CGAL/tags.h +++ b/STL_Extension/include/CGAL/tags.h @@ -39,6 +39,10 @@ template struct Boolean_tag { static const bool value = b; }; +/* In C++11, try: +template +using Boolean_tag = std::integral_constant; +*/ typedef Boolean_tag Tag_true; typedef Boolean_tag Tag_false; diff --git a/STL_Extension/test/STL_Extension/test_is_iterator.cpp b/STL_Extension/test/STL_Extension/test_is_iterator.cpp index 31aaf66957f..ffe3f0ad35d 100644 --- a/STL_Extension/test/STL_Extension/test_is_iterator.cpp +++ b/STL_Extension/test/STL_Extension/test_is_iterator.cpp @@ -2,14 +2,29 @@ #include #include #include +#include + +struct A { }; int main() { typedef std::vector::const_iterator vector_it; + typedef std::list::const_iterator list_it; typedef int* int_p; using CGAL::is_iterator; + using CGAL::is_iterator_type; + using CGAL::is_iterator_to; CGAL_static_assertion(is_iterator::value); + CGAL_static_assertion(is_iterator::value); CGAL_static_assertion(!is_iterator::value); CGAL_static_assertion(!is_iterator::value); CGAL_static_assertion(is_iterator::value); + + CGAL_static_assertion((is_iterator_type::value)); + CGAL_static_assertion((!is_iterator_type::value)); + CGAL_static_assertion((!is_iterator_type::value)); + + CGAL_static_assertion((is_iterator_to::value)); + CGAL_static_assertion((!is_iterator_to::value)); + CGAL_static_assertion((!is_iterator_to::value)); }