File: Intersection_traits.h

package info (click to toggle)
cgal 6.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 144,912 kB
  • sloc: cpp: 810,858; ansic: 208,477; sh: 493; python: 411; makefile: 286; javascript: 174
file content (200 lines) | stat: -rw-r--r-- 7,859 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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
// Copyright (c) 2011 GeometryFactory (France). All rights reserved.
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
//
// $URL: https://github.com/CGAL/cgal/blob/v6.1/Intersections_2/include/CGAL/Intersection_traits.h $
// $Id: include/CGAL/Intersection_traits.h b26b07a1242 $
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s)     : Philipp Möller

#ifndef CGAL_INTERSECTION_TRAITS_H
#define CGAL_INTERSECTION_TRAITS_H

#include <CGAL/Kernel_traits.h>
#include <CGAL/Object.h>
#include <CGAL/assertions.h>
#include <CGAL/Dimension.h>

#include <variant>

#include <type_traits>

#define CGAL_INTERSECTION_TRAITS_2(A, B, R1, R2)                \
  template<typename K>     \
  struct Intersection_traits<K, typename K::A, typename K::B>  { \
    typedef typename std::variant<typename K::R1, typename K::R2 >    \
                     variant_type;                                      \
    typedef typename std::optional< variant_type > result_type;       \
  };

#define CGAL_INTERSECTION_TRAITS_3(A, B, R1, R2, R3)            \
  template<typename K>     \
  struct Intersection_traits<K, typename K::A, typename K::B>  { \
    typedef typename std::variant<typename K::R1, typename K::R2,     \
                                    typename K::R3> variant_type;       \
    typedef typename std::optional< variant_type > result_type;       \
  };

