File: utils.h

package info (click to toggle)
cgal 6.1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 144,952 kB
  • sloc: cpp: 811,597; ansic: 208,576; sh: 493; python: 411; makefile: 286; javascript: 174
file content (176 lines) | stat: -rw-r--r-- 6,951 bytes parent folder | download
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