1 // Boost.Geometry (aka GGL, Generic Geometry Library)
3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
5 // This file was modified by Oracle on 2013-2016.
6 // Modifications copyright (c) 2013-2016 Oracle and/or its affiliates.
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
14 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
15 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
19 #include <boost/mpl/assert.hpp>
20 #include <boost/mpl/at.hpp>
21 #include <boost/mpl/begin.hpp>
22 #include <boost/mpl/deref.hpp>
23 #include <boost/mpl/end.hpp>
24 #include <boost/mpl/is_sequence.hpp>
25 #include <boost/mpl/next.hpp>
26 #include <boost/static_assert.hpp>
27 #include <boost/tuple/tuple.hpp>
28 #include <boost/type_traits/integral_constant.hpp>
30 #include <boost/geometry/core/assert.hpp>
31 #include <boost/geometry/core/coordinate_dimension.hpp>
32 #include <boost/geometry/core/exception.hpp>
33 #include <boost/geometry/util/condition.hpp>
35 namespace boost { namespace geometry {
37 #ifndef DOXYGEN_NO_DETAIL
38 namespace detail { namespace relate {
40 enum field { interior = 0, boundary = 1, exterior = 2 };
42 // TODO: IF THE RESULT IS UPDATED WITH THE MAX POSSIBLE VALUE FOR SOME PAIR OF GEOEMTRIES
43 // THE VALUE ALREADY STORED MUSN'T BE CHECKED
44 // update() calls chould be replaced with set() in those cases
45 // but for safety reasons (STATIC_ASSERT) we should check if parameter D is valid and set() doesn't do that
46 // so some additional function could be added, e.g. set_dim()
48 // --------------- MATRIX ----------------
52 template <std::size_t Height, std::size_t Width = Height>
56 typedef char value_type;
57 typedef std::size_t size_type;
58 typedef const char * const_iterator;
59 typedef const_iterator iterator;
61 static const std::size_t static_width = Width;
62 static const std::size_t static_height = Height;
63 static const std::size_t static_size = Width * Height;
67 ::memset(m_array, 'F', static_size);
70 template <field F1, field F2>
71 inline char get() const
73 BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
74 static const std::size_t index = F1 * Width + F2;
75 BOOST_STATIC_ASSERT(index < static_size);
76 return m_array[index];
79 template <field F1, field F2, char V>
82 BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
83 static const std::size_t index = F1 * Width + F2;
84 BOOST_STATIC_ASSERT(index < static_size);
88 inline char operator[](std::size_t index) const
90 BOOST_GEOMETRY_ASSERT(index < static_size);
91 return m_array[index];
94 inline const_iterator begin() const
99 inline const_iterator end() const
101 return m_array + static_size;
104 inline static std::size_t size()
109 inline const char * data() const
114 inline std::string str() const
116 return std::string(m_array, static_size);
120 char m_array[static_size];
125 template <typename Matrix>
129 typedef Matrix result_type;
131 static const bool interrupt = false;
136 result_type const& result() const
141 result_type const& matrix() const
146 result_type & matrix()
151 template <field F1, field F2, char D>
152 inline bool may_update() const
154 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
156 char const c = m_matrix.template get<F1, F2>();
157 return D > c || c > '9';
160 template <field F1, field F2, char V>
163 static const bool in_bounds = F1 < Matrix::static_height
164 && F2 < Matrix::static_width;
165 typedef boost::integral_constant<bool, in_bounds> in_bounds_t;
166 set_dispatch<F1, F2, V>(in_bounds_t());
169 template <field F1, field F2, char D>
172 static const bool in_bounds = F1 < Matrix::static_height
173 && F2 < Matrix::static_width;
174 typedef boost::integral_constant<bool, in_bounds> in_bounds_t;
175 update_dispatch<F1, F2, D>(in_bounds_t());
179 template <field F1, field F2, char V>
180 inline void set_dispatch(integral_constant<bool, true>)
182 static const std::size_t index = F1 * Matrix::static_width + F2;
183 BOOST_STATIC_ASSERT(index < Matrix::static_size);
184 BOOST_STATIC_ASSERT(('0' <= V && V <= '9') || V == 'T' || V == 'F');
185 m_matrix.template set<F1, F2, V>();
187 template <field F1, field F2, char V>
188 inline void set_dispatch(integral_constant<bool, false>)
191 template <field F1, field F2, char D>
192 inline void update_dispatch(integral_constant<bool, true>)
194 static const std::size_t index = F1 * Matrix::static_width + F2;
195 BOOST_STATIC_ASSERT(index < Matrix::static_size);
196 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
197 char const c = m_matrix.template get<F1, F2>();
198 if ( D > c || c > '9')
199 m_matrix.template set<F1, F2, D>();
201 template <field F1, field F2, char D>
202 inline void update_dispatch(integral_constant<bool, false>)
208 // --------------- RUN-TIME MASK ----------------
212 template <std::size_t Height, std::size_t Width = Height>
216 static const std::size_t static_width = Width;
217 static const std::size_t static_height = Height;
218 static const std::size_t static_size = Width * Height;
220 inline mask(const char * s)
223 char * const last = m_array + static_size;
224 for ( ; it != last && *s != '\0' ; ++it, ++s )
232 ::memset(it, '*', last - it);
236 inline mask(const char * s, std::size_t count)
238 if ( count > static_size )
244 std::for_each(s, s + count, check_char);
245 ::memcpy(m_array, s, count);
247 if ( count < static_size )
249 ::memset(m_array + count, '*', static_size - count);
253 template <field F1, field F2>
254 inline char get() const
256 BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
257 static const std::size_t index = F1 * Width + F2;
258 BOOST_STATIC_ASSERT(index < static_size);
259 return m_array[index];
263 static inline void check_char(char c)
265 bool const is_valid = c == '*' || c == 'T' || c == 'F'
266 || ( c >= '0' && c <= '9' );
269 throw geometry::invalid_input_exception();
273 char m_array[static_size];
278 template <typename Mask, bool InterruptEnabled>
279 struct interrupt_dispatch
281 template <field F1, field F2, char V>
282 static inline bool apply(Mask const&)
288 template <typename Mask>
289 struct interrupt_dispatch<Mask, true>
291 template <field F1, field F2, char V>
292 static inline bool apply(Mask const& mask)
294 char m = mask.template get<F1, F2>();
295 return check_element<V>(m);
299 static inline bool check_element(char m)
301 if ( BOOST_GEOMETRY_CONDITION(V >= '0' && V <= '9') )
303 return m == 'F' || ( m < V && m >= '0' && m <= '9' );
305 else if ( BOOST_GEOMETRY_CONDITION(V == 'T') )
313 template <typename Masks, int I = 0, int N = boost::tuples::length<Masks>::value>
314 struct interrupt_dispatch_tuple
316 template <field F1, field F2, char V>
317 static inline bool apply(Masks const& masks)
319 typedef typename boost::tuples::element<I, Masks>::type mask_type;
320 mask_type const& mask = boost::get<I>(masks);
321 return interrupt_dispatch<mask_type, true>::template apply<F1, F2, V>(mask)
322 && interrupt_dispatch_tuple<Masks, I+1>::template apply<F1, F2, V>(masks);
326 template <typename Masks, int N>
327 struct interrupt_dispatch_tuple<Masks, N, N>
329 template <field F1, field F2, char V>
330 static inline bool apply(Masks const& )
336 //template <typename T0, typename T1, typename T2, typename T3, typename T4,
337 // typename T5, typename T6, typename T7, typename T8, typename T9>
338 //struct interrupt_dispatch<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, true>
340 // typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
342 // template <field F1, field F2, char V>
343 // static inline bool apply(mask_type const& mask)
345 // return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
349 template <typename Head, typename Tail>
350 struct interrupt_dispatch<boost::tuples::cons<Head, Tail>, true>
352 typedef boost::tuples::cons<Head, Tail> mask_type;
354 template <field F1, field F2, char V>
355 static inline bool apply(mask_type const& mask)
357 return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
361 template <field F1, field F2, char V, bool InterruptEnabled, typename Mask>
362 inline bool interrupt(Mask const& mask)
364 return interrupt_dispatch<Mask, InterruptEnabled>
365 ::template apply<F1, F2, V>(mask);
370 template <typename Mask>
371 struct may_update_dispatch
373 template <field F1, field F2, char D, typename Matrix>
374 static inline bool apply(Mask const& mask, Matrix const& matrix)
376 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
378 char const m = mask.template get<F1, F2>();
386 char const c = matrix.template get<F1, F2>();
387 return c == 'F'; // if it's T or between 0 and 9, the result will be the same
389 else if ( m >= '0' && m <= '9' )
391 char const c = matrix.template get<F1, F2>();
392 return D > c || c > '9';
399 template <typename Masks, int I = 0, int N = boost::tuples::length<Masks>::value>
400 struct may_update_dispatch_tuple
402 template <field F1, field F2, char D, typename Matrix>
403 static inline bool apply(Masks const& masks, Matrix const& matrix)
405 typedef typename boost::tuples::element<I, Masks>::type mask_type;
406 mask_type const& mask = boost::get<I>(masks);
407 return may_update_dispatch<mask_type>::template apply<F1, F2, D>(mask, matrix)
408 || may_update_dispatch_tuple<Masks, I+1>::template apply<F1, F2, D>(masks, matrix);
412 template <typename Masks, int N>
413 struct may_update_dispatch_tuple<Masks, N, N>
415 template <field F1, field F2, char D, typename Matrix>
416 static inline bool apply(Masks const& , Matrix const& )
422 //template <typename T0, typename T1, typename T2, typename T3, typename T4,
423 // typename T5, typename T6, typename T7, typename T8, typename T9>
424 //struct may_update_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
426 // typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
428 // template <field F1, field F2, char D, typename Matrix>
429 // static inline bool apply(mask_type const& mask, Matrix const& matrix)
431 // return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
435 template <typename Head, typename Tail>
436 struct may_update_dispatch< boost::tuples::cons<Head, Tail> >
438 typedef boost::tuples::cons<Head, Tail> mask_type;
440 template <field F1, field F2, char D, typename Matrix>
441 static inline bool apply(mask_type const& mask, Matrix const& matrix)
443 return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
447 template <field F1, field F2, char D, typename Mask, typename Matrix>
448 inline bool may_update(Mask const& mask, Matrix const& matrix)
450 return may_update_dispatch<Mask>
451 ::template apply<F1, F2, D>(mask, matrix);
456 template <typename Mask>
457 struct check_dispatch
459 template <typename Matrix>
460 static inline bool apply(Mask const& mask, Matrix const& matrix)
462 return per_one<interior, interior>(mask, matrix)
463 && per_one<interior, boundary>(mask, matrix)
464 && per_one<interior, exterior>(mask, matrix)
465 && per_one<boundary, interior>(mask, matrix)
466 && per_one<boundary, boundary>(mask, matrix)
467 && per_one<boundary, exterior>(mask, matrix)
468 && per_one<exterior, interior>(mask, matrix)
469 && per_one<exterior, boundary>(mask, matrix)
470 && per_one<exterior, exterior>(mask, matrix);
473 template <field F1, field F2, typename Matrix>
474 static inline bool per_one(Mask const& mask, Matrix const& matrix)
476 const char mask_el = mask.template get<F1, F2>();
477 const char el = matrix.template get<F1, F2>();
479 if ( mask_el == 'F' )
483 else if ( mask_el == 'T' )
485 return el == 'T' || ( el >= '0' && el <= '9' );
487 else if ( mask_el >= '0' && mask_el <= '9' )
489 return el == mask_el;
496 template <typename Masks, int I = 0, int N = boost::tuples::length<Masks>::value>
497 struct check_dispatch_tuple
499 template <typename Matrix>
500 static inline bool apply(Masks const& masks, Matrix const& matrix)
502 typedef typename boost::tuples::element<I, Masks>::type mask_type;
503 mask_type const& mask = boost::get<I>(masks);
504 return check_dispatch<mask_type>::apply(mask, matrix)
505 || check_dispatch_tuple<Masks, I+1>::apply(masks, matrix);
509 template <typename Masks, int N>
510 struct check_dispatch_tuple<Masks, N, N>
512 template <typename Matrix>
513 static inline bool apply(Masks const&, Matrix const&)
519 //template <typename T0, typename T1, typename T2, typename T3, typename T4,
520 // typename T5, typename T6, typename T7, typename T8, typename T9>
521 //struct check_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
523 // typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
525 // template <typename Matrix>
526 // static inline bool apply(mask_type const& mask, Matrix const& matrix)
528 // return check_dispatch_tuple<mask_type>::apply(mask, matrix);
532 template <typename Head, typename Tail>
533 struct check_dispatch< boost::tuples::cons<Head, Tail> >
535 typedef boost::tuples::cons<Head, Tail> mask_type;
537 template <typename Matrix>
538 static inline bool apply(mask_type const& mask, Matrix const& matrix)
540 return check_dispatch_tuple<mask_type>::apply(mask, matrix);
544 template <typename Mask, typename Matrix>
545 inline bool check_matrix(Mask const& mask, Matrix const& matrix)
547 return check_dispatch<Mask>::apply(mask, matrix);
552 template <typename MatrixOrMask>
555 static const std::size_t value = MatrixOrMask::static_width;
558 template <typename Tuple,
560 int N = boost::tuples::length<Tuple>::value>
561 struct matrix_width_tuple
563 static const std::size_t
564 current = matrix_width<typename boost::tuples::element<I, Tuple>::type>::value;
565 static const std::size_t
566 next = matrix_width_tuple<Tuple, I+1>::value;
568 static const std::size_t
569 value = current > next ? current : next;
572 template <typename Tuple, int N>
573 struct matrix_width_tuple<Tuple, N, N>
575 static const std::size_t value = 0;
578 template <typename Head, typename Tail>
579 struct matrix_width< boost::tuples::cons<Head, Tail> >
581 static const std::size_t
582 value = matrix_width_tuple< boost::tuples::cons<Head, Tail> >::value;
587 template <typename Mask, bool Interrupt>
589 : private matrix_handler
591 relate::matrix<matrix_width<Mask>::value>
594 typedef matrix_handler
596 relate::matrix<matrix_width<Mask>::value>
600 typedef bool result_type;
604 inline explicit mask_handler(Mask const& m)
609 result_type result() const
612 && check_matrix(m_mask, base_t::matrix());
615 template <field F1, field F2, char D>
616 inline bool may_update() const
618 return detail::relate::may_update<F1, F2, D>(
619 m_mask, base_t::matrix()
623 template <field F1, field F2, char V>
626 if ( relate::interrupt<F1, F2, V, Interrupt>(m_mask) )
632 base_t::template set<F1, F2, V>();
636 template <field F1, field F2, char V>
639 if ( relate::interrupt<F1, F2, V, Interrupt>(m_mask) )
645 base_t::template update<F1, F2, V>();
653 // --------------- COMPILE-TIME MASK ----------------
655 // static_check_characters
659 typename First = typename boost::mpl::begin<Seq>::type,
660 typename Last = typename boost::mpl::end<Seq>::type
662 struct static_check_characters
663 : static_check_characters
666 typename boost::mpl::next<First>::type
669 typedef typename boost::mpl::deref<First>::type type;
670 static const char value = type::value;
671 static const bool is_valid = (value >= '0' && value <= '9')
672 || value == 'T' || value == 'F' || value == '*';
673 BOOST_MPL_ASSERT_MSG((is_valid),
674 INVALID_STATIC_MASK_CHARACTER,
678 template <typename Seq, typename Last>
679 struct static_check_characters<Seq, Last, Last>
688 std::size_t Width = Height
692 static const std::size_t static_width = Width;
693 static const std::size_t static_height = Height;
694 static const std::size_t static_size = Width * Height;
697 std::size_t(boost::mpl::size<Seq>::type::value) == static_size);
699 template <detail::relate::field F1, detail::relate::field F2>
702 BOOST_STATIC_ASSERT(std::size_t(F1) < static_height);
703 BOOST_STATIC_ASSERT(std::size_t(F2) < static_width);
705 static const char value
706 = boost::mpl::at_c<Seq, F1 * static_width + F2>::type::value;
710 // check static_mask characters
711 enum { mask_check = sizeof(static_check_characters<Seq>) };
714 // static_should_handle_element
716 template <typename StaticMask, field F1, field F2, bool IsSequence>
717 struct static_should_handle_element_dispatch
719 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
720 static const bool value = mask_el == 'F'
722 || ( mask_el >= '0' && mask_el <= '9' );
725 template <typename First, typename Last, field F1, field F2>
726 struct static_should_handle_element_sequence
728 typedef typename boost::mpl::deref<First>::type StaticMask;
730 static const bool value
731 = static_should_handle_element_dispatch
735 boost::mpl::is_sequence<StaticMask>::value
737 || static_should_handle_element_sequence
739 typename boost::mpl::next<First>::type,
745 template <typename Last, field F1, field F2>
746 struct static_should_handle_element_sequence<Last, Last, F1, F2>
748 static const bool value = false;
751 template <typename StaticMask, field F1, field F2>
752 struct static_should_handle_element_dispatch<StaticMask, F1, F2, true>
754 static const bool value
755 = static_should_handle_element_sequence
757 typename boost::mpl::begin<StaticMask>::type,
758 typename boost::mpl::end<StaticMask>::type,
763 template <typename StaticMask, field F1, field F2>
764 struct static_should_handle_element
766 static const bool value
767 = static_should_handle_element_dispatch
771 boost::mpl::is_sequence<StaticMask>::value
777 template <typename StaticMask, char V, field F1, field F2, bool InterruptEnabled, bool IsSequence>
778 struct static_interrupt_dispatch
780 static const bool value = false;
783 template <typename StaticMask, char V, field F1, field F2, bool IsSequence>
784 struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, IsSequence>
786 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
788 static const bool value
789 = ( V >= '0' && V <= '9' ) ?
790 ( mask_el == 'F' || ( mask_el < V && mask_el >= '0' && mask_el <= '9' ) ) :
791 ( ( V == 'T' ) ? mask_el == 'F' : false );
794 template <typename First, typename Last, char V, field F1, field F2>
795 struct static_interrupt_sequence
797 typedef typename boost::mpl::deref<First>::type StaticMask;
799 static const bool value
800 = static_interrupt_dispatch
805 boost::mpl::is_sequence<StaticMask>::value
807 && static_interrupt_sequence
809 typename boost::mpl::next<First>::type,
815 template <typename Last, char V, field F1, field F2>
816 struct static_interrupt_sequence<Last, Last, V, F1, F2>
818 static const bool value = true;
821 template <typename StaticMask, char V, field F1, field F2>
822 struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, true>
824 static const bool value
825 = static_interrupt_sequence
827 typename boost::mpl::begin<StaticMask>::type,
828 typename boost::mpl::end<StaticMask>::type,
833 template <typename StaticMask, char V, field F1, field F2, bool EnableInterrupt>
834 struct static_interrupt
836 static const bool value
837 = static_interrupt_dispatch
842 boost::mpl::is_sequence<StaticMask>::value
848 template <typename StaticMask, char D, field F1, field F2, bool IsSequence>
849 struct static_may_update_dispatch
851 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
852 static const int version
855 : mask_el >= '0' && mask_el <= '9' ? 2
858 template <typename Matrix>
859 static inline bool apply(Matrix const& matrix)
861 return apply_dispatch(matrix, integral_constant<int, version>());
865 template <typename Matrix>
866 static inline bool apply_dispatch(Matrix const& , integral_constant<int, 0>)
871 template <typename Matrix>
872 static inline bool apply_dispatch(Matrix const& matrix, integral_constant<int, 1>)
874 char const c = matrix.template get<F1, F2>();
875 return c == 'F'; // if it's T or between 0 and 9, the result will be the same
877 // mask_el >= '0' && mask_el <= '9'
878 template <typename Matrix>
879 static inline bool apply_dispatch(Matrix const& matrix, integral_constant<int, 2>)
881 char const c = matrix.template get<F1, F2>();
882 return D > c || c > '9';
885 template <typename Matrix>
886 static inline bool apply_dispatch(Matrix const&, integral_constant<int, 3>)
892 template <typename First, typename Last, char D, field F1, field F2>
893 struct static_may_update_sequence
895 typedef typename boost::mpl::deref<First>::type StaticMask;
897 template <typename Matrix>
898 static inline bool apply(Matrix const& matrix)
900 return static_may_update_dispatch
904 boost::mpl::is_sequence<StaticMask>::value
906 || static_may_update_sequence
908 typename boost::mpl::next<First>::type,
915 template <typename Last, char D, field F1, field F2>
916 struct static_may_update_sequence<Last, Last, D, F1, F2>
918 template <typename Matrix>
919 static inline bool apply(Matrix const& /*matrix*/)
925 template <typename StaticMask, char D, field F1, field F2>
926 struct static_may_update_dispatch<StaticMask, D, F1, F2, true>
928 template <typename Matrix>
929 static inline bool apply(Matrix const& matrix)
931 return static_may_update_sequence
933 typename boost::mpl::begin<StaticMask>::type,
934 typename boost::mpl::end<StaticMask>::type,
940 template <typename StaticMask, char D, field F1, field F2>
941 struct static_may_update
943 template <typename Matrix>
944 static inline bool apply(Matrix const& matrix)
946 return static_may_update_dispatch
950 boost::mpl::is_sequence<StaticMask>::value
955 // static_check_matrix
957 template <typename StaticMask, bool IsSequence>
958 struct static_check_dispatch
960 template <typename Matrix>
961 static inline bool apply(Matrix const& matrix)
963 return per_one<interior, interior>::apply(matrix)
964 && per_one<interior, boundary>::apply(matrix)
965 && per_one<interior, exterior>::apply(matrix)
966 && per_one<boundary, interior>::apply(matrix)
967 && per_one<boundary, boundary>::apply(matrix)
968 && per_one<boundary, exterior>::apply(matrix)
969 && per_one<exterior, interior>::apply(matrix)
970 && per_one<exterior, boundary>::apply(matrix)
971 && per_one<exterior, exterior>::apply(matrix);
974 template <field F1, field F2>
977 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
978 static const int version
981 : mask_el >= '0' && mask_el <= '9' ? 2
984 template <typename Matrix>
985 static inline bool apply(Matrix const& matrix)
987 const char el = matrix.template get<F1, F2>();
988 return apply_dispatch(el, integral_constant<int, version>());
992 static inline bool apply_dispatch(char el, integral_constant<int, 0>)
997 static inline bool apply_dispatch(char el, integral_constant<int, 1>)
999 return el == 'T' || ( el >= '0' && el <= '9' );
1001 // mask_el >= '0' && mask_el <= '9'
1002 static inline bool apply_dispatch(char el, integral_constant<int, 2>)
1004 return el == mask_el;
1007 static inline bool apply_dispatch(char /*el*/, integral_constant<int, 3>)
1014 template <typename First, typename Last>
1015 struct static_check_sequence
1017 typedef typename boost::mpl::deref<First>::type StaticMask;
1019 template <typename Matrix>
1020 static inline bool apply(Matrix const& matrix)
1022 return static_check_dispatch
1025 boost::mpl::is_sequence<StaticMask>::value
1027 || static_check_sequence
1029 typename boost::mpl::next<First>::type,
1035 template <typename Last>
1036 struct static_check_sequence<Last, Last>
1038 template <typename Matrix>
1039 static inline bool apply(Matrix const& /*matrix*/)
1045 template <typename StaticMask>
1046 struct static_check_dispatch<StaticMask, true>
1048 template <typename Matrix>
1049 static inline bool apply(Matrix const& matrix)
1051 return static_check_sequence
1053 typename boost::mpl::begin<StaticMask>::type,
1054 typename boost::mpl::end<StaticMask>::type
1059 template <typename StaticMask>
1060 struct static_check_matrix
1062 template <typename Matrix>
1063 static inline bool apply(Matrix const& matrix)
1065 return static_check_dispatch
1068 boost::mpl::is_sequence<StaticMask>::value
1073 // static_mask_handler
1075 template <typename StaticMask, bool Interrupt>
1076 class static_mask_handler
1077 : private matrix_handler< matrix<3> >
1079 typedef matrix_handler< relate::matrix<3> > base_type;
1082 typedef bool result_type;
1086 inline static_mask_handler()
1090 inline explicit static_mask_handler(StaticMask const& /*dummy*/)
1094 result_type result() const
1096 return (!Interrupt || !interrupt)
1097 && static_check_matrix<StaticMask>::apply(base_type::matrix());
1100 template <field F1, field F2, char D>
1101 inline bool may_update() const
1103 return static_may_update<StaticMask, D, F1, F2>::
1104 apply(base_type::matrix());
1107 template <field F1, field F2>
1108 static inline bool expects()
1110 return static_should_handle_element<StaticMask, F1, F2>::value;
1113 template <field F1, field F2, char V>
1116 static const bool interrupt_c = static_interrupt<StaticMask, V, F1, F2, Interrupt>::value;
1117 static const bool should_handle = static_should_handle_element<StaticMask, F1, F2>::value;
1118 static const int version = interrupt_c ? 0
1122 set_dispatch<F1, F2, V>(integral_constant<int, version>());
1125 template <field F1, field F2, char V>
1126 inline void update()
1128 static const bool interrupt_c = static_interrupt<StaticMask, V, F1, F2, Interrupt>::value;
1129 static const bool should_handle = static_should_handle_element<StaticMask, F1, F2>::value;
1130 static const int version = interrupt_c ? 0
1134 update_dispatch<F1, F2, V>(integral_constant<int, version>());
1138 // Interrupt && interrupt
1139 template <field F1, field F2, char V>
1140 inline void set_dispatch(integral_constant<int, 0>)
1144 // else should_handle
1145 template <field F1, field F2, char V>
1146 inline void set_dispatch(integral_constant<int, 1>)
1148 base_type::template set<F1, F2, V>();
1151 template <field F1, field F2, char V>
1152 inline void set_dispatch(integral_constant<int, 2>)
1155 // Interrupt && interrupt
1156 template <field F1, field F2, char V>
1157 inline void update_dispatch(integral_constant<int, 0>)
1161 // else should_handle
1162 template <field F1, field F2, char V>
1163 inline void update_dispatch(integral_constant<int, 1>)
1165 base_type::template update<F1, F2, V>();
1168 template <field F1, field F2, char V>
1169 inline void update_dispatch(integral_constant<int, 2>)
1173 // --------------- UTIL FUNCTIONS ----------------
1177 template <field F1, field F2, char V, typename Result>
1178 inline void set(Result & res)
1180 res.template set<F1, F2, V>();
1183 template <field F1, field F2, char V, bool Transpose>
1186 template <typename Result>
1187 static inline void apply(Result & res)
1189 res.template set<F1, F2, V>();
1193 template <field F1, field F2, char V>
1194 struct set_dispatch<F1, F2, V, true>
1196 template <typename Result>
1197 static inline void apply(Result & res)
1199 res.template set<F2, F1, V>();
1203 template <field F1, field F2, char V, bool Transpose, typename Result>
1204 inline void set(Result & res)
1206 set_dispatch<F1, F2, V, Transpose>::apply(res);
1211 template <field F1, field F2, char D, typename Result>
1212 inline void update(Result & res)
1214 res.template update<F1, F2, D>();
1217 template <field F1, field F2, char D, bool Transpose>
1218 struct update_result_dispatch
1220 template <typename Result>
1221 static inline void apply(Result & res)
1223 update<F1, F2, D>(res);
1227 template <field F1, field F2, char D>
1228 struct update_result_dispatch<F1, F2, D, true>
1230 template <typename Result>
1231 static inline void apply(Result & res)
1233 update<F2, F1, D>(res);
1237 template <field F1, field F2, char D, bool Transpose, typename Result>
1238 inline void update(Result & res)
1240 update_result_dispatch<F1, F2, D, Transpose>::apply(res);
1245 template <field F1, field F2, char D, typename Result>
1246 inline bool may_update(Result const& res)
1248 return res.template may_update<F1, F2, D>();
1251 template <field F1, field F2, char D, bool Transpose>
1252 struct may_update_result_dispatch
1254 template <typename Result>
1255 static inline bool apply(Result const& res)
1257 return may_update<F1, F2, D>(res);
1261 template <field F1, field F2, char D>
1262 struct may_update_result_dispatch<F1, F2, D, true>
1264 template <typename Result>
1265 static inline bool apply(Result const& res)
1267 return may_update<F2, F1, D>(res);
1271 template <field F1, field F2, char D, bool Transpose, typename Result>
1272 inline bool may_update(Result const& res)
1274 return may_update_result_dispatch<F1, F2, D, Transpose>::apply(res);
1279 template <typename Geometry>
1280 struct result_dimension
1282 BOOST_STATIC_ASSERT(geometry::dimension<Geometry>::value >= 0);
1283 static const char value
1284 = ( geometry::dimension<Geometry>::value <= 9 ) ?
1285 ( '0' + geometry::dimension<Geometry>::value ) :
1289 }} // namespace detail::relate
1290 #endif // DOXYGEN_NO_DETAIL
1292 }} // namespace boost::geometry
1294 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP