1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
4 // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
6 // This file was modified by Oracle on 2013-2020.
7 // Modifications copyright (c) 2013-2020 Oracle and/or its affiliates.
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
11 // Use, modification and distribution is subject to the Boost Software License,
12 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
13 // http://www.boost.org/LICENSE_1_0.txt)
15 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
16 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
21 #include <type_traits>
23 #include <boost/throw_exception.hpp>
24 #include <boost/tuple/tuple.hpp>
26 #include <boost/geometry/core/assert.hpp>
27 #include <boost/geometry/core/coordinate_dimension.hpp>
28 #include <boost/geometry/core/exception.hpp>
29 #include <boost/geometry/core/static_assert.hpp>
30 #include <boost/geometry/util/condition.hpp>
31 #include <boost/geometry/util/sequence.hpp>
33 namespace boost { namespace geometry {
35 #ifndef DOXYGEN_NO_DETAIL
36 namespace detail { namespace relate {
38 enum field { interior = 0, boundary = 1, exterior = 2 };
40 // TODO: IF THE RESULT IS UPDATED WITH THE MAX POSSIBLE VALUE FOR SOME PAIR OF GEOEMTRIES
41 // THE VALUE ALREADY STORED MUSN'T BE CHECKED
42 // update() calls chould be replaced with set() in those cases
43 // but for safety reasons (STATIC_ASSERT) we should check if parameter D is valid and set() doesn't do that
44 // so some additional function could be added, e.g. set_dim()
46 // --------------- MATRIX ----------------
50 template <std::size_t Height, std::size_t Width = Height>
54 typedef char value_type;
55 typedef std::size_t size_type;
56 typedef const char * const_iterator;
57 typedef const_iterator iterator;
59 static const std::size_t static_width = Width;
60 static const std::size_t static_height = Height;
61 static const std::size_t static_size = Width * Height;
65 ::memset(m_array, 'F', static_size);
68 template <field F1, field F2>
69 inline char get() const
71 BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
72 static const std::size_t index = F1 * Width + F2;
73 BOOST_STATIC_ASSERT(index < static_size);
74 return m_array[index];
77 template <field F1, field F2, char V>
80 BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
81 static const std::size_t index = F1 * Width + F2;
82 BOOST_STATIC_ASSERT(index < static_size);
86 inline char operator[](std::size_t index) const
88 BOOST_GEOMETRY_ASSERT(index < static_size);
89 return m_array[index];
92 inline const_iterator begin() const
97 inline const_iterator end() const
99 return m_array + static_size;
102 inline static std::size_t size()
107 inline const char * data() const
112 inline std::string str() const
114 return std::string(m_array, static_size);
118 char m_array[static_size];
123 template <typename Matrix>
127 typedef Matrix result_type;
129 static const bool interrupt = false;
134 result_type const& result() const
139 result_type const& matrix() const
144 result_type & matrix()
149 template <field F1, field F2, char D>
150 inline bool may_update() const
152 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
154 char const c = m_matrix.template get<F1, F2>();
155 return D > c || c > '9';
158 template <field F1, field F2, char V>
161 static const bool in_bounds = F1 < Matrix::static_height
162 && F2 < Matrix::static_width;
163 typedef std::integral_constant<bool, in_bounds> in_bounds_t;
164 set_dispatch<F1, F2, V>(in_bounds_t());
167 template <field F1, field F2, char D>
170 static const bool in_bounds = F1 < Matrix::static_height
171 && F2 < Matrix::static_width;
172 typedef std::integral_constant<bool, in_bounds> in_bounds_t;
173 update_dispatch<F1, F2, D>(in_bounds_t());
177 template <field F1, field F2, char V>
178 inline void set_dispatch(std::true_type)
180 static const std::size_t index = F1 * Matrix::static_width + F2;
181 BOOST_STATIC_ASSERT(index < Matrix::static_size);
182 BOOST_STATIC_ASSERT(('0' <= V && V <= '9') || V == 'T' || V == 'F');
183 m_matrix.template set<F1, F2, V>();
185 template <field F1, field F2, char V>
186 inline void set_dispatch(std::false_type)
189 template <field F1, field F2, char D>
190 inline void update_dispatch(std::true_type)
192 static const std::size_t index = F1 * Matrix::static_width + F2;
193 BOOST_STATIC_ASSERT(index < Matrix::static_size);
194 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
195 char const c = m_matrix.template get<F1, F2>();
196 if ( D > c || c > '9')
197 m_matrix.template set<F1, F2, D>();
199 template <field F1, field F2, char D>
200 inline void update_dispatch(std::false_type)
206 // --------------- RUN-TIME MASK ----------------
210 template <std::size_t Height, std::size_t Width = Height>
214 static const std::size_t static_width = Width;
215 static const std::size_t static_height = Height;
216 static const std::size_t static_size = Width * Height;
218 inline mask(const char * s)
221 char * const last = m_array + static_size;
222 for ( ; it != last && *s != '\0' ; ++it, ++s )
230 ::memset(it, '*', last - it);
234 inline mask(const char * s, std::size_t count)
236 if ( count > static_size )
242 std::for_each(s, s + count, check_char);
243 ::memcpy(m_array, s, count);
245 if ( count < static_size )
247 ::memset(m_array + count, '*', static_size - count);
251 template <field F1, field F2>
252 inline char get() const
254 BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
255 static const std::size_t index = F1 * Width + F2;
256 BOOST_STATIC_ASSERT(index < static_size);
257 return m_array[index];
261 static inline void check_char(char c)
263 bool const is_valid = c == '*' || c == 'T' || c == 'F'
264 || ( c >= '0' && c <= '9' );
267 BOOST_THROW_EXCEPTION(geometry::invalid_input_exception());
271 char m_array[static_size];
276 template <typename Mask, bool InterruptEnabled>
277 struct interrupt_dispatch
279 template <field F1, field F2, char V>
280 static inline bool apply(Mask const&)
286 template <typename Mask>
287 struct interrupt_dispatch<Mask, true>
289 template <field F1, field F2, char V>
290 static inline bool apply(Mask const& mask)
292 char m = mask.template get<F1, F2>();
293 return check_element<V>(m);
297 static inline bool check_element(char m)
299 if ( BOOST_GEOMETRY_CONDITION(V >= '0' && V <= '9') )
301 return m == 'F' || ( m < V && m >= '0' && m <= '9' );
303 else if ( BOOST_GEOMETRY_CONDITION(V == 'T') )
311 template <typename Masks, int I = 0, int N = std::tuple_size<Masks>::value>
312 struct interrupt_dispatch_tuple
314 template <field F1, field F2, char V>
315 static inline bool apply(Masks const& masks)
317 typedef typename std::tuple_element<I, Masks>::type mask_type;
318 mask_type const& mask = std::get<I>(masks);
319 return interrupt_dispatch<mask_type, true>::template apply<F1, F2, V>(mask)
320 && interrupt_dispatch_tuple<Masks, I+1>::template apply<F1, F2, V>(masks);
324 template <typename Masks, int N>
325 struct interrupt_dispatch_tuple<Masks, N, N>
327 template <field F1, field F2, char V>
328 static inline bool apply(Masks const& )
334 template <typename ...Masks>
335 struct interrupt_dispatch<std::tuple<Masks...>, true>
337 typedef std::tuple<Masks...> mask_type;
339 template <field F1, field F2, char V>
340 static inline bool apply(mask_type const& mask)
342 return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
346 template <field F1, field F2, char V, bool InterruptEnabled, typename Mask>
347 inline bool interrupt(Mask const& mask)
349 return interrupt_dispatch<Mask, InterruptEnabled>
350 ::template apply<F1, F2, V>(mask);
355 template <typename Mask>
356 struct may_update_dispatch
358 template <field F1, field F2, char D, typename Matrix>
359 static inline bool apply(Mask const& mask, Matrix const& matrix)
361 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
363 char const m = mask.template get<F1, F2>();
371 char const c = matrix.template get<F1, F2>();
372 return c == 'F'; // if it's T or between 0 and 9, the result will be the same
374 else if ( m >= '0' && m <= '9' )
376 char const c = matrix.template get<F1, F2>();
377 return D > c || c > '9';
384 template <typename Masks, int I = 0, int N = std::tuple_size<Masks>::value>
385 struct may_update_dispatch_tuple
387 template <field F1, field F2, char D, typename Matrix>
388 static inline bool apply(Masks const& masks, Matrix const& matrix)
390 typedef typename std::tuple_element<I, Masks>::type mask_type;
391 mask_type const& mask = std::get<I>(masks);
392 return may_update_dispatch<mask_type>::template apply<F1, F2, D>(mask, matrix)
393 || may_update_dispatch_tuple<Masks, I+1>::template apply<F1, F2, D>(masks, matrix);
397 template <typename Masks, int N>
398 struct may_update_dispatch_tuple<Masks, N, N>
400 template <field F1, field F2, char D, typename Matrix>
401 static inline bool apply(Masks const& , Matrix const& )
407 template <typename ...Masks>
408 struct may_update_dispatch<std::tuple<Masks...>>
410 typedef std::tuple<Masks...> mask_type;
412 template <field F1, field F2, char D, typename Matrix>
413 static inline bool apply(mask_type const& mask, Matrix const& matrix)
415 return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
419 template <field F1, field F2, char D, typename Mask, typename Matrix>
420 inline bool may_update(Mask const& mask, Matrix const& matrix)
422 return may_update_dispatch<Mask>
423 ::template apply<F1, F2, D>(mask, matrix);
428 template <typename Mask>
429 struct check_dispatch
431 template <typename Matrix>
432 static inline bool apply(Mask const& mask, Matrix const& matrix)
434 return per_one<interior, interior>(mask, matrix)
435 && per_one<interior, boundary>(mask, matrix)
436 && per_one<interior, exterior>(mask, matrix)
437 && per_one<boundary, interior>(mask, matrix)
438 && per_one<boundary, boundary>(mask, matrix)
439 && per_one<boundary, exterior>(mask, matrix)
440 && per_one<exterior, interior>(mask, matrix)
441 && per_one<exterior, boundary>(mask, matrix)
442 && per_one<exterior, exterior>(mask, matrix);
445 template <field F1, field F2, typename Matrix>
446 static inline bool per_one(Mask const& mask, Matrix const& matrix)
448 const char mask_el = mask.template get<F1, F2>();
449 const char el = matrix.template get<F1, F2>();
451 if ( mask_el == 'F' )
455 else if ( mask_el == 'T' )
457 return el == 'T' || ( el >= '0' && el <= '9' );
459 else if ( mask_el >= '0' && mask_el <= '9' )
461 return el == mask_el;
468 template <typename Masks, int I = 0, int N = std::tuple_size<Masks>::value>
469 struct check_dispatch_tuple
471 template <typename Matrix>
472 static inline bool apply(Masks const& masks, Matrix const& matrix)
474 typedef typename std::tuple_element<I, Masks>::type mask_type;
475 mask_type const& mask = std::get<I>(masks);
476 return check_dispatch<mask_type>::apply(mask, matrix)
477 || check_dispatch_tuple<Masks, I+1>::apply(masks, matrix);
481 template <typename Masks, int N>
482 struct check_dispatch_tuple<Masks, N, N>
484 template <typename Matrix>
485 static inline bool apply(Masks const&, Matrix const&)
491 template <typename ...Masks>
492 struct check_dispatch<std::tuple<Masks...>>
494 typedef std::tuple<Masks...> mask_type;
496 template <typename Matrix>
497 static inline bool apply(mask_type const& mask, Matrix const& matrix)
499 return check_dispatch_tuple<mask_type>::apply(mask, matrix);
503 template <typename Mask, typename Matrix>
504 inline bool check_matrix(Mask const& mask, Matrix const& matrix)
506 return check_dispatch<Mask>::apply(mask, matrix);
511 template <typename MatrixOrMask>
514 static const std::size_t value = MatrixOrMask::static_width;
517 template <typename Tuple,
519 int N = std::tuple_size<Tuple>::value>
520 struct matrix_width_tuple
522 static const std::size_t
523 current = matrix_width<typename std::tuple_element<I, Tuple>::type>::value;
524 static const std::size_t
525 next = matrix_width_tuple<Tuple, I+1>::value;
527 static const std::size_t
528 value = current > next ? current : next;
531 template <typename Tuple, int N>
532 struct matrix_width_tuple<Tuple, N, N>
534 static const std::size_t value = 0;
537 template <typename ...Masks>
538 struct matrix_width<std::tuple<Masks...>>
540 static const std::size_t
541 value = matrix_width_tuple<std::tuple<Masks...>>::value;
546 template <typename Mask, bool Interrupt>
548 : private matrix_handler
550 relate::matrix<matrix_width<Mask>::value>
553 typedef matrix_handler
555 relate::matrix<matrix_width<Mask>::value>
559 typedef bool result_type;
563 inline explicit mask_handler(Mask const& m)
568 result_type result() const
571 && check_matrix(m_mask, base_t::matrix());
574 template <field F1, field F2, char D>
575 inline bool may_update() const
577 return detail::relate::may_update<F1, F2, D>(
578 m_mask, base_t::matrix()
582 template <field F1, field F2, char V>
585 if ( relate::interrupt<F1, F2, V, Interrupt>(m_mask) )
591 base_t::template set<F1, F2, V>();
595 template <field F1, field F2, char V>
598 if ( relate::interrupt<F1, F2, V, Interrupt>(m_mask) )
604 base_t::template update<F1, F2, V>();
612 // --------------- FALSE MASK ----------------
614 struct false_mask {};
616 // --------------- COMPILE-TIME MASK ----------------
618 // static_check_characters
619 template <typename Seq>
620 struct static_check_characters {};
622 template <char C, char ...Cs>
623 struct static_check_characters<std::integer_sequence<char, C, Cs...>>
624 : static_check_characters<std::integer_sequence<char, Cs...>>
626 typedef std::integer_sequence<char, C, Cs...> type;
627 static const bool is_valid = (C >= '0' && C <= '9')
628 || C == 'T' || C == 'F' || C == '*';
629 BOOST_GEOMETRY_STATIC_ASSERT((is_valid),
630 "Invalid static mask character",
634 template <char ...Cs>
635 struct static_check_characters<std::integral_constant<char, Cs...>>
640 template <typename Seq, std::size_t Height, std::size_t Width = Height>
643 static const std::size_t static_width = Width;
644 static const std::size_t static_height = Height;
645 static const std::size_t static_size = Width * Height;
648 std::size_t(util::sequence_size<Seq>::value) == static_size);
650 template <detail::relate::field F1, detail::relate::field F2>
653 BOOST_STATIC_ASSERT(std::size_t(F1) < static_height);
654 BOOST_STATIC_ASSERT(std::size_t(F2) < static_width);
656 static const char value
657 = util::sequence_element<F1 * static_width + F2, Seq>::value;
661 // check static_mask characters
662 enum { mask_check = sizeof(static_check_characters<Seq>) };
665 // static_should_handle_element
669 typename StaticMask, field F1, field F2,
670 bool IsSequence = util::is_sequence<StaticMask>::value
672 struct static_should_handle_element_dispatch
674 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
675 static const bool value = mask_el == 'F'
677 || ( mask_el >= '0' && mask_el <= '9' );
682 typename Seq, field F1, field F2,
684 std::size_t N = util::sequence_size<Seq>::value
686 struct static_should_handle_element_sequence
688 typedef typename util::sequence_element<I, Seq>::type StaticMask;
690 static const bool value
691 = static_should_handle_element_dispatch
695 || static_should_handle_element_sequence
701 template <typename Seq, field F1, field F2, std::size_t N>
702 struct static_should_handle_element_sequence<Seq, F1, F2, N, N>
704 static const bool value = false;
707 template <typename StaticMask, field F1, field F2>
708 struct static_should_handle_element_dispatch<StaticMask, F1, F2, true>
710 static const bool value
711 = static_should_handle_element_sequence
717 template <typename StaticMask, field F1, field F2>
718 struct static_should_handle_element
720 static const bool value
721 = static_should_handle_element_dispatch
731 typename StaticMask, char V, field F1, field F2,
732 bool InterruptEnabled,
733 bool IsSequence = util::is_sequence<StaticMask>::value
735 struct static_interrupt_dispatch
737 static const bool value = false;
740 template <typename StaticMask, char V, field F1, field F2, bool IsSequence>
741 struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, IsSequence>
743 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
745 static const bool value
746 = ( V >= '0' && V <= '9' ) ?
747 ( mask_el == 'F' || ( mask_el < V && mask_el >= '0' && mask_el <= '9' ) ) :
748 ( ( V == 'T' ) ? mask_el == 'F' : false );
753 typename Seq, char V, field F1, field F2,
755 std::size_t N = util::sequence_size<Seq>::value
757 struct static_interrupt_sequence
759 typedef typename util::sequence_element<I, Seq>::type StaticMask;
761 static const bool value
762 = static_interrupt_dispatch
764 StaticMask, V, F1, F2, true
766 && static_interrupt_sequence
768 Seq, V, F1, F2, I + 1
772 template <typename Seq, char V, field F1, field F2, std::size_t N>
773 struct static_interrupt_sequence<Seq, V, F1, F2, N, N>
775 static const bool value = true;
778 template <typename StaticMask, char V, field F1, field F2>
779 struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, true>
781 static const bool value
782 = static_interrupt_sequence
784 StaticMask, V, F1, F2
788 template <typename StaticMask, char V, field F1, field F2, bool EnableInterrupt>
789 struct static_interrupt
791 static const bool value
792 = static_interrupt_dispatch
794 StaticMask, V, F1, F2, EnableInterrupt
802 typename StaticMask, char D, field F1, field F2,
803 bool IsSequence = util::is_sequence<StaticMask>::value
805 struct static_may_update_dispatch
807 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
808 static const int version
811 : mask_el >= '0' && mask_el <= '9' ? 2
814 // TODO: use std::enable_if_t instead of std::integral_constant
816 template <typename Matrix>
817 static inline bool apply(Matrix const& matrix)
819 return apply_dispatch(matrix, std::integral_constant<int, version>());
823 template <typename Matrix>
824 static inline bool apply_dispatch(Matrix const& , std::integral_constant<int, 0>)
829 template <typename Matrix>
830 static inline bool apply_dispatch(Matrix const& matrix, std::integral_constant<int, 1>)
832 char const c = matrix.template get<F1, F2>();
833 return c == 'F'; // if it's T or between 0 and 9, the result will be the same
835 // mask_el >= '0' && mask_el <= '9'
836 template <typename Matrix>
837 static inline bool apply_dispatch(Matrix const& matrix, std::integral_constant<int, 2>)
839 char const c = matrix.template get<F1, F2>();
840 return D > c || c > '9';
843 template <typename Matrix>
844 static inline bool apply_dispatch(Matrix const&, std::integral_constant<int, 3>)
852 typename Seq, char D, field F1, field F2,
854 std::size_t N = util::sequence_size<Seq>::value
856 struct static_may_update_sequence
858 typedef typename util::sequence_element<I, Seq>::type StaticMask;
860 template <typename Matrix>
861 static inline bool apply(Matrix const& matrix)
863 return static_may_update_dispatch
865 StaticMask, D, F1, F2
867 || static_may_update_sequence
869 Seq, D, F1, F2, I + 1
874 template <typename Seq, char D, field F1, field F2, std::size_t N>
875 struct static_may_update_sequence<Seq, D, F1, F2, N, N>
877 template <typename Matrix>
878 static inline bool apply(Matrix const& /*matrix*/)
884 template <typename StaticMask, char D, field F1, field F2>
885 struct static_may_update_dispatch<StaticMask, D, F1, F2, true>
887 template <typename Matrix>
888 static inline bool apply(Matrix const& matrix)
890 return static_may_update_sequence
892 StaticMask, D, F1, F2
897 template <typename StaticMask, char D, field F1, field F2>
898 struct static_may_update
900 template <typename Matrix>
901 static inline bool apply(Matrix const& matrix)
903 return static_may_update_dispatch
905 StaticMask, D, F1, F2
910 // static_check_matrix
915 bool IsSequence = util::is_sequence<StaticMask>::value
917 struct static_check_dispatch
919 template <typename Matrix>
920 static inline bool apply(Matrix const& matrix)
922 return per_one<interior, interior>::apply(matrix)
923 && per_one<interior, boundary>::apply(matrix)
924 && per_one<interior, exterior>::apply(matrix)
925 && per_one<boundary, interior>::apply(matrix)
926 && per_one<boundary, boundary>::apply(matrix)
927 && per_one<boundary, exterior>::apply(matrix)
928 && per_one<exterior, interior>::apply(matrix)
929 && per_one<exterior, boundary>::apply(matrix)
930 && per_one<exterior, exterior>::apply(matrix);
933 template <field F1, field F2>
936 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
937 static const int version
940 : mask_el >= '0' && mask_el <= '9' ? 2
943 // TODO: use std::enable_if_t instead of std::integral_constant
945 template <typename Matrix>
946 static inline bool apply(Matrix const& matrix)
948 const char el = matrix.template get<F1, F2>();
949 return apply_dispatch(el, std::integral_constant<int, version>());
953 static inline bool apply_dispatch(char el, std::integral_constant<int, 0>)
958 static inline bool apply_dispatch(char el, std::integral_constant<int, 1>)
960 return el == 'T' || ( el >= '0' && el <= '9' );
962 // mask_el >= '0' && mask_el <= '9'
963 static inline bool apply_dispatch(char el, std::integral_constant<int, 2>)
965 return el == mask_el;
968 static inline bool apply_dispatch(char /*el*/, std::integral_constant<int, 3>)
979 std::size_t N = util::sequence_size<Seq>::value
981 struct static_check_sequence
983 typedef typename util::sequence_element<I, Seq>::type StaticMask;
985 template <typename Matrix>
986 static inline bool apply(Matrix const& matrix)
988 return static_check_dispatch
992 || static_check_sequence
999 template <typename Seq, std::size_t N>
1000 struct static_check_sequence<Seq, N, N>
1002 template <typename Matrix>
1003 static inline bool apply(Matrix const& /*matrix*/)
1009 template <typename StaticMask>
1010 struct static_check_dispatch<StaticMask, true>
1012 template <typename Matrix>
1013 static inline bool apply(Matrix const& matrix)
1015 return static_check_sequence
1022 template <typename StaticMask>
1023 struct static_check_matrix
1025 template <typename Matrix>
1026 static inline bool apply(Matrix const& matrix)
1028 return static_check_dispatch
1035 // static_mask_handler
1037 template <typename StaticMask, bool Interrupt>
1038 class static_mask_handler
1039 : private matrix_handler< matrix<3> >
1041 typedef matrix_handler< relate::matrix<3> > base_type;
1044 typedef bool result_type;
1048 inline static_mask_handler()
1052 inline explicit static_mask_handler(StaticMask const& /*dummy*/)
1056 result_type result() const
1058 return (!Interrupt || !interrupt)
1059 && static_check_matrix<StaticMask>::apply(base_type::matrix());
1062 template <field F1, field F2, char D>
1063 inline bool may_update() const
1065 return static_may_update<StaticMask, D, F1, F2>::
1066 apply(base_type::matrix());
1069 template <field F1, field F2>
1070 static inline bool expects()
1072 return static_should_handle_element<StaticMask, F1, F2>::value;
1075 template <field F1, field F2, char V>
1078 static const bool interrupt_c = static_interrupt<StaticMask, V, F1, F2, Interrupt>::value;
1079 static const bool should_handle = static_should_handle_element<StaticMask, F1, F2>::value;
1080 static const int version = interrupt_c ? 0
1084 set_dispatch<F1, F2, V>(integral_constant<int, version>());
1087 template <field F1, field F2, char V>
1088 inline void update()
1090 static const bool interrupt_c = static_interrupt<StaticMask, V, F1, F2, Interrupt>::value;
1091 static const bool should_handle = static_should_handle_element<StaticMask, F1, F2>::value;
1092 static const int version = interrupt_c ? 0
1096 update_dispatch<F1, F2, V>(integral_constant<int, version>());
1100 // Interrupt && interrupt
1101 template <field F1, field F2, char V>
1102 inline void set_dispatch(integral_constant<int, 0>)
1106 // else should_handle
1107 template <field F1, field F2, char V>
1108 inline void set_dispatch(integral_constant<int, 1>)
1110 base_type::template set<F1, F2, V>();
1113 template <field F1, field F2, char V>
1114 inline void set_dispatch(integral_constant<int, 2>)
1117 // Interrupt && interrupt
1118 template <field F1, field F2, char V>
1119 inline void update_dispatch(integral_constant<int, 0>)
1123 // else should_handle
1124 template <field F1, field F2, char V>
1125 inline void update_dispatch(integral_constant<int, 1>)
1127 base_type::template update<F1, F2, V>();
1130 template <field F1, field F2, char V>
1131 inline void update_dispatch(integral_constant<int, 2>)
1135 // --------------- UTIL FUNCTIONS ----------------
1139 template <field F1, field F2, char V, typename Result>
1140 inline void set(Result & res)
1142 res.template set<F1, F2, V>();
1145 template <field F1, field F2, char V, bool Transpose>
1148 template <typename Result>
1149 static inline void apply(Result & res)
1151 res.template set<F1, F2, V>();
1155 template <field F1, field F2, char V>
1156 struct set_dispatch<F1, F2, V, true>
1158 template <typename Result>
1159 static inline void apply(Result & res)
1161 res.template set<F2, F1, V>();
1165 template <field F1, field F2, char V, bool Transpose, typename Result>
1166 inline void set(Result & res)
1168 set_dispatch<F1, F2, V, Transpose>::apply(res);
1173 template <field F1, field F2, char D, typename Result>
1174 inline void update(Result & res)
1176 res.template update<F1, F2, D>();
1179 template <field F1, field F2, char D, bool Transpose>
1180 struct update_result_dispatch
1182 template <typename Result>
1183 static inline void apply(Result & res)
1185 update<F1, F2, D>(res);
1189 template <field F1, field F2, char D>
1190 struct update_result_dispatch<F1, F2, D, true>
1192 template <typename Result>
1193 static inline void apply(Result & res)
1195 update<F2, F1, D>(res);
1199 template <field F1, field F2, char D, bool Transpose, typename Result>
1200 inline void update(Result & res)
1202 update_result_dispatch<F1, F2, D, Transpose>::apply(res);
1207 template <field F1, field F2, char D, typename Result>
1208 inline bool may_update(Result const& res)
1210 return res.template may_update<F1, F2, D>();
1213 template <field F1, field F2, char D, bool Transpose>
1214 struct may_update_result_dispatch
1216 template <typename Result>
1217 static inline bool apply(Result const& res)
1219 return may_update<F1, F2, D>(res);
1223 template <field F1, field F2, char D>
1224 struct may_update_result_dispatch<F1, F2, D, true>
1226 template <typename Result>
1227 static inline bool apply(Result const& res)
1229 return may_update<F2, F1, D>(res);
1233 template <field F1, field F2, char D, bool Transpose, typename Result>
1234 inline bool may_update(Result const& res)
1236 return may_update_result_dispatch<F1, F2, D, Transpose>::apply(res);
1241 template <typename Geometry>
1242 struct result_dimension
1244 BOOST_STATIC_ASSERT(geometry::dimension<Geometry>::value >= 0);
1245 static const char value
1246 = ( geometry::dimension<Geometry>::value <= 9 ) ?
1247 ( '0' + geometry::dimension<Geometry>::value ) :
1251 }} // namespace detail::relate
1252 #endif // DOXYGEN_NO_DETAIL
1254 }} // namespace boost::geometry
1256 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP