summaryrefslogtreecommitdiff
path: root/boost/polygon/detail/polygon_90_set_view.hpp
blob: 53beec8da1e00014d1c40d595e6d5e7c2d5b0d74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
/*
  Copyright 2008 Intel Corporation
 
  Use, modification and distribution are subject to the Boost Software License,
  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  http://www.boost.org/LICENSE_1_0.txt).
*/
#ifndef BOOST_POLYGON_POLYGON_90_SET_VIEW_HPP
#define BOOST_POLYGON_POLYGON_90_SET_VIEW_HPP
namespace boost { namespace polygon{
  struct operator_provides_storage {};
  struct operator_requires_copy {};

  template <typename value_type, typename arg_type>
  inline void insert_into_view_arg(value_type& dest, const arg_type& arg, orientation_2d orient);

  template <typename ltype, typename rtype, typename op_type>
  class polygon_90_set_view;

  template <typename ltype, typename rtype, typename op_type>
  struct polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> > {
    typedef typename polygon_90_set_view<ltype, rtype, op_type>::coordinate_type coordinate_type;
    typedef typename polygon_90_set_view<ltype, rtype, op_type>::iterator_type iterator_type;
    typedef typename polygon_90_set_view<ltype, rtype, op_type>::operator_arg_type operator_arg_type;

    static inline iterator_type begin(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set); 
    static inline iterator_type end(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set);

    static inline orientation_2d orient(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set);

    static inline bool clean(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set);

    static inline bool sorted(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set);
  };

    template <typename value_type, typename ltype, typename rtype, typename op_type>
    struct compute_90_set_value {
      static
      void value(value_type& output_, const ltype& lvalue_, const rtype& rvalue_, orientation_2d orient_) {
        value_type linput_(orient_);
        value_type rinput_(orient_);
        orientation_2d orient_l = polygon_90_set_traits<ltype>::orient(lvalue_);
        orientation_2d orient_r = polygon_90_set_traits<rtype>::orient(rvalue_);
        //std::cout << "compute_90_set_value-0 orientations (left, right, out):\t" << orient_l.to_int()
        //        << "," << orient_r.to_int() << "," << orient_.to_int() << std::endl;
        insert_into_view_arg(linput_, lvalue_, orient_l);
        insert_into_view_arg(rinput_, rvalue_, orient_r);
        output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(),
                                     rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>()); 
      }
    };

    template <typename value_type, typename lcoord, typename rcoord, typename op_type>
    struct compute_90_set_value<value_type, polygon_90_set_data<lcoord>, polygon_90_set_data<rcoord>, op_type> {
      static
      void value(value_type& output_, const polygon_90_set_data<lcoord>& lvalue_,
                 const polygon_90_set_data<rcoord>& rvalue_, orientation_2d orient_) {
        orientation_2d orient_l = lvalue_.orient();
        orientation_2d orient_r = rvalue_.orient();
        value_type linput_(orient_);
        value_type rinput_(orient_);
        //std::cout << "compute_90_set_value-1 orientations (left, right, out):\t" << orient_l.to_int()
        //          << "," << orient_r.to_int() << "," << orient_.to_int() << std::endl;
        if((orient_ == orient_l) && (orient_== orient_r)){ // assume that most of the time this condition is met
          lvalue_.sort();
          rvalue_.sort();
          output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(),
                                       rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount<op_type>()); 
        }else if((orient_ != orient_l) && (orient_!= orient_r)){ // both the orientations are not equal to input
          // easier way is to ignore the input orientation and use the input data's orientation, but not done so
          insert_into_view_arg(linput_, lvalue_, orient_l);
          insert_into_view_arg(rinput_, rvalue_, orient_r);
          output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(),
                                       rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>()); 
        }else if(orient_ != orient_l){ // left hand side orientation is different
          insert_into_view_arg(linput_, lvalue_, orient_l);
          rvalue_.sort();
          output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(),
                                       rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount<op_type>()); 
        } else if(orient_ != orient_r){ // right hand side orientation is different
          insert_into_view_arg(rinput_, rvalue_, orient_r);
          lvalue_.sort();
          output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(),
                                       rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>()); 
        }
      }
    };

    template <typename value_type, typename lcoord, typename rtype, typename op_type>
    struct compute_90_set_value<value_type, polygon_90_set_data<lcoord>, rtype, op_type> {
      static
      void value(value_type& output_, const polygon_90_set_data<lcoord>& lvalue_,
                 const rtype& rvalue_, orientation_2d orient_) {
         value_type rinput_(orient_);
         lvalue_.sort();
         orientation_2d orient_r = polygon_90_set_traits<rtype>::orient(rvalue_);
         //std::cout << "compute_90_set_value-2 orientations (right, out):\t" << orient_r.to_int()
         //          << "," << orient_.to_int() << std::endl;
         insert_into_view_arg(rinput_, rvalue_, orient_r);
         output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(),
                                      rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>()); 
      }
    };

    template <typename value_type, typename ltype, typename rcoord, typename op_type>
    struct compute_90_set_value<value_type, ltype, polygon_90_set_data<rcoord>, op_type> {
      static
      void value(value_type& output_, const ltype& lvalue_,
                 const polygon_90_set_data<rcoord>& rvalue_, orientation_2d orient_) {
        value_type linput_(orient_);
        orientation_2d orient_l = polygon_90_set_traits<ltype>::orient(lvalue_);
        insert_into_view_arg(linput_, lvalue_, orient_l);
        rvalue_.sort();
        //std::cout << "compute_90_set_value-3 orientations (left, out):\t" << orient_l.to_int()
        //          << "," << orient_.to_int() << std::endl;

        output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(),
                                     rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount<op_type>()); 
      }
    };

  template <typename ltype, typename rtype, typename op_type>
  class polygon_90_set_view {
  public:
    typedef typename polygon_90_set_traits<ltype>::coordinate_type coordinate_type;
    typedef polygon_90_set_data<coordinate_type> value_type;
    typedef typename value_type::iterator_type iterator_type;
    typedef polygon_90_set_view operator_arg_type;
  private:
    const ltype& lvalue_;
    const rtype& rvalue_;
    orientation_2d orient_;
    op_type op_;
    mutable value_type output_;
    mutable bool evaluated_;
    polygon_90_set_view& operator=(const polygon_90_set_view&);
  public:
    polygon_90_set_view(const ltype& lvalue,
                     const rtype& rvalue,
                     orientation_2d orient,
                     op_type op) :
      lvalue_(lvalue), rvalue_(rvalue), orient_(orient), op_(op), output_(orient), evaluated_(false) {}

    // get iterator to begin vertex data
  private:
    const value_type& value() const {
      if(!evaluated_) {
        evaluated_ = true;
        compute_90_set_value<value_type, ltype, rtype, op_type>::value(output_, lvalue_, rvalue_, orient_);
      }
      return output_;
    }
  public:
    iterator_type begin() const { return value().begin(); }
    iterator_type end() const { return value().end(); }

    orientation_2d orient() const { return orient_; }
    bool dirty() const { return false; } //result of a boolean is clean
    bool sorted() const { return true; } //result of a boolean is sorted

//     template <typename input_iterator_type>
//     void set(input_iterator_type input_begin, input_iterator_type input_end, 
//              orientation_2d orient) const {
//       orient_ = orient;
//       output_.clear();
//       output_.insert(output_.end(), input_begin, input_end);
//       gtlsort(output_.begin(), output_.end());
//     }
    void sort() const {} //is always sorted
  };

  template <typename ltype, typename rtype, typename op_type>
  struct geometry_concept<polygon_90_set_view<ltype, rtype, op_type> > {
    typedef polygon_90_set_concept type;
  };

  template <typename ltype, typename rtype, typename op_type>
  typename polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::iterator_type
  polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
  begin(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) {
    return polygon_set.begin();
  }
  template <typename ltype, typename rtype, typename op_type>
  typename polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::iterator_type
  polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
  end(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) {
    return polygon_set.end();
  }
