#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 { namespace internal { template struct Map_tuple_tags_to_tuple_types; #ifdef CGAL_CXX0X template struct Map_tuple_tags_to_tuple_types > { typedef cpp0x::tuple::type...> type; }; #else template struct Map_tuple_tags_to_tuple_types > { typedef cpp0x::tuple<> type; }; #define CODE(Z,N,_) template \ struct Map_tuple_tags_to_tuple_types > { \ typedef cpp0x::tuple::type BOOST_PP_INTERCEPT)> type; \ }; BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_) #undef CODE #endif } 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(); } }; #ifdef CGAL_CXX0X template struct Object_converter > { typedef Object result_type; template result_type operator()(Object const& o, F const& f) const { if (const T * ptr = object_cast(&o)) return make_object(f(*ptr)); else return Object_converter >()(o,f); } }; #else #define CODE(Z,N,_) template \ struct Object_converter > { \ typedef Object result_type; \ template \ result_type operator()(Object const& o, F const& f) const { \ if (const T0 * ptr = object_cast(&o)) \ return make_object(f(*ptr)); \ else \ return Object_converter >()(o,f); \ } \ }; BOOST_PP_REPEAT_FROM_TO(1,11,CODE,_) #undef CODE #endif //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); } 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_tuple_tags_to_tuple_types::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