1 // Copyright (c) 2007,2009,2010,2011 Tel-Aviv University (Israel).
2 // All rights reserved.
3 //
4 // This file is part of CGAL (www.cgal.org).
5 //
6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Arrangement_on_surface_2/include/CGAL/Arr_tags.h $
7 // $Id: Arr_tags.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
9 //
10 //
11 // Author(s): Efi Fogel <efif@post.tau.ac.il>
12 // Eric Berberich <ericb@post.tau.ac.il>
13
14 #ifndef CGAL_ARR_TAGS_H
15 #define CGAL_ARR_TAGS_H
16
17 #include <CGAL/license/Arrangement_on_surface_2.h>
18
19 #include <CGAL/disable_warnings.h>
20
21 #include <CGAL/config.h>
22 #include <boost/type_traits.hpp>
23 #include <boost/mpl/bool.hpp>
24 #include <boost/mpl/if.hpp>
25 #include <boost/mpl/and.hpp>
26 #include <boost/mpl/or.hpp>
27 #include <boost/mpl/not.hpp>
28 #include <boost/mpl/logical.hpp>
29 #include <boost/mpl/has_xxx.hpp>
30
31 /*! \file
32 * Definition of the tags for the arrangement package.
33 */
34
35 namespace CGAL {
36
37 struct Arr_boundary_side_tag {};
38 struct Arr_oblivious_side_tag : public virtual Arr_boundary_side_tag {};
39 struct Arr_open_side_tag : public virtual Arr_oblivious_side_tag {};
40 struct Arr_closed_side_tag : public virtual Arr_oblivious_side_tag {};
41 struct Arr_contracted_side_tag : public virtual Arr_oblivious_side_tag {};
42 struct Arr_identified_side_tag : public virtual Arr_oblivious_side_tag {};
43
44 BOOST_MPL_HAS_XXX_TRAIT_DEF(Left_side_category)
BOOST_MPL_HAS_XXX_TRAIT_DEF(Bottom_side_category)45 BOOST_MPL_HAS_XXX_TRAIT_DEF(Bottom_side_category)
46 BOOST_MPL_HAS_XXX_TRAIT_DEF(Top_side_category)
47 BOOST_MPL_HAS_XXX_TRAIT_DEF(Right_side_category)
48
49 namespace internal {
50
51 //! type to provide left side tag (is oblivious if not existing)
52 template < class Traits_, bool B >
53 struct Get_left_side_category {};
54
55 template < class Traits_ >
56 struct Get_left_side_category< Traits_, true > {
57 typedef typename Traits_::Left_side_category Category;
58 };
59
60 template < class Traits_ >
61 struct Get_left_side_category< Traits_, false > {
62 typedef Arr_oblivious_side_tag Category;
63 };
64
65 template < class Traits_ >
66 struct Arr_complete_left_side_category {
67 public:
68 typedef Traits_ Traits;
69
70 typedef typename
71 Get_left_side_category< Traits, has_Left_side_category< Traits >::value >::Category Category;
72 };
73
74 template < class GeometryTraits_2, bool b >
75 struct Validate_left_side_category {};
76
77 template < class GeometryTraits_2 >
78 struct Validate_left_side_category< GeometryTraits_2, true > {
79 template <typename T>
80 void missing__Left_side_category() {}
81 };
82
83 template < class GeometryTraits_2 >
84 struct Validate_left_side_category< GeometryTraits_2, false > {
85 template <typename T>
86 void missing__Left_side_category()
87 {
88 T
89 missing__Left_side_category__assuming__Arr_oblivious_side_tag__instead;
90 }
91 };
92
93
94 //! type to provide bottom side tag (is oblivious if not existing)
95 template < class Traits_, bool B >
96 struct Get_bottom_side_category {
97 };
98
99 template < class Traits_ >
100 struct Get_bottom_side_category< Traits_, true > {
101 typedef typename Traits_::Bottom_side_category Category;
102 };
103
104 template < class Traits_ >
105 struct Get_bottom_side_category< Traits_, false > {
106 typedef Arr_oblivious_side_tag Category;
107 };
108
109 template < class Traits_ >
110 struct Arr_complete_bottom_side_category {
111
112 public:
113
114 typedef Traits_ Traits;
115
116 typedef typename
117 Get_bottom_side_category< Traits, has_Bottom_side_category< Traits >::value >::Category
118 Category;
119 };
120
121 template < class GeometryTraits_2, bool b >
122 struct Validate_bottom_side_category {};
123
124 template < class GeometryTraits_2 >
125 struct Validate_bottom_side_category< GeometryTraits_2, true > {
126 template <typename T>
127 void missing__Bottom_side_category() {}
128 };
129
130 template < class GeometryTraits_2 >
131 struct Validate_bottom_side_category< GeometryTraits_2, false > {
132 template <typename T>
133 void missing__Bottom_side_category()
134 {
135 T
136 missing__Bottom_side_category__assuming__Arr_oblivious_side_tag__instead;
137 }
138 };
139
140
141 //! type to provide top side tag (is oblivious if not existing)
142 template < class Traits_, bool B >
143 struct Get_top_side_category {
144 };
145
146 template < class Traits_ >
147 struct Get_top_side_category< Traits_, true > {
148 typedef typename Traits_::Top_side_category Category;
149 };
150
151 template < class Traits_ >
152 struct Get_top_side_category< Traits_, false > {
153 typedef Arr_oblivious_side_tag Category;
154 };
155
156 template < class Traits_ >
157 struct Arr_complete_top_side_category {
158
159 public:
160
161 typedef Traits_ Traits;
162
163 typedef typename
164 Get_top_side_category< Traits, has_Top_side_category< Traits >::value >::Category Category;
165 };
166
167 template < class GeometryTraits_2, bool b >
168 struct Validate_top_side_category {};
169
170 template < class GeometryTraits_2 >
171 struct Validate_top_side_category< GeometryTraits_2, true > {
172 template <typename T>
173 void missing__Top_side_category() {}
174 };
175
176 template < class GeometryTraits_2 >
177 struct Validate_top_side_category< GeometryTraits_2, false > {
178 template <typename T>
179 void missing__Top_side_category()
180 {
181 T missing__Top_side_category__assuming__Arr_oblivious_side_tag__instead;
182 }
183 };
184
185
186 //! type to provide right side tag (is oblivious if not existing)
187 template < class Traits_, bool B >
188 struct Get_right_side_category {
189 };
190
191 template < class Traits_ >
192 struct Get_right_side_category< Traits_, true > {
193 typedef typename Traits_::Right_side_category Category;
194 };
195
196 template < class Traits_ >
197 struct Get_right_side_category< Traits_, false > {
198 typedef Arr_oblivious_side_tag Category;
199 };
200
201 template < class Traits_ >
202 struct Arr_complete_right_side_category {
203
204 public:
205
206 typedef Traits_ Traits;
207
208 typedef typename
209 Get_right_side_category< Traits, has_Right_side_category< Traits >::value >::Category
210 Category;
211 };
212
213 template < class GeometryTraits_2, bool b >
214 struct Validate_right_side_category {};
215
216 template < class GeometryTraits_2 >
217 struct Validate_right_side_category< GeometryTraits_2, true > {
218 template <typename T>
219 void missing__Right_side_category() {}
220 };
221
222 template < class GeometryTraits_2 >
223 struct Validate_right_side_category< GeometryTraits_2, false > {
224 template <typename T>
225 void missing__Right_side_category()
226 {
227 T
228 missing__Right_side_category__assuming__Arr_oblivious_side_tag__instead;
229 }
230 };
231
232 } // namespace internal
233
234 struct Arr_boundary_cond_tag{};
235 struct Arr_all_sides_oblivious_tag : public virtual Arr_boundary_cond_tag{};
236 struct Arr_not_all_sides_oblivious_tag : public virtual Arr_boundary_cond_tag{};
237
238 struct Arr_has_identified_side_tag :
239 public virtual Arr_not_all_sides_oblivious_tag{};
240 struct Arr_has_contracted_side_tag :
241 public virtual Arr_not_all_sides_oblivious_tag{};
242 struct Arr_has_closed_side_tag :
243 public virtual Arr_not_all_sides_oblivious_tag{};
244 struct Arr_has_open_side_tag :
245 public virtual Arr_not_all_sides_oblivious_tag{};
246
247 struct Arr_all_sides_open_tag : public virtual Arr_not_all_sides_oblivious_tag{};
248
249 struct Arr_all_sides_non_open_tag {};
250 struct Arr_not_all_sides_non_open_tag {};
251
252 /*!\brief Struct to determine whether all side tags are "oblivious"
253 */
254 template < class ArrLeftSideCategory, class ArrBottomSideCategory,
255 class ArrTopSideCategory, class ArrRightSideCategory >
256 struct Arr_are_all_sides_oblivious_tag {
257
258 public:
259
260 //! This instance's first template parameter
261 typedef ArrLeftSideCategory Left_side_category;
262
263 //! This instance's second template parameter
264 typedef ArrBottomSideCategory Bottom_side_category;
265
266 //! This instance's third template parameter
267 typedef ArrTopSideCategory Top_side_category;
268
269 //! This instance's fourth template parameter
270 typedef ArrRightSideCategory Right_side_category;
271
272 private:
273
274 typedef boost::mpl::bool_< true > true_;
275 typedef boost::mpl::bool_< false > false_;
276
277 typedef boost::mpl::if_<
278 boost::is_same< Left_side_category, Arr_oblivious_side_tag >,
279 true_, false_ >
280 Left_oblivious;
281
282 typedef boost::mpl::if_<
283 boost::is_same< Bottom_side_category, Arr_oblivious_side_tag >,
284 true_, false_ >
285 Bottom_oblivious;
286
287 typedef boost::mpl::if_<
288 boost::is_same< Top_side_category, Arr_oblivious_side_tag >,
289 true_, false_ >
290 Top_oblivious;
291
292 typedef boost::mpl::if_<
293 boost::is_same< Right_side_category, Arr_oblivious_side_tag >,
294 true_, false_ >
295 Right_oblivious;
296
297 public:
298
299 /*!\brief
300 * boolean tag that is Arr_all_sides_oblivious_tag if all sides are
301 * oblivious, otherwise Arr_not_all_sides_oblivious_tag
302 */
303 typedef typename boost::mpl::if_<
304 boost::mpl::and_< Left_oblivious, Bottom_oblivious,
305 Top_oblivious, Right_oblivious >,
306 Arr_all_sides_oblivious_tag,
307 Arr_not_all_sides_oblivious_tag >::type result;
308
309 };
310
311 /*!\brief Struct to determine whether all side tags are "non-open"
312 */
313 template < class ArrLeftSideCategory, class ArrBottomSideCategory,
314 class ArrTopSideCategory, class ArrRightSideCategory >
315 struct Arr_are_all_sides_non_open_tag {
316
317 public:
318
319 //! This instance's first template parameter
320 typedef ArrLeftSideCategory Left_side_category;
321
322 //! This instance's second template parameter
323 typedef ArrBottomSideCategory Bottom_side_category;
324
325 //! This instance's third template parameter
326 typedef ArrTopSideCategory Top_side_category;
327
328 //! This instance's fourth template parameter
329 typedef ArrRightSideCategory Right_side_category;
330
331 private:
332
333 typedef boost::mpl::bool_< true > true_;
334 typedef boost::mpl::bool_< false > false_;
335
336 typedef boost::mpl::if_<
337 boost::is_same< Left_side_category, Arr_open_side_tag >,
338 true_, false_ >
339 Left_open;
340
341 typedef boost::mpl::if_<
342 boost::is_same< Bottom_side_category, Arr_open_side_tag >,
343 true_, false_ >
344 Bottom_open;
345
346 typedef boost::mpl::if_<
347 boost::is_same< Top_side_category, Arr_open_side_tag >,
348 true_, false_ >
349 Top_open;
350
351 typedef boost::mpl::if_<
352 boost::is_same< Right_side_category, Arr_open_side_tag >,
353 true_, false_ >
354 Right_open;
355
356 public:
357
358 /*!\brief
359 * boolean tag that is Arr_all_sides_non_open_tag if all sides are non-open,
360 * otherwise Arr_not_all_sides_non_open_tag
361 */
362 typedef typename boost::mpl::if_<
363 boost::mpl::and_< boost::mpl::not_< Left_open >,
364 boost::mpl::not_< Bottom_open >,
365 boost::mpl::not_< Top_open >,
366 boost::mpl::not_< Right_open > >,
367 Arr_all_sides_non_open_tag,
368 Arr_not_all_sides_non_open_tag >::type result;
369 };
370
371
372 /*!\brief Struct to check consistent tagging of identifications
373 */
374 template < class ArrLeftSideCategory, class ArrBottomSideCategory,
375 class ArrTopSideCategory, class ArrRightSideCategory >
376 struct Arr_sane_identified_tagging {
377
378 public:
379
380 //! This instance's first template parameter
381 typedef ArrLeftSideCategory Left_side_category;
382
383 //! This instance's second template parameter
384 typedef ArrBottomSideCategory Bottom_side_category;
385
386 //! This instance's third template parameter
387 typedef ArrTopSideCategory Top_side_category;
388
389 //! This instance's fourth template parameter
390 typedef ArrRightSideCategory Right_side_category;
391
392 private:
393
394 typedef boost::mpl::bool_< true > true_;
395 typedef boost::mpl::bool_< false > false_;
396
397 typedef boost::mpl::if_<
398 boost::is_same< Left_side_category, Arr_identified_side_tag >,
399 true_, false_ >
400 Left_identified;
401
402 typedef boost::mpl::if_<
403 boost::is_same< Bottom_side_category, Arr_identified_side_tag >,
404 true_, false_ >
405 Bottom_identified;
406
407 typedef boost::mpl::if_<
408 boost::is_same< Top_side_category, Arr_identified_side_tag >,
409 true_, false_ >
410 Top_identified;
411
412 typedef boost::mpl::if_<
413 boost::is_same< Right_side_category, Arr_identified_side_tag >,
414 true_, false_ >
415 Right_identified;
416
417 typedef boost::mpl::and_< Left_identified, Right_identified > LR_identified;
418
419 typedef boost::mpl::and_< Bottom_identified, Top_identified > BT_identified;
420
421 typedef boost::mpl::and_< boost::mpl::not_< Left_identified>,
422 boost::mpl::not_< Right_identified > >
423 LR_non_identified;
424
425 typedef boost::mpl::and_< boost::mpl::not_< Bottom_identified >,
426 boost::mpl::not_< Top_identified > >
427 BT_non_identified;
428
429 typedef boost::mpl::or_< LR_identified, LR_non_identified > LR_ok;
430 typedef boost::mpl::or_< BT_identified, BT_non_identified > BT_ok;
431
432 public:
433
434 /*!\brief
435 * boolean tag that is bool_<true> if opposite sides are either
436 * both identified or both non-identified,
437 * otherwise bool_<false>
438 */
439 typedef boost::mpl::and_< LR_ok, BT_ok > result;
440
441 };
442
443 /*! Checks whether one of two boundary sides are identified
444 * Observe that if one side is identified, the opposite side must be identified
445 * as well. Thus:
446 * (i) When Arr_has_identified_sides is used to check whether two opposite
447 * sides are identified, the check for the second side is redundant.
448 * (ii) When Arr_has_identified_sides is used to check whether two non-opposite
449 * sides are identified, the check applies to all four sides.
450 */
451 template <class ArrSideOneCategory, class ArrSideTwoCategory>
452 struct Arr_has_identified_sides {
453 public:
454 //! This instance's first template parameter
455 typedef ArrSideOneCategory Side_one_category;
456
457 //! This instance's second template parameter
458 typedef ArrSideTwoCategory Side_two_category;
459
460 private:
461 typedef boost::mpl::bool_<true> true_;
462 typedef boost::mpl::bool_<false> false_;
463
464 typedef boost::mpl::if_<
465 boost::is_same<Side_one_category, Arr_identified_side_tag>,
466 true_, false_>
467 Side_one_identified;
468
469 typedef boost::mpl::if_<
470 boost::is_same<Side_two_category, Arr_identified_side_tag>,
471 true_, false_>
472 Side_two_identified;
473
474 public:
475 /*!\brief
476 * boolean tag that is bool_<true> if one side is identified,
477 * otherwise bool_<false>
478 */
479 typedef boost::mpl::or_<Side_one_identified, Side_two_identified> result;
480 };
481
482 /*! Checks whether one of two boundary sides are contracted
483 */
484 template <class ArrSideOneCategory, class ArrSideTwoCategory>
485 struct Arr_has_contracted_sides_two {
486 public:
487 //! This instance's first template parameter
488 typedef ArrSideOneCategory Side_one_category;
489
490 //! This instance's second template parameter
491 typedef ArrSideTwoCategory Side_two_category;
492
493 private:
494 typedef boost::mpl::bool_<true> true_;
495 typedef boost::mpl::bool_<false> false_;
496
497 typedef boost::mpl::if_<
498 boost::is_same<Side_one_category, Arr_contracted_side_tag>,
499 true_, false_>
500 Side_one_contracted;
501
502 typedef boost::mpl::if_<
503 boost::is_same<Side_two_category, Arr_contracted_side_tag>,
504 true_, false_>
505 Side_two_contracted;
506
507 public:
508 /*!\brief
509 * boolean tag that is bool_<true> if one side is identified,
510 * otherwise bool_<false>
511 */
512 typedef boost::mpl::or_<Side_one_contracted, Side_two_contracted> result;
513 };
514
515 /*! Checks whether one of two boundary sides are closed
516 */
517 template <class ArrSideOneCategory, class ArrSideTwoCategory>
518 struct Arr_has_closed_sides_two {
519 public:
520 //! This instance's first template parameter
521 typedef ArrSideOneCategory Side_one_category;
522
523 //! This instance's second template parameter
524 typedef ArrSideTwoCategory Side_two_category;
525
526 private:
527 typedef boost::mpl::bool_<true> true_;
528 typedef boost::mpl::bool_<false> false_;
529
530 typedef boost::mpl::if_<
531 boost::is_same<Side_one_category, Arr_closed_side_tag>,
532 true_, false_>
533 Side_one_closed;
534
535 typedef boost::mpl::if_<
536 boost::is_same<Side_two_category, Arr_closed_side_tag>,
537 true_, false_>
538 Side_two_closed;
539
540 public:
541 /*!\brief
542 * boolean tag that is bool_<true> if one side is identified,
543 * otherwise bool_<false>
544 */
545 typedef boost::mpl::or_<Side_one_closed, Side_two_closed> result;
546 };
547
548 /*! Checks whether one of two boundary sides are open
549 */
550 template <class ArrSideOneCategory, class ArrSideTwoCategory>
551 struct Arr_has_open_sides_two {
552 public:
553 //! This instance's first template parameter
554 typedef ArrSideOneCategory Side_one_category;
555
556 //! This instance's second template parameter
557 typedef ArrSideTwoCategory Side_two_category;
558
559 private:
560 typedef boost::mpl::bool_<true> true_;
561 typedef boost::mpl::bool_<false> false_;
562
563 typedef boost::mpl::if_<
564 boost::is_same<Side_one_category, Arr_open_side_tag>,
565 true_, false_>
566 Side_one_open;
567
568 typedef boost::mpl::if_<
569 boost::is_same<Side_two_category, Arr_open_side_tag>,
570 true_, false_>
571 Side_two_open;
572
573 public:
574 /*!\brief
575 * boolean tag that is bool_<true> if one side is identified,
576 * otherwise bool_<false>
577 */
578 typedef boost::mpl::or_<Side_one_open, Side_two_open> result;
579 };
580
581 /*! Categorizes two boundary sides:
582 * If one side is identified => Arr_has_identified_side_tag
583 * Otherwise if one side is contracted => Arr_has_contracted_side_tag
584 * Otherwise if one side is closed => Arr_has_closed_side_tag
585 * Otherwise if one side is open => Arr_has_open_side_tag
586 * Otherwise => Arr_all_sides_oblivious_tag
587 */
588 template < class ArrSideOneCategory, class ArrSideTwoCategory>
589 struct Arr_two_sides_category {
590 public:
591 //! This instance's first template parameter
592 typedef ArrSideOneCategory Side_one_category;
593
594 //! This instance's second template parameter
595 typedef ArrSideTwoCategory Side_two_category;
596
597 private:
598 // One of the two sides is identified
599 typedef typename Arr_has_identified_sides<Side_one_category,
600 Side_two_category>::result
601 Is_identified;
602
603 // One of the two sides is contracted
604 typedef typename Arr_has_contracted_sides_two<Side_one_category,
605 Side_two_category>::result
606 Is_contracted;
607
608 // One of the two sides is closed
609 typedef typename Arr_has_closed_sides_two<Side_one_category,
610 Side_two_category>::result
611 Is_closed;
612
613 // One of the two sides is open
614 typedef typename Arr_has_open_sides_two<Side_one_category,
615 Side_two_category>::result
616 Is_open;
617
618 public:
619 typedef typename boost::mpl::if_<Is_identified, Arr_has_identified_side_tag,
620 typename boost::mpl::if_<Is_contracted, Arr_has_contracted_side_tag,
621 typename boost::mpl::if_<Is_closed, Arr_has_closed_side_tag,
622 typename boost::mpl::if_<Is_open, Arr_has_open_side_tag,
623 Arr_all_sides_oblivious_tag>::type>::type>::type>::type
624 result;
625 };
626
627 /*! Categorizes all sides:
628 * If one side is identified => Arr_has_identified_side_tag
629 * Otherwise if one side is contracted => Arr_has_contracted_side_tag
630 * Otherwise if one side is closed => Arr_has_closed_side_tag
631 * Otherwise if one side is open => Arr_has_open_side_tag
632 * Otherwise (all sides oblivious) => Arr_all_sides_oblivious_tag
633 */
634 template < class ArrSideOneCategory, class ArrSideTwoCategory>
635 struct Arr_all_sides_category {
636 public:
637 };
638
639 } // namespace CGAL
640
641 #include <CGAL/enable_warnings.h>
642
643 #endif
644
645