#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 #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 R_::FT FT; typedef typename R::template Type::type Point; typedef typename R::Orientation result_type; typedef typename R::LA::template Matrix::type Matrix; template result_type operator()(Iter f, Iter e)const{ typename R::template Functor::type c(this->kernel()); typename R::template 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 R::template 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 R_::FT FT; typedef typename R::template Type::type Point; typedef typename R::Orientation 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 R::template 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 f, Iter const&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,_) FT 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 R_::FT FT; \ typedef typename R::template Type::type Point; \ typedef typename R::Orientation result_type; \ result_type operator()(Point const&x, BOOST_PP_ENUM_PARAMS(N,Point const&p)) const { \ typename R::template 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 e)const{ \ Point const&x=*f; \ BOOST_PP_REPEAT(N,VAR3,) \ return operator()(x,BOOST_PP_ENUM_PARAMS(N,p)); \ } \ }; BOOST_PP_REPEAT_FROM_TO(2, 7, CODE, _ ) #undef CODE #undef VAR2 #undef VAR #endif template struct Orientation_of_vectors : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Orientation_of_vectors) typedef R_ R; typedef typename R_::FT FT; typedef typename R::template Type::type Vector; typedef typename R::Orientation result_type; typedef typename R::LA::template Matrix::type Matrix; template result_type operator()(Iter f, Iter e)const{ typename R::template Functor::type c(this->kernel()); typename R::template Functor::type vd(this->kernel()); 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 }; #if 0 template::value> struct Orientation : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(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::template Functor::type OP; typedef typename R::template 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 R::template 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 R_::FT FT; typedef typename R::Vector Vector; typedef typename R::Point Point; typedef typename R::Orientation result_type; typedef typename R::template Functor::type OP; typedef typename R::template Functor::type OV; typedef typename R::LA::template Matrix::type 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 R_::FT FT; typedef typename R::template Type::type Point; typedef typename R::Oriented_side result_type; typedef typename Increment_dimension::type D1; typedef typename Increment_dimension::type D2; typedef typename R::LA::template Matrix::type Matrix; template result_type operator()(Iter f, Iter const& e)const{ typename R::template Functor::type c(this->kernel()); typename R::template Functor::type pd(this->kernel()); Point const& p0=*f++; int d=pd(p0); FT sq=0; 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 }; template struct Construct_opposite_vector : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Construct_opposite_vector) typedef R_ R; typedef typename R_::FT FT; typedef typename R::template Type::type Vector; typedef typename R::template Functor >::type CV; typedef typename R::template 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())); } }; template struct Construct_sum_of_vectors : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Construct_sum_of_vectors) typedef R_ R; typedef typename R_::FT FT; typedef typename R::template Type::type Vector; typedef typename R::template Functor >::type CV; typedef typename R::template 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())); } }; template struct Construct_difference_of_vectors : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Construct_difference_of_vectors) typedef R_ R; typedef typename R_::FT FT; typedef typename R::template Type::type Vector; typedef typename R::template Functor >::type CV; typedef typename R::template 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())); } }; template struct Construct_midpoint : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Construct_midpoint) typedef R_ R; typedef typename R_::FT FT; typedef typename R::template Type::type Point; typedef typename R::template Functor >::type CP; typedef typename R::template Functor >::type CI; typedef Point result_type; typedef Point first_argument_type; typedef Point second_argument_type; struct Average : std::binary_function { 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(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())); } }; template struct Compute_squared_length : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Compute_squared_length) typedef R_ R; typedef typename R_::FT FT; typedef typename R::template Type::type Vector; typedef typename R::template Functor >::type CI; typedef FT 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 FT(0)+... return std::accumulate(make_transforming_iterator(ci(a,Begin_tag()),f),make_transforming_iterator(ci(a,End_tag()),f),FT(0)); } }; template struct Compute_squared_distance : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Compute_squared_distance) typedef R_ R; typedef typename R_::FT FT; typedef typename R::template Type::type Point; typedef typename R::template Functor >::type CI; typedef FT result_type; typedef Point first_argument_type; typedef Point second_argument_type; struct Sq_diff : std::binary_function { 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(this->kernel()); Sq_diff f; // TODO: avoid this FT(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),FT(0)); } }; template struct Compare_distance : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Compare_distance) typedef R_ R; typedef typename R_::FT FT; typedef typename R::template Type::type Point; typedef typename R::template Functor::type CSD; typedef typename R_::Comparison_result 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)); } }; template struct Less_point_cartesian_coordinate : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Less_point_cartesian_coordinate) typedef R_ R; typedef typename R_::FT FT; typedef typename R::Boolean result_type; typedef typename R::template 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::type Is_exact; template result_type operator()(V const&a, W const&b, I i)const{ Cc c(this->kernel()); return c(a,i) struct Compare_point_cartesian_coordinate : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Compare_point_cartesian_coordinate) typedef R_ R; typedef typename R_::FT FT; typedef typename R::Comparison_result result_type; typedef typename R::template 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::type 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)); } }; template struct Compare_lexicographically : private Store_kernel { CGAL_FUNCTOR_INIT_STORE(Compare_lexicographically) typedef R_ R; typedef typename R_::FT FT; typedef typename R::Comparison_result result_type; typedef typename R::template 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::type 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; } }; } } #include #endif // CGAL_KERNEL_D_FUNCTION_OBJECTS_CARTESIAN_H