#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 namespace CGAL { //TODO: special case when K1==K2 (or they are very close?) template class CartesianD_converter_; template class CartesianD_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);} }; #ifdef CGAL_CXX0X template class CartesianD_converter_ > : public CartesianD_converter_ > { typedef CartesianD_converter_ > Base; typedef KO_converter KOC; 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 operator()(K1_Obj const& o)const{ return KOC()(this->myself().kernel(),this->myself().kernel2(),this->myself(),o); } template struct result:Base::template result{}; template struct result {typedef K2_Obj type;}; }; #else #define CODE(Z,N,_) \ template class CartesianD_converter_ > \ : public CartesianD_converter_ > \ { \ typedef CartesianD_converter_ > Base; \ typedef KO_converter KOC; \ typedef typename KOC::argument_type K1_Obj; \ typedef typename KOC::result_type K2_Obj; \ public: \ using Base::operator(); \ K2_Obj operator()(K1_Obj const& o)const{ \ return KOC()(this->myself().kernel(),this->myself().kernel2(),this->myself(),o); \ } \ template struct result:Base::template result{}; \ template struct result {typedef K2_Obj type;}; \ }; BOOST_PP_REPEAT_FROM_TO(0, 8, CODE, _ ) #undef CODE #endif template > class CartesianD_converter : public Store_kernel, public Store_kernel2, public CartesianD_converter_,K1,K2,List_> { typedef CartesianD_converter Self; typedef Self Final_; typedef CartesianD_converter_ Base; typedef typename K1::FT FT1; typedef typename K2::FT 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: CartesianD_converter(){} CartesianD_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);} template transforming_iterator,It>::type> operator()(It const& it)const { return make_transforming_iterator(it,*this); } Object operator()(const Object &obj) const { //TODO: use the tags from List_ instead #define CGAL_Kernel_obj(X,Y) \ if (const typename K1::template Type::type * ptr = object_cast::type>(&obj)) \ return make_object(operator()(*ptr)); #include /* if (const std::vector * ptr = object_cast >(&obj)) { std::vector res ( operator()(ptr->begin()), operator()(ptr->end()) ); return make_object(res); } */ CGAL_error_msg("Cartesiand_converter is unable to determine what is wrapped in the Object"); return Object(); } //TODO: convert boost::variant }; } //namespace CGAL #endif // CGAL_KERNEL_D_CARTESIAN_CONVERTER_H