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