A beginning.

This commit is contained in:
Marc Glisse 2011-05-09 14:08:57 +00:00
parent 1cd3febf83
commit 146ee6dbd1
22 changed files with 1843 additions and 0 deletions

View File

@ -0,0 +1,123 @@
// Copyright (c) 2008 INRIA Sophia-Antipolis (France).
// 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) : Sylvain Pion
#ifndef CGAL_DIMENSION_H
#define CGAL_DIMENSION_H
#include <CGAL/basic.h>
#include <CGAL/Kernel_traits.h>
#include <limits>
#ifdef CGAL_USE_EIGEN
#include <Eigen/Core>
#endif
namespace CGAL {
#ifdef CGAL_USE_EIGEN
const int UNKNOWN_DIMENSION=Eigen::Dynamic;
#else
const int UNKNOWN_DIMENSION=std::numeric_limits<int>::max();
#endif
bool check_dimension(int d1, int d2){
//return (d2==UNKNOWN_DIMENSION)||(d1<=d2);
return d1<=d2;
}
// These tag classes help dispatching functions based on a geometric dimension.
template < int dim >
struct Dimension_tag
{
static const int value = dim;
};
struct Dynamic_dimension_tag {
static const int value = UNKNOWN_DIMENSION;
};
namespace internal {
template < typename D >
struct Dim_value {
static const int value = D::value;
};
template <>
struct Dim_value <Dynamic_dimension_tag> {};
} // namespace internal
// Ambient_dimension gives access to the dimension of the ambient space of an object.
template < typename T, typename K = typename Kernel_traits<T>::Kernel >
struct Ambient_dimension
: public internal::Dim_value< typename K::template Ambient_dimension<T>::type >
{
typedef typename K::template Ambient_dimension<T>::type type;
};
// Feature_dimension gives access to the dimension of an object.
template < typename T, typename K = typename Kernel_traits<T>::Kernel >
struct Feature_dimension
: public internal::Dim_value< typename K::template Feature_dimension<T>::type >
{
typedef typename K::template Feature_dimension<T>::type type;
};
// Change the dimension
template<class D,int i=1>struct Increment_dimension {
typedef Dynamic_dimension_tag type;
};
template<int d,int i>struct Increment_dimension<Dimension_tag<d>,i> {
typedef Dimension_tag<d+i> type;
};
template<class D1,class D2>struct Product_dimension {
typedef Dynamic_dimension_tag type;
};
template<int d1,int d2>struct Product_dimension<Dimension_tag<d1>,Dimension_tag<d2> > {
typedef Dimension_tag<d1*d2> type;
};
#ifdef CGAL_USE_EIGEN
// Convert to Eigen's notion of dimension
template <class Dim_> struct Eigen_dimension {
enum { value=Eigen::Dynamic };
};
template <int d> struct Eigen_dimension<Dimension_tag<d> > {
enum { value=d };
};
// and convert back
template <int d> struct Dimension_eigen {
typedef Dimension_tag<d> type;
};
template <> struct Dimension_eigen<Eigen::Dynamic> {
typedef Dynamic_dimension_tag type;
};
#endif
} //namespace CGAL
#endif // CGAL_DIMENSION_H

View File

@ -0,0 +1,112 @@
#ifndef CGAL_KERNEL_D_CARTESIAN_LA_BASE_H
#define CGAL_KERNEL_D_CARTESIAN_LA_BASE_H
#include <CGAL/basic.h>
#include <CGAL/representation_tags.h>
#include <CGAL/functor_tags.h>
#include <CGAL/Uncertain.h>
#include <CGAL/Kernel_d/Dimension_base.h>
#include <CGAL/Kernel_d/Cartesian_LA_functors.h>
#ifdef CGAL_USE_EIGEN
#include <CGAL/LA_eigen/LA.h>
#else
#include <CGAL/LA_default/LA.h>
#endif
namespace CGAL {
template < typename FT_, typename Dim_>
struct Cartesian_LA_base_d : public Dimension_base<Dim_>
{
typedef FT_ FT;
typedef Cartesian_LA_base_d<FT_,Dim_> Self;
typedef Cartesian_tag Rep_tag;
typedef Cartesian_tag Kernel_tag;
typedef Dim_ Default_ambient_dimension;
typedef Dim_ Max_ambient_dimension;
#ifdef CGAL_USE_EIGEN
typedef CGAL::LA_eigen<FT> LA;
#else
typedef CGAL::LA_default<FT> LA;
#endif
typedef typename Same_uncertainty_nt<bool, FT>::type
Boolean;
typedef typename Same_uncertainty_nt<CGAL::Sign, FT>::type
Sign;
typedef typename Same_uncertainty_nt<CGAL::Comparison_result, FT>::type
Comparison_result;
typedef typename Same_uncertainty_nt<CGAL::Orientation, FT>::type
Orientation;
typedef typename Same_uncertainty_nt<CGAL::Oriented_side, FT>::type
Oriented_side;
typedef typename Same_uncertainty_nt<CGAL::Bounded_side, FT>::type
Bounded_side;
typedef typename Same_uncertainty_nt<CGAL::Angle, FT>::type
Angle;
typedef typename LA::template Vector<Dim_> LA_vector_selector;
typedef typename LA_vector_selector::type LA_vector;
typedef typename LA_vector_selector::Constructor Constructor;
typedef typename LA_vector_selector::const_iterator Cartesian_const_iterator;
// convert types to the new way? painful to use...
typedef LA_vector Point;
typedef LA_vector Vector;
// old way
typedef CartesianDVectorBase::Construct_LA_vector<Self> Construct_point;
typedef CartesianDVectorBase::Construct_LA_vector<Self> Construct_vector;
typedef CartesianDVectorBase::Construct_cartesian_const_iterator<Self> Construct_cartesian_const_iterator;
typedef CartesianDVectorBase::Construct_sum_of_vectors<Self> Construct_sum_of_vectors;
typedef CartesianDVectorBase::Construct_difference_of_vectors<Self> Construct_difference_of_vectors;
typedef CartesianDVectorBase::Construct_opposite_vector<Self> Construct_opposite_vector;
typedef CartesianDVectorBase::Construct_midpoint<Self> Construct_midpoint;
typedef CartesianDVectorBase::Compute_cartesian_coordinate<Self> Compute_cartesian_coordinate;
// new way
template<class, /* C++ sucks */ int=0> struct Construct {
typedef Null_functor type;
};
template<int i> struct Construct<Construct_vector_tag,i> {
typedef CartesianDVectorBase::Construct_LA_vector<Self> type;
};
template<int i> struct Construct<Construct_point_tag,i> {
typedef CartesianDVectorBase::Construct_LA_vector<Self> type;
};
template<int i> struct Construct<Construct_cartesian_const_iterator_tag,i> {
typedef CartesianDVectorBase::Construct_cartesian_const_iterator<Self> type;
};
template<int i> struct Construct<Construct_sum_of_vectors_tag,i> {
typedef CartesianDVectorBase::Construct_sum_of_vectors<Self> type;
};
template<int i> struct Construct<Construct_difference_of_vectors_tag,i> {
typedef CartesianDVectorBase::Construct_difference_of_vectors<Self> type;
};
template<int i> struct Construct<Construct_opposite_vector_tag,i> {
typedef CartesianDVectorBase::Construct_opposite_vector<Self> type;
};
template<int i> struct Construct<Construct_midpoint_tag,i> {
typedef CartesianDVectorBase::Construct_midpoint<Self> type;
};
template<class,int=0> struct Compute {
typedef Null_functor type;
};
template<int i> struct Compute<Compute_cartesian_coordinate_tag,i> {
typedef CartesianDVectorBase::Compute_cartesian_coordinate<Self> type;
};
template<class,int=0> struct Predicate {
typedef Null_functor type;
};
CGAL_CONSTEXPR Cartesian_LA_base_d(){}
CGAL_CONSTEXPR Cartesian_LA_base_d(int d):Dimension_base<Dim_>(d){}
};
} //namespace CGAL
#endif // CGAL_KERNEL_D_CARTESIAN_LA_BASE_H

View File

@ -0,0 +1,192 @@
#ifndef CGAL_CARTESIAN_LA_FUNCTORS_H
#define CGAL_CARTESIAN_LA_FUNCTORS_H
#include <CGAL/marcutils.h>
#include <CGAL/is_iterator.h>
#include <CGAL/argument_swaps.h>
#include <CGAL/Kernel/Return_base_tag.h>
#include <CGAL/transforming_iterator.h>
namespace CGAL {
namespace CartesianDVectorBase {
#ifndef CGAL_CXX0X
namespace internal {
template<class R_,int dim_> struct Construct_LA_vector_;
#define CODE(Z,N,_) template<class R> struct Construct_LA_vector_<R,N> { \
typedef typename R::Constructor Constructor; \
typedef typename R::FT FT; \
typedef typename R::LA_vector result_type; \
result_type operator() \
(BOOST_PP_ENUM_PARAMS(N,FT const& t)) const { \
return typename Constructor::Values()(BOOST_PP_ENUM_PARAMS(N,t)); \
} \
result_type operator() \
(BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(N),FT const& t)) const { \
return typename Constructor::Values_divide()(t##N,BOOST_PP_ENUM_PARAMS(N,t)); \
} \
};
BOOST_PP_REPEAT_FROM_TO(2, 11, CODE, _ )
#undef CODE
}
#endif
template<class R_> struct Construct_LA_vector
#ifndef CGAL_CXX0X
: internal::Construct_LA_vector_<R_,R_::Default_ambient_dimension::value>
#endif
{
typedef R_ R;
typedef typename R::Constructor Constructor;
typedef typename R::FT FT;
typedef typename R::LA_vector result_type;
typedef typename R_::Default_ambient_dimension Dimension;
static const int dim=Dimension::value;
result_type operator()(int d)const{
CGAL_assertion(d==dim);
return typename Constructor::Dimension()(d);
}
result_type operator()()const{
return typename Constructor::Dimension()(dim);
}
result_type operator()(result_type const& v)const{
return v;
}
#ifdef CGAL_CXX0X
result_type operator()(result_type&& v)const{
return std::move(v);
}
#endif
#ifdef CGAL_CXX0X
template<class...U>
typename std::enable_if<Constructible_from_each<FT,U...>::value &&
(sizeof...(U)==dim), result_type>::type
operator()(U&&...u)const{
return typename Constructor::Values()(std::forward<U>(u)...);
}
//template<class...U,class=typename std::enable_if<Constructible_from_each<FT,U...>::value>::type,class=typename std::enable_if<(sizeof...(U)==dim+1)>::type,class=void>
template<class...U>
typename std::enable_if<Constructible_from_each<FT,U...>::value &&
(sizeof...(U)==dim+1), result_type>::type
operator()(U&&...u)const{
return Apply_to_last_then_rest()(typename Constructor::Values_divide(),std::forward<U>(u)...);
}
#else
using internal::Construct_LA_vector_<R_,R::Default_ambient_dimension::value>::operator();
#endif
template<class Iter> typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
(Iter const&f,Iter const&g,Cartesian_tag)const
{
int d=std::distance(f,g);
CGAL_assertion(d==dim);
return typename Constructor::Iterator()(dim,f,g);
}
template<class Iter> typename boost::enable_if<is_iterator_type<Iter,std::bidirectional_iterator_tag>,result_type>::type operator()
(Iter const&f,Iter g,Homogeneous_tag)const
{
--g;
return this->operator()(f,g,*g);
}
template<class Iter> typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
(Iter const&f,Iter const&g)const
{
return this->operator()(f,g,typename R::Rep_tag());
}
template<class Iter,class NT> typename boost::enable_if<is_iterator_type<Iter,std::forward_iterator_tag>,result_type>::type operator()
(Iter const&f,Iter const&g,NT const&l)const
{
int d=std::distance(f,g);
CGAL_assertion(d==dim);
return typename Constructor::Iterator()(dim,CGAL::make_transforming_iterator(f,Divide<FT,NT>(l)),CGAL::make_transforming_iterator(g,Divide<FT,NT>(l)));
}
};
template<class R_> struct Compute_cartesian_coordinate {
typedef R_ R;
typedef typename R_::FT FT;
typedef typename R::LA_vector first_argument_type;
typedef int second_argument_type;
typedef Tag_true Is_exact;
#ifdef CGAL_CXX0X
typedef decltype(std::declval<const first_argument_type>()[0]) result_type;
#else
typedef FT result_type; // FT const& doesn't work with some LA
#endif
result_type operator()(first_argument_type const& v,int i)const{
return v[i];
}
};
template<class R_> struct Construct_cartesian_const_iterator {
typedef R_ R;
typedef typename R::LA_vector argument_type;
typedef typename R::LA_vector_selector S_;
typedef typename R::Cartesian_const_iterator result_type;
result_type begin(argument_type const& v)const{
return S_::vector_begin(v);
}
result_type end(argument_type const& v)const{
return S_::vector_end(v);
}
};
template<class R_> struct Construct_midpoint {
typedef R_ R;
typedef typename R::Point first_argument_type;
typedef typename R::Point second_argument_type;
typedef typename R::Point result_type;
result_type operator()(result_type const& a, result_type const& b)const{
return (a+b)/2;
}
};
template<class R_> struct Construct_sum_of_vectors {
typedef R_ R;
typedef typename R::Vector first_argument_type;
typedef typename R::Vector second_argument_type;
typedef typename R::Vector result_type;
result_type operator()(result_type const& a, result_type const& b)const{
return a+b;
}
};
template<class R_> struct Construct_difference_of_vectors {
typedef R_ R;
typedef typename R::Vector first_argument_type;
typedef typename R::Vector second_argument_type;
typedef typename R::Vector result_type;
result_type operator()(result_type const& a, result_type const& b)const{
return a-b;
}
};
template<class R_> struct Construct_opposite_vector {
typedef R_ R;
typedef typename R::Vector result_type;
typedef typename R::Vector argument_type;
result_type operator()(result_type const& v)const{
return -v;
}
};
template<class R_> struct Compute_scalar_product {
typedef R_ R;
typedef typename R::LA LA;
typedef typename R::FT result_type;
typedef typename R::Vector first_argument_type;
typedef typename R::Vector second_argument_type;
result_type operator()(first_argument_type const& a, second_argument_type const& b)const{
return LA::dot_product(a,b);
}
};
}
} // namespace CGAL
#endif // CGAL_CARTESIAN_LA_FUNCTORS_H

View File

@ -0,0 +1,28 @@
#ifndef CGAL_KERNEL_D_CARTESIAN_BASE_H
#define CGAL_KERNEL_D_CARTESIAN_BASE_H
#include <CGAL/basic.h>
#include <CGAL/Kernel_d/Cartesian_complete.h>
#include <CGAL/Kernel_d/Cartesian_LA_base.h>
namespace CGAL {
template < typename FT_, typename Dim_>
struct Cartesian_base_d : public
Cartesian_complete_predicates<
Cartesian_complete_constructors<
Cartesian_complete_computes<
Cartesian_complete_types<
Cartesian_LA_base_d<FT_,Dim_>
>, false, Cartesian_base_d<FT_,Dim_>
>, false, Cartesian_base_d<FT_,Dim_>
>, false, Cartesian_base_d<FT_,Dim_>
>
{
CGAL_CONSTEXPR Cartesian_base_d(){}
CGAL_CONSTEXPR Cartesian_base_d(int d):Dimension_base<Dim_>(d){}
};
} //namespace CGAL
#endif // CGAL_KERNEL_D_CARTESIAN_BASE_H

View File

