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
22 #include <type_traits>
24 #include <boost/throw_exception.hpp>
25 #include <boost/tuple/tuple.hpp>
27 #include <boost/geometry/core/assert.hpp>
28 #include <boost/geometry/core/coordinate_dimension.hpp>
29 #include <boost/geometry/core/exception.hpp>
30 #include <boost/geometry/core/static_assert.hpp>
31 #include <boost/geometry/util/condition.hpp>
32 #include <boost/geometry/util/sequence.hpp>
34 namespace boost { namespace geometry {
36 #ifndef DOXYGEN_NO_DETAIL
37 namespace detail { namespace relate {
39 enum field { interior = 0, boundary = 1, exterior = 2 };
41 // TODO: IF THE RESULT IS UPDATED WITH THE MAX POSSIBLE VALUE FOR SOME PAIR OF GEOEMTRIES
42 // THE VALUE ALREADY STORED MUSN'T BE CHECKED
43 // update() calls chould be replaced with set() in those cases
44 // but for safety reasons (STATIC_ASSERT) we should check if parameter D is valid and set() doesn't do that
45 // so some additional function could be added, e.g. set_dim()
47 // --------------- MATRIX ----------------
51 template <std::size_t Height, std::size_t Width = Height>
55 typedef char value_type;
56 typedef std::size_t size_type;
57 typedef const char * const_iterator;
58 typedef const_iterator iterator;
60 static const std::size_t static_width = Width;
61 static const std::size_t static_height = Height;
62 static const std::size_t static_size = Width * Height;
66 ::memset(m_array, 'F', static_size);
69 template <field F1, field F2>
70 inline char get() const
72 BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
73 static const std::size_t index = F1 * Width + F2;
74 BOOST_STATIC_ASSERT(index < static_size);
75 return m_array[index];
78 template <field F1, field F2, char V>
81 BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
82 static const std::size_t index = F1 * Width + F2;
83 BOOST_STATIC_ASSERT(index < static_size);
87 inline char operator[](std::size_t index) const
89 BOOST_GEOMETRY_ASSERT(index < static_size);
90 return m_array[index];
93 inline const_iterator begin() const
98 inline const_iterator end() const
100 return m_array + static_size;
103 inline static std::size_t size()
108 inline const char * data() const
113 inline std::string str() const
115 return std::string(m_array, static_size);
119 char m_array[static_size];
124 template <typename Matrix>
128 typedef Matrix result_type;
130 static const bool interrupt = false;
135 result_type const& result() const
140 result_type const& matrix() const
145 result_type & matrix()
150 template <field F1, field F2, char D>
151 inline bool may_update() const
153 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
155 char const c = m_matrix.template get<F1, F2>();
156 return D > c || c > '9';
159 template <field F1, field F2, char V>
162 static const bool in_bounds = F1 < Matrix::static_height
163 && F2 < Matrix::static_width;
164 typedef std::integral_constant<bool, in_bounds> in_bounds_t;
165 set_dispatch<F1, F2, V>(in_bounds_t());
168 template <field F1, field F2, char D>
171 static const bool in_bounds = F1 < Matrix::static_height
172 && F2 < Matrix::static_width;
173 typedef std::integral_constant<bool, in_bounds> in_bounds_t;
174 update_dispatch<F1, F2, D>(in_bounds_t());
178 template <field F1, field F2, char V>
179 inline void set_dispatch(std::true_type)
181 static const std::size_t index = F1 * Matrix::static_width + F2;
182 BOOST_STATIC_ASSERT(index < Matrix::static_size);
183 BOOST_STATIC_ASSERT(('0' <= V && V <= '9') || V == 'T' || V == 'F');
184 m_matrix.template set<F1, F2, V>();
186 template <field F1, field F2, char V>
187 inline void set_dispatch(std::false_type)
190 template <field F1, field F2, char D>
191 inline void update_dispatch(std::true_type)
193 static const std::size_t index = F1 * Matrix::static_width + F2;
194 BOOST_STATIC_ASSERT(index < Matrix::static_size);
195 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
196 char const c = m_matrix.template get<F1, F2>();
197 if ( D > c || c > '9')
198 m_matrix.template set<F1, F2, D>();
200 template <field F1, field F2, char D>
201 inline void update_dispatch(std::false_type)
207 // --------------- RUN-TIME MASK ----------------
211 template <std::size_t Height, std::size_t Width = Height>
215 static const std::size_t static_width = Width;
216 static const std::size_t static_height = Height;
217 static const std::size_t static_size = Width * Height;
219 inline mask(const char * s)
222 char * const last = m_array + static_size;
223 for ( ; it != last && *s != '\0' ; ++it, ++s )
231 ::memset(it, '*', last - it);
235 inline mask(const char * s, std::size_t count)
237 if ( count > static_size )
243 std::for_each(s, s + count, check_char);
244 ::memcpy(m_array, s, count);
246 if ( count < static_size )
248 ::memset(m_array + count, '*', static_size - count);
252 template <field F1, field F2>
253 inline char get() const
255 BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
256 static const std::size_t index = F1 * Width + F2;
257 BOOST_STATIC_ASSERT(index < static_size);
258 return m_array[index];
262 static inline void check_char(char c)
264 bool const is_valid = c == '*' || c == 'T' || c == 'F'
265 || ( c >= '0' && c <= '9' );
268 BOOST_THROW_EXCEPTION(geometry::invalid_input_exception());
272 char m_array[static_size];
277 template <typename Mask, bool InterruptEnabled>
278 struct interrupt_dispatch
280 template <field F1, field F2, char V>
281 static inline bool apply(Mask const&)
287 template <typename Mask>
288 struct interrupt_dispatch<Mask, true>
290 template <field F1, field F2, char V>
291 static inline bool apply(Mask const& mask)
293 char m = mask.template get<F1, F2>();
294 return check_element<V>(m);
298 static inline bool check_element(char m)
300 if ( BOOST_GEOMETRY_CONDITION(V >= '0' && V <= '9') )
302 return m == 'F' || ( m < V && m >= '0' && m <= '9' );
304 else if ( BOOST_GEOMETRY_CONDITION(V == 'T') )
312 template <typename Masks, int I = 0, int N = std::tuple_size<Masks>::value>
313 struct interrupt_dispatch_tuple
315 template <field F1, field F2, char V>
316 static inline bool apply(Masks const& masks)
318 typedef typename std::tuple_element<I, Masks>::type mask_type;
319 mask_type const& mask = std::get<I>(masks);
320 return interrupt_dispatch<mask_type, true>::template apply<F1, F2, V>(mask)
321 && interrupt_dispatch_tuple<Masks, I+1>::template apply<F1, F2, V>(masks);
325 template <typename Masks, int N>
326 struct interrupt_dispatch_tuple<Masks, N, N>
328 template <field F1, field F2, char V>
329 static inline bool apply(Masks const& )
335 template <typename ...Masks>
336 struct interrupt_dispatch<std::tuple<Masks...>, true>
338 typedef std::tuple<Masks...> mask_type;
340 template <field F1, field F2, char V>
341 static inline bool apply(mask_type const& mask)
343 return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
347 template <field F1, field F2, char V, bool InterruptEnabled, typename Mask>
348 inline bool interrupt(Mask const& mask)
350 return interrupt_dispatch<Mask, InterruptEnabled>
351 ::template apply<F1, F2, V>(mask);
356 template <typename Mask>
357 struct may_update_dispatch
359 template <field F1, field F2, char D, typename Matrix>
360 static inline bool apply(Mask const& mask, Matrix const& matrix)
362 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
364 char const m = mask.template get<F1, F2>();
372 char const c = matrix.template get<F1, F2>();
373 return c == 'F'; // if it's T or between 0 and 9, the result will be the same
375 else if ( m >= '0' && m <= '9' )
377 char const c = matrix.template get<F1, F2>();
378 return D > c || c > '9';
385 template <typename Masks, int I = 0, int N = std::tuple_size<Masks>::value>
386 struct may_update_dispatch_tuple
388 template <field F1, field F2, char D, typename Matrix>
389 static inline bool apply(Masks const& masks, Matrix const& matrix)
391 typedef typename std::tuple_element<I, Masks>::type mask_type;
392 mask_type const& mask = std::get<I>(masks);
393 return may_update_dispatch<mask_type>::template apply<F1, F2, D>(mask, matrix)
394 || may_update_dispatch_tuple<Masks, I+1>::template apply<F1, F2, D>(masks, matrix);
398 template <typename Masks, int N>
399 struct may_update_dispatch_tuple<Masks, N, N>
401 template <field F1, field F2, char D, typename Matrix>
402 static inline bool apply(Masks const& , Matrix const& )
408 template <typename ...Masks>
409 struct may_update_dispatch<std::tuple<Masks...>>
411 typedef std::tuple<Masks...> mask_type;
413 template <field F1, field F2, char D, typename Matrix>
414 static inline bool apply(mask_type const& mask, Matrix const& matrix)
416 return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
420 template <field F1, field F2, char D, typename Mask, typename Matrix>
421 inline bool may_update(Mask const& mask, Matrix const& matrix)
423 return may_update_dispatch<Mask>
424 ::template apply<F1, F2, D>(mask, matrix);
429 template <typename Mask>
430 struct check_dispatch
432 template <typename Matrix>
433 static inline bool apply(Mask const& mask, Matrix const& matrix)
435 return per_one<interior, interior>(mask, matrix)
436 && per_one<interior, boundary>(mask, matrix)
437 && per_one<interior, exterior>(mask, matrix)
438 && per_one<boundary, interior>(mask, matrix)
439 && per_one<boundary, boundary>(mask, matrix)
440 && per_one<boundary, exterior>(mask, matrix)
441 && per_one<exterior, interior>(mask, matrix)
442 && per_one<exterior, boundary>(mask, matrix)
443 && per_one<exterior, exterior>(mask, matrix);
446 template <field F1, field F2, typename Matrix>
447 static inline bool per_one(Mask const& mask, Matrix const& matrix)
449 const char mask_el = mask.template get<F1, F2>();
450 const char el = matrix.template get<F1, F2>();
452 if ( mask_el == 'F' )
456 else if ( mask_el == 'T' )
458 return el == 'T' || ( el >= '0' && el <= '9' );
460 else if ( mask_el >= '0' && mask_el <= '9' )
462 return el == mask_el;
469 template <typename Masks, int I = 0, int N = std::tuple_size<Masks>::value>
470 struct check_dispatch_tuple
472 template <typename Matrix>
473 static inline bool apply(Masks const& masks, Matrix const& matrix)
475 typedef typename std::tuple_element<I, Masks>::type mask_type;
476 mask_type const& mask = std::get<I>(masks);
477 return check_dispatch<mask_type>::apply(mask, matrix)
478 || check_dispatch_tuple<Masks, I+1>::apply(masks, matrix);
482 template <typename Masks, int N>
483 struct check_dispatch_tuple<Masks, N, N>
485 template <typename Matrix>
486 static inline bool apply(Masks const&, Matrix const&)
492 template <typename ...Masks>
493 struct check_dispatch<std::tuple<Masks...>>
495 typedef std::tuple<Masks...> mask_type;
497 template <typename Matrix>
498 static inline bool apply(mask_type const& mask, Matrix const& matrix)
500 return check_dispatch_tuple<mask_type>::apply(mask, matrix);
504 template <typename Mask, typename Matrix>
505 inline bool check_matrix(Mask const& mask, Matrix const& matrix)
507 return check_dispatch<Mask>::apply(mask, matrix);
512 template <typename MatrixOrMask>
515 static const std::size_t value = MatrixOrMask::static_width;
518 template <typename Tuple,
520 int N = std::tuple_size<Tuple>::value>
521 struct matrix_width_tuple
523 static const std::size_t
524 current = matrix_width<typename std::tuple_element<I, Tuple>::type>::value;
525 static const std::size_t
526 next = matrix_width_tuple<Tuple, I+1>::value;
528 static const std::size_t
529 value = current > next ? current : next;
532 template <typename Tuple, int N>
533 struct matrix_width_tuple<Tuple, N, N>
535 static const std::size_t value = 0;
538 template <typename ...Masks>
539 struct matrix_width<std::tuple<Masks...>>
541 static const std::size_t
542 value = matrix_width_tuple<std::tuple<Masks...>>::value;
547 template <typename Mask, bool Interrupt>
549 : private matrix_handler
551 relate::matrix<matrix_width<Mask>::value>
554 typedef matrix_handler
556 relate::matrix<matrix_width<Mask>::value>
560 typedef bool result_type;
564 inline explicit mask_handler(Mask const& m)
569 result_type result() const
572 && check_matrix(m_mask, base_t::matrix());
575 template <field F1, field F2, char D>
576 inline bool may_update() const
578 return detail::relate::may_update<F1, F2, D>(
579 m_mask, base_t::matrix()
583 template <field F1, field F2, char V>
586 if ( relate::interrupt<F1, F2, V, Interrupt>(m_mask) )
592 base_t::template set<F1, F2, V>();
596 template <field F1, field F2, char V>
599 if ( relate::interrupt<F1, F2, V, Interrupt>(m_mask) )
605 base_t::template update<F1, F2, V>();
613 // --------------- FALSE MASK ----------------
615 struct false_mask {};
617 // --------------- COMPILE-TIME MASK ----------------
619 // static_check_characters
620 template <typename Seq>
621 struct static_check_characters {};
623 template <char C, char ...Cs>
624 struct static_check_characters<std::integer_sequence<char, C, Cs...>>
625 : static_check_characters<std::integer_sequence<char, Cs...>>
627 typedef std::integer_sequence<char, C, Cs...> type;
628 static const bool is_valid = (C >= '0' && C <= '9')
629 || C == 'T' || C == 'F' || C == '*';
630 BOOST_GEOMETRY_STATIC_ASSERT((is_valid),
631 "Invalid static mask character",
635 template <char ...Cs>
636 struct static_check_characters<std::integral_constant<char, Cs...>>
641 template <typename Seq, std::size_t Height, std::size_t Width = Height>
644 static const std::size_t static_width = Width;
645 static const std::size_t static_height = Height;
646 static const std::size_t static_size = Width * Height;
649 std::size_t(util::sequence_size<Seq>::value) == static_size);
651 template <detail::relate::field F1, detail::relate::field F2>
654 BOOST_STATIC_ASSERT(std::size_t(F1) < static_height);
655 BOOST_STATIC_ASSERT(std::size_t(F2) < static_width);
657 static const char value
658 = util::sequence_element<F1 * static_width + F2, Seq>::value;
662 // check static_mask characters
663 enum { mask_check = sizeof(static_check_characters<Seq>) };
666 // static_should_handle_element
670 typename StaticMask, field F1, field F2,
671 bool IsSequence = util::is_sequence<StaticMask>::value
673 struct static_should_handle_element_dispatch
675 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
676 static const bool value = mask_el == 'F'
678 || ( mask_el >= '0' && mask_el <= '9' );
683 typename Seq, field F1, field F2,
685 std::size_t N = util::sequence_size<Seq>::value
687 struct static_should_handle_element_sequence
689 typedef typename util::sequence_element<I, Seq>::type StaticMask;
691 static const bool value
692 = static_should_handle_element_dispatch
696 || static_should_handle_element_sequence
702 template <typename Seq, field F1, field F2, std::size_t N>
703 struct static_should_handle_element_sequence<Seq, F1, F2, N, N>
705 static const bool value = false;
708 template <typename StaticMask, field F1, field F2>
709 struct static_should_handle_element_dispatch<StaticMask, F1, F2, true>
711 static const bool value
712 = static_should_handle_element_sequence
718 template <typename StaticMask, field F1, field F2>
719 struct static_should_handle_element
721 static const bool value
722 = static_should_handle_element_dispatch
732 typename StaticMask, char V, field F1, field F2,
733 bool InterruptEnabled,
734 bool IsSequence = util::is_sequence<StaticMask>::value
736 struct static_interrupt_dispatch
738 static const bool value = false;
741 template <typename StaticMask, char V, field F1, field F2, bool IsSequence>
742 struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, IsSequence>
744 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
746 static const bool value
747 = ( V >= '0' && V <= '9' ) ?
748 ( mask_el == 'F' || ( mask_el < V && mask_el >= '0' && mask_el <= '9' ) ) :
749 ( ( V == 'T' ) ? mask_el == 'F' : false );
754 typename Seq, char V, field F1, field F2,
756 std::size_t N = util::sequence_size<Seq>::value
758 struct static_interrupt_sequence
760 typedef typename util::sequence_element<I, Seq>::type StaticMask;
762 static const bool value
763 = static_interrupt_dispatch
765 StaticMask, V, F1, F2, true
767 && static_interrupt_sequence
769 Seq, V, F1, F2, I + 1
773 template <typename Seq, char V, field F1, field F2, std::size_t N>
774 struct static_interrupt_sequence<Seq, V, F1, F2, N, N>
776 static const bool value = true;
779 template <typename StaticMask, char V, field F1, field F2>
780 struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, true>
782 static const bool value
783 = static_interrupt_sequence
785 StaticMask, V, F1, F2
789 template <typename StaticMask, char V, field F1, field F2, bool EnableInterrupt>
790 struct static_interrupt
792 static const bool value
793 = static_interrupt_dispatch
795 StaticMask, V, F1, F2, EnableInterrupt
803 typename StaticMask, char D, field F1, field F2,
804 bool IsSequence = util::is_sequence<StaticMask>::value
806 struct static_may_update_dispatch
808 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
809 static const int version
812 : mask_el >= '0' && mask_el <= '9' ? 2
815 // TODO: use std::enable_if_t instead of std::integral_constant
817 template <typename Matrix>
818 static inline bool apply(Matrix const& matrix)
820 return apply_dispatch(matrix, std::integral_constant<int, version>());
824 template <typename Matrix>
825 static inline bool apply_dispatch(Matrix const& , std::integral_constant<int, 0>)
830 template <typename Matrix>
831 static inline bool apply_dispatch(Matrix const& matrix, std::integral_constant<int, 1>)
833 char const c = matrix.template get<F1, F2>();
834 return c == 'F'; // if it's T or between 0 and 9, the result will be the same
836 // mask_el >= '0' && mask_el <= '9'
837 template <typename Matrix>
838 static inline bool apply_dispatch(Matrix const& matrix, std::integral_constant<int, 2>)
840 char const c = matrix.template get<F1, F2>();
841 return D > c || c > '9';
844 template <typename Matrix>
845 static inline bool apply_dispatch(Matrix const&, std::integral_constant<int, 3>)
853 typename Seq, char D, field F1, field F2,
855 std::size_t N = util::sequence_size<Seq>::value
857 struct static_may_update_sequence
859 typedef typename util::sequence_element<I, Seq>::type StaticMask;
861 template <typename Matrix>
862 static inline bool apply(Matrix const& matrix)
864 return static_may_update_dispatch
866 StaticMask, D, F1, F2
868 || static_may_update_sequence
870 Seq, D, F1, F2, I + 1
875 template <typename Seq, char D, field F1, field F2, std::size_t N>
876 struct static_may_update_sequence<Seq, D, F1, F2, N, N>
878 template <typename Matrix>
879 static inline bool apply(Matrix const& /*matrix*/)
885 template <typename StaticMask, char D, field F1, field F2>
886 struct static_may_update_dispatch<StaticMask, D, F1, F2, true>
888 template <typename Matrix>
889 static inline bool apply(Matrix const& matrix)
891 return static_may_update_sequence
893 StaticMask, D, F1, F2
898 template <typename StaticMask, char D, field F1, field F2>
899 struct static_may_update
901 template <typename Matrix>
902 static inline bool apply(Matrix const& matrix)
904 return static_may_update_dispatch
906 StaticMask, D, F1, F2
911 // static_check_matrix
916 bool IsSequence = util::is_sequence<StaticMask>::value
918 struct static_check_dispatch
920 template <typename Matrix>
921 static inline bool apply(Matrix const& matrix)
923 return per_one<interior, interior>::apply(matrix)
924 && per_one<interior, boundary>::apply(matrix)
925 && per_one<interior, exterior>::apply(matrix)
926 && per_one<boundary, interior>::apply(matrix)
927 && per_one<boundary, boundary>::apply(matrix)
928 && per_one<boundary, exterior>::apply(matrix)
929 && per_one<exterior, interior>::apply(matrix)
930 && per_one<exterior, boundary>::apply(matrix)
931 && per_one<exterior, exterior>::apply(matrix);
934 template <field F1, field F2>
937 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
938 static const int version
941 : mask_el >= '0' && mask_el <= '9' ? 2
944 // TODO: use std::enable_if_t instead of std::integral_constant
946 template <typename Matrix>
947 static inline bool apply(Matrix const& matrix)
949 const char el = matrix.template get<F1, F2>();
950 return apply_dispatch(el, std::integral_constant<int, version>());
954 static inline bool apply_dispatch(char el, std::integral_constant<int, 0>)
959 static inline bool apply_dispatch(char el, std::integral_constant<int, 1>)
961 return el == 'T' || ( el >= '0' && el <= '9' );
963 // mask_el >= '0' && mask_el <= '9'
964 static inline bool apply_dispatch(char el, std::integral_constant<int, 2>)
966 return el == mask_el;
969 static inline bool apply_dispatch(char /*el*/, std::integral_constant<int, 3>)
980 std::size_t N = util::sequence_size<Seq>::value
982 struct static_check_sequence
984 typedef typename util::sequence_element<I, Seq>::type StaticMask;
986 template <typename Matrix>
987 static inline bool apply(Matrix const& matrix)
989 return static_check_dispatch
993 || static_check_sequence
1000 template <typename Seq, std::size_t N>
1001 struct static_check_sequence<Seq, N, N>
1003 template <typename Matrix>
1004 static inline bool apply(Matrix const& /*matrix*/)
1010 template <typename StaticMask>
1011 struct static_check_dispatch<StaticMask, true>
1013 template <typename Matrix>
1014 static inline bool apply(Matrix const& matrix)
1016 return static_check_sequence
1023 template <typename StaticMask>
1024 struct static_check_matrix
1026 template <typename Matrix>
1027 static inline bool apply(Matrix const& matrix)
1029 return static_check_dispatch
1036 // static_mask_handler
1038 template <typename StaticMask, bool Interrupt>
1039 class static_mask_handler
1040 : private matrix_handler< matrix<3> >
1042 typedef matrix_handler< relate::matrix<3> > base_type;
1045 typedef bool result_type;
1049 inline static_mask_handler()
1053 inline explicit static_mask_handler(StaticMask const& /*dummy*/)
1057 result_type result() const
1059 return (!Interrupt || !interrupt)
1060 && static_check_matrix<StaticMask>::apply(base_type::matrix());
1063 template <field F1, field F2, char D>
1064 inline bool may_update() const
1066 return static_may_update<StaticMask, D, F1, F2>::
1067 apply(base_type::matrix());
1070 template <field F1, field F2>
1071 static inline bool expects()
1073 return static_should_handle_element<StaticMask, F1, F2>::value;
1076 template <field F1, field F2, char V>
1079 static const bool interrupt_c = static_interrupt<StaticMask, V, F1, F2, Interrupt>::value;
1080 static const bool should_handle = static_should_handle_element<StaticMask, F1, F2>::value;
1081 static const int version = interrupt_c ? 0
1085 set_dispatch<F1, F2, V>(integral_constant<int, version>());
1088 template <field F1, field F2, char V>
1089 inline void update()
1091 static const bool interrupt_c = static_interrupt<StaticMask, V, F1, F2, Interrupt>::value;
1092 static const bool should_handle = static_should_handle_element<StaticMask, F1, F2>::value;
1093 static const int version = interrupt_c ? 0
1097 update_dispatch<F1, F2, V>(integral_constant<int, version>());
1101 // Interrupt && interrupt
1102 template <field F1, field F2, char V>
1103 inline void set_dispatch(integral_constant<int, 0>)
1107 // else should_handle
1108 template <field F1, field F2, char V>
1109 inline void set_dispatch(integral_constant<int, 1>)
1111 base_type::template set<F1, F2, V>();
1114 template <field F1, field F2, char V>
1115 inline void set_dispatch(integral_constant<int, 2>)
1118 // Interrupt && interrupt
1119 template <field F1, field F2, char V>
1120 inline void update_dispatch(integral_constant<int, 0>)
1124 // else should_handle
1125 template <field F1, field F2, char V>
1126 inline void update_dispatch(integral_constant<int, 1>)
1128 base_type::template update<F1, F2, V>();
1131 template <field F1, field F2, char V>
1132 inline void update_dispatch(integral_constant<int, 2>)
1136 // --------------- UTIL FUNCTIONS ----------------
1140 template <field F1, field F2, char V, typename Result>
1141 inline void set(Result & res)
1143 res.template set<F1, F2, V>();
1146 template <field F1, field F2, char V, bool Transpose>
1149 template <typename Result>
1150 static inline void apply(Result & res)
1152 res.template set<F1, F2, V>();
1156 template <field F1, field F2, char V>
1157 struct set_dispatch<F1, F2, V, true>
1159 template <typename Result>
1160 static inline void apply(Result & res)
1162 res.template set<F2, F1, V>();
1166 template <field F1, field F2, char V, bool Transpose, typename Result>
1167 inline void set(Result & res)
1169 set_dispatch<F1, F2, V, Transpose>::apply(res);
1174 template <field F1, field F2, char D, typename Result>
1175 inline void update(Result & res)
1177 res.template update<F1, F2, D>();
1180 template <field F1, field F2, char D, bool Transpose>
1181 struct update_result_dispatch
1183 template <typename Result>
1184 static inline void apply(Result & res)
1186 update<F1, F2, D>(res);
1190 template <field F1, field F2, char D>
1191 struct update_result_dispatch<F1, F2, D, true>
1193 template <typename Result>
1194 static inline void apply(Result & res)
1196 update<F2, F1, D>(res);
1200 template <field F1, field F2, char D, bool Transpose, typename Result>
1201 inline void update(Result & res)
1203 update_result_dispatch<F1, F2, D, Transpose>::apply(res);
1208 template <field F1, field F2, char D, typename Result>
1209 inline bool may_update(Result const& res)
1211 return res.template may_update<F1, F2, D>();
1214 template <field F1, field F2, char D, bool Transpose>
1215 struct may_update_result_dispatch
1217 template <typename Result>
1218 static inline bool apply(Result const& res)
1220 return may_update<F1, F2, D>(res);
1224 template <field F1, field F2, char D>
1225 struct may_update_result_dispatch<F1, F2, D, true>
1227 template <typename Result>
1228 static inline bool apply(Result const& res)
1230 return may_update<F2, F1, D>(res);
1234 template <field F1, field F2, char D, bool Transpose, typename Result>
1235 inline bool may_update(Result const& res)
1237 return may_update_result_dispatch<F1, F2, D, Transpose>::apply(res);
1242 template <typename Geometry>
1243 struct result_dimension
1245 BOOST_STATIC_ASSERT(geometry::dimension<Geometry>::value >= 0);
1246 static const char value
1247 = ( geometry::dimension<Geometry>::value <= 9 ) ?
1248 ( '0' + geometry::dimension<Geometry>::value ) :
1252 }} // namespace detail::relate
1253 #endif // DOXYGEN_NO_DETAIL
1255 }} // namespace boost::geometry
1257 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP