annotate DEPENDENCIES/generic/include/boost/geometry/algorithms/detail/relate/result.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents f46d142149f5
children
rev   line source
Chris@102 1 // Boost.Geometry (aka GGL, Generic Geometry Library)
Chris@102 2
Chris@102 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
Chris@102 4
Chris@102 5 // This file was modified by Oracle on 2013, 2014, 2015.
Chris@102 6 // Modifications copyright (c) 2013-2015 Oracle and/or its affiliates.
Chris@102 7
Chris@102 8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
Chris@102 9
Chris@102 10 // Use, modification and distribution is subject to the Boost Software License,
Chris@102 11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@102 12 // http://www.boost.org/LICENSE_1_0.txt)
Chris@102 13
Chris@102 14 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
Chris@102 15 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP
Chris@102 16
Chris@102 17 #include <boost/tuple/tuple.hpp>
Chris@102 18
Chris@102 19 #include <boost/mpl/is_sequence.hpp>
Chris@102 20 #include <boost/mpl/begin.hpp>
Chris@102 21 #include <boost/mpl/end.hpp>
Chris@102 22 #include <boost/mpl/next.hpp>
Chris@102 23 #include <boost/mpl/at.hpp>
Chris@102 24 #include <boost/mpl/vector_c.hpp>
Chris@102 25
Chris@102 26 #include <boost/geometry/core/topological_dimension.hpp>
Chris@102 27 #include <boost/geometry/util/condition.hpp>
Chris@102 28
Chris@102 29 // TEMP - move this header to geometry/detail
Chris@102 30 #include <boost/geometry/index/detail/tuples.hpp>
Chris@102 31
Chris@102 32 namespace boost { namespace geometry {
Chris@102 33
Chris@102 34 #ifndef DOXYGEN_NO_DETAIL
Chris@102 35 namespace detail { namespace relate {
Chris@102 36
Chris@102 37 enum field { interior = 0, boundary = 1, exterior = 2 };
Chris@102 38
Chris@102 39 // TODO: IF THE RESULT IS UPDATED WITH THE MAX POSSIBLE VALUE FOR SOME PAIR OF GEOEMTRIES
Chris@102 40 // THE VALUE ALREADY STORED MUSN'T BE CHECKED
Chris@102 41 // update() calls chould be replaced with set() in those cases
Chris@102 42 // but for safety reasons (STATIC_ASSERT) we should check if parameter D is valid and set() doesn't do that
Chris@102 43 // so some additional function could be added, e.g. set_dim()
Chris@102 44
Chris@102 45 // matrix
Chris@102 46
Chris@102 47 // TODO add height?
Chris@102 48
Chris@102 49 template <std::size_t Width>
Chris@102 50 class matrix
Chris@102 51 {
Chris@102 52 BOOST_STATIC_ASSERT(Width == 2 || Width == 3);
Chris@102 53
Chris@102 54 public:
Chris@102 55
Chris@102 56 static const std::size_t size = Width * Width;
Chris@102 57
Chris@102 58 inline matrix()
Chris@102 59 {
Chris@102 60 ::memset(m_array, 'F', size);
Chris@102 61 }
Chris@102 62
Chris@102 63 template <field F1, field F2>
Chris@102 64 inline char get() const
Chris@102 65 {
Chris@102 66 static const bool in_bounds = F1 * Width + F2 < size;
Chris@102 67 return get_dispatch<F1, F2>(integral_constant<bool, in_bounds>());
Chris@102 68 }
Chris@102 69
Chris@102 70 template <field F1, field F2, char V>
Chris@102 71 inline void set()
Chris@102 72 {
Chris@102 73 static const bool in_bounds = F1 * Width + F2 < size;
Chris@102 74 set_dispatch<F1, F2, V>(integral_constant<bool, in_bounds>());
Chris@102 75 }
Chris@102 76
Chris@102 77 template <field F1, field F2, char D>
Chris@102 78 inline void update()
Chris@102 79 {
Chris@102 80 static const bool in_bounds = F1 * Width + F2 < size;
Chris@102 81 update_dispatch<F1, F2, D>(integral_constant<bool, in_bounds>());
Chris@102 82 }
Chris@102 83
Chris@102 84 inline const char * data() const
Chris@102 85 {
Chris@102 86 return m_array;
Chris@102 87 }
Chris@102 88
Chris@102 89 private:
Chris@102 90 template <field F1, field F2>
Chris@102 91 inline char get_dispatch(integral_constant<bool, true>) const
Chris@102 92 {
Chris@102 93 return m_array[F1 * Width + F2];
Chris@102 94 }
Chris@102 95 template <field F1, field F2>
Chris@102 96 inline char get_dispatch(integral_constant<bool, false>) const
Chris@102 97 {
Chris@102 98 return 'F';
Chris@102 99 }
Chris@102 100
Chris@102 101 template <field F1, field F2, char V>
Chris@102 102 inline void set_dispatch(integral_constant<bool, true>)
Chris@102 103 {
Chris@102 104 BOOST_STATIC_ASSERT(('0' <= V && V <= '9') || V == 'T' || V == 'F');
Chris@102 105 m_array[F1 * Width + F2] = V;
Chris@102 106 }
Chris@102 107 template <field F1, field F2, char V>
Chris@102 108 inline void set_dispatch(integral_constant<bool, false>)
Chris@102 109 {}
Chris@102 110
Chris@102 111 template <field F1, field F2, char D>
Chris@102 112 inline void update_dispatch(integral_constant<bool, true>)
Chris@102 113 {
Chris@102 114 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
Chris@102 115 char c = m_array[F1 * Width + F2];
Chris@102 116 if ( D > c || c > '9')
Chris@102 117 m_array[F1 * Width + F2] = D;
Chris@102 118 }
Chris@102 119 template <field F1, field F2, char D>
Chris@102 120 inline void update_dispatch(integral_constant<bool, false>)
Chris@102 121 {}
Chris@102 122
Chris@102 123 char m_array[size];
Chris@102 124 };
Chris@102 125
Chris@102 126 // TODO add EnableDimensions parameter?
Chris@102 127
Chris@102 128 struct matrix9 {};
Chris@102 129 //struct matrix4 {};
Chris@102 130
Chris@102 131 // matrix_width
Chris@102 132
Chris@102 133 template <typename MatrixOrMask>
Chris@102 134 struct matrix_width
Chris@102 135 : not_implemented<MatrixOrMask>
Chris@102 136 {};
Chris@102 137
Chris@102 138 template <>
Chris@102 139 struct matrix_width<matrix9>
Chris@102 140 {
Chris@102 141 static const std::size_t value = 3;
Chris@102 142 };
Chris@102 143
Chris@102 144 // matrix_handler
Chris@102 145
Chris@102 146 template <typename Matrix>
Chris@102 147 class matrix_handler
Chris@102 148 : private matrix<matrix_width<Matrix>::value>
Chris@102 149 {
Chris@102 150 typedef matrix<matrix_width<Matrix>::value> base_t;
Chris@102 151
Chris@102 152 public:
Chris@102 153 typedef std::string result_type;
Chris@102 154
Chris@102 155 static const bool interrupt = false;
Chris@102 156
Chris@102 157 matrix_handler(Matrix const&)
Chris@102 158 {}
Chris@102 159
Chris@102 160 result_type result() const
Chris@102 161 {
Chris@102 162 return std::string(this->data(),
Chris@102 163 this->data() + base_t::size);
Chris@102 164 }
Chris@102 165
Chris@102 166 template <field F1, field F2, char D>
Chris@102 167 inline bool may_update() const
Chris@102 168 {
Chris@102 169 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
Chris@102 170
Chris@102 171 char const c = static_cast<base_t const&>(*this).template get<F1, F2>();
Chris@102 172 return D > c || c > '9';
Chris@102 173 }
Chris@102 174
Chris@102 175 //template <field F1, field F2>
Chris@102 176 //inline char get() const
Chris@102 177 //{
Chris@102 178 // return static_cast<base_t const&>(*this).template get<F1, F2>();
Chris@102 179 //}
Chris@102 180
Chris@102 181 template <field F1, field F2, char V>
Chris@102 182 inline void set()
Chris@102 183 {
Chris@102 184 static_cast<base_t&>(*this).template set<F1, F2, V>();
Chris@102 185 }
Chris@102 186
Chris@102 187 template <field F1, field F2, char D>
Chris@102 188 inline void update()
Chris@102 189 {
Chris@102 190 static_cast<base_t&>(*this).template update<F1, F2, D>();
Chris@102 191 }
Chris@102 192 };
Chris@102 193
Chris@102 194 // RUN-TIME MASKS
Chris@102 195
Chris@102 196 // mask9
Chris@102 197
Chris@102 198 class mask9
Chris@102 199 {
Chris@102 200 public:
Chris@102 201 static const std::size_t width = 3; // TEMP
Chris@102 202
Chris@102 203 inline mask9(std::string const& de9im_mask)
Chris@102 204 {
Chris@102 205 // TODO: throw an exception here?
Chris@102 206 BOOST_ASSERT(de9im_mask.size() == 9);
Chris@102 207 ::memcpy(m_mask, de9im_mask.c_str(), 9);
Chris@102 208 }
Chris@102 209
Chris@102 210 template <field F1, field F2>
Chris@102 211 inline char get() const
Chris@102 212 {
Chris@102 213 return m_mask[F1 * 3 + F2];
Chris@102 214 }
Chris@102 215
Chris@102 216 private:
Chris@102 217 char m_mask[9];
Chris@102 218 };
Chris@102 219
Chris@102 220 // interrupt()
Chris@102 221
Chris@102 222 template <typename Mask, bool InterruptEnabled>
Chris@102 223 struct interrupt_dispatch
Chris@102 224 {
Chris@102 225 template <field F1, field F2, char V>
Chris@102 226 static inline bool apply(Mask const&)
Chris@102 227 {
Chris@102 228 return false;
Chris@102 229 }
Chris@102 230 };
Chris@102 231
Chris@102 232 template <typename Mask>
Chris@102 233 struct interrupt_dispatch<Mask, true>
Chris@102 234 {
Chris@102 235 template <field F1, field F2, char V>
Chris@102 236 static inline bool apply(Mask const& mask)
Chris@102 237 {
Chris@102 238 char m = mask.template get<F1, F2>();
Chris@102 239 return check_element<V>(m);
Chris@102 240 }
Chris@102 241
Chris@102 242 template <char V>
Chris@102 243 static inline bool check_element(char m)
Chris@102 244 {
Chris@102 245 if ( BOOST_GEOMETRY_CONDITION(V >= '0' && V <= '9') )
Chris@102 246 {
Chris@102 247 return m == 'F' || ( m < V && m >= '0' && m <= '9' );
Chris@102 248 }
Chris@102 249 else if ( BOOST_GEOMETRY_CONDITION(V == 'T') )
Chris@102 250 {
Chris@102 251 return m == 'F';
Chris@102 252 }
Chris@102 253 return false;
Chris@102 254 }
Chris@102 255 };
Chris@102 256
Chris@102 257 template <typename Masks, int I = 0, int N = boost::tuples::length<Masks>::value>
Chris@102 258 struct interrupt_dispatch_tuple
Chris@102 259 {
Chris@102 260 template <field F1, field F2, char V>
Chris@102 261 static inline bool apply(Masks const& masks)
Chris@102 262 {
Chris@102 263 typedef typename boost::tuples::element<I, Masks>::type mask_type;
Chris@102 264 mask_type const& mask = boost::get<I>(masks);
Chris@102 265 return interrupt_dispatch<mask_type, true>::template apply<F1, F2, V>(mask)
Chris@102 266 && interrupt_dispatch_tuple<Masks, I+1>::template apply<F1, F2, V>(masks);
Chris@102 267 }
Chris@102 268 };
Chris@102 269
Chris@102 270 template <typename Masks, int N>
Chris@102 271 struct interrupt_dispatch_tuple<Masks, N, N>
Chris@102 272 {
Chris@102 273 template <field F1, field F2, char V>
Chris@102 274 static inline bool apply(Masks const& )
Chris@102 275 {
Chris@102 276 return true;
Chris@102 277 }
Chris@102 278 };
Chris@102 279
Chris@102 280 template <typename T0, typename T1, typename T2, typename T3, typename T4,
Chris@102 281 typename T5, typename T6, typename T7, typename T8, typename T9>
Chris@102 282 struct interrupt_dispatch<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, true>
Chris@102 283 {
Chris@102 284 typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
Chris@102 285
Chris@102 286 template <field F1, field F2, char V>
Chris@102 287 static inline bool apply(mask_type const& mask)
Chris@102 288 {
Chris@102 289 return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
Chris@102 290 }
Chris@102 291 };
Chris@102 292
Chris@102 293 template <typename Head, typename Tail>
Chris@102 294 struct interrupt_dispatch<boost::tuples::cons<Head, Tail>, true>
Chris@102 295 {
Chris@102 296 typedef boost::tuples::cons<Head, Tail> mask_type;
Chris@102 297
Chris@102 298 template <field F1, field F2, char V>
Chris@102 299 static inline bool apply(mask_type const& mask)
Chris@102 300 {
Chris@102 301 return interrupt_dispatch_tuple<mask_type>::template apply<F1, F2, V>(mask);
Chris@102 302 }
Chris@102 303 };
Chris@102 304
Chris@102 305 template <field F1, field F2, char V, bool InterruptEnabled, typename Mask>
Chris@102 306 inline bool interrupt(Mask const& mask)
Chris@102 307 {
Chris@102 308 return interrupt_dispatch<Mask, InterruptEnabled>
Chris@102 309 ::template apply<F1, F2, V>(mask);
Chris@102 310 }
Chris@102 311
Chris@102 312 // may_update()
Chris@102 313
Chris@102 314 template <typename Mask>
Chris@102 315 struct may_update_dispatch
Chris@102 316 {
Chris@102 317 template <field F1, field F2, char D, typename Matrix>
Chris@102 318 static inline bool apply(Mask const& mask, Matrix const& matrix)
Chris@102 319 {
Chris@102 320 BOOST_STATIC_ASSERT('0' <= D && D <= '9');
Chris@102 321
Chris@102 322 char const m = mask.template get<F1, F2>();
Chris@102 323
Chris@102 324 if ( m == 'F' )
Chris@102 325 {
Chris@102 326 return true;
Chris@102 327 }
Chris@102 328 else if ( m == 'T' )
Chris@102 329 {
Chris@102 330 char const c = matrix.template get<F1, F2>();
Chris@102 331 return c == 'F'; // if it's T or between 0 and 9, the result will be the same
Chris@102 332 }
Chris@102 333 else if ( m >= '0' && m <= '9' )
Chris@102 334 {
Chris@102 335 char const c = matrix.template get<F1, F2>();
Chris@102 336 return D > c || c > '9';
Chris@102 337 }
Chris@102 338
Chris@102 339 return false;
Chris@102 340 }
Chris@102 341 };
Chris@102 342
Chris@102 343 template <typename Masks, int I = 0, int N = boost::tuples::length<Masks>::value>
Chris@102 344 struct may_update_dispatch_tuple
Chris@102 345 {
Chris@102 346 template <field F1, field F2, char D, typename Matrix>
Chris@102 347 static inline bool apply(Masks const& masks, Matrix const& matrix)
Chris@102 348 {
Chris@102 349 typedef typename boost::tuples::element<I, Masks>::type mask_type;
Chris@102 350 mask_type const& mask = boost::get<I>(masks);
Chris@102 351 return may_update_dispatch<mask_type>::template apply<F1, F2, D>(mask, matrix)
Chris@102 352 || may_update_dispatch_tuple<Masks, I+1>::template apply<F1, F2, D>(masks, matrix);
Chris@102 353 }
Chris@102 354 };
Chris@102 355
Chris@102 356 template <typename Masks, int N>
Chris@102 357 struct may_update_dispatch_tuple<Masks, N, N>
Chris@102 358 {
Chris@102 359 template <field F1, field F2, char D, typename Matrix>
Chris@102 360 static inline bool apply(Masks const& , Matrix const& )
Chris@102 361 {
Chris@102 362 return false;
Chris@102 363 }
Chris@102 364 };
Chris@102 365
Chris@102 366 template <typename T0, typename T1, typename T2, typename T3, typename T4,
Chris@102 367 typename T5, typename T6, typename T7, typename T8, typename T9>
Chris@102 368 struct may_update_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
Chris@102 369 {
Chris@102 370 typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
Chris@102 371
Chris@102 372 template <field F1, field F2, char D, typename Matrix>
Chris@102 373 static inline bool apply(mask_type const& mask, Matrix const& matrix)
Chris@102 374 {
Chris@102 375 return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
Chris@102 376 }
Chris@102 377 };
Chris@102 378
Chris@102 379 template <typename Head, typename Tail>
Chris@102 380 struct may_update_dispatch< boost::tuples::cons<Head, Tail> >
Chris@102 381 {
Chris@102 382 typedef boost::tuples::cons<Head, Tail> mask_type;
Chris@102 383
Chris@102 384 template <field F1, field F2, char D, typename Matrix>
Chris@102 385 static inline bool apply(mask_type const& mask, Matrix const& matrix)
Chris@102 386 {
Chris@102 387 return may_update_dispatch_tuple<mask_type>::template apply<F1, F2, D>(mask, matrix);
Chris@102 388 }
Chris@102 389 };
Chris@102 390
Chris@102 391 template <field F1, field F2, char D, typename Mask, typename Matrix>
Chris@102 392 inline bool may_update(Mask const& mask, Matrix const& matrix)
Chris@102 393 {
Chris@102 394 return may_update_dispatch<Mask>
Chris@102 395 ::template apply<F1, F2, D>(mask, matrix);
Chris@102 396 }
Chris@102 397
Chris@102 398 // check_matrix()
Chris@102 399
Chris@102 400 template <typename Mask>
Chris@102 401 struct check_dispatch
Chris@102 402 {
Chris@102 403 template <typename Matrix>
Chris@102 404 static inline bool apply(Mask const& mask, Matrix const& matrix)
Chris@102 405 {
Chris@102 406 return per_one<interior, interior>(mask, matrix)
Chris@102 407 && per_one<interior, boundary>(mask, matrix)
Chris@102 408 && per_one<interior, exterior>(mask, matrix)
Chris@102 409 && per_one<boundary, interior>(mask, matrix)
Chris@102 410 && per_one<boundary, boundary>(mask, matrix)
Chris@102 411 && per_one<boundary, exterior>(mask, matrix)
Chris@102 412 && per_one<exterior, interior>(mask, matrix)
Chris@102 413 && per_one<exterior, boundary>(mask, matrix)
Chris@102 414 && per_one<exterior, exterior>(mask, matrix);
Chris@102 415 }
Chris@102 416
Chris@102 417 template <field F1, field F2, typename Matrix>
Chris@102 418 static inline bool per_one(Mask const& mask, Matrix const& matrix)
Chris@102 419 {
Chris@102 420 const char mask_el = mask.template get<F1, F2>();
Chris@102 421 const char el = matrix.template get<F1, F2>();
Chris@102 422
Chris@102 423 if ( mask_el == 'F' )
Chris@102 424 {
Chris@102 425 return el == 'F';
Chris@102 426 }
Chris@102 427 else if ( mask_el == 'T' )
Chris@102 428 {
Chris@102 429 return el == 'T' || ( el >= '0' && el <= '9' );
Chris@102 430 }
Chris@102 431 else if ( mask_el >= '0' && mask_el <= '9' )
Chris@102 432 {
Chris@102 433 return el == mask_el;
Chris@102 434 }
Chris@102 435
Chris@102 436 return true;
Chris@102 437 }
Chris@102 438 };
Chris@102 439
Chris@102 440 template <typename Masks, int I = 0, int N = boost::tuples::length<Masks>::value>
Chris@102 441 struct check_dispatch_tuple
Chris@102 442 {
Chris@102 443 template <typename Matrix>
Chris@102 444 static inline bool apply(Masks const& masks, Matrix const& matrix)
Chris@102 445 {
Chris@102 446 typedef typename boost::tuples::element<I, Masks>::type mask_type;
Chris@102 447 mask_type const& mask = boost::get<I>(masks);
Chris@102 448 return check_dispatch<mask_type>::apply(mask, matrix)
Chris@102 449 || check_dispatch_tuple<Masks, I+1>::apply(masks, matrix);
Chris@102 450 }
Chris@102 451 };
Chris@102 452
Chris@102 453 template <typename Masks, int N>
Chris@102 454 struct check_dispatch_tuple<Masks, N, N>
Chris@102 455 {
Chris@102 456 template <typename Matrix>
Chris@102 457 static inline bool apply(Masks const&, Matrix const&)
Chris@102 458 {
Chris@102 459 return false;
Chris@102 460 }
Chris@102 461 };
Chris@102 462
Chris@102 463 template <typename T0, typename T1, typename T2, typename T3, typename T4,
Chris@102 464 typename T5, typename T6, typename T7, typename T8, typename T9>
Chris@102 465 struct check_dispatch< boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
Chris@102 466 {
Chris@102 467 typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> mask_type;
Chris@102 468
Chris@102 469 template <typename Matrix>
Chris@102 470 static inline bool apply(mask_type const& mask, Matrix const& matrix)
Chris@102 471 {
Chris@102 472 return check_dispatch_tuple<mask_type>::apply(mask, matrix);
Chris@102 473 }
Chris@102 474 };
Chris@102 475
Chris@102 476 template <typename Head, typename Tail>
Chris@102 477 struct check_dispatch< boost::tuples::cons<Head, Tail> >
Chris@102 478 {
Chris@102 479 typedef boost::tuples::cons<Head, Tail> mask_type;
Chris@102 480
Chris@102 481 template <typename Matrix>
Chris@102 482 static inline bool apply(mask_type const& mask, Matrix const& matrix)
Chris@102 483 {
Chris@102 484 return check_dispatch_tuple<mask_type>::apply(mask, matrix);
Chris@102 485 }
Chris@102 486 };
Chris@102 487
Chris@102 488 template <typename Mask, typename Matrix>
Chris@102 489 inline bool check_matrix(Mask const& mask, Matrix const& matrix)
Chris@102 490 {
Chris@102 491 return check_dispatch<Mask>::apply(mask, matrix);
Chris@102 492 }
Chris@102 493
Chris@102 494 // matrix_width
Chris@102 495
Chris@102 496 template <>
Chris@102 497 struct matrix_width<mask9>
Chris@102 498 {
Chris@102 499 static const std::size_t value = 3;
Chris@102 500 };
Chris@102 501
Chris@102 502 template <typename Tuple,
Chris@102 503 int I = 0,
Chris@102 504 int N = boost::tuples::length<Tuple>::value>
Chris@102 505 struct matrix_width_tuple
Chris@102 506 {
Chris@102 507 static const std::size_t
Chris@102 508 current = matrix_width<typename boost::tuples::element<I, Tuple>::type>::value;
Chris@102 509 static const std::size_t
Chris@102 510 next = matrix_width_tuple<Tuple, I+1>::value;
Chris@102 511
Chris@102 512 static const std::size_t
Chris@102 513 value = current > next ? current : next;
Chris@102 514 };
Chris@102 515
Chris@102 516 template <typename Tuple, int N>
Chris@102 517 struct matrix_width_tuple<Tuple, N, N>
Chris@102 518 {
Chris@102 519 static const std::size_t value = 0;
Chris@102 520 };
Chris@102 521
Chris@102 522 template <typename Head, typename Tail>
Chris@102 523 struct matrix_width< boost::tuples::cons<Head, Tail> >
Chris@102 524 {
Chris@102 525 static const std::size_t
Chris@102 526 value = matrix_width_tuple< boost::tuples::cons<Head, Tail> >::value;
Chris@102 527 };
Chris@102 528
Chris@102 529 // matrix_handler
Chris@102 530
Chris@102 531 template <typename Mask, bool Interrupt>
Chris@102 532 class mask_handler
Chris@102 533 : private matrix<matrix_width<Mask>::value>
Chris@102 534 {
Chris@102 535 typedef matrix<matrix_width<Mask>::value> base_t;
Chris@102 536
Chris@102 537 public:
Chris@102 538 typedef bool result_type;
Chris@102 539
Chris@102 540 bool interrupt;
Chris@102 541
Chris@102 542 inline mask_handler(Mask const& m)
Chris@102 543 : interrupt(false)
Chris@102 544 , m_mask(m)
Chris@102 545 {}
Chris@102 546
Chris@102 547 result_type result() const
Chris@102 548 {
Chris@102 549 return !interrupt
Chris@102 550 && check_matrix(m_mask, static_cast<base_t const&>(*this));
Chris@102 551 }
Chris@102 552
Chris@102 553 template <field F1, field F2, char D>
Chris@102 554 inline bool may_update() const
Chris@102 555 {
Chris@102 556 return detail::relate::may_update<F1, F2, D>(
Chris@102 557 m_mask, static_cast<base_t const&>(*this)
Chris@102 558 );
Chris@102 559 }
Chris@102 560
Chris@102 561 //template <field F1, field F2>
Chris@102 562 //inline char get() const
Chris@102 563 //{
Chris@102 564 // return static_cast<base_t const&>(*this).template get<F1, F2>();
Chris@102 565 //}
Chris@102 566
Chris@102 567 template <field F1, field F2, char V>
Chris@102 568 inline void set()
Chris@102 569 {
Chris@102 570 if ( relate::interrupt<F1, F2, V, Interrupt>(m_mask) )
Chris@102 571 {
Chris@102 572 interrupt = true;
Chris@102 573 }
Chris@102 574 else
Chris@102 575 {
Chris@102 576 base_t::template set<F1, F2, V>();
Chris@102 577 }
Chris@102 578 }
Chris@102 579
Chris@102 580 template <field F1, field F2, char V>
Chris@102 581 inline void update()
Chris@102 582 {
Chris@102 583 if ( relate::interrupt<F1, F2, V, Interrupt>(m_mask) )
Chris@102 584 {
Chris@102 585 interrupt = true;
Chris@102 586 }
Chris@102 587 else
Chris@102 588 {
Chris@102 589 base_t::template update<F1, F2, V>();
Chris@102 590 }
Chris@102 591 }
Chris@102 592
Chris@102 593 private:
Chris@102 594 Mask const& m_mask;
Chris@102 595 };
Chris@102 596
Chris@102 597 // STATIC MASKS
Chris@102 598
Chris@102 599 // static_mask
Chris@102 600
Chris@102 601 template <char II, char IB, char IE,
Chris@102 602 char BI, char BB, char BE,
Chris@102 603 char EI, char EB, char EE>
Chris@102 604 class static_mask
Chris@102 605 {
Chris@102 606 typedef boost::mpl::vector_c
Chris@102 607 <
Chris@102 608 char, II, IB, IE, BI, BB, BE, EI, EB, EE
Chris@102 609 > vector_type;
Chris@102 610
Chris@102 611 public:
Chris@102 612 template <field F1, field F2>
Chris@102 613 struct get
Chris@102 614 {
Chris@102 615 BOOST_STATIC_ASSERT(F1 * 3 + F2 < boost::mpl::size<vector_type>::value);
Chris@102 616
Chris@102 617 static const char value
Chris@102 618 = boost::mpl::at_c<vector_type, F1 * 3 + F2>::type::value;
Chris@102 619 };
Chris@102 620 };
Chris@102 621
Chris@102 622 // static_should_handle_element
Chris@102 623
Chris@102 624 template <typename StaticMask, field F1, field F2, bool IsSequence>
Chris@102 625 struct static_should_handle_element_dispatch
Chris@102 626 {
Chris@102 627 static const char mask_el = StaticMask::template get<F1, F2>::value;
Chris@102 628 static const bool value = mask_el == 'F'
Chris@102 629 || mask_el == 'T'
Chris@102 630 || ( mask_el >= '0' && mask_el <= '9' );
Chris@102 631 };
Chris@102 632
Chris@102 633 template <typename First, typename Last, field F1, field F2>
Chris@102 634 struct static_should_handle_element_sequence
Chris@102 635 {
Chris@102 636 typedef typename boost::mpl::deref<First>::type StaticMask;
Chris@102 637
Chris@102 638 static const bool value
Chris@102 639 = static_should_handle_element_dispatch
Chris@102 640 <
Chris@102 641 StaticMask,
Chris@102 642 F1, F2,
Chris@102 643 boost::mpl::is_sequence<StaticMask>::value
Chris@102 644 >::value
Chris@102 645 || static_should_handle_element_sequence
Chris@102 646 <
Chris@102 647 typename boost::mpl::next<First>::type,
Chris@102 648 Last,
Chris@102 649 F1, F2
Chris@102 650 >::value;
Chris@102 651 };
Chris@102 652
Chris@102 653 template <typename Last, field F1, field F2>
Chris@102 654 struct static_should_handle_element_sequence<Last, Last, F1, F2>
Chris@102 655 {
Chris@102 656 static const bool value = false;
Chris@102 657 };
Chris@102 658
Chris@102 659 template <typename StaticMask, field F1, field F2>
Chris@102 660 struct static_should_handle_element_dispatch<StaticMask, F1, F2, true>
Chris@102 661 {
Chris@102 662 static const bool value
Chris@102 663 = static_should_handle_element_sequence
Chris@102 664 <
Chris@102 665 typename boost::mpl::begin<StaticMask>::type,
Chris@102 666 typename boost::mpl::end<StaticMask>::type,
Chris@102 667 F1, F2
Chris@102 668 >::value;
Chris@102 669 };
Chris@102 670
Chris@102 671 template <typename StaticMask, field F1, field F2>
Chris@102 672 struct static_should_handle_element
Chris@102 673 {
Chris@102 674 static const bool value
Chris@102 675 = static_should_handle_element_dispatch
Chris@102 676 <
Chris@102 677 StaticMask,
Chris@102 678 F1, F2,
Chris@102 679 boost::mpl::is_sequence<StaticMask>::value
Chris@102 680 >::value;
Chris@102 681 };
Chris@102 682
Chris@102 683 // static_interrupt
Chris@102 684
Chris@102 685 template <typename StaticMask, char V, field F1, field F2, bool InterruptEnabled, bool IsSequence>
Chris@102 686 struct static_interrupt_dispatch
Chris@102 687 {
Chris@102 688 static const bool value = false;
Chris@102 689 };
Chris@102 690
Chris@102 691 template <typename StaticMask, char V, field F1, field F2, bool IsSequence>
Chris@102 692 struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, IsSequence>
Chris@102 693 {
Chris@102 694 static const char mask_el = StaticMask::template get<F1, F2>::value;
Chris@102 695
Chris@102 696 static const bool value
Chris@102 697 = ( V >= '0' && V <= '9' ) ?
Chris@102 698 ( mask_el == 'F' || ( mask_el < V && mask_el >= '0' && mask_el <= '9' ) ) :
Chris@102 699 ( ( V == 'T' ) ? mask_el == 'F' : false );
Chris@102 700 };
Chris@102 701
Chris@102 702 template <typename First, typename Last, char V, field F1, field F2>
Chris@102 703 struct static_interrupt_sequence
Chris@102 704 {
Chris@102 705 typedef typename boost::mpl::deref<First>::type StaticMask;
Chris@102 706
Chris@102 707 static const bool value
Chris@102 708 = static_interrupt_dispatch
Chris@102 709 <
Chris@102 710 StaticMask,
Chris@102 711 V, F1, F2,
Chris@102 712 true,
Chris@102 713 boost::mpl::is_sequence<StaticMask>::value
Chris@102 714 >::value
Chris@102 715 && static_interrupt_sequence
Chris@102 716 <
Chris@102 717 typename boost::mpl::next<First>::type,
Chris@102 718 Last,
Chris@102 719 V, F1, F2
Chris@102 720 >::value;
Chris@102 721 };
Chris@102 722
Chris@102 723 template <typename Last, char V, field F1, field F2>
Chris@102 724 struct static_interrupt_sequence<Last, Last, V, F1, F2>
Chris@102 725 {
Chris@102 726 static const bool value = true;
Chris@102 727 };
Chris@102 728
Chris@102 729 template <typename StaticMask, char V, field F1, field F2>
Chris@102 730 struct static_interrupt_dispatch<StaticMask, V, F1, F2, true, true>
Chris@102 731 {
Chris@102 732 static const bool value
Chris@102 733 = static_interrupt_sequence
Chris@102 734 <
Chris@102 735 typename boost::mpl::begin<StaticMask>::type,
Chris@102 736 typename boost::mpl::end<StaticMask>::type,
Chris@102 737 V, F1, F2
Chris@102 738 >::value;
Chris@102 739 };
Chris@102 740
Chris@102 741 template <typename StaticMask, char V, field F1, field F2, bool EnableInterrupt>
Chris@102 742 struct static_interrupt
Chris@102 743 {
Chris@102 744 static const bool value
Chris@102 745 = static_interrupt_dispatch
Chris@102 746 <
Chris@102 747 StaticMask,
Chris@102 748 V, F1, F2,
Chris@102 749 EnableInterrupt,
Chris@102 750 boost::mpl::is_sequence<StaticMask>::value
Chris@102 751 >::value;
Chris@102 752 };
Chris@102 753
Chris@102 754 // static_may_update
Chris@102 755
Chris@102 756 template <typename StaticMask, char D, field F1, field F2, bool IsSequence>
Chris@102 757 struct static_may_update_dispatch
Chris@102 758 {
Chris@102 759 static const char mask_el = StaticMask::template get<F1, F2>::value;
Chris@102 760 static const int version
Chris@102 761 = mask_el == 'F' ? 0
Chris@102 762 : mask_el == 'T' ? 1
Chris@102 763 : mask_el >= '0' && mask_el <= '9' ? 2
Chris@102 764 : 3;
Chris@102 765
Chris@102 766 template <typename Matrix>
Chris@102 767 static inline bool apply(Matrix const& matrix)
Chris@102 768 {
Chris@102 769 return apply_dispatch(matrix, integral_constant<int, version>());
Chris@102 770 }
Chris@102 771
Chris@102 772 // mask_el == 'F'
Chris@102 773 template <typename Matrix>
Chris@102 774 static inline bool apply_dispatch(Matrix const& , integral_constant<int, 0>)
Chris@102 775 {
Chris@102 776 return true;
Chris@102 777 }
Chris@102 778 // mask_el == 'T'
Chris@102 779 template <typename Matrix>
Chris@102 780 static inline bool apply_dispatch(Matrix const& matrix, integral_constant<int, 1>)
Chris@102 781 {
Chris@102 782 char const c = matrix.template get<F1, F2>();
Chris@102 783 return c == 'F'; // if it's T or between 0 and 9, the result will be the same
Chris@102 784 }
Chris@102 785 // mask_el >= '0' && mask_el <= '9'
Chris@102 786 template <typename Matrix>
Chris@102 787 static inline bool apply_dispatch(Matrix const& matrix, integral_constant<int, 2>)
Chris@102 788 {
Chris@102 789 char const c = matrix.template get<F1, F2>();
Chris@102 790 return D > c || c > '9';
Chris@102 791 }
Chris@102 792 // else
Chris@102 793 template <typename Matrix>
Chris@102 794 static inline bool apply_dispatch(Matrix const&, integral_constant<int, 3>)
Chris@102 795 {
Chris@102 796 return false;
Chris@102 797 }
Chris@102 798 };
Chris@102 799
Chris@102 800 template <typename First, typename Last, char D, field F1, field F2>
Chris@102 801 struct static_may_update_sequence
Chris@102 802 {
Chris@102 803 typedef typename boost::mpl::deref<First>::type StaticMask;
Chris@102 804
Chris@102 805 template <typename Matrix>
Chris@102 806 static inline bool apply(Matrix const& matrix)
Chris@102 807 {
Chris@102 808 return static_may_update_dispatch
Chris@102 809 <
Chris@102 810 StaticMask,
Chris@102 811 D, F1, F2,
Chris@102 812 boost::mpl::is_sequence<StaticMask>::value
Chris@102 813 >::apply(matrix)
Chris@102 814 || static_may_update_sequence
Chris@102 815 <
Chris@102 816 typename boost::mpl::next<First>::type,
Chris@102 817 Last,
Chris@102 818 D, F1, F2
Chris@102 819 >::apply(matrix);
Chris@102 820 }
Chris@102 821 };
Chris@102 822
Chris@102 823 template <typename Last, char D, field F1, field F2>
Chris@102 824 struct static_may_update_sequence<Last, Last, D, F1, F2>
Chris@102 825 {
Chris@102 826 template <typename Matrix>
Chris@102 827 static inline bool apply(Matrix const& /*matrix*/)
Chris@102 828 {
Chris@102 829 return false;
Chris@102 830 }
Chris@102 831 };
Chris@102 832
Chris@102 833 template <typename StaticMask, char D, field F1, field F2>
Chris@102 834 struct static_may_update_dispatch<StaticMask, D, F1, F2, true>
Chris@102 835 {
Chris@102 836 template <typename Matrix>
Chris@102 837 static inline bool apply(Matrix const& matrix)
Chris@102 838 {
Chris@102 839 return static_may_update_sequence
Chris@102 840 <
Chris@102 841 typename boost::mpl::begin<StaticMask>::type,
Chris@102 842 typename boost::mpl::end<StaticMask>::type,
Chris@102 843 D, F1, F2
Chris@102 844 >::apply(matrix);
Chris@102 845 }
Chris@102 846 };
Chris@102 847
Chris@102 848 template <typename StaticMask, char D, field F1, field F2>
Chris@102 849 struct static_may_update
Chris@102 850 {
Chris@102 851 template <typename Matrix>
Chris@102 852 static inline bool apply(Matrix const& matrix)
Chris@102 853 {
Chris@102 854 return static_may_update_dispatch
Chris@102 855 <
Chris@102 856 StaticMask,
Chris@102 857 D, F1, F2,
Chris@102 858 boost::mpl::is_sequence<StaticMask>::value
Chris@102 859 >::apply(matrix);
Chris@102 860 }
Chris@102 861 };
Chris@102 862
Chris@102 863 // static_check
Chris@102 864
Chris@102 865 template <typename StaticMask, bool IsSequence>
Chris@102 866 struct static_check_dispatch
Chris@102 867 {
Chris@102 868 template <typename Matrix>
Chris@102 869 static inline bool apply(Matrix const& matrix)
Chris@102 870 {
Chris@102 871 return per_one<interior, interior>::apply(matrix)
Chris@102 872 && per_one<interior, boundary>::apply(matrix)
Chris@102 873 && per_one<interior, exterior>::apply(matrix)
Chris@102 874 && per_one<boundary, interior>::apply(matrix)
Chris@102 875 && per_one<boundary, boundary>::apply(matrix)
Chris@102 876 && per_one<boundary, exterior>::apply(matrix)
Chris@102 877 && per_one<exterior, interior>::apply(matrix)
Chris@102 878 && per_one<exterior, boundary>::apply(matrix)
Chris@102 879 && per_one<exterior, exterior>::apply(matrix);
Chris@102 880 }
Chris@102 881
Chris@102 882 template <field F1, field F2>
Chris@102 883 struct per_one
Chris@102 884 {
Chris@102 885 static const char mask_el = StaticMask::template get<F1, F2>::value;
Chris@102 886 static const int version
Chris@102 887 = mask_el == 'F' ? 0
Chris@102 888 : mask_el == 'T' ? 1
Chris@102 889 : mask_el >= '0' && mask_el <= '9' ? 2
Chris@102 890 : 3;
Chris@102 891
Chris@102 892 template <typename Matrix>
Chris@102 893 static inline bool apply(Matrix const& matrix)
Chris@102 894 {
Chris@102 895 const char el = matrix.template get<F1, F2>();
Chris@102 896 return apply_dispatch(el, integral_constant<int, version>());
Chris@102 897 }
Chris@102 898
Chris@102 899 // mask_el == 'F'
Chris@102 900 static inline bool apply_dispatch(char el, integral_constant<int, 0>)
Chris@102 901 {
Chris@102 902 return el == 'F';
Chris@102 903 }
Chris@102 904 // mask_el == 'T'
Chris@102 905 static inline bool apply_dispatch(char el, integral_constant<int, 1>)
Chris@102 906 {
Chris@102 907 return el == 'T' || ( el >= '0' && el <= '9' );
Chris@102 908 }
Chris@102 909 // mask_el >= '0' && mask_el <= '9'
Chris@102 910 static inline bool apply_dispatch(char el, integral_constant<int, 2>)
Chris@102 911 {
Chris@102 912 return el == mask_el;
Chris@102 913 }
Chris@102 914 // else
Chris@102 915 static inline bool apply_dispatch(char /*el*/, integral_constant<int, 3>)
Chris@102 916 {
Chris@102 917 return true;
Chris@102 918 }
Chris@102 919 };
Chris@102 920 };
Chris@102 921
Chris@102 922 template <typename First, typename Last>
Chris@102 923 struct static_check_sequence
Chris@102 924 {
Chris@102 925 typedef typename boost::mpl::deref<First>::type StaticMask;
Chris@102 926
Chris@102 927 template <typename Matrix>
Chris@102 928 static inline bool apply(Matrix const& matrix)
Chris@102 929 {
Chris@102 930 return static_check_dispatch
Chris@102 931 <
Chris@102 932 StaticMask,
Chris@102 933 boost::mpl::is_sequence<StaticMask>::value
Chris@102 934 >::apply(matrix)
Chris@102 935 || static_check_sequence
Chris@102 936 <
Chris@102 937 typename boost::mpl::next<First>::type,
Chris@102 938 Last
Chris@102 939 >::apply(matrix);
Chris@102 940 }
Chris@102 941 };
Chris@102 942
Chris@102 943 template <typename Last>
Chris@102 944 struct static_check_sequence<Last, Last>
Chris@102 945 {
Chris@102 946 template <typename Matrix>
Chris@102 947 static inline bool apply(Matrix const& /*matrix*/)
Chris@102 948 {
Chris@102 949 return false;
Chris@102 950 }
Chris@102 951 };
Chris@102 952
Chris@102 953 template <typename StaticMask>
Chris@102 954 struct static_check_dispatch<StaticMask, true>
Chris@102 955 {
Chris@102 956 template <typename Matrix>
Chris@102 957 static inline bool apply(Matrix const& matrix)
Chris@102 958 {
Chris@102 959 return static_check_sequence
Chris@102 960 <
Chris@102 961 typename boost::mpl::begin<StaticMask>::type,
Chris@102 962 typename boost::mpl::end<StaticMask>::type
Chris@102 963 >::apply(matrix);
Chris@102 964 }
Chris@102 965 };
Chris@102 966
Chris@102 967 template <typename StaticMask>
Chris@102 968 struct static_check_matrix
Chris@102 969 {
Chris@102 970 template <typename Matrix>
Chris@102 971 static inline bool apply(Matrix const& matrix)
Chris@102 972 {
Chris@102 973 return static_check_dispatch
Chris@102 974 <
Chris@102 975 StaticMask,
Chris@102 976 boost::mpl::is_sequence<StaticMask>::value
Chris@102 977 >::apply(matrix);
Chris@102 978 }
Chris@102 979 };
Chris@102 980
Chris@102 981 // static_mask_handler
Chris@102 982
Chris@102 983 template <typename StaticMask, bool Interrupt>
Chris@102 984 class static_mask_handler
Chris@102 985 : private matrix<3>
Chris@102 986 {
Chris@102 987 typedef matrix<3> base_t;
Chris@102 988
Chris@102 989 public:
Chris@102 990 typedef bool result_type;
Chris@102 991
Chris@102 992 bool interrupt;
Chris@102 993
Chris@102 994 inline static_mask_handler(StaticMask const& /*dummy*/)
Chris@102 995 : interrupt(false)
Chris@102 996 {}
Chris@102 997
Chris@102 998 result_type result() const
Chris@102 999 {
Chris@102 1000 return (!Interrupt || !interrupt)
Chris@102 1001 && static_check_matrix<StaticMask>::
Chris@102 1002 apply(static_cast<base_t const&>(*this));
Chris@102 1003 }
Chris@102 1004
Chris@102 1005 template <field F1, field F2, char D>
Chris@102 1006 inline bool may_update() const
Chris@102 1007 {
Chris@102 1008 return static_may_update<StaticMask, D, F1, F2>::
Chris@102 1009 apply(static_cast<base_t const&>(*this));
Chris@102 1010 }
Chris@102 1011
Chris@102 1012 template <field F1, field F2>
Chris@102 1013 static inline bool expects()
Chris@102 1014 {
Chris@102 1015 return static_should_handle_element<StaticMask, F1, F2>::value;
Chris@102 1016 }
Chris@102 1017
Chris@102 1018 //template <field F1, field F2>
Chris@102 1019 //inline char get() const
Chris@102 1020 //{
Chris@102 1021 // return base_t::template get<F1, F2>();
Chris@102 1022 //}
Chris@102 1023
Chris@102 1024 template <field F1, field F2, char V>
Chris@102 1025 inline void set()
Chris@102 1026 {
Chris@102 1027 static const bool interrupt_c = static_interrupt<StaticMask, V, F1, F2, Interrupt>::value;
Chris@102 1028 static const bool should_handle = static_should_handle_element<StaticMask, F1, F2>::value;
Chris@102 1029 static const int version = interrupt_c ? 0
Chris@102 1030 : should_handle ? 1
Chris@102 1031 : 2;
Chris@102 1032
Chris@102 1033 set_dispatch<F1, F2, V>(integral_constant<int, version>());
Chris@102 1034 }
Chris@102 1035
Chris@102 1036 template <field F1, field F2, char V>
Chris@102 1037 inline void update()
Chris@102 1038 {
Chris@102 1039 static const bool interrupt_c = static_interrupt<StaticMask, V, F1, F2, Interrupt>::value;
Chris@102 1040 static const bool should_handle = static_should_handle_element<StaticMask, F1, F2>::value;
Chris@102 1041 static const int version = interrupt_c ? 0
Chris@102 1042 : should_handle ? 1
Chris@102 1043 : 2;
Chris@102 1044
Chris@102 1045 update_dispatch<F1, F2, V>(integral_constant<int, version>());
Chris@102 1046 }
Chris@102 1047
Chris@102 1048 private:
Chris@102 1049 // Interrupt && interrupt
Chris@102 1050 template <field F1, field F2, char V>
Chris@102 1051 inline void set_dispatch(integral_constant<int, 0>)
Chris@102 1052 {
Chris@102 1053 interrupt = true;
Chris@102 1054 }
Chris@102 1055 // else should_handle
Chris@102 1056 template <field F1, field F2, char V>
Chris@102 1057 inline void set_dispatch(integral_constant<int, 1>)
Chris@102 1058 {
Chris@102 1059 base_t::template set<F1, F2, V>();
Chris@102 1060 }
Chris@102 1061 // else
Chris@102 1062 template <field F1, field F2, char V>
Chris@102 1063 inline void set_dispatch(integral_constant<int, 2>)
Chris@102 1064 {}
Chris@102 1065
Chris@102 1066 // Interrupt && interrupt
Chris@102 1067 template <field F1, field F2, char V>
Chris@102 1068 inline void update_dispatch(integral_constant<int, 0>)
Chris@102 1069 {
Chris@102 1070 interrupt = true;
Chris@102 1071 }
Chris@102 1072 // else should_handle
Chris@102 1073 template <field F1, field F2, char V>
Chris@102 1074 inline void update_dispatch(integral_constant<int, 1>)
Chris@102 1075 {
Chris@102 1076 base_t::template update<F1, F2, V>();
Chris@102 1077 }
Chris@102 1078 // else
Chris@102 1079 template <field F1, field F2, char V>
Chris@102 1080 inline void update_dispatch(integral_constant<int, 2>)
Chris@102 1081 {}
Chris@102 1082 };
Chris@102 1083
Chris@102 1084 // OPERATORS
Chris@102 1085
Chris@102 1086 template <typename Mask1, typename Mask2> inline
Chris@102 1087 boost::tuples::cons<
Chris@102 1088 Mask1,
Chris@102 1089 boost::tuples::cons<Mask2, boost::tuples::null_type>
Chris@102 1090 >
Chris@102 1091 operator||(Mask1 const& m1, Mask2 const& m2)
Chris@102 1092 {
Chris@102 1093 namespace bt = boost::tuples;
Chris@102 1094
Chris@102 1095 return
Chris@102 1096 bt::cons< Mask1, bt::cons<Mask2, bt::null_type> >
Chris@102 1097 ( m1, bt::cons<Mask2, bt::null_type>(m2, bt::null_type()) );
Chris@102 1098 }
Chris@102 1099
Chris@102 1100 template <typename Head, typename Tail, typename Mask> inline
Chris@102 1101 typename index::detail::tuples::push_back<
Chris@102 1102 boost::tuples::cons<Head, Tail>, Mask
Chris@102 1103 >::type
Chris@102 1104 operator||(boost::tuples::cons<Head, Tail> const& t, Mask const& m)
Chris@102 1105 {
Chris@102 1106 namespace bt = boost::tuples;
Chris@102 1107
Chris@102 1108 return
Chris@102 1109 index::detail::tuples::push_back<
Chris@102 1110 bt::cons<Head, Tail>, Mask
Chris@102 1111 >::apply(t, m);
Chris@102 1112 }
Chris@102 1113
Chris@102 1114 // PREDEFINED MASKS
Chris@102 1115
Chris@102 1116 // TODO:
Chris@102 1117 // 1. specialize for simplified masks if available
Chris@102 1118 // e.g. for TOUCHES use 1 mask for A/A
Chris@102 1119 // 2. Think about dimensions > 2 e.g. should TOUCHES be true
Chris@102 1120 // if the interior of the Areal overlaps the boundary of the Volumetric
Chris@102 1121 // like it's true for Linear/Areal
Chris@102 1122
Chris@102 1123 // EQUALS
Chris@102 1124 template <typename Geometry1, typename Geometry2>
Chris@102 1125 struct static_mask_equals_type
Chris@102 1126 {
Chris@102 1127 typedef static_mask<'T', '*', 'F', '*', '*', 'F', 'F', 'F', '*'> type; // wikipedia
Chris@102 1128 //typedef static_mask<'T', 'F', 'F', 'F', 'T', 'F', 'F', 'F', 'T'> type; // OGC
Chris@102 1129 };
Chris@102 1130
Chris@102 1131 // DISJOINT
Chris@102 1132 typedef static_mask<'F', 'F', '*', 'F', 'F', '*', '*', '*', '*'> static_mask_disjoint;
Chris@102 1133
Chris@102 1134 // TOUCHES - NOT P/P
Chris@102 1135 template <typename Geometry1,
Chris@102 1136 typename Geometry2,
Chris@102 1137 std::size_t Dim1 = topological_dimension<Geometry1>::value,
Chris@102 1138 std::size_t Dim2 = topological_dimension<Geometry2>::value>
Chris@102 1139 struct static_mask_touches_impl
Chris@102 1140 {
Chris@102 1141 typedef boost::mpl::vector<
Chris@102 1142 static_mask<'F', 'T', '*', '*', '*', '*', '*', '*', '*'>,
Chris@102 1143 static_mask<'F', '*', '*', 'T', '*', '*', '*', '*', '*'>,
Chris@102 1144 static_mask<'F', '*', '*', '*', 'T', '*', '*', '*', '*'>
Chris@102 1145 > type;
Chris@102 1146 };
Chris@102 1147 // According to OGC, doesn't apply to P/P
Chris@102 1148 // Using the above mask the result would be always false
Chris@102 1149 template <typename Geometry1, typename Geometry2>
Chris@102 1150 struct static_mask_touches_impl<Geometry1, Geometry2, 0, 0>
Chris@102 1151 : not_implemented<typename geometry::tag<Geometry1>::type,
Chris@102 1152 typename geometry::tag<Geometry2>::type>
Chris@102 1153 {};
Chris@102 1154
Chris@102 1155 template <typename Geometry1, typename Geometry2>
Chris@102 1156 struct static_mask_touches_type
Chris@102 1157 : static_mask_touches_impl<Geometry1, Geometry2>
Chris@102 1158 {};
Chris@102 1159
Chris@102 1160 // WITHIN
Chris@102 1161 typedef static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'> static_mask_within;
Chris@102 1162
Chris@102 1163 // COVERED_BY (non OGC)
Chris@102 1164 typedef boost::mpl::vector<
Chris@102 1165 static_mask<'T', '*', 'F', '*', '*', 'F', '*', '*', '*'>,
Chris@102 1166 static_mask<'*', 'T', 'F', '*', '*', 'F', '*', '*', '*'>,
Chris@102 1167 static_mask<'*', '*', 'F', 'T', '*', 'F', '*', '*', '*'>,
Chris@102 1168 static_mask<'*', '*', 'F', '*', 'T', 'F', '*', '*', '*'>
Chris@102 1169 > static_mask_covered_by;
Chris@102 1170
Chris@102 1171 // CROSSES
Chris@102 1172 // dim(G1) < dim(G2) - P/L P/A L/A
Chris@102 1173 template <typename Geometry1,
Chris@102 1174 typename Geometry2,
Chris@102 1175 std::size_t Dim1 = topological_dimension<Geometry1>::value,
Chris@102 1176 std::size_t Dim2 = topological_dimension<Geometry2>::value,
Chris@102 1177 bool D1LessD2 = (Dim1 < Dim2)
Chris@102 1178 >
Chris@102 1179 struct static_mask_crosses_impl
Chris@102 1180 {
Chris@102 1181 typedef static_mask<'T', '*', 'T', '*', '*', '*', '*', '*', '*'> type;
Chris@102 1182 };
Chris@102 1183 // TODO: I'm not sure if this one below should be available!
Chris@102 1184 // dim(G1) > dim(G2) - L/P A/P A/L
Chris@102 1185 template <typename Geometry1, typename Geometry2,
Chris@102 1186 std::size_t Dim1, std::size_t Dim2
Chris@102 1187 >
Chris@102 1188 struct static_mask_crosses_impl<Geometry1, Geometry2, Dim1, Dim2, false>
Chris@102 1189 {
Chris@102 1190 typedef static_mask<'T', '*', '*', '*', '*', '*', 'T', '*', '*'> type;
Chris@102 1191 };
Chris@102 1192 // dim(G1) == dim(G2) - P/P A/A
Chris@102 1193 template <typename Geometry1, typename Geometry2,
Chris@102 1194 std::size_t Dim
Chris@102 1195 >
Chris@102 1196 struct static_mask_crosses_impl<Geometry1, Geometry2, Dim, Dim, false>
Chris@102 1197 : not_implemented<typename geometry::tag<Geometry1>::type,
Chris@102 1198 typename geometry::tag<Geometry2>::type>
Chris@102 1199 {};
Chris@102 1200 // dim(G1) == 1 && dim(G2) == 1 - L/L
Chris@102 1201 template <typename Geometry1, typename Geometry2>
Chris@102 1202 struct static_mask_crosses_impl<Geometry1, Geometry2, 1, 1, false>
Chris@102 1203 {
Chris@102 1204 typedef static_mask<'0', '*', '*', '*', '*', '*', '*', '*', '*'> type;
Chris@102 1205 };
Chris@102 1206
Chris@102 1207 template <typename Geometry1, typename Geometry2>
Chris@102 1208 struct static_mask_crosses_type
Chris@102 1209 : static_mask_crosses_impl<Geometry1, Geometry2>
Chris@102 1210 {};
Chris@102 1211
Chris@102 1212 // OVERLAPS
Chris@102 1213
Chris@102 1214 // dim(G1) != dim(G2) - NOT P/P, L/L, A/A
Chris@102 1215 template <typename Geometry1,
Chris@102 1216 typename Geometry2,
Chris@102 1217 std::size_t Dim1 = topological_dimension<Geometry1>::value,
Chris@102 1218 std::size_t Dim2 = topological_dimension<Geometry2>::value
Chris@102 1219 >
Chris@102 1220 struct static_mask_overlaps_impl
Chris@102 1221 : not_implemented<typename geometry::tag<Geometry1>::type,
Chris@102 1222 typename geometry::tag<Geometry2>::type>
Chris@102 1223 {};
Chris@102 1224 // dim(G1) == D && dim(G2) == D - P/P A/A
Chris@102 1225 template <typename Geometry1, typename Geometry2, std::size_t Dim>
Chris@102 1226 struct static_mask_overlaps_impl<Geometry1, Geometry2, Dim, Dim>
Chris@102 1227 {
Chris@102 1228 typedef static_mask<'T', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
Chris@102 1229 };
Chris@102 1230 // dim(G1) == 1 && dim(G2) == 1 - L/L
Chris@102 1231 template <typename Geometry1, typename Geometry2>
Chris@102 1232 struct static_mask_overlaps_impl<Geometry1, Geometry2, 1, 1>
Chris@102 1233 {
Chris@102 1234 typedef static_mask<'1', '*', 'T', '*', '*', '*', 'T', '*', '*'> type;
Chris@102 1235 };
Chris@102 1236
Chris@102 1237 template <typename Geometry1, typename Geometry2>
Chris@102 1238 struct static_mask_overlaps_type
Chris@102 1239 : static_mask_overlaps_impl<Geometry1, Geometry2>
Chris@102 1240 {};
Chris@102 1241
Chris@102 1242 // RESULTS/HANDLERS UTILS
Chris@102 1243
Chris@102 1244 template <field F1, field F2, char V, typename Result>
Chris@102 1245 inline void set(Result & res)
Chris@102 1246 {
Chris@102 1247 res.template set<F1, F2, V>();
Chris@102 1248 }
Chris@102 1249
Chris@102 1250 template <field F1, field F2, char V, bool Transpose>
Chris@102 1251 struct set_dispatch
Chris@102 1252 {
Chris@102 1253 template <typename Result>
Chris@102 1254 static inline void apply(Result & res)
Chris@102 1255 {
Chris@102 1256 res.template set<F1, F2, V>();
Chris@102 1257 }
Chris@102 1258 };
Chris@102 1259
Chris@102 1260 template <field F1, field F2, char V>
Chris@102 1261 struct set_dispatch<F1, F2, V, true>
Chris@102 1262 {
Chris@102 1263 template <typename Result>
Chris@102 1264 static inline void apply(Result & res)
Chris@102 1265 {
Chris@102 1266 res.template set<F2, F1, V>();
Chris@102 1267 }
Chris@102 1268 };
Chris@102 1269
Chris@102 1270 template <field F1, field F2, char V, bool Transpose, typename Result>
Chris@102 1271 inline void set(Result & res)
Chris@102 1272 {
Chris@102 1273 set_dispatch<F1, F2, V, Transpose>::apply(res);
Chris@102 1274 }
Chris@102 1275
Chris@102 1276 template <char V, typename Result>
Chris@102 1277 inline void set(Result & res)
Chris@102 1278 {
Chris@102 1279 res.template set<interior, interior, V>();
Chris@102 1280 res.template set<interior, boundary, V>();
Chris@102 1281 res.template set<interior, exterior, V>();
Chris@102 1282 res.template set<boundary, interior, V>();
Chris@102 1283 res.template set<boundary, boundary, V>();
Chris@102 1284 res.template set<boundary, exterior, V>();
Chris@102 1285 res.template set<exterior, interior, V>();
Chris@102 1286 res.template set<exterior, boundary, V>();
Chris@102 1287 res.template set<exterior, exterior, V>();
Chris@102 1288 }
Chris@102 1289
Chris@102 1290 template <char II, char IB, char IE, char BI, char BB, char BE, char EI, char EB, char EE, typename Result>
Chris@102 1291 inline void set(Result & res)
Chris@102 1292 {
Chris@102 1293 res.template set<interior, interior, II>();
Chris@102 1294 res.template set<interior, boundary, IB>();
Chris@102 1295 res.template set<interior, exterior, IE>();
Chris@102 1296 res.template set<boundary, interior, BI>();
Chris@102 1297 res.template set<boundary, boundary, BB>();
Chris@102 1298 res.template set<boundary, exterior, BE>();
Chris@102 1299 res.template set<exterior, interior, EI>();
Chris@102 1300 res.template set<exterior, boundary, EB>();
Chris@102 1301 res.template set<exterior, exterior, EE>();
Chris@102 1302 }
Chris@102 1303
Chris@102 1304 template <field F1, field F2, char D, typename Result>
Chris@102 1305 inline void update(Result & res)
Chris@102 1306 {
Chris@102 1307 res.template update<F1, F2, D>();
Chris@102 1308 }
Chris@102 1309
Chris@102 1310 template <field F1, field F2, char D, bool Transpose>
Chris@102 1311 struct update_result_dispatch
Chris@102 1312 {
Chris@102 1313 template <typename Result>
Chris@102 1314 static inline void apply(Result & res)
Chris@102 1315 {
Chris@102 1316 update<F1, F2, D>(res);
Chris@102 1317 }
Chris@102 1318 };
Chris@102 1319
Chris@102 1320 template <field F1, field F2, char D>
Chris@102 1321 struct update_result_dispatch<F1, F2, D, true>
Chris@102 1322 {
Chris@102 1323 template <typename Result>
Chris@102 1324 static inline void apply(Result & res)
Chris@102 1325 {
Chris@102 1326 update<F2, F1, D>(res);
Chris@102 1327 }
Chris@102 1328 };
Chris@102 1329
Chris@102 1330 template <field F1, field F2, char D, bool Transpose, typename Result>
Chris@102 1331 inline void update(Result & res)
Chris@102 1332 {
Chris@102 1333 update_result_dispatch<F1, F2, D, Transpose>::apply(res);
Chris@102 1334 }
Chris@102 1335
Chris@102 1336 template <field F1, field F2, char D, typename Result>
Chris@102 1337 inline bool may_update(Result const& res)
Chris@102 1338 {
Chris@102 1339 return res.template may_update<F1, F2, D>();
Chris@102 1340 }
Chris@102 1341
Chris@102 1342 template <field F1, field F2, char D, bool Transpose>
Chris@102 1343 struct may_update_result_dispatch
Chris@102 1344 {
Chris@102 1345 template <typename Result>
Chris@102 1346 static inline bool apply(Result const& res)
Chris@102 1347 {
Chris@102 1348 return may_update<F1, F2, D>(res);
Chris@102 1349 }
Chris@102 1350 };
Chris@102 1351
Chris@102 1352 template <field F1, field F2, char D>
Chris@102 1353 struct may_update_result_dispatch<F1, F2, D, true>
Chris@102 1354 {
Chris@102 1355 template <typename Result>
Chris@102 1356 static inline bool apply(Result const& res)
Chris@102 1357 {
Chris@102 1358 return may_update<F2, F1, D>(res);
Chris@102 1359 }
Chris@102 1360 };
Chris@102 1361
Chris@102 1362 template <field F1, field F2, char D, bool Transpose, typename Result>
Chris@102 1363 inline bool may_update(Result const& res)
Chris@102 1364 {
Chris@102 1365 return may_update_result_dispatch<F1, F2, D, Transpose>::apply(res);
Chris@102 1366 }
Chris@102 1367
Chris@102 1368 template <typename Result, char II, char IB, char IE, char BI, char BB, char BE, char EI, char EB, char EE>
Chris@102 1369 inline Result return_result()
Chris@102 1370 {
Chris@102 1371 Result res;
Chris@102 1372 set<II, IB, IE, BI, BB, BE, EI, EB, EE>(res);
Chris@102 1373 return res;
Chris@102 1374 }
Chris@102 1375
Chris@102 1376 template <typename Geometry>
Chris@102 1377 struct result_dimension
Chris@102 1378 {
Chris@102 1379 BOOST_STATIC_ASSERT(geometry::dimension<Geometry>::value >= 0);
Chris@102 1380 static const char value
Chris@102 1381 = ( geometry::dimension<Geometry>::value <= 9 ) ?
Chris@102 1382 ( '0' + geometry::dimension<Geometry>::value ) :
Chris@102 1383 'T';
Chris@102 1384 };
Chris@102 1385
Chris@102 1386 }} // namespace detail::relate
Chris@102 1387 #endif // DOXYGEN_NO_DETAIL
Chris@102 1388
Chris@102 1389 }} // namespace boost::geometry
Chris@102 1390
Chris@102 1391 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_RESULT_HPP