@ -0,0 +1,92 @@
#ifndef CGAL_KERNEL_D_CARTESIAN_CHANGE_FT_H
#define CGAL_KERNEL_D_CARTESIAN_CHANGE_FT_H
#include <CGAL/basic.h>
#include <CGAL/NT_converter.h>
#include <CGAL/transforming_iterator.h>
#include <CGAL/Kernel_d/Cartesian_complete.h>
namespace CGAL {
template < typename Base_, typename FT_>
struct Cartesian_change_FT_base : public
Base_
{
CGAL_CONSTEXPR Cartesian_change_FT_base(){}
CGAL_CONSTEXPR Cartesian_change_FT_base(int d):Base_(d){}
typedef Base_ Kernel_base;
typedef FT_ RT;
typedef FT_ FT;
typedef CGAL::LA_eigen<FT> LA;
typedef typename Same_uncertainty_nt<bool, FT>::type
Boolean;
typedef typename Same_uncertainty_nt<CGAL::Sign, FT>::type
Sign;
typedef typename Same_uncertainty_nt<CGAL::Comparison_result, FT>::type
Comparison_result;
typedef typename Same_uncertainty_nt<CGAL::Orientation, FT>::type
Orientation;
typedef typename Same_uncertainty_nt<CGAL::Oriented_side, FT>::type
Oriented_side;
typedef typename Same_uncertainty_nt<CGAL::Bounded_side, FT>::type
Bounded_side;
typedef typename Same_uncertainty_nt<CGAL::Angle, FT>::type
Angle;
typedef NT_converter<typename Kernel_base::FT,FT> FT_converter;
typedef transforming_iterator<FT_converter,typename Kernel_base::Cartesian_const_iterator> Cartesian_const_iterator;
//FIXME: what if the functor's constructor takes a kernel as argument?
struct Construct_cartesian_const_iterator {
typedef typename Kernel_base::template Construct<Construct_cartesian_const_iterator_tag>::type Functor_base;
Functor_base f;
typedef Cartesian_const_iterator result_type;
template<class T>
result_type begin(T const& v)const{
return make_transforming_iterator(f.begin(v),FT_converter());
}
template<class T>
result_type end(T const& v)const{
return make_transforming_iterator(f.end(v),FT_converter());
}
};
struct Compute_cartesian_coordinate {
typedef typename Kernel_base::template Compute<Compute_cartesian_coordinate_tag>::type Functor_base;
Functor_base f;
typedef FT result_type;
template<class Obj_>
result_type operator()(Obj_ const& v,int i)const{
return FT_converter()(f(v,i));
}
};
template<class T,int i=0> struct Compute { typedef Null_functor type; };
template<int i> struct Compute<Compute_cartesian_coordinate_tag,i> {
typedef Compute_cartesian_coordinate type;
};
template<class T,int i=0> struct Predicate { typedef Null_functor type; };
template<class T,int i=0> struct Construct :
Kernel_base::template Construct<T> { };
template<int i> struct Construct<Construct_cartesian_const_iterator_tag,i> {
typedef Construct_cartesian_const_iterator type;
};
};
template < typename Base_, typename FT_>
struct Cartesian_change_FT : public
Cartesian_complete_predicates<
Cartesian_complete_computes<
Cartesian_change_FT_base<Base_,FT_>
, true, Cartesian_change_FT<Base_,FT_> >
, true, Cartesian_change_FT<Base_,FT_> >
{
CGAL_CONSTEXPR Cartesian_change_FT(){}
CGAL_CONSTEXPR Cartesian_change_FT(int d):Cartesian_change_FT_base<Base_,FT_>(d){}
};
} //namespace CGAL
#endif // CGAL_KERNEL_D_CARTESIAN_CHANGE_FT_H

View File

@ -0,0 +1,118 @@
#ifndef CGAL_KERNEL_D_CARTESIAN_COMPLETE_H
#define CGAL_KERNEL_D_CARTESIAN_COMPLETE_H
#include <CGAL/Kernel_d/function_objects_cartesian.h>
#include <CGAL/Kernel_d/Segmentd.h>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/has_xxx.hpp>
namespace CGAL {
namespace internal {
BOOST_MPL_HAS_XXX_TRAIT_DEF(Segment)
BOOST_MPL_HAS_XXX_TRAIT_DEF(Ray)
BOOST_MPL_HAS_XXX_TRAIT_DEF(Direction)
BOOST_MPL_HAS_XXX_TRAIT_DEF(Line)
}
template<class R_,bool force_=false> struct Cartesian_complete_types
: public R_
{
typedef R_ Kernel_base;
#define CGAL_Kernel_obj2(X) typedef typename boost::mpl::if_c<force_||!internal::has_##X<R_>::value,X##Cd<R_>,R_>::type::X X;
#include <CGAL/Kernel_d/interface_macros.h>
};
template<class R_,bool force_=false,class Derived_=R_> struct Cartesian_complete_constructors
: public R_
{
typedef R_ Kernel_base;
template<class F> struct Construct {
typedef typename Kernel_base::template Construct<F>::type Base_functor;
typedef typename boost::mpl::if_<boost::is_same<Base_functor,Null_functor>,
typename Cartesian_complete_constructors<R_,true,Derived_>::template Construct<F>::type,
Base_functor>::type type;
};
};
template<class R_,class Derived_> struct Cartesian_complete_constructors <R_,true,Derived_>
: public R_
{
typedef R_ Kernel_base;
template<class F, int i=0> struct Construct
: Kernel_base::template Construct<F>
{ };
#define CGAL_Kernel_cons2(F,f) \
template<int i> struct Construct <F##_tag,i> { \
typedef CartesianDKernelFunctors::F<Derived_> type; \
type f() const { return type(); } \
};
#include <CGAL/Kernel_d/interface_macros.h>
};
template<class R_,bool force_=false,class Derived_=R_> struct Cartesian_complete_predicates
: public R_
{
typedef R_ Kernel_base;
template<class F> struct Predicate {
typedef typename Kernel_base::template Predicate<F>::type Base_functor;
typedef typename boost::mpl::if_<boost::is_same<Base_functor,Null_functor>,
typename Cartesian_complete_predicates<R_,true,Derived_>::template Predicate<F>::type,
Base_functor>::type type;
};
};
template<class R_,class Derived_> struct Cartesian_complete_predicates <R_,true,Derived_>
: public R_
{
typedef R_ Kernel_base;
template<class F, int i=0> struct Predicate
: Kernel_base::template Predicate<F>
{ };
#define CGAL_Kernel_pred(F,f) \
template<int i> struct Predicate <F##_tag,i> { \
typedef CartesianDKernelFunctors::F<Derived_> type; \
type f() const { return type(); } \
};
#include <CGAL/Kernel_d/interface_macros.h>
};
template<class R_,bool force_=false,class Derived_=R_> struct Cartesian_complete_computes
: public R_
{
typedef R_ Kernel_base;
template<class F> struct Compute {
typedef typename Kernel_base::template Compute<F>::type Base_functor;
typedef typename boost::mpl::if_<boost::is_same<Base_functor,Null_functor>,
typename Cartesian_complete_computes<R_,true,Derived_>::template Compute<F>::type,
Base_functor>::type type;
};
};
template<class R_,class Derived_> struct Cartesian_complete_computes <R_,true,Derived_>
: public R_
{
typedef R_ Kernel_base;
template<class F, int i=0> struct Compute
: Kernel_base::template Compute<F>
{ };
#define CGAL_Kernel_comp2(F,f) \
template<int i> struct Compute <F##_tag,i> { \
typedef CartesianDKernelFunctors::F<Derived_> type; \
type f() const { return type(); } \
};
#include <CGAL/Kernel_d/interface_macros.h>
};
}
#endif // CGAL_KERNEL_D_CARTESIAN_COMPLETE_H

View File

