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-2016.
7 // Modifications copyright (c) 2013-2016 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
20 #include <boost/mpl/assert.hpp>
21 #include <boost/mpl/at.hpp>
22 #include <boost/mpl/begin.hpp>
23 #include <boost/mpl/deref.hpp>
24 #include <boost/mpl/end.hpp>
25 #include <boost/mpl/is_sequence.hpp>
26 #include <boost/mpl/next.hpp>
27 #include <boost/static_assert.hpp>
28 #include <boost/throw_exception.hpp>
29 #include <boost/tuple/tuple.hpp>
30 #include <boost/type_traits/integral_constant.hpp>
32 #include <boost/geometry/core/assert.hpp>
33 #include <boost/geometry/core/coordinate_dimension.hpp>
34 #include <boost/geometry/core/exception.hpp>
35 #include <boost/geometry/util/condition.hpp>
37 namespace boost { namespace geometry {
39 #ifndef DOXYGEN_NO_DETAIL
40 namespace detail { namespace relate {
42 enum field { interior = 0, boundary = 1, exterior = 2 };
44 // TODO: IF THE RESULT IS UPDATED WITH THE MAX POSSIBLE VALUE FOR SOME PAIR OF GEOEMTRIES
45 // THE VALUE ALREADY STORED MUSN'T BE CHECKED
46 // update() calls chould be replaced with set() in those cases
47 // but for safety reasons (STATIC_ASSERT) we should check if parameter D is valid and set() doesn't do that
48 // so some additional function could be added, e.g. set_dim()
50 // --------------- MATRIX ----------------
54 template <std::size_t Height, std::size_t Width = Height>
58 typedef char value_type;
59 typedef std::size_t size_type;
60 typedef const char * const_iterator;
61 typedef const_iterator iterator;
63 static const std::size_t static_width = Width;
64 static const std::size_t static_height = Height;
65 static const std::size_t static_size = Width * Height;
69 ::memset(m_array, 'F', static_size);
72 template <field F1, field F2>
73 inline char get() const
75 BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
76 static const std::size_t index = F1 * Width + F2;
77 BOOST_STATIC_ASSERT(index < static_size);
78 return m_array[index];
81 template <field F1, field F2, char V>
84 BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
85 static const std::size_t index = F1 * Width + F2;
86 BOOST_STATIC_ASSERT(index < static_size);
90 inline char operator[](std::size_t index) const
92 BOOST_GEOMETRY_ASSERT(index < static_size);
93 return m_array[index];
96 inline const_iterator begin() const
101 inline const_iterator end() const
103 return m_array + static_size;
106 inline static std::size_t size()
111 inline const char * data() const
116 inline std::string str() const
118 return std::string(m_array, static_size);
122 char m_array[static_size];
127 template <typename Matrix>
131 typedef Matrix result_type;
133 static const bool interrupt = false;
138 result_type const& result() const
143 result_type const& matrix() const
148 result_type & matrix()
153 template <field F1, field F2, char D>
154 inline bool may_update() const
156 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
158 char const c = m_matrix.template get<F1, F2>();
159 return D > c || c > '9';
162 template <field F1, field F2, char V>
165 static const bool in_bounds = F1 < Matrix::static_height
166 && F2 < Matrix::static_width;
167 typedef boost::integral_constant<bool, in_bounds> in_bounds_t;
168 set_dispatch<F1, F2, V>(in_bounds_t());
171 template <field F1, field F2, char D>
174 static const bool in_bounds = F1 < Matrix::static_height
175 && F2 < Matrix::static_width;
176 typedef boost::integral_constant<bool, in_bounds> in_bounds_t;
177 update_dispatch<F1, F2, D>(in_bounds_t());
181 template <field F1, field F2, char V>
182 inline void set_dispatch(integral_constant<bool, true>)
184 static const std::size_t index = F1 * Matrix::static_width + F2;
185 BOOST_STATIC_ASSERT(index < Matrix::static_size);
186 BOOST_STATIC_ASSERT(('0' <= V && V <= '9') || V == 'T' || V == 'F');
187 m_matrix.template set<F1, F2, V>();
189 template <field F1, field F2, char V>
190 inline void set_dispatch(integral_constant<bool, false>)
193 template <field F1, field F2, char D>
194 inline void update_dispatch(integral_constant<bool, true>)
196 static const std::size_t index = F1 * Matrix::static_width + F2;
197 BOOST_STATIC_ASSERT(index < Matrix::static_size);
198 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
199 char const c = m_matrix.template get<F1, F2>();
200 if ( D > c || c > '9')
201 m_matrix.template set<F1, F2, D>();
203 template <field F1, field F2, char D>
204 inline void update_dispatch(integral_constant<bool, false>)
210 // --------------- RUN-TIME MASK ----------------
214 template <std::size_t Height, std::size_t Width = Height>
218 static const std::size_t static_width = Width;
219 static const std::size_t static_height = Height;
220 static const std::size_t static_size = Width * Height;
222 inline mask(const char * s)
225 char * const last = m_array + static_size;
226 for ( ; it != last && *s != '\0' ; ++it, ++s )
234 ::memset(it, '*', last - it);
238 inline mask(const char * s, std::size_t count)
240 if ( count > static_size )
246 std::for_each(s, s + count, check_char);
247 ::memcpy(m_array, s, count);
249 if ( count < static_size )
251 ::memset(m_array + count, '*', static_size - count);
255 template <field F1, field F2>
256 inline char get() const
258 BOOST_STATIC_ASSERT(F1 < Height && F2 < Width);
259 static const std::size_t index = F1 * Width + F2;
260 BOOST_STATIC_ASSERT(index < static_size);
261 return m_array[index];
265 static inline void check_char(char c)
267 bool const is_valid = c == '*' || c == 'T' || c == 'F'
268 || ( c >= '0' && c <= '9' );
271 BOOST_THROW_EXCEPTION(geometry::invalid_input_exception());
275 char m_array[static_size];
280 template <typename Mask, bool InterruptEnabled>
281 struct interrupt_dispatch
283 template <field F1, field F2, char V>
284 static inline bool apply(Mask const&)
290 template <typename Mask>
291 struct interrupt_dispatch<Mask, true>
293 template <field F1, field F2, char V>
294 static inline bool apply(Mask const& mask)
296 char m = mask.template get<F1, F2>();
297 return check_element<V>(m);
301 static inline bool check_element(char m)
303 if ( BOOST_GEOMETRY_CONDITION(V >= '0' && V <= '9') )
305 return m == 'F' || ( m < V && m >= '0' && m <= '9' );
307 else if ( BOOST_GEOMETRY_CONDITION(V == 'T') )
315 template <typename Masks, int I = 0, int N = boost::tuples::length<Masks>::value>
316 struct interrupt_dispatch_tuple
318 template <field F1, field F2, char V>
319 static inline bool apply(Masks const& masks)
321 typedef typename boost::tuples::element<I, Masks>::type mask_type;
322 mask_type const& mask = boost::get<I>(masks);
323 return interrupt_dispatch<mask_type, true>::template apply<F1, F2, V>(mask)
324 && interrupt_dispatch_tuple<Masks, I+1>::template apply<F1, F2, V>(masks);
328 template <typename Masks, int N>
329 struct interrupt_dispatch_tuple<Masks, N, N>
331 template <field F1, field F2, char V>
332 static inline bool apply(Masks const& )
338 //template <typename T0, typename T1, typename T2, typename T3, typename T4,
339 // typename T5, typename T6, typename T7, typename T8, typename T9>
340 //struct interrupt_dispatch<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, true>
342 // typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
344 // template <field F1, field F2, char V>
345 // static inline bool apply(mask_type const& mask)
347 // return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
351 template <typename Head, typename Tail>
352 struct interrupt_dispatch<boost::tuples::cons<Head, Tail>, true>
354 typedef boost::tuples::cons<Head, Tail> mask_type;
356 template <field F1, field F2, char V>
357 static inline bool apply(mask_type const& mask)
359 return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
363 template <field F1, field F2, char V, bool InterruptEnabled, typename Mask>
364 inline bool interrupt(Mask const& mask)
366 return interrupt_dispatch<Mask, InterruptEnabled>
367 ::template apply<F1, F2, V>(mask);
372 template <typename Mask>
373 struct may_update_dispatch
375 template <field F1, field F2, char D, typename Matrix>
376 static inline bool apply(Mask const& mask, Matrix const& matrix)
378 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
380 char const m = mask.template get<F1, F2>();
388 char const c = matrix.template get<F1, F2>();
389 return c == 'F'; // if it's T or between 0 and 9, the result will be the same
391 else if ( m >= '0' && m <= '9' )
393 char const c = matrix.template get<F1, F2>();
394 return D > c || c > '9';
401 template <typename Masks, int I = 0, int N = boost::tuples::length<Masks>::value>
402 struct may_update_dispatch_tuple
404 template <field F1, field F2, char D, typename Matrix>
405 static inline bool apply(Masks const& masks, Matrix const& matrix)
407 typedef typename boost::tuples::element<I, Masks>::type mask_type;
408 mask_type const& mask = boost::get<I>(masks);
409 return may_update_dispatch<mask_type>::template apply<F1, F2, D>(mask, matrix)
410 || may_update_dispatch_tuple<Masks, I+1>::template apply<F1, F2, D>(masks, matrix);
414 template <typename Masks, int N>
415 struct may_update_dispatch_tuple<Masks, N, N>
417 template <field F1, field F2, char D, typename Matrix>
418 static inline bool apply(Masks const& , Matrix const& )
424 //template <typename T0, typename T1, typename T2, typename T3, typename T4,
425 // typename T5, typename T6, typename T7, typename T8, typename T9>
426 //struct may_update_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
428 // typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
430 // template <field F1, field F2, char D, typename Matrix>
431 // static inline bool apply(mask_type const& mask, Matrix const& matrix)
433 // return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
437 template <typename Head, typename Tail>
438 struct may_update_dispatch< boost::tuples::cons<Head, Tail> >
440 typedef boost::tuples::cons<Head, Tail> mask_type;
442 template <field F1, field F2, char D, typename Matrix>
443 static inline bool apply(mask_type const& mask, Matrix const& matrix)
445 return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
449 template <field F1, field F2, char D, typename Mask, typename Matrix>
450 inline bool may_update(Mask const& mask, Matrix const& matrix)
452 return may_update_dispatch<Mask>
453 ::template apply<F1, F2, D>(mask, matrix);
458 template <typename Mask>
459 struct check_dispatch
461 template <typename Matrix>
462 static inline bool apply(Mask const& mask, Matrix const& matrix)
464 return per_one<interior, interior>(mask, matrix)
465 && per_one<interior, boundary>(mask, matrix)
466 && per_one<interior, exterior>(mask, matrix)
467 && per_one<boundary, interior>(mask, matrix)
468 && per_one<boundary, boundary>(mask, matrix)
469 && per_one<boundary, exterior>(mask, matrix)
470 && per_one<exterior, interior>(mask, matrix)
471 && per_one<exterior, boundary>(mask, matrix)
472 && per_one<exterior, exterior>(mask, matrix);
475 template <field F1, field F2, typename Matrix>
476 static inline bool per_one(Mask const& mask, Matrix const& matrix)
478 const char mask_el = mask.template get<F1, F2>();
479 const char el = matrix.template get<F1, F2>();
481 if ( mask_el == 'F' )
485 else if ( mask_el == 'T' )
487 return el == 'T' || ( el >= '0' && el <= '9' );
489 else if ( mask_el >= '0' && mask_el <= '9' )
491 return el == mask_el;
498 template <typename Masks, int I = 0, int N = boost::tuples::length<Masks>::value>
499 struct check_dispatch_tuple
501 template <typename Matrix>
502 static inline bool apply(Masks const& masks, Matrix const& matrix)
504 typedef typename boost::tuples::element<I, Masks>::type mask_type;
505 mask_type const& mask = boost::get<I>(masks);
506 return check_dispatch<mask_type>::apply(mask, matrix)
507 || check_dispatch_tuple<Masks, I+1>::apply(masks, matrix);
511 template <typename Masks, int N>
512 struct check_dispatch_tuple<Masks, N, N>
514 template <typename Matrix>
515 static inline bool apply(Masks const&, Matrix const&)
521 //template <typename T0, typename T1, typename T2, typename T3, typename T4,
522 // typename T5, typename T6, typename T7, typename T8, typename T9>
523 //struct check_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
525 // typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
527 // template <typename Matrix>
528 // static inline bool apply(mask_type const& mask, Matrix const& matrix)
530 // return check_dispatch_tuple<mask_type>::apply(mask, matrix);
534 template <typename Head, typename Tail>
535 struct check_dispatch< boost::tuples::cons<Head, Tail> >
537 typedef boost::tuples::cons<Head, Tail> mask_type;
539 template <typename Matrix>
540 static inline bool apply(mask_type const& mask, Matrix const& matrix)
542 return check_dispatch_tuple<mask_type>::apply(mask, matrix);
546 template <typename Mask, typename Matrix>
547 inline bool check_matrix(Mask const& mask, Matrix const& matrix)
549 return check_dispatch<Mask>::apply(mask, matrix);
554 template <typename MatrixOrMask>
557 static const std::size_t value = MatrixOrMask::static_width;
560 template <typename Tuple,
562 int N = boost::tuples::length<Tuple>::value>
563 struct matrix_width_tuple
565 static const std::size_t
566 current = matrix_width<typename boost::tuples::element<I, Tuple>::type>::value;
567 static const std::size_t
568 next = matrix_width_tuple<Tuple, I+1>::value;
570 static const std::size_t
571 value = current > next ? current : next;
574 template <typename Tuple, int N>
575 struct matrix_width_tuple<Tuple, N, N>
577 static const std::size_t value = 0;
580 template <typename Head, typename Tail>
581 struct matrix_width< boost::tuples::cons<Head, Tail> >
583 static const std::size_t
584 value = matrix_width_tuple< boost::tuples::cons<Head, Tail> >::value;
589 template <typename Mask, bool Interrupt>
591 : private matrix_handler
593 relate::matrix<matrix_width<Mask>::value>
596 typedef matrix_handler
598 relate::matrix<matrix_width<Mask>::value>
602 typedef bool result_type;
606 inline explicit mask_handler(Mask const& m)
611 result_type result() const
614 && check_matrix(m_mask, base_t::matrix());
617 template <field F1, field F2, char D>
618 inline bool may_update() const
620 return detail::relate::may_update<F1, F2, D>(
621 m_mask, base_t::matrix()
625 template <field F1, field F2, char V>
628 if ( relate::interrupt<F1, F2, V, Interrupt>(m_mask) )
634 base_t::template set<F1, F2, V>();
638 template <field F1, field F2, char V>
641 if ( relate::interrupt<F1, F2, V, Interrupt>(m_mask) )
647 base_t::template update<F1, F2, V>();
655 // --------------- COMPILE-TIME MASK ----------------
657 // static_check_characters
661 typename First = typename boost::mpl::begin<Seq>::type,
662 typename Last = typename boost::mpl::end<Seq>::type
664 struct static_check_characters
665 : static_check_characters
668 typename boost::mpl::next<First>::type
671 typedef typename boost::mpl::deref<First>::type type;
672 static const char value = type::value;
673 static const bool is_valid = (value >= '0' && value <= '9')
674 || value == 'T' || value == 'F' || value == '*';
675 BOOST_MPL_ASSERT_MSG((is_valid),
676 INVALID_STATIC_MASK_CHARACTER,
680 template <typename Seq, typename Last>
681 struct static_check_characters<Seq, Last, Last>
690 std::size_t Width = Height
694 static const std::size_t static_width = Width;
695 static const std::size_t static_height = Height;
696 static const std::size_t static_size = Width * Height;
699 std::size_t(boost::mpl::size<Seq>::type::value) == static_size);
701 template <detail::relate::field F1, detail::relate::field F2>
704 BOOST_STATIC_ASSERT(std::size_t(F1) < static_height);
705 BOOST_STATIC_ASSERT(std::size_t(F2) < static_width);
707 static const char value
708 = boost::mpl::at_c<Seq, F1 * static_width + F2>::type::value;
712 // check static_mask characters
713 enum { mask_check = sizeof(static_check_characters<Seq>) };
716 // static_should_handle_element
718 template <typename StaticMask, field F1, field F2, bool IsSequence>
719 struct static_should_handle_element_dispatch
721 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
722 static const bool value = mask_el == 'F'
724 || ( mask_el >= '0' && mask_el <= '9' );
727 template <typename First, typename Last, field F1, field F2>
728 struct static_should_handle_element_sequence
730 typedef typename boost::mpl::deref<First>::type StaticMask;
732 static const bool value
733 = static_should_handle_element_dispatch
737 boost::mpl::is_sequence<StaticMask>::value
739 || static_should_handle_element_sequence
741 typename boost::mpl::next<First>::type,
747 template <typename Last, field F1, field F2>
748 struct static_should_handle_element_sequence<Last, Last, F1, F2>
750 static const bool value = false;
753 template <typename StaticMask, field F1, field F2>
754 struct static_should_handle_element_dispatch<StaticMask, F1, F2, true>
756 static const bool value
757 = static_should_handle_element_sequence
759 typename boost::mpl::begin<StaticMask>::type,
760 typename boost::mpl::end<StaticMask>::type,
765 template <typename StaticMask, field F1, field F2>
766 struct static_should_handle_element
768 static const bool value
769 = static_should_handle_element_dispatch
773 boost::mpl::is_sequence<StaticMask>::value
779 template <typename StaticMask, char V, field F1, field F2, bool InterruptEnabled, bool IsSequence>
780 struct static_interrupt_dispatch
782 static const bool value = false;
785 template <typename StaticMask, char V, field F1, field F2, bool IsSequence>
786 struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, IsSequence>
788 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
790 static const bool value
791 = ( V >= '0' && V <= '9' ) ?
792 ( mask_el == 'F' || ( mask_el < V && mask_el >= '0' && mask_el <= '9' ) ) :
793 ( ( V == 'T' ) ? mask_el == 'F' : false );
796 template <typename First, typename Last, char V, field F1, field F2>
797 struct static_interrupt_sequence
799 typedef typename boost::mpl::deref<First>::type StaticMask;
801 static const bool value
802 = static_interrupt_dispatch
807 boost::mpl::is_sequence<StaticMask>::value
809 && static_interrupt_sequence
811 typename boost::mpl::next<First>::type,
817 template <typename Last, char V, field F1, field F2>
818 struct static_interrupt_sequence<Last, Last, V, F1, F2>
820 static const bool value = true;
823 template <typename StaticMask, char V, field F1, field F2>
824 struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, true>
826 static const bool value
827 = static_interrupt_sequence
829 typename boost::mpl::begin<StaticMask>::type,
830 typename boost::mpl::end<StaticMask>::type,
835 template <typename StaticMask, char V, field F1, field F2, bool EnableInterrupt>
836 struct static_interrupt
838 static const bool value
839 = static_interrupt_dispatch
844 boost::mpl::is_sequence<StaticMask>::value
850 template <typename StaticMask, char D, field F1, field F2, bool IsSequence>
851 struct static_may_update_dispatch
853 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
854 static const int version
857 : mask_el >= '0' && mask_el <= '9' ? 2
860 template <typename Matrix>
861 static inline bool apply(Matrix const& matrix)
863 return apply_dispatch(matrix, integral_constant<int, version>());
867 template <typename Matrix>
868 static inline bool apply_dispatch(Matrix const& , integral_constant<int, 0>)
873 template <typename Matrix>
874 static inline bool apply_dispatch(Matrix const& matrix, integral_constant<int, 1>)
876 char const c = matrix.template get<F1, F2>();
877 return c == 'F'; // if it's T or between 0 and 9, the result will be the same
879 // mask_el >= '0' && mask_el <= '9'
880 template <typename Matrix>
881 static inline bool apply_dispatch(Matrix const& matrix, integral_constant<int, 2>)
883 char const c = matrix.template get<F1, F2>();
884 return D > c || c > '9';
887 template <typename Matrix>
888 static inline bool apply_dispatch(Matrix const&, integral_constant<int, 3>)
894 template <typename First, typename Last, char D, field F1, field F2>
895 struct static_may_update_sequence
897 typedef typename boost::mpl::deref<First>::type StaticMask;
899 template <typename Matrix>
900 static inline bool apply(Matrix const& matrix)
902 return static_may_update_dispatch
906 boost::mpl::is_sequence<StaticMask>::value
908 || static_may_update_sequence
910 typename boost::mpl::next<First>::type,
917 template <typename Last, char D, field F1, field F2>
918 struct static_may_update_sequence<Last, Last, D, F1, F2>
920 template <typename Matrix>
921 static inline bool apply(Matrix const& /*matrix*/)
927 template <typename StaticMask, char D, field F1, field F2>
928 struct static_may_update_dispatch<StaticMask, D, F1, F2, true>
930 template <typename Matrix>
931 static inline bool apply(Matrix const& matrix)
933 return static_may_update_sequence
935 typename boost::mpl::begin<StaticMask>::type,
936 typename boost::mpl::end<StaticMask>::type,
942 template <typename StaticMask, char D, field F1, field F2>
943 struct static_may_update
945 template <typename Matrix>
946 static inline bool apply(Matrix const& matrix)
948 return static_may_update_dispatch
952 boost::mpl::is_sequence<StaticMask>::value
957 // static_check_matrix
959 template <typename StaticMask, bool IsSequence>
960 struct static_check_dispatch
962 template <typename Matrix>
963 static inline bool apply(Matrix const& matrix)
965 return per_one<interior, interior>::apply(matrix)
966 && per_one<interior, boundary>::apply(matrix)
967 && per_one<interior, exterior>::apply(matrix)
968 && per_one<boundary, interior>::apply(matrix)
969 && per_one<boundary, boundary>::apply(matrix)
970 && per_one<boundary, exterior>::apply(matrix)
971 && per_one<exterior, interior>::apply(matrix)
972 && per_one<exterior, boundary>::apply(matrix)
973 && per_one<exterior, exterior>::apply(matrix);
976 template <field F1, field F2>
979 static const char mask_el = StaticMask::template static_get<F1, F2>::value;
980 static const int version
983 : mask_el >= '0' && mask_el <= '9' ? 2
986 template <typename Matrix>
987 static inline bool apply(Matrix const& matrix)
989 const char el = matrix.template get<F1, F2>();
990 return apply_dispatch(el, integral_constant<int, version>());
994 static inline bool apply_dispatch(char el, integral_constant<int, 0>)
999 static inline bool apply_dispatch(char el, integral_constant<int, 1>)
1001 return el == 'T' || ( el >= '0' && el <= '9' );
1003 // mask_el >= '0' && mask_el <= '9'
1004 static inline bool apply_dispatch(char el, integral_constant<int, 2>)
1006 return el == mask_el;
1009 static inline bool apply_dispatch(char /*el*/, integral_constant<int, 3>)
1016 template <typename First, typename Last>
1017 struct static_check_sequence
1019 typedef typename boost::mpl::deref<First>::type StaticMask;
1021 template <typename Matrix>
1022 static inline bool apply(Matrix const& matrix)
1024 return static_check_dispatch
1027 boost::mpl::is_sequence<StaticMask>::value
1029 || static_check_sequence
1031 typename boost::mpl::next<First>::type,
1037 template <typename Last>
1038 struct static_check_sequence<Last, Last>
1040 template <typename Matrix>
1041 static inline bool apply(Matrix const& /*matrix*/)
1047 template <typename StaticMask>
1048 struct static_check_dispatch<StaticMask, true>
1050 template <typename Matrix>
1051 static inline bool apply(Matrix const& matrix)
1053 return static_check_sequence
1055 typename boost::mpl::begin<StaticMask>::type,
1056 typename boost::mpl::end<StaticMask>::type
1061 template <typename StaticMask>
1062 struct static_check_matrix
1064 template <typename Matrix>
1065 static inline bool apply(Matrix const& matrix)
1067 return static_check_dispatch
1070 boost::mpl::is_sequence<StaticMask>::value
1075 // static_mask_handler
1077 template <typename StaticMask, bool Interrupt>
1078 class static_mask_handler
1079 : private matrix_handler< matrix<3> >
1081 typedef matrix_handler< relate::matrix<3> > base_type;
1084 typedef bool result_type;
1088 inline static_mask_handler()
1092 inline explicit static_mask_handler(StaticMask const& /*dummy*/)
1096 result_type result() const
1098 return (!Interrupt || !interrupt)
1099 && static_check_matrix<StaticMask>::apply(base_type::matrix());
1102 template <field F1, field F2, char D>
1103 inline bool may_update() const
1105 return static_may_update<StaticMask, D, F1, F2>::
1106 apply(base_type::matrix());
1109 template <field F1, field F2>
1110 static inline bool expects()
1112 return static_should_handle_element<StaticMask, F1, F2>::value;
1115 template <field F1, field F2, char V>
1118 static const bool interrupt_c = static_interrupt<StaticMask, V, F1, F2, Interrupt>::value;
1119 static const bool should_handle = static_should_handle_element<StaticMask, F1, F2>::value;
1120 static const int version = interrupt_c ? 0
1124 set_dispatch<F1, F2, V>(integral_constant<int, version>());
1127 template <field F1, field F2, char V>
1128 inline void update()
1130 static const bool interrupt_c = static_interrupt<StaticMask, V, F1, F2, Interrupt>::value;
1131 static const bool should_handle = static_should_handle_element<StaticMask, F1, F2>::value;
1132 static const int version = interrupt_c ? 0
1136 update_dispatch<F1, F2, V>(integral_constant<int, version>());
1140 // Interrupt && interrupt
1141 template <field F1, field F2, char V>
1142 inline void set_dispatch(integral_constant<int, 0>)
1146 // else should_handle
1147 template <field F1, field F2, char V>
1148 inline void set_dispatch(integral_constant<int, 1>)
1150 base_type::template set<F1, F2, V>();
1153 template <field F1, field F2, char V>
1154 inline void set_dispatch(integral_constant<int, 2>)
1157 // Interrupt && interrupt
1158 template <field F1, field F2, char V>
1159 inline void update_dispatch(integral_constant<int, 0>)
1163 // else should_handle
1164 template <field F1, field F2, char V>
1165 inline void update_dispatch(integral_constant<int, 1>)
1167 base_type::template update<F1, F2, V>();
1170 template <field F1, field F2, char V>
1171 inline void update_dispatch(integral_constant<int, 2>)
1175 // --------------- UTIL FUNCTIONS ----------------
1179 template <field F1, field F2, char V, typename Result>
1180 inline void set(Result & res)
1182 res.template set<F1, F2, V>();
1185 template <field F1, field F2, char V, bool Transpose>
1188 template <typename Result>
1189 static inline void apply(Result & res)
1191 res.template set<F1, F2, V>();
1195 template <field F1, field F2, char V>
1196 struct set_dispatch<F1, F2, V, true>
1198 template <typename Result>
1199 static inline void apply(Result & res)
1201 res.template set<F2, F1, V>();
1205 template <field F1, field F2, char V, bool Transpose, typename Result>
1206 inline void set(Result & res)
1208 set_dispatch<F1, F2, V, Transpose>::apply(res);
1213 template <field F1, field F2, char D, typename Result>
1214 inline void update(Result & res)
1216 res.template update<F1, F2, D>();
1219 template <field F1, field F2, char D, bool Transpose>
1220 struct update_result_dispatch
1222 template <typename Result>
1223 static inline void apply(Result & res)
1225 update<F1, F2, D>(res);
1229 template <field F1, field F2, char D>
1230 struct update_result_dispatch<F1, F2, D, true>
1232 template <typename Result>
1233 static inline void apply(Result & res)
1235 update<F2, F1, D>(res);
1239 template <field F1, field F2, char D, bool Transpose, typename Result>
1240 inline void update(Result & res)
1242 update_result_dispatch<F1, F2, D, Transpose>::apply(res);
1247 template <field F1, field F2, char D, typename Result>
1248 inline bool may_update(Result const& res)
1250 return res.template may_update<F1, F2, D>();
1253 template <field F1, field F2, char D, bool Transpose>
1254 struct may_update_result_dispatch
1256 template <typename Result>
1257 static inline bool apply(Result const& res)
1259 return may_update<F1, F2, D>(res);
1263 template <field F1, field F2, char D>
1264 struct may_update_result_dispatch<F1, F2, D, true>
1266 template <typename Result>
1267 static inline bool apply(Result const& res)
1269 return may_update<F2, F1, D>(res);
1273 template <field F1, field F2, char D, bool Transpose, typename Result>
1274 inline bool may_update(Result const& res)
1276 return may_update_result_dispatch<F1, F2, D, Transpose>::apply(res);
1281 template <typename Geometry>
1282 struct result_dimension
1284 BOOST_STATIC_ASSERT(geometry::dimension<Geometry>::value >= 0);
1285 static const char value
1286 = ( geometry::dimension<Geometry>::value <= 9 ) ?
1287 ( '0' + geometry::dimension<Geometry>::value ) :
1291 }} // namespace detail::relate
1292 #endif // DOXYGEN_NO_DETAIL
1294 }} // namespace boost::geometry
1296 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP