// 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_MARCUTILS #define CGAL_MARCUTILS #include #if defined(BOOST_MSVC) # pragma warning(push) # pragma warning(disable:4003) // not enough actual parameters for macro 'BOOST_PP_EXPAND_I' // http://lists.boost.org/boost-users/2014/11/83291.php #endif #ifdef CGAL_CXX11 #include #include #define CGAL_FORWARDABLE(T) T&& #define CGAL_FORWARD(T,t) std::forward(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 #include #include #include #include #include #include #ifdef CGAL_CXX11 #define CGAL_BOOSTD std:: #else #define CGAL_BOOSTD boost:: #endif namespace CGAL { namespace internal { BOOST_MPL_HAS_XXX_TRAIT_DEF(type) } template ::value /*false*/> struct Has_type_different_from : boost::false_type {}; template struct Has_type_different_from : boost::mpl::not_ > {}; template struct Wrap_type { typedef T type; }; // 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 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_CXX11 template inline typename std::conditional::value&&std::is_arithmetic::type>::value,T,U&&>::type forward_safe(V&& u) { return std::forward(u); } #else template inline U const& forward_safe(U const& u) { return u; } #endif #ifdef CGAL_CXX11 template struct Constructible_from_each; template struct Constructible_from_each{ enum { value=std::is_convertible::value&&Constructible_from_each::value }; }; template struct Constructible_from_each{ enum { value=true }; }; #else // currently only used in C++0X code #endif template struct Scale { #ifndef CGAL_CXX11 template struct result; template struct result { typedef FT type; }; #endif T const& scale; Scale(T const& t):scale(t){} template #ifdef CGAL_CXX11 auto operator()(FT&& x)const->decltype(scale*std::forward(x)) #else FT operator()(FT const& x)const #endif { return scale*CGAL_FORWARD(FT,x); } }; template struct Divide { #if !defined(CGAL_CXX11) || !defined(BOOST_RESULT_OF_USE_DECLTYPE) // requires boost > 1.44 // shouldn't be needed with C++0X //template struct result; //template struct result { // typedef FT type; //}; typedef NT result_type; #endif T const& scale; Divide(T const& t):scale(t){} template #ifdef CGAL_CXX11 //FIXME: gcc complains for Gmpq //auto operator()(FT&& x)const->decltype(Rational_traits().make_rational(std::forward(x),scale)) NT operator()(FT&& x)const #else NT operator()(FT const& x)const #endif { return Rational_traits(). make_rational(CGAL_FORWARD(FT,x),scale); } }; template struct has_cheap_constructor : boost::is_arithmetic{}; template struct has_cheap_constructor > { enum { value=true }; }; // like std::multiplies but allows mixing types // in C++11 in doesn't need to be a template template < class Ret > struct multiplies { template #ifdef CGAL_CXX11 auto operator()(A&&a,B&&b)const->decltype(std::forward(a)*std::forward(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 #ifdef CGAL_CXX11 auto operator()(A&&a,B&&b)const->decltype(std::forward(a)/std::forward(b)) #else Ret operator()(A const& a, B const& b)const #endif { return CGAL_FORWARD(A,a)/CGAL_FORWARD(B,b); } }; #ifdef CGAL_CXX11 using std::decay; #else template struct decay : boost::remove_cv::type> {}; #endif template struct Type_copy_ref { typedef U type; }; template struct Type_copy_ref { typedef U& type; }; #ifdef CGAL_CXX11 template struct Type_copy_ref { typedef U&& type; }; #endif template struct Type_copy_cv { typedef U type; }; template struct Type_copy_cv { typedef U const type; }; template struct Type_copy_cv { typedef U volatile type; }; template struct Type_copy_cv { typedef U const volatile type; }; template struct Type_copy_cvref : Type_copy_ref::type,U>::type> {}; struct Dereference_functor { template struct result{}; template struct result { typedef typename std::iterator_traits::reference type; }; template typename result::type operator()(It const&i)const{ return *i; } }; #ifdef CGAL_CXX11 template struct Indices{}; template struct Next_increasing_indices; template struct Next_increasing_indices > { typedef Indices type; }; template struct N_increasing_indices { typedef typename Next_increasing_indices::type>::type type; }; template<> struct N_increasing_indices<0> { typedef Indices<> type; }; namespace internal { template inline typename std::result_of::type do_call_on_tuple_elements(F&&f, std::tuple&&t, Indices&&) { return f(std::get(std::move(t))...); } } // internal template inline typename std::result_of::type call_on_tuple_elements(F&&f, std::tuple&&t) { return internal::do_call_on_tuple_elements(std::forward(f),std::move(t), typename N_increasing_indices::type()); } #else #define CGAL_VAR(Z,N,_) cpp0x::get(t) #define CGAL_CODE(Z,N,_) template \ inline Res call_on_tuple_elements(F const&f, \ cpp0x::tuple const&t) { \ return f(BOOST_PP_ENUM(N,CGAL_VAR,)); \ } template inline Res call_on_tuple_elements(F const&f, cpp0x::tuple<>) { return f(); } BOOST_PP_REPEAT_FROM_TO(1, 8, CGAL_CODE, _ ) #undef CGAL_CODE #undef CGAL_VAR #endif template struct Factory { typedef A result_type; #ifdef CGAL_CXX11 template result_type operator()(U&&...u)const{ return A(std::forward(u)...); } #else result_type operator()()const{ return A(); } #define CGAL_CODE(Z,N,_) template \ result_type operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,U,const&u))const{ \ return A(BOOST_PP_ENUM_PARAMS(N,u)); \ } BOOST_PP_REPEAT_FROM_TO(1, 8, CGAL_CODE, _ ) #undef CGAL_CODE #endif }; } // TODO: make a Cartesian-only variant // WARNING: do not use the Req* parameters too much, they can cause circular instanciations and are only useful for dispatching. #define CGAL_STRIP_PAREN_(...) __VA_ARGS__ #define CGAL_STRIP_PAREN(...) CGAL_STRIP_PAREN_ __VA_ARGS__ // What to do with O? pass it down to other functors or drop it? #define CGAL_KD_DEFAULT_FUNCTOR(Tg,Name,ReqTyp,ReqFun) \ template \ struct Get_functor::value \ || !Provides_types >::value \ || !Provides_functors >::value \ , int, void>::type> \ { \ typedef CGAL_STRIP_PAREN_ Name type; \ typedef K Bound_kernel; \ } // Not used yet, may need some changes. #define CGAL_KD_DEFAULT_TYPE(Tg,Name,ReqTyp,ReqFun) \ template \ struct Get_type::value \ || !Provides_types >::value \ || !Provides_functors >::value \ , int, void>::type> \ { \ typedef CGAL_STRIP_PAREN_ Name type; \ typedef K Bound_kernel; \ } #if defined(BOOST_MSVC) # pragma warning(pop) #endif #endif