1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
// Copyright (c) 2014
// INRIA Saclay-Ile de France (France)
//
// This file is part of CGAL (www.cgal.org)
//
// $URL: https://github.com/CGAL/cgal/blob/v6.1.1/NewKernel_d/include/CGAL/NewKernel_d/utils.h $
// $Id: include/CGAL/NewKernel_d/utils.h 08b27d3db14 $
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : Marc Glisse
#ifndef CGAL_MARCUTILS
#define CGAL_MARCUTILS
#include <CGAL/config.h>
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable:4003) // not enough actual parameters for macro 'BOOST_PP_EXPAND_I'
// https://lists.boost.org/boost-users/2014/11/83291.php
#endif
#include <type_traits>
#include <utility>
#include <boost/preprocessor/repetition.hpp>
#include <CGAL/Rational_traits.h>
#include <CGAL/tuple.h>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/not.hpp>
#include <boost/type_traits.hpp>
namespace CGAL {
namespace internal {
BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
}
template <class T, class No, bool=internal::has_type<T>::value /*false*/>
struct Has_type_different_from : std::false_type {};
template <class T, class No>
struct Has_type_different_from <T, No, true>
: std::bool_constant<!std::is_same_v<typename T::type, No>> {};
template <class T> 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 dependent
// (and thus usable in SFINAE), although that's not a great design.
template<class A,class B> struct Second_arg {
typedef B type;
};
// like std::forward, except for basic types where it does a cast, to
// avoid issues with narrowing conversions
template<class T,class U,class V> inline
typename std::conditional<std::is_arithmetic<T>::value&&std::is_arithmetic<typename std::remove_reference<U>::type>::value,T,U&&>::type
forward_safe(V&& u) { return std::forward<U>(u); }
template<class...> struct Constructible_from_each;
template<class To,class From1,class...From> struct Constructible_from_each<To,From1,From...>{
enum { value=std::is_convertible<From1,To>::value&&Constructible_from_each<To,From...>::value };
};
template<class To> struct Constructible_from_each<To>{
enum { value=true };
};
template<class T> struct Scale {
T const& scale;
Scale(T const& t):scale(t){}
template<class FT>
decltype(auto) operator()(FT&& x)const
{
return (scale*std::forward<FT>(x));
}
};
template<class NT,class T> struct Divide {
T const& scale;
Divide(T const& t):scale(t){}
template<class FT>
//FIXME: gcc complains for Gmpq
//decltype(auto) operator()(FT&& x)const
NT operator()(FT&& x)const
{
return Rational_traits<NT>().
make_rational(std::forward<FT>(x),scale);
}
};
template <class NT> struct has_cheap_constructor : std::is_arithmetic<NT>{};
template <bool p> struct has_cheap_constructor<Interval_nt<p> > {
enum { value=true };
};
using std::decay;
template<class T,class U> struct Type_copy_ref { typedef U type; };
template<class T,class U> struct Type_copy_ref<T&,U> { typedef U& type; };
template<class T,class U> struct Type_copy_ref<T&&,U> { typedef U&& type; };
template<class T,class U> struct Type_copy_cv { typedef U type; };
template<class T,class U> struct Type_copy_cv<T const,U> { typedef U const type; };
template<class T,class U> struct Type_copy_cv<T volatile,U> { typedef U volatile type; };
template<class T,class U> struct Type_copy_cv<T const volatile,U> { typedef U const volatile type; };
template<class T,class U> struct Type_copy_cvref :
Type_copy_ref<T,typename Type_copy_cv<std::remove_reference_t<T>,U>::type> {};
struct Dereference_functor {
template<class> struct result{};
template<class It> struct result<Dereference_functor(It)> {
typedef typename std::iterator_traits<It>::reference type;
};
template<class It> decltype(auto)
operator()(It const&i)const{
return *i;
}
};
namespace internal {
template<class F,class...U,std::size_t...I> inline decltype(auto)
do_call_on_tuple_elements(F&&f, std::tuple<U...>&&t, std::index_sequence<I...>&&) {
return f(std::get<I>(std::move(t))...);
}
} // internal
template<class F,class...U>
inline decltype(auto)
call_on_tuple_elements(F&&f, std::tuple<U...>&&t) {
return internal::do_call_on_tuple_elements(std::forward<F>(f),std::move(t),
std::make_index_sequence<sizeof...(U)>());
}
template<class A> struct Factory {
typedef A result_type;
template<class...U> result_type operator()(U&&...u)const{
return A(std::forward<U>(u)...);
}
};
}
// TODO: make a Cartesian-only variant
// WARNING: do not use the Req* parameters too much, they can cause circular instantiations 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 <class K, class O> \
struct Get_functor<K, Tg, O, \
std::conditional_t< \
Provides_functor_i<K, Tg, O>::value \
|| !Provides_types<K, boost::mpl::vector<CGAL_STRIP_PAREN_ ReqTyp> >::value \
|| !Provides_functors<K, boost::mpl::vector<CGAL_STRIP_PAREN_ ReqFun> >::value \
, int, void>> \
{ \
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 <class K> \
struct Get_type<K, Tg, \
std::conditional_t< \
Provides_type_i<K, Tg>::value \
|| !Provides_types<K, boost::mpl::vector<CGAL_STRIP_PAREN_ ReqTyp> >::value \
|| !Provides_functors<K, boost::mpl::vector<CGAL_STRIP_PAREN_ ReqFun> >::value \
, int, void>> \
{ \
typedef CGAL_STRIP_PAREN_ Name type; \
typedef K Bound_kernel; \
}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#endif
|