// Copyright (c) 2014 // INRIA Saclay-Ile de France (France) // // 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) : Marc Glisse #ifndef CGAL_FUNCTOR_TAGS_H #define CGAL_FUNCTOR_TAGS_H #include // for Null_tag #include #ifdef CGAL_CXX11 #include #include #endif #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_CXX11 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> {}; //// This version does not like Functor //namespace internal { BOOST_MPL_HAS_XXX_TEMPLATE_NAMED_DEF(has_Functor,Functor,false) } // This version lets us use non-type template parameters, but fails with older EDG-based compilers (Intel 14). 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 CGAL_DECL_OBJ_(X,Y) \ template \ struct Typedef_tag_type : Base { typedef Obj X; }; \ template \ struct Get_type_category { typedef Y##_tag type; } #define CGAL_DECL_OBJ(X,Y) struct X##_tag {}; \ CGAL_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. CGAL_DECL_OBJ(FT, Number); CGAL_DECL_OBJ(RT, Number); CGAL_DECL_OBJ(Bool, Discrete); // Boolean_tag is already taken, and is a template :-( CGAL_DECL_OBJ(Comparison_result, Discrete); CGAL_DECL_OBJ(Sign, Discrete); CGAL_DECL_OBJ(Orientation, Discrete); // Note: duplicate with the functor tag! CGAL_DECL_OBJ(Oriented_side, Discrete); CGAL_DECL_OBJ(Bounded_side, Discrete); CGAL_DECL_OBJ(Angle, Discrete); CGAL_DECL_OBJ(Flat_orientation, Discrete); CGAL_DECL_OBJ(Vector, Object); CGAL_DECL_OBJ(Point, Object); CGAL_DECL_OBJ(Segment, Object); CGAL_DECL_OBJ(Sphere, Object); CGAL_DECL_OBJ(Line, Object); CGAL_DECL_OBJ(Direction, Object); CGAL_DECL_OBJ(Hyperplane, Object); CGAL_DECL_OBJ(Ray, Object); CGAL_DECL_OBJ(Iso_box, Object); CGAL_DECL_OBJ(Bbox, Object); CGAL_DECL_OBJ(Aff_transformation, Object); CGAL_DECL_OBJ(Weighted_point, Object); #undef CGAL_DECL_OBJ_ #undef CGAL_DECL_OBJ // Intel fails with those, and they are not so useful. // CGAL_KD_DEFAULT_TYPE(RT_tag,(typename Get_type::type),(),()); // CGAL_KD_DEFAULT_TYPE(FT_tag,(CGAL::Quotient::type>),(),()); #define CGAL_SMURF2(A,B) CGAL_KD_DEFAULT_TYPE(A##_tag,(typename Same_uncertainty_nt::type>::type),(RT_tag),()) #define CGAL_SMURF1(A) CGAL_SMURF2(A,CGAL::A) CGAL_SMURF2(Bool, bool); CGAL_SMURF1(Sign); CGAL_SMURF1(Comparison_result); CGAL_SMURF1(Orientation); CGAL_SMURF1(Oriented_side); CGAL_SMURF1(Bounded_side); CGAL_SMURF1(Angle); #undef CGAL_SMURF1 #undef CGAL_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 CGAL_DECL_COMPUTE(X) struct X##_tag {}; \ templatestruct Get_functor_category{typedef Compute_tag type;} CGAL_DECL_COMPUTE(Compute_point_cartesian_coordinate); CGAL_DECL_COMPUTE(Compute_vector_cartesian_coordinate); CGAL_DECL_COMPUTE(Compute_homogeneous_coordinate); CGAL_DECL_COMPUTE(Squared_distance); CGAL_DECL_COMPUTE(Squared_distance_to_origin); CGAL_DECL_COMPUTE(Squared_length); CGAL_DECL_COMPUTE(Squared_radius); CGAL_DECL_COMPUTE(Squared_circumradius); CGAL_DECL_COMPUTE(Scalar_product); CGAL_DECL_COMPUTE(Hyperplane_translation); CGAL_DECL_COMPUTE(Value_at); CGAL_DECL_COMPUTE(Point_weight); CGAL_DECL_COMPUTE(Power_distance); CGAL_DECL_COMPUTE(Power_distance_to_point); #undef CGAL_DECL_COMPUTE #define CGAL_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; } CGAL_DECL_ITER_OBJ(Vector_cartesian_const_iterator, FT, Compute_vector_cartesian_coordinate, Vector); CGAL_DECL_ITER_OBJ(Point_cartesian_const_iterator, FT, Compute_point_cartesian_coordinate, Point); #undef CGAL_DECL_ITER_OBJ templatestruct map_result_tag{typedef Null_type type;}; templatestruct map_result_tag >{typedef T type;}; templatestruct Get_functor_category,B,C> : boost::mpl::if_c::is_iterator, Construct_iterator_tag, Construct_tag> {}; // Really? templatestruct Get_functor_category,B,C>{typedef Misc_tag type;}; #define CGAL_DECL_CONSTRUCT(X,Y) struct X##_tag {}; \ template<>struct map_result_tag{typedef Y##_tag type;}; \ templatestruct Get_functor_category{typedef Construct_tag type;} CGAL_DECL_CONSTRUCT(Midpoint,Point); CGAL_DECL_CONSTRUCT(Center_of_sphere,Point); CGAL_DECL_CONSTRUCT(Point_of_sphere,Point); CGAL_DECL_CONSTRUCT(Segment_extremity,Point); CGAL_DECL_CONSTRUCT(Sum_of_vectors,Vector); CGAL_DECL_CONSTRUCT(Difference_of_vectors,Vector); CGAL_DECL_CONSTRUCT(Opposite_vector,Vector); CGAL_DECL_CONSTRUCT(Scaled_vector,Vector); CGAL_DECL_CONSTRUCT(Orthogonal_vector,Vector); CGAL_DECL_CONSTRUCT(Difference_of_points,Vector); CGAL_DECL_CONSTRUCT(Translated_point,Point); CGAL_DECL_CONSTRUCT(Point_to_vector,Vector); CGAL_DECL_CONSTRUCT(Vector_to_point,Point); CGAL_DECL_CONSTRUCT(Construct_min_vertex,Point); CGAL_DECL_CONSTRUCT(Construct_max_vertex,Point); CGAL_DECL_CONSTRUCT(Construct_circumcenter,Point); CGAL_DECL_CONSTRUCT(Point_drop_weight,Point); CGAL_DECL_CONSTRUCT(Power_center,Weighted_point); #undef CGAL_DECL_CONSTRUCT #if 0 #define CGAL_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;} CGAL_DECL_ITER_CONSTRUCT(Construct_point_cartesian_const_iterator,Point_cartesian_const_iterator); CGAL_DECL_ITER_CONSTRUCT(Construct_vector_cartesian_const_iterator,Vector_cartesian_const_iterator); #undef CGAL_DECL_ITER_CONSTRUCT #endif //FIXME: choose a convention: prefix with Predicate_ ? #define CGAL_DECL_PREDICATE_(X) \ templatestruct Get_functor_category{typedef Predicate_tag type;} #define CGAL_DECL_PREDICATE(X) struct X##_tag {}; \ CGAL_DECL_PREDICATE_(X) CGAL_DECL_PREDICATE(Less_point_cartesian_coordinate); CGAL_DECL_PREDICATE(Compare_point_cartesian_coordinate); CGAL_DECL_PREDICATE(Compare_distance); CGAL_DECL_PREDICATE(Compare_lexicographically); CGAL_DECL_PREDICATE(Less_lexicographically); CGAL_DECL_PREDICATE(Less_or_equal_lexicographically); CGAL_DECL_PREDICATE(Equal_points); CGAL_DECL_PREDICATE(Has_on_positive_side); CGAL_DECL_PREDICATE_(Orientation); // duplicate with the type CGAL_DECL_PREDICATE_(Oriented_side); // duplicate with the type CGAL_DECL_PREDICATE(Orientation_of_points); CGAL_DECL_PREDICATE(Orientation_of_vectors); CGAL_DECL_PREDICATE(Side_of_oriented_sphere); CGAL_DECL_PREDICATE(Side_of_bounded_sphere); CGAL_DECL_PREDICATE(Side_of_bounded_circumsphere); CGAL_DECL_PREDICATE(Contained_in_affine_hull); CGAL_DECL_PREDICATE(In_flat_orientation); CGAL_DECL_PREDICATE(In_flat_side_of_oriented_sphere); CGAL_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 CGAL_DECL_PREDICATE(Linear_rank); CGAL_DECL_PREDICATE(Affine_rank); CGAL_DECL_PREDICATE(Linearly_independent); CGAL_DECL_PREDICATE(Affinely_independent); CGAL_DECL_PREDICATE(Contained_in_linear_hull); CGAL_DECL_PREDICATE(Contained_in_simplex); CGAL_DECL_PREDICATE(Power_side_of_power_sphere_raw); CGAL_DECL_PREDICATE(Power_side_of_power_sphere); CGAL_DECL_PREDICATE(In_flat_power_side_of_power_sphere_raw); CGAL_DECL_PREDICATE(In_flat_power_side_of_power_sphere); #undef CGAL_DECL_PREDICATE #define CGAL_DECL_MISC(X) struct X##_tag {}; \ templatestruct Get_functor_category{typedef Misc_tag type;} //TODO: split into _begin and _end ? //CGAL_DECL_MISC(Construct_point_cartesian_const_iterator); //CGAL_DECL_MISC(Construct_vector_cartesian_const_iterator); CGAL_DECL_MISC(Point_dimension); CGAL_DECL_MISC(Vector_dimension); CGAL_DECL_MISC(Linear_base); // Find a more appropriate category? #undef CGAL_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