//   template <typename ltype, typename rtype, typename op_type>
//   template <typename input_iterator_type>
//   void polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
//   set(polygon_90_set_view<ltype, rtype, op_type>& polygon_set, 
//       input_iterator_type input_begin, input_iterator_type input_end,
//       orientation_2d orient) {
//     polygon_set.set(input_begin, input_end, orient);
//   }
  template <typename ltype, typename rtype, typename op_type>
  orientation_2d polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
  orient(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) { 
    return polygon_set.orient(); }
  template <typename ltype, typename rtype, typename op_type>
  bool polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
  clean(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) { 
    return true; }
  template <typename ltype, typename rtype, typename op_type>
  bool polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
  sorted(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) { 
    return true; }

  template <typename value_type, typename arg_type>
  inline void insert_into_view_arg(value_type& dest, const arg_type& arg, orientation_2d orient) {
    typedef typename polygon_90_set_traits<arg_type>::iterator_type literator;
    literator itr1, itr2;
    itr1 = polygon_90_set_traits<arg_type>::begin(arg);
    itr2 = polygon_90_set_traits<arg_type>::end(arg);
    dest.insert(itr1, itr2, orient);
    dest.sort();
  }
  
  template <typename T>
  template <typename ltype, typename rtype, typename op_type>
  inline polygon_90_set_data<T>& polygon_90_set_data<T>::operator=(const polygon_90_set_view<ltype, rtype, op_type>& that) {
    set(that.begin(), that.end(), that.orient());
    dirty_ = false;
    unsorted_ = false;
    return *this;
  }
  
  template <typename T>
  template <typename ltype, typename rtype, typename op_type>
  inline polygon_90_set_data<T>::polygon_90_set_data(const polygon_90_set_view<ltype, rtype, op_type>& that) :
    orient_(that.orient()), data_(that.begin(), that.end()), dirty_(false), unsorted_(false) {}
  
  template <typename geometry_type_1, typename geometry_type_2>
  struct self_assign_operator_lvalue {
    typedef geometry_type_1& type;
  };
    
  template <typename type_1, typename type_2>
  struct by_value_binary_operator {
    typedef type_1 type;
  };
    
    template <typename geometry_type_1, typename geometry_type_2, typename op_type>
    geometry_type_1& self_assignment_boolean_op(geometry_type_1& lvalue_, const geometry_type_2& rvalue_) {
      typedef geometry_type_1 ltype;
      typedef geometry_type_2 rtype;
      typedef typename polygon_90_set_traits<ltype>::coordinate_type coordinate_type;
      typedef polygon_90_set_data<coordinate_type> value_type;
      orientation_2d orient_ = polygon_90_set_traits<ltype>::orient(lvalue_);
      //BM: rvalue_ data set may have its own orientation for scanline
      orientation_2d orient_r = polygon_90_set_traits<rtype>::orient(rvalue_);
      //std::cout << "self-assignment boolean-op (left, right, out):\t" << orient_.to_int()
      //          << "," << orient_r.to_int() << "," << orient_.to_int() << std::endl;
      value_type linput_(orient_);
      // BM: the rinput_ set's (that stores the rvalue_ dataset  polygons) scanline orientation is *forced*
      // to be same as linput
      value_type rinput_(orient_);
      //BM: The output dataset's scanline orient is set as equal to first input dataset's (lvalue_) orientation
      value_type output_(orient_); 
      insert_into_view_arg(linput_, lvalue_, orient_);
      // BM: The last argument orient_r is the user initialized scanline orientation for rvalue_ data set.
      // But since rinput (see above) is initialized to scanline orientation consistent with the lvalue_
      // data set, this insertion operation will change the incoming rvalue_ dataset's scanline orientation
      insert_into_view_arg(rinput_, rvalue_, orient_r);
      // BM: boolean operation and output uses lvalue_ dataset's scanline orientation.
      output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(),
                                   rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>()); 
      polygon_90_set_mutable_traits<geometry_type_1>::set(lvalue_, output_.begin(), output_.end(), orient_);
      return lvalue_;
    }
  
  namespace operators {
  struct y_ps90_b : gtl_yes {};

  template <typename geometry_type_1, typename geometry_type_2>
  typename enable_if< typename gtl_and_3< y_ps90_b,
    typename is_polygon_90_set_type<geometry_type_1>::type,
    typename is_polygon_90_set_type<geometry_type_2>::type>::type,
                       polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryOr> >::type
  operator|(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
    return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryOr> 
      (lvalue, rvalue, 
       polygon_90_set_traits<geometry_type_1>::orient(lvalue),
       boolean_op::BinaryOr());
  }
  
  struct y_ps90_p : gtl_yes {};

  template <typename geometry_type_1, typename geometry_type_2>
  typename enable_if< 
    typename gtl_and_3< y_ps90_p,
      typename gtl_if<typename is_polygon_90_set_type<geometry_type_1>::type>::type,
      typename gtl_if<typename is_polygon_90_set_type<geometry_type_2>::type>::type>::type,
    polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryOr> >::type
  operator+(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
    return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryOr> 
      (lvalue, rvalue, 
       polygon_90_set_traits<geometry_type_1>::orient(lvalue),
       boolean_op::BinaryOr());
  }
  
  struct y_ps90_s : gtl_yes {};

  template <typename geometry_type_1, typename geometry_type_2>
  typename enable_if< typename gtl_and_3< y_ps90_s,
    typename is_polygon_90_set_type<geometry_type_1>::type,
    typename is_polygon_90_set_type<geometry_type_2>::type>::type,
                       polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd> >::type
  operator*(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
    return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd> 
      (lvalue, rvalue, 
       polygon_90_set_traits<geometry_type_1>::orient(lvalue),
       boolean_op::BinaryAnd());
  }
  
  struct y_ps90_a : gtl_yes {};

  template <typename geometry_type_1, typename geometry_type_2>
  typename enable_if< typename gtl_and_3< y_ps90_a,
    typename is_polygon_90_set_type<geometry_type_1>::type,
    typename is_polygon_90_set_type<geometry_type_2>::type>::type,
                       polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd> >::type
  operator&(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
    return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd> 
      (lvalue, rvalue, 
       polygon_90_set_traits<geometry_type_1>::orient(lvalue),
       boolean_op::BinaryAnd());
  }

  struct y_ps90_x : gtl_yes {};

  template <typename geometry_type_1, typename geometry_type_2>
  typename enable_if< typename gtl_and_3< y_ps90_x,
    typename is_polygon_90_set_type<geometry_type_1>::type,
    typename is_polygon_90_set_type<geometry_type_2>::type>::type,
                       polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryXor> >::type
  operator^(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
    return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryXor> 
      (lvalue, rvalue, 
       polygon_90_set_traits<geometry_type_1>::orient(lvalue),
       boolean_op::BinaryXor());
  }
  
  struct y_ps90_m : gtl_yes {};

  template <typename geometry_type_1, typename geometry_type_2>
  typename enable_if< typename gtl_and_3< y_ps90_m,
    typename gtl_if<typename is_polygon_90_set_type<geometry_type_1>::type>::type,
    typename gtl_if<typename is_polygon_90_set_type<geometry_type_2>::type>::type>::type,
                       polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryNot> >::type
  operator-(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
    return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryNot> 
      (lvalue, rvalue, 
       polygon_90_set_traits<geometry_type_1>::orient(lvalue),
       boolean_op::BinaryNot());
  }
  
  struct y_ps90_pe : gtl_yes {};

  template <typename coordinate_type_1, typename geometry_type_2>
  typename enable_if< typename gtl_and< y_ps90_pe, typename is_polygon_90_set_type<geometry_type_2>::type>::type,
                       polygon_90_set_data<coordinate_type_1> >::type &
  operator+=(polygon_90_set_data<coordinate_type_1>& lvalue, const geometry_type_2& rvalue) {
    lvalue.insert(polygon_90_set_traits<geometry_type_2>::begin(rvalue), polygon_90_set_traits<geometry_type_2>::end(rvalue),
                  polygon_90_set_traits<geometry_type_2>::orient(rvalue));
    return lvalue;
  }
  
  struct y_ps90_be : gtl_yes {};
  //
  template <typename coordinate_type_1, typename geometry_type_2>
  typename enable_if< typename gtl_and< y_ps90_be, typename is_polygon_90_set_type<geometry_type_2>::type>::type, 
                       polygon_90_set_data<coordinate_type_1> >::type &
  operator|=(polygon_90_set_data<coordinate_type_1>& lvalue, const geometry_type_2& rvalue) {
    return lvalue += rvalue;
  }

  struct y_ps90_pe2 : gtl_yes {};

  //normal self assignment boolean operations
  template <typename geometry_type_1, typename geometry_type_2>
  typename enable_if< typename gtl_and_3< y_ps90_pe2, typename is_mutable_polygon_90_set_type<geometry_type_1>::type, 
                                         typename is_polygon_90_set_type<geometry_type_2>::type>::type, 
                       geometry_type_1>::type &
  operator+=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
    return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryOr>(lvalue, rvalue);
  }

  struct y_ps90_be2 : gtl_yes {};

  template <typename geometry_type_1, typename geometry_type_2>
  typename enable_if< typename gtl_and_3<y_ps90_be2, typename is_mutable_polygon_90_set_type<geometry_type_1>::type, 
                                         typename is_polygon_90_set_type<geometry_type_2>::type>::type, 
                       geometry_type_1>::type &
  operator|=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
    return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryOr>(lvalue, rvalue);
  }

  struct y_ps90_se : gtl_yes {};

  template <typename geometry_type_1, typename geometry_type_2>
  typename enable_if< typename gtl_and_3<y_ps90_se, typename is_mutable_polygon_90_set_type<geometry_type_1>::type, 
                                         typename is_polygon_90_set_type<geometry_type_2>::type>::type, 
                       geometry_type_1>::type &
  operator*=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
    return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd>(lvalue, rvalue);
  }
 
  struct y_ps90_ae : gtl_yes {};

  template <typename geometry_type_1, typename geometry_type_2>
  typename enable_if< typename gtl_and_3<y_ps90_ae, typename is_mutable_polygon_90_set_type<geometry_type_1>::type, 
                                         typename is_polygon_90_set_type<geometry_type_2>::type>::type, 
                       geometry_type_1>::type &
  operator&=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
    return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd>(lvalue, rvalue);
  }

  struct y_ps90_xe : gtl_yes {};

  template <typename geometry_type_1, typename geometry_type_2>
  typename enable_if< typename gtl_and_3<y_ps90_xe, typename is_mutable_polygon_90_set_type<geometry_type_1>::type, 
                                         typename is_polygon_90_set_type<geometry_type_2>::type>::type, 
                       geometry_type_1>::type &
  operator^=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
    return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryXor>(lvalue, rvalue);
  }

  struct y_ps90_me : gtl_yes {};

  template <typename geometry_type_1, typename geometry_type_2>
  typename enable_if< typename gtl_and_3< y_ps90_me, typename is_mutable_polygon_90_set_type<geometry_type_1>::type, 
                                         typename is_polygon_90_set_type<geometry_type_2>::type>::type, 
                       geometry_type_1>::type &
  operator-=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
    return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryNot>(lvalue, rvalue);
  }

  struct y_ps90_rpe : gtl_yes {};

  template <typename geometry_type_1, typename coordinate_type_1>
  typename enable_if< typename gtl_and_3<y_ps90_rpe,
    typename is_mutable_polygon_90_set_type<geometry_type_1>::type, 
    typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type,
                       geometry_type_1>::type &
  operator+=(geometry_type_1& lvalue, coordinate_type_1 rvalue) {
    return resize(lvalue, rvalue);
  }

  struct y_ps90_rme : gtl_yes {};

  template <typename geometry_type_1, typename coordinate_type_1>
  typename enable_if< typename gtl_and_3<y_ps90_rme,
    typename is_mutable_polygon_90_set_type<geometry_type_1>::type, 
    typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type,
                       geometry_type_1>::type &
  operator-=(geometry_type_1& lvalue, coordinate_type_1 rvalue) {
    return resize(lvalue, -rvalue);
  }

  struct y_ps90_rp : gtl_yes {};

  template <typename geometry_type_1, typename coordinate_type_1>
  typename enable_if< typename gtl_and_3<y_ps90_rp,
    typename gtl_if<typename is_mutable_polygon_90_set_type<geometry_type_1>::type>::type, 
    typename gtl_if<typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type>::type,
  geometry_type_1>::type
  operator+(const geometry_type_1& lvalue, coordinate_type_1 rvalue) {
    geometry_type_1 retval(lvalue);
    retval += rvalue;
    return retval;
  }

  struct y_ps90_rm : gtl_yes {};

  template <typename geometry_type_1, typename coordinate_type_1>
  typename enable_if< typename gtl_and_3<y_ps90_rm,
    typename gtl_if<typename is_mutable_polygon_90_set_type<geometry_type_1>::type>::type, 
    typename gtl_if<typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type>::type,
  geometry_type_1>::type
  operator-(const geometry_type_1& lvalue, coordinate_type_1 rvalue) {
    geometry_type_1 retval(lvalue);
    retval -= rvalue;
    return retval;
  }
  }
}
}
#endif