#define CGAL_INTERSECTION_FUNCTION(A, B, DIM)                           \
  template<typename K>                                                  \
  inline                                                                \
  decltype(auto) \
  intersection(const A<K>& a, const B<K>& b) {                          \
    return BOOST_PP_CAT(K().intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \
  }                                                                     \
  template<typename K>                                                  \
  inline                                                                \
  decltype(auto) \
  intersection(const B<K>& b, const A<K>& a) {                          \
    return BOOST_PP_CAT(K().intersect_, BOOST_PP_CAT(DIM, _object()(b, a))); \
  }

#define CGAL_INTERSECTION_FUNCTION_SELF(A, DIM)                         \
  template<typename K>                                                  \
  inline                                                                \
  decltype(auto) \
  intersection(const A<K> & a, const A<K> & b) {                          \
    return BOOST_PP_CAT(K().intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \
  }

#define CGAL_DO_INTERSECT_FUNCTION(A, B, DIM)              \
  template<typename K>                                     \
  inline typename K::Boolean                               \
  do_intersect(const A<K>& a, const B<K>& b) {             \
    return BOOST_PP_CAT(K().do_intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \
  }                                                        \
  template<typename K>                                     \
  inline typename K::Boolean                               \
  do_intersect(const B<K>& b, const A<K>& a) {             \
    return BOOST_PP_CAT(K().do_intersect_, BOOST_PP_CAT(DIM, _object()(b, a))); \
  }

#define CGAL_DO_INTERSECT_FUNCTION_SELF(A, DIM)                         \
  template<typename K>                                                  \
  inline typename K::Boolean                                            \
  do_intersect(const A<K> & a, const A<K> & b) {                          \
    return BOOST_PP_CAT(K().do_intersect_, BOOST_PP_CAT(DIM, _object()(a, b))); \
  }

namespace CGAL {

// only declarationn
template<typename, typename, typename>
struct Intersection_traits {
  // This defaults to Object, if we use VERSION < 2 and do nothing
  // otherwise.
};


namespace Intersections {
namespace internal {

// this function is used to call either make_object or a
// Intersection_traits::result_type constructor to create return
// values. The Object version takes some dummy template arguments
// that are needed for the return of the Intersection_traits. In
// theory a one parameter variant could be returned, but this
// _could_ come with conversion overhead and so we rather go for
// the real type.
// Overloads for empty returns are also provided.
  template<typename F, typename A, typename B, typename T>
  decltype(auto)
  intersection_return(T&& t) { return decltype(std::declval<F>()(std::declval<A>(), std::declval<B>()))(std::forward<T>(t)); }
  template<typename F, typename A, typename B>
  decltype(auto)
  intersection_return() { return decltype(std::declval<F>()(std::declval<A>(), std::declval<B>()))(); }

// Something similar to wrap around boost::get and object_cast to
// prevent ifdefing too much. Another way could be to introduce an
// overload of boost::get for Object.  We only provide the pointer
// casts here. But use references to const as parameters. This makes
// it somewhat nicer.
template<typename T>
inline
const T* intersect_get(const CGAL::Object& o) {
  return CGAL::object_cast<T>(&o);
}

template<typename T, typename ... U>
inline
const T* intersect_get(const std::optional< std::variant<U...> >& v) {
  return std::get_if<T>(&*v);
}

template<typename T, typename ... U>
inline
const T* intersect_get(const std::variant<U...> & v) {
  return std::get_if<T>(&v);
}

template<typename A, typename B>
decltype(auto)
intersection_impl(const A& a, const B& b, CGAL::Dimension_tag<2>) {
  typedef typename CGAL::Kernel_traits<A>::Kernel Kernel;
  return Kernel().intersect_2_object()(a, b);
}

template<typename A, typename B>
decltype(auto)
intersection_impl(const A& a, const B& b, Dimension_tag<3>) {
  typedef typename CGAL::Kernel_traits<A>::Kernel Kernel;
  return Kernel().intersect_3_object()(a, b);
}

template<typename A, typename B>
typename Intersection_traits< typename CGAL::Kernel_traits<A>::Kernel, A, B>::result_type
intersection_impl(const A& a, const B& b, Dynamic_dimension_tag) {
  typedef typename CGAL::Kernel_traits<A>::Kernel Kernel;
  return Kernel().intersect_d_object()(a, b);
}

template<typename A, typename B>
inline auto // K::Boolean
do_intersect_impl(const A& a, const B& b, CGAL::Dimension_tag<2>) {
  typedef typename CGAL::Kernel_traits<A>::Kernel Kernel;
  return Kernel().do_intersect_2_object()(a, b);
}

template<typename A, typename B>
inline auto // K::Boolean
do_intersect_impl(const A& a, const B& b, Dimension_tag<3>) {
  typedef typename CGAL::Kernel_traits<A>::Kernel Kernel;
  return Kernel().do_intersect_3_object()(a, b);
}

template<typename A, typename B>
inline auto // K::Boolean
do_intersect_impl(const A& a, const B& b, Dynamic_dimension_tag) {
  typedef typename CGAL::Kernel_traits<A>::Kernel Kernel;
  return Kernel().do_intersect_d_object()(a, b);
}

} // namespace internal
} // namespace Intersections

// See overloads in the respective header files

// template<typename A, typename B>
// inline
// typename Intersection_traits< typename Kernel_traits<A>::Kernel, A, B>::result_type >::type
// intersection(const A& a, const B& b) {
//   static_assert(std::is_same<typename A::Ambient_dimension, typename B::Ambient_dimension>::value),
//                               "intersection with objects of different dimensions not supported";
//   return internal::intersection_impl(a, b, typename A::Ambient_dimension());
// }

// template<typename A, typename B>
// inline
// auto // K::Boolean
// do_intersect(const A& a, const B& b) {
//   static_assert(std::is_same<typename A::Ambient_dimension, typename B::Ambient_dimension>::value,
//                         "do_intersect with objects of different dimensions not supported");
//   return internal::do_intersect_impl(a, b, typename A::Ambient_dimension());
// }

} // CGAL

#endif /* CGAL_INTERSECTION_TRAITS_H */