@ -0,0 +1,77 @@
#ifndef CGAL_KERNEL_D_CARTESIAN_FILTER_NT_H
#define CGAL_KERNEL_D_CARTESIAN_FILTER_NT_H
#include <CGAL/basic.h>
#include <CGAL/Kernel_d/Cartesian_change_FT.h>
#include <CGAL/internal/Exact_type_selector.h>
namespace CGAL {
template < typename Base_ >
struct Cartesian_filter_NT : public Base_
{
CGAL_CONSTEXPR Cartesian_filter_NT(){}
CGAL_CONSTEXPR Cartesian_filter_NT(int d):Base_(d){}
typedef Base_ Kernel_base;
typedef Cartesian_change_FT<Kernel_base,Interval_nt_advanced> K1;
typedef typename internal::Exact_type_selector<typename Kernel_base::FT>::Type Exact_nt;
typedef Cartesian_change_FT<Kernel_base,Exact_nt> K2;
template<class T,int i=0> struct Predicate {
struct type {
//TODO: use compression (derive from a compressed_pair?)
typedef typename K1::template Predicate<T>::type P1; P1 p1;
typedef typename K2::template Predicate<T>::type P2; P2 p2;
typedef typename P2::result_type result_type;
//FIXME: if predicate's constructor takes a kernel as argument, how do we translate that?
#ifdef CGAL_CXX0X
template<class...U> type(U&&...u):p1(std::forward<U>(u)...),p2(std::forward<U>(u)...){}
#else
//FIXME: usual boost preprocessor magic
#endif
#ifdef CGAL_CXX0X
template<class...U> result_type operator()(U&&...u)const{
{
Protect_FPU_rounding<true> p;
try {
typename P1::result_type res=p1(u...); // don't forward as u may be reused
if(is_certain(res)) return get_certain(res);
} catch (Uncertain_conversion_exception) {}
}
return p2(std::forward<U>(u)...);
}
#else
//FIXME: usual boost preprocessor magic
result_type operator()()const{ // does it make sense to have 0 argument?
{
Protect_FPU_rounding<true> p;
try {
typename P1::result_type res=p1();
if(is_certain(res)) return get_certain(res);
} catch (Uncertain_conversion_exception) {}
}
return p2();
}
#define CODE(Z,N,_) template<BOOST_PP_ENUM_PARAMS(N,class T)> result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t))const{ \
{ \
Protect_FPU_rounding<true> p; \
try { \
typename P1::result_type res=p1(BOOST_PP_ENUM_PARAMS(N,t)); \
if(is_certain(res)) return get_certain(res); \
} catch (Uncertain_conversion_exception) {} \
} \
return p2(BOOST_PP_ENUM_PARAMS(N,t)); \
}
BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_)
#undef CODE
#endif
};
};
};
} //namespace CGAL
#endif // CGAL_KERNEL_D_CARTESIAN_FILTER_NT_H

View File

@ -0,0 +1,23 @@
#ifndef bd_h
#define db_h
#include <CGAL/Dimension.h>
#include <CGAL/assertions.h>
#include <CGAL/marcutils.h>
namespace CGAL {
template<class=Dynamic_dimension_tag> struct Dimension_base {
//TODO: add some assertions
Dimension_base(int dim=-1):dim_(dim){}
int dimension()const{return dim_;}
void set_dimension(int dim){dim_=dim;}
private:
int dim_;
};
template<int dim_> struct Dimension_base<Dimension_tag<dim_> > {
Dimension_base(){}
Dimension_base(int dim){CGAL_assertion(dim_==dim);}
int dimension()const{return dim_;}
void set_dimension(int dim){CGAL_assertion(dim_==dim);}
};
}
#endif

View File

@ -0,0 +1,45 @@
#ifndef CGAL_KERNELD_SEGMENTD_H
#define CGAL_KERNELD_SEGMENTD_H
#include <utility>
#define Segmentd SegmentCd
namespace CGAL {
template <class R_> class Segmentd {
typedef typename R_::FT FT_;
typedef typename R_::Point Point_;
typedef typename R_::Vector Vector_;
typedef typename R_::Construct_vector Cv_;
// typedef typename R_::Compute_squared_distance Csd_;
typedef std::pair<Point_,Point_> Data_;
Data_ data;
public:
typedef Segmentd<R_> Segment;
#ifdef CGAL_CXX0X
template<class...U>
Segmentd(U&&...u):data(std::forward<U>(u)...){}
#else
Segmentd(){}
Segmentd(Point_ const&a, Point_ const&b): data(a,b) {}
#endif
Point_ source()const{return data.first;}
Point_ target()const{return data.second;}
Point_ operator[](int i)const{
if((i%2)==0)
return data.first;
else
return data.second;
}
Segmentd opposite()const{
return Segmentd(data.second,data.first);
}
Vector_ vector()const{
return Cv_()(data.first,data.second);
}
// FT_ squared_length()const{
// return Csd_()(data.first,data.second);
// }
};
} // namespace CGAL
#undef Segmentd
#endif // CGAL_KERNELD_SEGMENTD_H

View File

@ -0,0 +1,183 @@
#ifndef CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H
#define CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H
#include <CGAL/marcutils.h>
#include <CGAL/is_iterator.h>
#include <CGAL/number_utils.h>
#include <CGAL/Kernel/Return_base_tag.h>
#include <CGAL/transforming_iterator.h>
#include <CGAL/transforming_pair_iterator.h>
#include <CGAL/functor_tags.h>
#include <CGAL/exactness.h>
#include <functional>
namespace CGAL {
namespace CartesianDKernelFunctors {
template<class R_> struct Orientation {
typedef R_ R;
typedef typename R_::FT FT;
typedef typename R::Vector Vector;
typedef typename R::Point Point;
typedef typename R::Orientation result_type;
typedef typename R::LA::template Matrix<typename R::Default_ambient_dimension,typename R::Default_ambient_dimension,typename R::Max_ambient_dimension,typename R::Max_ambient_dimension>::type Matrix;
template<class Iter>
result_type operator()(Iter f, Iter const& e, Vector_tag)const{
typename R::template Compute<Compute_cartesian_coordinate_tag>::type c;
Matrix m(R().dimension(),R().dimension());
for(int i=0;f!=e;++f,++i) {
for(int j=0;j<R().dimension();++j){
Vector const& v=*f;
m(i,j)=c(v,j);
}
}
return R::LA::sign_of_determinant(CGAL_MOVE(m));
}
template<class Iter>
result_type operator()(Iter f, Iter const& e, Point_tag)const{
typename R::template Compute<Compute_cartesian_coordinate_tag>::type c;
Matrix m(R().dimension(),R().dimension());
Point const& p0=*f++;
for(int i=0;f!=e;++f,++i) {
for(int j=0;j<R().dimension();++j){
Point const& p=*f;
m(i,j)=c(p,j)-c(p0,j);
}
}
return R::LA::sign_of_determinant(CGAL_MOVE(m));
}
template<class Iter>
result_type operator()(Iter const&f, Iter const& e)const{
typename std::iterator_traits<Iter>::difference_type d=std::distance(f,e);
int dim=R().dimension();
if(d==dim) return operator()(f,e,Vector_tag());
CGAL_assertion(d==dim+1);
return operator()(f,e,Point_tag());
}
//TODO: version that takes objects directly instead of iterators
};
template<class R_> struct Construct_opposite_vector {
typedef R_ R;
typedef typename R_::FT FT;
typedef typename R::Vector Vector;
typedef typename R::template Construct<Construct_vector_tag>::type CV;
typedef typename R::template Construct<Construct_cartesian_const_iterator_tag>::type CI;
typedef Vector result_type;
typedef Vector argument_type;
result_type operator()(Vector const&v)const{
CI ci;
return CV()(make_transforming_iterator(ci.begin(v),std::negate<FT>()),make_transforming_iterator(ci.end(v),std::negate<FT>()));
}
};
template<class R_> struct Construct_sum_of_vectors {
typedef R_ R;
typedef typename R_::FT FT;
typedef typename R::Vector Vector;
typedef typename R::template Construct<Construct_vector_tag>::type CV;
typedef typename R::template Construct<Construct_cartesian_const_iterator_tag>::type CI;
typedef Vector result_type;
typedef Vector first_argument_type;
typedef Vector second_argument_type;
result_type operator()(Vector const&a, Vector const&b)const{
CI ci;
return CV()(make_transforming_pair_iterator(ci.begin(a),ci.begin(b),std::plus<FT>()),make_transforming_pair_iterator(ci.end(a),ci.end(b),std::plus<FT>()));
}
};
template<class R_> struct Construct_difference_of_vectors {
typedef R_ R;
typedef typename R_::FT FT;
typedef typename R::Vector Vector;
typedef typename R::template Construct<Construct_vector_tag>::type CV;
typedef typename R::template Construct<Construct_cartesian_const_iterator_tag>::type CI;
typedef Vector result_type;
typedef Vector first_argument_type;
typedef Vector second_argument_type;
result_type operator()(Vector const&a, Vector const&b)const{
CI ci;
return CV()(make_transforming_pair_iterator(ci.begin(a),ci.begin(b),std::minus<FT>()),make_transforming_pair_iterator(ci.end(a),ci.end(b),std::minus<FT>()));
}
};
template<class R_> struct Construct_midpoint {
typedef R_ R;
typedef typename R_::FT FT;
typedef typename R::Point Point;
typedef typename R::template Construct<Construct_point_tag>::type CP;
typedef typename R::template Construct<Construct_cartesian_const_iterator_tag>::type CI;
typedef Point result_type;
typedef Point first_argument_type;
typedef Point second_argument_type;
struct Average : std::binary_function<FT,FT,FT> {
FT operator()(FT const&a, FT const&b)const{
return (a+b)/2;
}
};
result_type operator()(Point const&a, Point const&b)const{
CI ci;
//Divide<FT,int> half(2);
//return CP()(make_transforming_iterator(make_transforming_pair_iterator(ci.begin(a),ci.begin(b),std::plus<FT>()),half),make_transforming_iterator(make_transforming_pair_iterator(ci.end(a),ci.end(b),std::plus<FT>()),half));
return CP()(make_transforming_pair_iterator(ci.begin(a),ci.begin(b),Average()),make_transforming_pair_iterator(ci.end(a),ci.end(b),Average()));
}
};
template<class R_> struct Compute_squared_length {
typedef R_ R;
typedef typename R_::FT FT;
typedef typename R::Vector Vector;
typedef typename R::template Construct<Construct_cartesian_const_iterator_tag>::type CI;
typedef FT result_type;
typedef Vector argument_type;
result_type operator()(Vector const&a)const{
CI ci;
typename Algebraic_structure_traits<FT>::Square f;
// TODO: avoid this FT(0)+...
return std::accumulate(make_transforming_iterator(ci.begin(a),f),make_transforming_iterator(ci.end(a),f),FT(0));
}
};
template<class R_> struct Compute_squared_distance {
typedef R_ R;
typedef typename R_::FT FT;
typedef typename R::Point Point;
typedef typename R::template Construct<Construct_cartesian_const_iterator_tag>::type CI;
typedef FT result_type;
typedef Point first_argument_type;
typedef Point second_argument_type;
struct Sq_diff : std::binary_function<FT,FT,FT> {
FT operator()(FT const&a, FT const&b)const{
return CGAL::square(a-b);
}
};
result_type operator()(Point const&a, Point const&b)const{
CI ci;
Sq_diff f;
// TODO: avoid this FT(0)+...
return std::accumulate(make_transforming_pair_iterator(ci.begin(a),ci.begin(b),f),make_transforming_pair_iterator(ci.end(a),ci.end(b),f),FT(0));
}
};
template<class R_> struct Less_coordinate {
typedef R_ R;
typedef typename R_::FT FT;
typedef typename R::Comparison_result result_type;
typedef typename R::template Compute<Compute_cartesian_coordinate_tag>::type Cc;
typedef typename CGAL::Is_exact<Cc>::type Is_exact;
template<class V,class W,class I>
result_type operator()(V const&a, V const&b, I i)const{
Cc c;
return c(a,i)<c(b,i);
}
};
}
}
#endif // CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H

View File

@ -0,0 +1,69 @@
#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)
#endif
#ifndef CGAL_Kernel_obj1
# define CGAL_Kernel_obj1(X) CGAL_Kernel_obj(X)
#endif
#ifndef CGAL_Kernel_obj2
# define CGAL_Kernel_obj2(X) CGAL_Kernel_obj(X)
#endif
CGAL_Kernel_obj1(Vector)
CGAL_Kernel_obj1(Point)
CGAL_Kernel_obj2(Segment)
CGAL_Kernel_cons1(Construct_vector,
construct_vector_object)
CGAL_Kernel_cons1(Construct_point,
construct_point_object)
CGAL_Kernel_cons1(Construct_cartesian_const_iterator,
construct_cartesian_const_iterator_object)
CGAL_Kernel_cons2(Construct_sum_of_vectors,
construct_sum_of_vectors_object)
CGAL_Kernel_cons2(Construct_difference_of_vectors,
construct_difference_of_vectors_object)
CGAL_Kernel_cons2(Construct_opposite_vector,
construct_opposite_vector_object)
CGAL_Kernel_cons2(Construct_midpoint,
construct_midpoint_object)
CGAL_Kernel_comp1(Compute_cartesian_coordinate,
compute_cartesian_coordinate_object)
CGAL_Kernel_pred(Orientation,
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

View File

@ -0,0 +1,92 @@
#ifndef CGAL_LA_EIGEN_H
#define CGAL_LA_EIGEN_H
#ifndef CGAL_USE_EIGEN
#error Requires Eigen
#endif
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/utility/enable_if.hpp>
#include <CGAL/Dimension.h>
#include <Eigen/Dense>
#include <CGAL/LA_eigen/constructors.h>
#include <CGAL/iterator_from_indices.h>
namespace CGAL {
template<class NT_> struct LA_eigen {
typedef NT_ NT;
// Dim_ real dimension
// Max_dim_ upper bound on the dimension
template<class Dim_,class Max_dim_=Dim_> struct Vector {
typedef Eigen::Matrix<NT,Eigen_dimension<Dim_>::value,1,Eigen::ColMajor|Eigen::AutoAlign,Eigen_dimension<Max_dim_>::value,1> type;
typedef Construct_eigen<type> Constructor;
//typedef NT const* const_iterator;
//FIXME: use Matrix_base instead in the iterator?
typedef Iterator_from_indices<const type,const NT
#ifndef CGAL_CXX0X
,NT
#endif
> const_iterator;
template<class Vec_>static const_iterator vector_begin(Vec_ const&a){
return const_iterator(a,0);
}
template<class Vec_>static const_iterator vector_end(Vec_ const&a){
return const_iterator(a,a.size());
}
};
template<class Rows_,class Cols_=Rows_,class Max_rows_=Rows_,class Max_cols_=Cols_> struct Matrix {
//TODO: don't pass on the values of Max_* for an expensive NT
typedef Eigen::Matrix<NT,Eigen_dimension<Rows_>::value,Eigen_dimension<Cols_>::value,Eigen::ColMajor|Eigen::AutoAlign,Eigen_dimension<Max_rows_>::value,Eigen_dimension<Max_cols_>::value> type;
// typedef ... Constructor
// typedef ... Accessor
};
private:
template <class T> class Canonicalize_vector {
typedef typename Dimension_eigen<T::SizeAtCompileTime>::type S1;
typedef typename Dimension_eigen<T::MaxSizeAtCompileTime>::type S2;
public:
typedef typename Vector<S1,S2>::type type;
};
public:
template<class Vec_>static NT dot_product(Vec_ const&a,Vec_ const&b){
return a.dot(b);
}
template<class Mat_> static NT determinant(Mat_ const&m,bool=false){
return m.determinant();
}
template<class Mat_> static typename
Same_uncertainty_nt<CGAL::Sign, NT>::type
sign_of_determinant(Mat_ const&m,bool=false)
{
return CGAL::sign(m.determinant());
}
template<class Vec1,class Vec2> static typename Canonicalize_vector<Vec1>::type homogeneous_add(Vec1 const&a,Vec2 const&b){
//TODO: use compile-time size when available
int d=a.size();
typename Canonicalize_vector<Vec1>::type v(d);
v << b[d-1]*a.topRows(d-1)+a[d-1]*b.topRows(d-1), a[d-1]*b[d-1];
return v;
}
template<class Vec1,class Vec2> static typename Canonicalize_vector<Vec1>::type homogeneous_sub(Vec1 const&a,Vec2 const&b){
int d=a.size();
typename Canonicalize_vector<Vec1>::type v(d);
v << b[d-1]*a.topRows(d-1)-a[d-1]*b.topRows(d-1), a[d-1]*b[d-1];
return v;
}
template<class Vec1,class Vec2> static std::pair<NT,NT> homogeneous_dot_product(Vec1 const&a,Vec2 const&b){
int d=a.size();
return make_pair(a.topRows(d-1).dot(b.topRows(d-1)), a[d-1]*b[d-1]);
}
};
}
#endif

View File

@ -0,0 +1,110 @@
#ifndef ecs_h
#define ecs_h
#include <CGAL/marcutils.h>
#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
namespace CGAL {
template <class Vector_> struct Construct_eigen {
typedef Vector_ result_type;
typedef typename Vector_::Scalar NT;
struct Dimension {
result_type operator()(int d) const {
return result_type(d);
}
};
struct Iterator {
template<typename Iter>
result_type operator()(int d,Iter const& f,Iter const& e) const {
CGAL_assertion(d==std::distance(f,e));
CGAL_assertion(d<=std::min(result_type::SizeAtCompileTime,result_type::MaxSizeAtCompileTime));
result_type a(d);
// TODO: check the right way to do this
std::copy(f,e,&a[0]);
return a;
}
};
#if 0
struct Iterator_add_one {
template<typename Iter>
result_type operator()(int d,Iter const& f,Iter const& e) const {
CGAL_assertion(d==std::distance(f,e)+1);
CGAL_assertion(d<=std::min(result_type::SizeAtCompileTime,result_type::MaxSizeAtCompileTime));
result_type a;
std::copy(f,e,&a[0]);
a[d-1]=1;
return a;
}
};
#endif
struct Iterator_and_last {
template<typename Iter,typename T>
result_type operator()(int d,Iter const& f,Iter const& e,CGAL_FORWARDABLE(T) t) const {
CGAL_assertion(d==std::distance(f,e)+1);
CGAL_assertion(d<=std::min(result_type::SizeAtCompileTime,result_type::MaxSizeAtCompileTime));
result_type a;
std::copy(f,e,&a[0]);
a[d-1]=CGAL_FORWARD(T,t);
return a;
}
};
#ifdef CGAL_CXX0X
struct Initializer_list {
template<class...U>
result_type operator()(std::initializer_list<NT> l) const {
return Iterator()(l.size(),l.begin(),l.end());
}
};
#endif
struct Values {
#ifdef CGAL_CXX0X
template<class...U>
result_type operator()(U&&...u) const {
return Initializer_list()({forward_safe<NT,U>(u)...});
}
#else
#define CODE(Z,N,_) result_type operator()(BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \
CGAL_assertion(N<=std::min(result_type::SizeAtCompileTime,result_type::MaxSizeAtCompileTime)); \
result_type a(N); \
a << BOOST_PP_ENUM_PARAMS(N,t); \
return a; \
}
BOOST_PP_REPEAT_FROM_TO(1, 11, CODE, _ )
#undef CODE
#endif
};
struct Values_divide {
#ifdef CGAL_CXX0X
template<class H,class...U>
result_type operator()(H const&h,U&&...u) const {
return Initializer_list()({Rational_traits<NT>().make_rational(std::forward<U>(u),h)...});
}
#else
#define VAR(Z,N,_) ( t##N / h )
#define CODE(Z,N,_) template <class H> result_type \
operator()(H const&h, BOOST_PP_ENUM_PARAMS(N,NT const& t)) const { \
CGAL_assertion(N<=std::min(result_type::SizeAtCompileTime,result_type::MaxSizeAtCompileTime)); \
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

View File

@ -0,0 +1,69 @@
#ifndef CGAL_ARGUMENT_SWAPS_H
#define CGAL_ARGUMENT_SWAPS_H
#include <CGAL/config.h>
#include <utility>
#ifndef CGAL_CXX0X
#include <boost/preprocessor/repetition.hpp>
#include <boost/utility/result_of.hpp>
#endif
namespace CGAL {
#ifdef CGAL_CXX0X
namespace internal {
template<int,class...> struct Apply_to_last_then_rest_;
template<int d,class F,class T,class... U>
struct Apply_to_last_then_rest_<d,F,T,U...> {
typedef typename Apply_to_last_then_rest_<d-1,F,U...,T>::result_type result_type;
inline result_type operator()(F&&f,T&&t,U&&...u)const{
return Apply_to_last_then_rest_<d-1,F,U...,T>()(
std::forward<F>(f),
std::forward<U>(u)...,
std::forward<T>(t));
}
};
template<class F,class T,class... U>
struct Apply_to_last_then_rest_<0,F,T,U...> {
typedef decltype(std::declval<F>()(std::declval<T>(), std::declval<U>()...)) result_type;
inline result_type operator()(F&&f,T&&t,U&&...u)const{
return std::forward<F>(f)(std::forward<T>(t), std::forward<U>(u)...);
}
};
} // namespace internal
struct Apply_to_last_then_rest {
template<class F,class T,class...U> inline
typename internal::Apply_to_last_then_rest_<sizeof...(U),F,T,U...>::result_type
operator()(F&&f,T&&t,U&&...u)const{
return internal::Apply_to_last_then_rest_<sizeof...(U),F,T,U...>()(
std::forward<F>(f),
std::forward<T>(t),
std::forward<U>(u)...);
}
};
#else // CGAL_CXX0X
struct Apply_to_last_then_rest {
#define CODE(Z,N,_) template<class F,class T,BOOST_PP_ENUM_PARAMS(N,class T)> \
typename boost::result_of<F(T,BOOST_PP_ENUM_PARAMS(N,T))>::type \
operator()(F const&f, BOOST_PP_ENUM_BINARY_PARAMS(N,T,const&t), T const&t) const { \
return f(t,BOOST_PP_ENUM_PARAMS(N,t)); \
}
BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_)
#undef CODE
};
#endif // CGAL_CXX0X
} // namespace CGAL
#endif // CGAL_ARGUMENT_SWAPS_H

View File

@ -0,0 +1,19 @@
#ifndef CGAL_EXACTNESS_H
#define CGAL_EXACTNESS_H
#include <boost/mpl/has_xxx.hpp>
#include <CGAL/tags.h>
namespace CGAL {
namespace internal {
BOOST_MPL_HAS_XXX_TRAIT_DEF(Is_exact)
}
template<class T,bool=internal::has_Is_exact<T>::value> struct Is_exact {
enum { value=false };
typedef Tag_false type;
};
template<class T> struct Is_exact<T,true> {
typedef typename T::Is_exact type;
enum { value=type::value };
};
}
#endif // CGAL_EXACTNESS_H

View File

@ -0,0 +1,37 @@
#ifndef CGAL_FUNCTOR_TAGS_H
#define CGAL_FUNCTOR_TAGS_H
namespace CGAL {
class Null_type {~Null_type();}; // no such object should be created
struct Vector_tag {};
struct Point_tag {};
struct Segment_tag {};
struct Line_tag {};
struct Direction_tag {};
struct Ray_tag {};
struct Bbox_tag {};
struct Construct_vector_tag {};
struct Construct_point_tag {};
struct Construct_segment_tag {};
struct Construct_line_tag {};
struct Construct_direction_tag {};
struct Construct_ray_tag {};
struct Construct_cartesian_const_iterator_tag {};
struct Construct_midpoint_tag {};
struct Construct_sum_of_vectors_tag {};
struct Construct_difference_of_vectors_tag {};
struct Construct_opposite_vector_tag {};
struct Compute_cartesian_coordinate_tag {};
struct Compute_homogeneous_coordinate_tag {};
struct Compute_squared_distance_tag {};
struct Compute_squared_length_tag {};
struct Predicate_less_cartesian_coordinate_tag {};
//FIXME: choose a convention
struct Predicate_orientation_tag {};
struct Orientation_tag {};
struct Predicate_in_sphere_tag {};
}
#endif // CGAL_FUNCTOR_TAGS_H

View File

@ -0,0 +1,41 @@
#ifndef CGAL_ITERATOR_FROM_INDICES_H
#define CGAL_ITERATOR_FROM_INDICES_H
#include <boost/iterator/iterator_facade.hpp>
namespace CGAL {
//TODO: default type for Value_: typename same_cv<Container_,typename remove_cv<Container_>::type::value_type>::type
template <class Container_, class Value_, class Ref_=
#ifdef CGAL_CXX0X
decltype(std::declval<Container_>()[0])
#else
Value_&
#endif
>
class Iterator_from_indices
: public boost::iterator_facade<Iterator_from_indices<Container_,Value_,Ref_>,
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;
void increment(){ ++index; }
void decrement(){ --index; }
void advance(std::ptrdiff_t n){ index+=n; }
ptrdiff_t distance_to(Iterator_from_indices const& other)const{
return static_cast<ptrdiff_t>(other.index)
-static_cast<ptrdiff_t>(index);
}
bool equal(Iterator_from_indices const& other)const{
return index==other.index;
}
Ref_ dereference()const{
return cont[index];
}
public:
Iterator_from_indices(Container_& cont_,std::size_t n)
: cont(cont_), index(n) {}
};
}
#endif // CGAL_ITERATOR_FROM_INDICES_H

View File

@ -0,0 +1,129 @@
#ifndef marcutils
#define marcutils
#ifdef CGAL_CXX0X
#include <type_traits>
#include <utility>
#define CGAL_FORWARDABLE(T) T&&
#define CGAL_FORWARD(T,t) std::forward<T>(t)
#define CGAL_MOVE(t) std::move(t)
#define CGAL_CONSTEXPR constexpr
#else
#define CGAL_FORWARDABLE(T) T const&
#define CGAL_FORWARD(T,t) t
#define CGAL_MOVE(t) t
#define CGAL_CONSTEXPR
#endif
#include <boost/type_traits/is_arithmetic.hpp>
#include <boost/utility/enable_if.hpp>
#include <CGAL/Rational_traits.h>
namespace CGAL {
// tell a function f(a,b,c) that its real argument is a(b,c)
struct Eval_functor {};
// forget the first argument. Useful to make something dependant
// (and thus usable in SFINAE), although that's not a great design.
template<class A,class B> struct Second_arg {
typedef B type;
};
// like std::forward, except for basic types where it does a cast, to
// avoid issues with narrowing conversions
#ifdef CGAL_CXX0X
template<class T,class U,class V>
typename std::conditional<std::is_arithmetic<T>::value&&std::is_arithmetic<typename std::remove_reference<U>::type>::value,T,U&&>::type
forward_safe(V&& u) { return std::forward<U>(u); }
#else
template<class T,class U> U const& forward_safe(U const& u) {
return u;
}
#endif
#ifdef CGAL_CXX0X
template<class...> struct Constructible_from_each;
template<class To,class From1,class...From> struct Constructible_from_each<To,From1,From...>{
enum { value=std::is_convertible<From1,To>::value&&Constructible_from_each<To,From...>::value };
};
template<class To> struct Constructible_from_each<To>{
enum { value=true };
};
#else
// currently only used in C++0X code
#endif
template<class T> struct Scale {
T const& scale;
Scale(T const& t):scale(t){}
template<class FT>
#ifdef CGAL_CXX0X
auto operator()(FT&& x)const->decltype(scale*std::forward<FT>(x))
#else
FT operator()(FT const& x)const
#endif
{
return scale*CGAL_FORWARD(FT,x);
}
};
template<class NT,class T> struct Divide {
#if !defined(CGAL_CXX0X) || !defined(BOOST_RESULT_OF_USE_DECLTYPE)
// requires boost > 1.44
// shouldn't be needed with C++0X
//template<class> struct result;
//template<class FT> struct result<Divide(FT)> {
// typedef FT type;
//};
typedef NT result_type;
#endif
T const& scale;
Divide(T const& t):scale(t){}
template<class FT>
#ifdef CGAL_CXX0X
//FIXME: gcc complains for Gmpq
//auto operator()(FT&& x)const->decltype(Rational_traits<NT>().make_rational(std::forward<FT>(x),scale))
NT operator()(FT&& x)const
#else
NT operator()(FT const& x)const
#endif
{
return Rational_traits<NT>().
make_rational(CGAL_FORWARD(FT,x),scale);
}
};
template <class NT> struct has_cheap_constructor : boost::is_arithmetic<NT>{};
template <bool p> struct has_cheap_constructor<Interval_nt<p> > {
enum { value=true };
};
// like std::multiplies but allows mixing types
// in C++0x in doesn't need to be a template
template < class Ret >
struct multiplies {
template<class A,class B>
#ifdef CGAL_CXX0X
auto operator()(A&&a,B&&b)const->decltype(std::forward<A>(a)*std::forward<B>(b))
#else
Ret operator()(A const& a, B const& b)const
#endif
{
return CGAL_FORWARD(A,a)*CGAL_FORWARD(B,b);
}
};
template < class Ret >
struct division {
template<class A,class B>
#ifdef CGAL_CXX0X
auto operator()(A&&a,B&&b)const->decltype(std::forward<A>(a)/std::forward<B>(b))
#else
Ret operator()(A const& a, B const& b)const
#endif
{
return CGAL_FORWARD(A,a)/CGAL_FORWARD(B,b);
}
};
}
#endif

View File

@ -0,0 +1,43 @@
#ifndef myeigen_h
#define myeigen_h
#include <CGAL/basic.h>
#include <CGAL/Gmpq.h>
#include <Eigen/Core>
namespace Eigen {
template<> struct NumTraits<CGAL::Gmpq>
{
typedef CGAL::Gmpq Real;
typedef CGAL::Gmpq NonInteger;
typedef CGAL::Gmpq Nested;
enum {
IsComplex = 0,
IsInteger = 0,
IsSigned,
ReadCost = 10,
AddCost = 100,
MulCost = 1000
};
};
template<> struct NumTraits<CGAL::Interval_nt_advanced>
{
typedef CGAL::Interval_nt_advanced Real;
typedef CGAL::Interval_nt_advanced NonInteger;
typedef CGAL::Interval_nt_advanced Nested;
enum {
IsComplex = 0,
IsInteger = 0,
IsSigned,
ReadCost = 2,
AddCost = 2,
MulCost = 10
};
};
}
#endif

View File

@ -0,0 +1,42 @@
#ifndef CGAL_STATIC_INT_H
#define CGAL_STATIC_INT_H
#include <CGAL/constant.h>
namespace CGAL {
template <class NT> struct static_zero {
operator NT() const { return constant<NT,0>(); }
};
template <class NT> struct static_one {
operator NT() const { return constant<NT,1>(); }
};
template <class NT> static_zero<NT> operator-(static_zero<NT>) { return static_zero<NT>(); }
template <class NT> NT operator+(NT const& x, static_zero<NT>) { return x; }
template <class NT> NT operator+(static_zero<NT>, NT const& x) { return x; }
template <class NT> static_zero<NT> operator+(static_zero<NT>, static_zero<NT>) { return static_zero<NT>(); }
template <class NT> static_one<NT> operator+(static_zero<NT>, static_one<NT>) { return static_one<NT>(); }
template <class NT> static_one<NT> operator+(static_one<NT>, static_zero<NT>) { return static_one<NT>(); }
template <class NT> NT operator-(NT const& x, static_zero<NT>) { return x; }
template <class NT> NT operator-(static_zero<NT>, NT const& x) { return -x; }
template <class NT> static_zero<NT> operator-(static_zero<NT>, static_zero<NT>) { return static_zero<NT>(); }
template <class NT> static_zero<NT> operator-(static_one<NT>, static_one<NT>) { return static_zero<NT>(); }
template <class NT> static_one<NT> operator-(static_one<NT>, static_zero<NT>) { return static_one<NT>(); }
template <class NT> NT operator*(NT const& x, static_one<NT>) { return x; }
template <class NT> NT operator*(static_one<NT>, NT const& x) { return x; }
template <class NT> static_zero<NT> operator*(NT const&, static_zero<NT>) { return static_zero<NT>(); }
template <class NT> static_zero<NT> operator*(static_zero<NT>, NT const&) { return static_zero<NT>(); }
template <class NT> static_zero<NT> operator*(static_zero<NT>, static_zero<NT>) { return static_zero<NT>(); }
template <class NT> static_one<NT> operator*(static_one<NT>, static_one<NT>) { return static_one<NT>(); }
template <class NT> static_zero<NT> operator*(static_zero<NT>, static_one<NT>) { return static_zero<NT>(); }
template <class NT> static_zero<NT> operator*(static_one<NT>, static_zero<NT>) { return static_zero<NT>(); }
template <class NT> NT operator/(NT const& x, static_one<NT>) { return x; }
template <class NT> static_zero<NT> operator/(static_zero<NT>, NT const&) { return static_zero<NT>(); }
template <class NT> static_zero<NT> operator/(static_zero<NT>, static_one<NT>) { return static_zero<NT>(); }
template <class NT> static_one<NT> operator/(static_one<NT>, static_one<NT>) { return static_one<NT>(); }
}
#endif // CGAL_STATIC_INT_H

View File

@ -0,0 +1,92 @@
#ifndef CGAL_TRANSFORMING_ITERATOR_H
#define CGAL_TRANSFORMING_ITERATOR_H
#include <boost/iterator/iterator_adaptor.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/type_traits/is_empty.hpp>
#include <CGAL/Default.h>
#include <utility>
// Inspired by the boost version, but more compact and
// without any iterator_category games.
namespace CGAL {
namespace internal {
// non-empty case
template<class T,bool=boost::is_empty<T>::value> struct Functor_as_base {
Functor_as_base(){}
Functor_as_base(T const& t):f(t){}
//template<class T2> Functor_as_base(Functor_as_base<T2> const&g):f(g.functor()){}
T const& functor()const{return f;}
T & functor() {return f;}
private:
T f;
};
// empty case
template<class T> struct Functor_as_base<T,true> : public T {
Functor_as_base(){}
Functor_as_base(T const& t):T(t){}
//template<class T2> Functor_as_base(Functor_as_base<T2> const&g):T(g.functor()){}
T const& functor()const{return *this;}
T & functor() {return *this;}
};
template <typename Derived, typename F, typename Iter, typename Ref, typename Val>
class transforming_iterator_helper
{
typedef typename Default::Get<Ref,
#ifndef CGAL_CFG_NO_CPP0X_DECLTYPE
decltype(std::declval<F>()(std::declval<typename std::iterator_traits<Iter>::reference>()))
#else
typename boost::result_of<F(typename std::iterator_traits<Iter>::value_type)>::type
// should be reference instead of value_type
#endif
>::type reference;
typedef typename Default::Get<Val,typename boost::remove_cv<typename boost::remove_reference<reference>::type>::type>::type value_type;
public:
typedef boost::iterator_adaptor<
Derived,
Iter,
value_type,
typename std::iterator_traits<Iter>::iterator_category,
reference
> type;
};
}
template <typename F, typename Iter, typename Ref=Default, typename Val=Default>
class transforming_iterator
: public internal::transforming_iterator_helper<transforming_iterator<F,Iter,Ref,Val>,F,Iter,Ref,Val>::type,
private internal::Functor_as_base<F>
{
friend class boost::iterator_core_access;
typedef typename internal::transforming_iterator_helper<transforming_iterator,F,Iter,Ref,Val>::type Base;
typedef internal::Functor_as_base<F> Functor_base;
typename Base::reference dereference()const{
return functor()(*this->base_reference());
}
public:
using Functor_base::functor;
transforming_iterator(){}
explicit transforming_iterator(Iter const&i,F const& f=F())
:Base(i),Functor_base(f){}
template<class F2,class I2,class R2,class V2>
transforming_iterator(
transforming_iterator<F2,I2,R2,V2> const&i,
typename boost::enable_if_convertible<I2, Iter>::type* = 0,
typename boost::enable_if_convertible<F2, F>::type* = 0)
: Base(i.base()),Functor_base(i.functor()) {}
};
template <typename F, typename Iter>
transforming_iterator<F,Iter> make_transforming_iterator(Iter const&i, F const&f=F()) {
return transforming_iterator<F,Iter>(i,f);
}
}
#endif // CGAL_TRANSFORMING_ITERATOR_H

View File

@ -0,0 +1,107 @@
#ifndef CGAL_TRANSFORMING_PAIR_ITERATOR_H
#define CGAL_TRANSFORMING_PAIR_ITERATOR_H
// Should be a combination of transform_iterator and zip_iterator,
// but boost's iterator_category games are a pain.
#include <CGAL/transforming_iterator.h>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/static_assert.hpp>
namespace CGAL {
namespace internal {
template <class Cat1, class Cat2, bool=boost::is_convertible<Cat1,Cat2>::value>
struct Min_category {
BOOST_STATIC_ASSERT((boost::is_convertible<Cat2,Cat1>::value));
typedef Cat1 type;
};
template <class Cat1, class Cat2>
struct Min_category<Cat1,Cat2,true> {
typedef Cat2 type;
};
template <typename Derived, typename F, typename It1, typename It2, typename Ref, typename Val>
class transforming_pair_iterator_helper
{
typedef typename Min_category<
typename std::iterator_traits<It1>::iterator_category,
typename std::iterator_traits<It1>::iterator_category>
::type iterator_category;
typedef typename Default::Get<Ref,
#ifndef CGAL_CFG_NO_CPP0X_DECLTYPE
decltype(std::declval<F>()(std::declval<typename std::iterator_traits<It1>::reference>(),std::declval<typename std::iterator_traits<It2>::reference>()))
#else
typename boost::result_of<F(typename std::iterator_traits<It1>::value_type,typename std::iterator_traits<It2>::value_type)>::type
// should be reference instead of value_type
#endif
>::type reference;
typedef typename Default::Get<Val,typename boost::remove_cv<typename boost::remove_reference<reference>::type>::type>::type value_type;
public:
typedef boost::iterator_facade<
Derived,
value_type,
iterator_category,
reference
// expect ptrdiff_t is good enough for difference
> type;
};
}
template <typename F, typename It1, typename It2, typename Ref=Default, typename Val=Default>
class transforming_pair_iterator
: public internal::transforming_pair_iterator_helper<transforming_pair_iterator<F,It1,It2,Ref,Val>,F,It1,It2,Ref,Val>::type,
private internal::Functor_as_base<F>
{
It1 iter1; It2 iter2;
friend class boost::iterator_core_access;
typedef typename internal::transforming_pair_iterator_helper<transforming_pair_iterator,F,It1,It2,Ref,Val>::type Base;
typedef internal::Functor_as_base<F> Functor_base;
typename Base::reference dereference()const{
return functor()(*iter1,*iter2);
}
bool equal(transforming_pair_iterator const&i)const{
bool b=(iter1==i.iter1);
CGAL_assertion(b==(iter2==i.iter2));
//FIXME: or do we want only one driving iterator
return b;
}
void increment(){ ++iter1; ++iter2; }
void decrement(){ --iter1; --iter2; }
void advance(std::ptrdiff_t n){
std::advance(iter1,n);
std::advance(iter2,n);
}
std::ptrdiff_t distance_to(transforming_pair_iterator const&i)const{
std::ptrdiff_t dist=std::distance(iter1,i.iter1);
CGAL_assertion(dist==std::distance(iter2,i.iter2));
return dist;
}
public:
using Functor_base::functor;
transforming_pair_iterator(){}
explicit transforming_pair_iterator(It1 const&i1,It2 const&i2,F const& f=F())
:Functor_base(f),iter1(i1),iter2(i2){}
template<class F2,class J1,class J2,class R2,class V2>
transforming_pair_iterator(
transforming_pair_iterator<F2,J1,J2,R2,V2> const&i,
typename boost::enable_if_convertible<J1, It1>::type* = 0,
typename boost::enable_if_convertible<J2, It2>::type* = 0,
typename boost::enable_if_convertible<F2, F>::type* = 0)
: Functor_base(i.functor()),iter1(i.iter1),iter2(i.iter2) {}
};
template <typename F, typename It1, typename It2>
transforming_pair_iterator<F,It1,It2> make_transforming_pair_iterator(It1 const&i1, It2 const&i2, F const&f=F()) {
return transforming_pair_iterator<F,It1,It2>(i1,i2,f);
}
}
#endif // CGAL_TRANSFORMING_PAIR_ITERATOR_H