1 /*
2   Copyright 2008 Intel Corporation
3 
4   Use, modification and distribution are subject to the Boost Software License,
5   Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6   http://www.boost.org/LICENSE_1_0.txt).
7 */
8 #ifndef BOOST_POLYGON_POLYGON_90_SET_VIEW_HPP
9 #define BOOST_POLYGON_POLYGON_90_SET_VIEW_HPP
10 namespace boost { namespace polygon{
11   struct operator_provides_storage {};
12   struct operator_requires_copy {};
13 
14   template <typename value_type, typename arg_type>
15   inline void insert_into_view_arg(value_type& dest, const arg_type& arg, orientation_2d orient);
16 
17   template <typename ltype, typename rtype, typename op_type>
18   class polygon_90_set_view;
19 
20   template <typename ltype, typename rtype, typename op_type>
21   struct polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> > {
22     typedef typename polygon_90_set_view<ltype, rtype, op_type>::coordinate_type coordinate_type;
23     typedef typename polygon_90_set_view<ltype, rtype, op_type>::iterator_type iterator_type;
24     typedef typename polygon_90_set_view<ltype, rtype, op_type>::operator_arg_type operator_arg_type;
25 
26     static inline iterator_type begin(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set);
27     static inline iterator_type end(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set);
28 
29     static inline orientation_2d orient(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set);
30 
31     static inline bool clean(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set);
32 
33     static inline bool sorted(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set);
34   };
35 
36     template <typename value_type, typename ltype, typename rtype, typename op_type>
37     struct compute_90_set_value {
38       static
valueboost::polygon::compute_90_set_value39       void value(value_type& output_, const ltype& lvalue_, const rtype& rvalue_, orientation_2d orient_) {
40         value_type linput_(orient_);
41         value_type rinput_(orient_);
42         orientation_2d orient_l = polygon_90_set_traits<ltype>::orient(lvalue_);
43         orientation_2d orient_r = polygon_90_set_traits<rtype>::orient(rvalue_);
44         //std::cout << "compute_90_set_value-0 orientations (left, right, out):\t" << orient_l.to_int()
45         //        << "," << orient_r.to_int() << "," << orient_.to_int() << std::endl;
46         insert_into_view_arg(linput_, lvalue_, orient_l);
47         insert_into_view_arg(rinput_, rvalue_, orient_r);
48         output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(),
49                                      rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>());
50       }
51     };
52 
53     template <typename value_type, typename lcoord, typename rcoord, typename op_type>
54     struct compute_90_set_value<value_type, polygon_90_set_data<lcoord>, polygon_90_set_data<rcoord>, op_type> {
55       static
valueboost::polygon::compute_90_set_value56       void value(value_type& output_, const polygon_90_set_data<lcoord>& lvalue_,
57                  const polygon_90_set_data<rcoord>& rvalue_, orientation_2d orient_) {
58         orientation_2d orient_l = lvalue_.orient();
59         orientation_2d orient_r = rvalue_.orient();
60         value_type linput_(orient_);
61         value_type rinput_(orient_);
62         //std::cout << "compute_90_set_value-1 orientations (left, right, out):\t" << orient_l.to_int()
63         //          << "," << orient_r.to_int() << "," << orient_.to_int() << std::endl;
64         if((orient_ == orient_l) && (orient_== orient_r)){ // assume that most of the time this condition is met
65           lvalue_.sort();
66           rvalue_.sort();
67           output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(),
68                                        rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount<op_type>());
69         }else if((orient_ != orient_l) && (orient_!= orient_r)){ // both the orientations are not equal to input
70           // easier way is to ignore the input orientation and use the input data's orientation, but not done so
71           insert_into_view_arg(linput_, lvalue_, orient_l);
72           insert_into_view_arg(rinput_, rvalue_, orient_r);
73           output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(),
74                                        rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>());
75         }else if(orient_ != orient_l){ // left hand side orientation is different
76           insert_into_view_arg(linput_, lvalue_, orient_l);
77           rvalue_.sort();
78           output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(),
79                                        rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount<op_type>());
80         } else if(orient_ != orient_r){ // right hand side orientation is different
81           insert_into_view_arg(rinput_, rvalue_, orient_r);
82           lvalue_.sort();
83           output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(),
84                                        rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>());
85         }
86       }
87     };
88 
89     template <typename value_type, typename lcoord, typename rtype, typename op_type>
90     struct compute_90_set_value<value_type, polygon_90_set_data<lcoord>, rtype, op_type> {
91       static
valueboost::polygon::compute_90_set_value92       void value(value_type& output_, const polygon_90_set_data<lcoord>& lvalue_,
93                  const rtype& rvalue_, orientation_2d orient_) {
94          value_type rinput_(orient_);
95          lvalue_.sort();
96          orientation_2d orient_r = polygon_90_set_traits<rtype>::orient(rvalue_);
97          //std::cout << "compute_90_set_value-2 orientations (right, out):\t" << orient_r.to_int()
98          //          << "," << orient_.to_int() << std::endl;
99          insert_into_view_arg(rinput_, rvalue_, orient_r);
100          output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(),
101                                       rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>());
102       }
103     };
104 
105     template <typename value_type, typename ltype, typename rcoord, typename op_type>
106     struct compute_90_set_value<value_type, ltype, polygon_90_set_data<rcoord>, op_type> {
107       static
valueboost::polygon::compute_90_set_value108       void value(value_type& output_, const ltype& lvalue_,
109                  const polygon_90_set_data<rcoord>& rvalue_, orientation_2d orient_) {
110         value_type linput_(orient_);
111         orientation_2d orient_l = polygon_90_set_traits<ltype>::orient(lvalue_);
112         insert_into_view_arg(linput_, lvalue_, orient_l);
113         rvalue_.sort();
114         //std::cout << "compute_90_set_value-3 orientations (left, out):\t" << orient_l.to_int()
115         //          << "," << orient_.to_int() << std::endl;
116 
117         output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(),
118                                      rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount<op_type>());
119       }
120     };
121 
122   template <typename ltype, typename rtype, typename op_type>
123   class polygon_90_set_view {
124   public:
125     typedef typename polygon_90_set_traits<ltype>::coordinate_type coordinate_type;
126     typedef polygon_90_set_data<coordinate_type> value_type;
127     typedef typename value_type::iterator_type iterator_type;
128     typedef polygon_90_set_view operator_arg_type;
129   private:
130     const ltype& lvalue_;
131     const rtype& rvalue_;
132     orientation_2d orient_;
133     op_type op_;
134     mutable value_type output_;
135     mutable bool evaluated_;
136     polygon_90_set_view& operator=(const polygon_90_set_view&);
137   public:
polygon_90_set_view(const ltype & lvalue,const rtype & rvalue,orientation_2d orient,op_type op)138     polygon_90_set_view(const ltype& lvalue,
139                      const rtype& rvalue,
140                      orientation_2d orient,
141                      op_type op) :
142       lvalue_(lvalue), rvalue_(rvalue), orient_(orient), op_(op), output_(orient), evaluated_(false) {}
143 
144     // get iterator to begin vertex data
145   private:
value() const146     const value_type& value() const {
147       if(!evaluated_) {
148         evaluated_ = true;
149         compute_90_set_value<value_type, ltype, rtype, op_type>::value(output_, lvalue_, rvalue_, orient_);
150       }
151       return output_;
152     }
153   public:
begin() const154     iterator_type begin() const { return value().begin(); }
end() const155     iterator_type end() const { return value().end(); }
156 
orient() const157     orientation_2d orient() const { return orient_; }
dirty() const158     bool dirty() const { return false; } //result of a boolean is clean
sorted() const159     bool sorted() const { return true; } //result of a boolean is sorted
160 
161 //     template <typename input_iterator_type>
162 //     void set(input_iterator_type input_begin, input_iterator_type input_end,
163 //              orientation_2d orient) const {
164 //       orient_ = orient;
165 //       output_.clear();
166 //       output_.insert(output_.end(), input_begin, input_end);
167 //       polygon_sort(output_.begin(), output_.end());
168 //     }
sort() const169     void sort() const {} //is always sorted
170   };
171 
172   template <typename ltype, typename rtype, typename op_type>
173   struct geometry_concept<polygon_90_set_view<ltype, rtype, op_type> > {
174     typedef polygon_90_set_concept type;
175   };
176 
177   template <typename ltype, typename rtype, typename op_type>
178   typename polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::iterator_type
179   polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
begin(const polygon_90_set_view<ltype,rtype,op_type> & polygon_set)180   begin(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) {
181     return polygon_set.begin();
182   }
183   template <typename ltype, typename rtype, typename op_type>
184   typename polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::iterator_type
185   polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
end(const polygon_90_set_view<ltype,rtype,op_type> & polygon_set)186   end(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) {
187     return polygon_set.end();
188   }
189 //   template <typename ltype, typename rtype, typename op_type>
190 //   template <typename input_iterator_type>
191 //   void polygon_90_set_traits<polygon_90_set_view<ltype, rtype, op_type> >::
192 //   set(polygon_90_set_view<ltype, rtype, op_type>& polygon_set,
193 //       input_iterator_type input_begin, input_iterator_type input_end,
194 //       orientation_2d orient) {
195 //     polygon_set.set(input_begin, input_end, orient);
196 //   }
197   template <typename ltype, typename rtype, typename op_type>
198   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)199   orient(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) {
200     return polygon_set.orient(); }
201   template <typename ltype, typename rtype, typename op_type>
202   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)203   clean(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) {
204     return true; }
205   template <typename ltype, typename rtype, typename op_type>
206   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)207   sorted(const polygon_90_set_view<ltype, rtype, op_type>& polygon_set) {
208     return true; }
209 
210   template <typename value_type, typename arg_type>
insert_into_view_arg(value_type & dest,const arg_type & arg,orientation_2d orient)211   inline void insert_into_view_arg(value_type& dest, const arg_type& arg, orientation_2d orient) {
212     typedef typename polygon_90_set_traits<arg_type>::iterator_type literator;
213     literator itr1, itr2;
214     itr1 = polygon_90_set_traits<arg_type>::begin(arg);
215     itr2 = polygon_90_set_traits<arg_type>::end(arg);
216     dest.insert(itr1, itr2, orient);
217     dest.sort();
218   }
219 
220   template <typename T>
221   template <typename ltype, typename rtype, typename op_type>
operator =(const polygon_90_set_view<ltype,rtype,op_type> & that)222   inline polygon_90_set_data<T>& polygon_90_set_data<T>::operator=(const polygon_90_set_view<ltype, rtype, op_type>& that) {
223     set(that.begin(), that.end(), that.orient());
224     dirty_ = false;
225     unsorted_ = false;
226     return *this;
227   }
228 
229   template <typename T>
230   template <typename ltype, typename rtype, typename op_type>
polygon_90_set_data(const polygon_90_set_view<ltype,rtype,op_type> & that)231   inline polygon_90_set_data<T>::polygon_90_set_data(const polygon_90_set_view<ltype, rtype, op_type>& that) :
232     orient_(that.orient()), data_(that.begin(), that.end()), dirty_(false), unsorted_(false) {}
233 
234   template <typename geometry_type_1, typename geometry_type_2>
235   struct self_assign_operator_lvalue {
236     typedef geometry_type_1& type;
237   };
238 
239   template <typename type_1, typename type_2>
240   struct by_value_binary_operator {
241     typedef type_1 type;
242   };
243 
244     template <typename geometry_type_1, typename geometry_type_2, typename op_type>
245     geometry_type_1& self_assignment_boolean_op(geometry_type_1& lvalue_, const geometry_type_2& rvalue_) {
246       typedef geometry_type_1 ltype;
247       typedef geometry_type_2 rtype;
248       typedef typename polygon_90_set_traits<ltype>::coordinate_type coordinate_type;
249       typedef polygon_90_set_data<coordinate_type> value_type;
250       orientation_2d orient_ = polygon_90_set_traits<ltype>::orient(lvalue_);
251       //BM: rvalue_ data set may have its own orientation for scanline
252       orientation_2d orient_r = polygon_90_set_traits<rtype>::orient(rvalue_);
253       //std::cout << "self-assignment boolean-op (left, right, out):\t" << orient_.to_int()
254       //          << "," << orient_r.to_int() << "," << orient_.to_int() << std::endl;
255       value_type linput_(orient_);
256       // BM: the rinput_ set's (that stores the rvalue_ dataset  polygons) scanline orientation is *forced*
257       // to be same as linput
258       value_type rinput_(orient_);
259       //BM: The output dataset's scanline orient is set as equal to first input dataset's (lvalue_) orientation
260       value_type output_(orient_);
261       insert_into_view_arg(linput_, lvalue_, orient_);
262       // BM: The last argument orient_r is the user initialized scanline orientation for rvalue_ data set.
263       // But since rinput (see above) is initialized to scanline orientation consistent with the lvalue_
264       // data set, this insertion operation will change the incoming rvalue_ dataset's scanline orientation
265       insert_into_view_arg(rinput_, rvalue_, orient_r);
266       // BM: boolean operation and output uses lvalue_ dataset's scanline orientation.
267       output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(),
268                                    rinput_.begin(), rinput_.end(), boolean_op::BinaryCount<op_type>());
269       polygon_90_set_mutable_traits<geometry_type_1>::set(lvalue_, output_.begin(), output_.end(), orient_);
270       return lvalue_;
271     }
272 
273   namespace operators {
274   struct y_ps90_b : gtl_yes {};
275 
276   template <typename geometry_type_1, typename geometry_type_2>
277   typename enable_if< typename gtl_and_3< y_ps90_b,
278     typename is_polygon_90_set_type<geometry_type_1>::type,
279     typename is_polygon_90_set_type<geometry_type_2>::type>::type,
280                        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)281   operator|(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
282     return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryOr>
283       (lvalue, rvalue,
284        polygon_90_set_traits<geometry_type_1>::orient(lvalue),
285        boolean_op::BinaryOr());
286   }
287 
288   struct y_ps90_p : gtl_yes {};
289 
290   template <typename geometry_type_1, typename geometry_type_2>
291   typename enable_if<
292     typename gtl_and_3< y_ps90_p,
293       typename gtl_if<typename is_polygon_90_set_type<geometry_type_1>::type>::type,
294       typename gtl_if<typename is_polygon_90_set_type<geometry_type_2>::type>::type>::type,
295     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)296   operator+(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
297     return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryOr>
298       (lvalue, rvalue,
299        polygon_90_set_traits<geometry_type_1>::orient(lvalue),
300        boolean_op::BinaryOr());
301   }
302 
303   struct y_ps90_s : gtl_yes {};
304 
305   template <typename geometry_type_1, typename geometry_type_2>
306   typename enable_if< typename gtl_and_3< y_ps90_s,
307     typename is_polygon_90_set_type<geometry_type_1>::type,
308     typename is_polygon_90_set_type<geometry_type_2>::type>::type,
309                        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)310   operator*(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
311     return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd>
312       (lvalue, rvalue,
313        polygon_90_set_traits<geometry_type_1>::orient(lvalue),
314        boolean_op::BinaryAnd());
315   }
316 
317   struct y_ps90_a : gtl_yes {};
318 
319   template <typename geometry_type_1, typename geometry_type_2>
320   typename enable_if< typename gtl_and_3< y_ps90_a,
321     typename is_polygon_90_set_type<geometry_type_1>::type,
322     typename is_polygon_90_set_type<geometry_type_2>::type>::type,
323                        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)324   operator&(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
325     return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd>
326       (lvalue, rvalue,
327        polygon_90_set_traits<geometry_type_1>::orient(lvalue),
328        boolean_op::BinaryAnd());
329   }
330 
331   struct y_ps90_x : gtl_yes {};
332 
333   template <typename geometry_type_1, typename geometry_type_2>
334   typename enable_if< typename gtl_and_3< y_ps90_x,
335     typename is_polygon_90_set_type<geometry_type_1>::type,
336     typename is_polygon_90_set_type<geometry_type_2>::type>::type,
337                        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)338   operator^(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
339     return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryXor>
340       (lvalue, rvalue,
341        polygon_90_set_traits<geometry_type_1>::orient(lvalue),
342        boolean_op::BinaryXor());
343   }
344 
345   struct y_ps90_m : gtl_yes {};
346 
347   template <typename geometry_type_1, typename geometry_type_2>
348   typename enable_if< typename gtl_and_3< y_ps90_m,
349     typename gtl_if<typename is_polygon_90_set_type<geometry_type_1>::type>::type,
350     typename gtl_if<typename is_polygon_90_set_type<geometry_type_2>::type>::type>::type,
351                        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)352   operator-(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
353     return polygon_90_set_view<geometry_type_1, geometry_type_2, boolean_op::BinaryNot>
354       (lvalue, rvalue,
355        polygon_90_set_traits<geometry_type_1>::orient(lvalue),
356        boolean_op::BinaryNot());
357   }
358 
359   struct y_ps90_pe : gtl_yes {};
360 
361   template <typename coordinate_type_1, typename geometry_type_2>
362   typename enable_if< typename gtl_and< y_ps90_pe, typename is_polygon_90_set_type<geometry_type_2>::type>::type,
363                        polygon_90_set_data<coordinate_type_1> >::type &
operator +=(polygon_90_set_data<coordinate_type_1> & lvalue,const geometry_type_2 & rvalue)364   operator+=(polygon_90_set_data<coordinate_type_1>& lvalue, const geometry_type_2& rvalue) {
365     lvalue.insert(polygon_90_set_traits<geometry_type_2>::begin(rvalue), polygon_90_set_traits<geometry_type_2>::end(rvalue),
366                   polygon_90_set_traits<geometry_type_2>::orient(rvalue));
367     return lvalue;
368   }
369 
370   struct y_ps90_be : gtl_yes {};
371   //
372   template <typename coordinate_type_1, typename geometry_type_2>
373   typename enable_if< typename gtl_and< y_ps90_be, typename is_polygon_90_set_type<geometry_type_2>::type>::type,
374                        polygon_90_set_data<coordinate_type_1> >::type &
operator |=(polygon_90_set_data<coordinate_type_1> & lvalue,const geometry_type_2 & rvalue)375   operator|=(polygon_90_set_data<coordinate_type_1>& lvalue, const geometry_type_2& rvalue) {
376     return lvalue += rvalue;
377   }
378 
379   struct y_ps90_pe2 : gtl_yes {};
380 
381   //normal self assignment boolean operations
382   template <typename geometry_type_1, typename geometry_type_2>
383   typename enable_if< typename gtl_and_3< y_ps90_pe2, typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
384                                          typename is_polygon_90_set_type<geometry_type_2>::type>::type,
385                        geometry_type_1>::type &
operator +=(geometry_type_1 & lvalue,const geometry_type_2 & rvalue)386   operator+=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
387     return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryOr>(lvalue, rvalue);
388   }
389 
390   struct y_ps90_be2 : gtl_yes {};
391 
392   template <typename geometry_type_1, typename geometry_type_2>
393   typename enable_if< typename gtl_and_3<y_ps90_be2, typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
394                                          typename is_polygon_90_set_type<geometry_type_2>::type>::type,
395                        geometry_type_1>::type &
operator |=(geometry_type_1 & lvalue,const geometry_type_2 & rvalue)396   operator|=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
397     return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryOr>(lvalue, rvalue);
398   }
399 
400   struct y_ps90_se : gtl_yes {};
401 
402   template <typename geometry_type_1, typename geometry_type_2>
403   typename enable_if< typename gtl_and_3<y_ps90_se, typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
404                                          typename is_polygon_90_set_type<geometry_type_2>::type>::type,
405                        geometry_type_1>::type &
operator *=(geometry_type_1 & lvalue,const geometry_type_2 & rvalue)406   operator*=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
407     return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd>(lvalue, rvalue);
408   }
409 
410   struct y_ps90_ae : gtl_yes {};
411 
412   template <typename geometry_type_1, typename geometry_type_2>
413   typename enable_if< typename gtl_and_3<y_ps90_ae, typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
414                                          typename is_polygon_90_set_type<geometry_type_2>::type>::type,
415                        geometry_type_1>::type &
operator &=(geometry_type_1 & lvalue,const geometry_type_2 & rvalue)416   operator&=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
417     return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryAnd>(lvalue, rvalue);
418   }
419 
420   struct y_ps90_xe : gtl_yes {};
421 
422   template <typename geometry_type_1, typename geometry_type_2>
423   typename enable_if< typename gtl_and_3<y_ps90_xe, typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
424                                          typename is_polygon_90_set_type<geometry_type_2>::type>::type,
425                        geometry_type_1>::type &
operator ^=(geometry_type_1 & lvalue,const geometry_type_2 & rvalue)426   operator^=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
427     return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryXor>(lvalue, rvalue);
428   }
429 
430   struct y_ps90_me : gtl_yes {};
431 
432   template <typename geometry_type_1, typename geometry_type_2>
433   typename enable_if< typename gtl_and_3< y_ps90_me, typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
434                                          typename is_polygon_90_set_type<geometry_type_2>::type>::type,
435                        geometry_type_1>::type &
operator -=(geometry_type_1 & lvalue,const geometry_type_2 & rvalue)436   operator-=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
437     return self_assignment_boolean_op<geometry_type_1, geometry_type_2, boolean_op::BinaryNot>(lvalue, rvalue);
438   }
439 
440   struct y_ps90_rpe : gtl_yes {};
441 
442   template <typename geometry_type_1, typename coordinate_type_1>
443   typename enable_if< typename gtl_and_3<y_ps90_rpe,
444     typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
445     typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type,
446                        geometry_type_1>::type &
operator +=(geometry_type_1 & lvalue,coordinate_type_1 rvalue)447   operator+=(geometry_type_1& lvalue, coordinate_type_1 rvalue) {
448     return resize(lvalue, rvalue);
449   }
450 
451   struct y_ps90_rme : gtl_yes {};
452 
453   template <typename geometry_type_1, typename coordinate_type_1>
454   typename enable_if< typename gtl_and_3<y_ps90_rme,
455     typename is_mutable_polygon_90_set_type<geometry_type_1>::type,
456     typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type,
457                        geometry_type_1>::type &
operator -=(geometry_type_1 & lvalue,coordinate_type_1 rvalue)458   operator-=(geometry_type_1& lvalue, coordinate_type_1 rvalue) {
459     return resize(lvalue, -rvalue);
460   }
461 
462   struct y_ps90_rp : gtl_yes {};
463 
464   template <typename geometry_type_1, typename coordinate_type_1>
465   typename enable_if< typename gtl_and_3<y_ps90_rp,
466     typename gtl_if<typename is_mutable_polygon_90_set_type<geometry_type_1>::type>::type,
467     typename gtl_if<typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type>::type,
468   geometry_type_1>::type
operator +(const geometry_type_1 & lvalue,coordinate_type_1 rvalue)469   operator+(const geometry_type_1& lvalue, coordinate_type_1 rvalue) {
470     geometry_type_1 retval(lvalue);
471     retval += rvalue;
472     return retval;
473   }
474 
475   struct y_ps90_rm : gtl_yes {};
476 
477   template <typename geometry_type_1, typename coordinate_type_1>
478   typename enable_if< typename gtl_and_3<y_ps90_rm,
479     typename gtl_if<typename is_mutable_polygon_90_set_type<geometry_type_1>::type>::type,
480     typename gtl_if<typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type, coordinate_concept>::type>::type>::type,
481   geometry_type_1>::type
operator -(const geometry_type_1 & lvalue,coordinate_type_1 rvalue)482   operator-(const geometry_type_1& lvalue, coordinate_type_1 rvalue) {
483     geometry_type_1 retval(lvalue);
484     retval -= rvalue;
485     return retval;
486   }
487   }
488 }
489 }
490 #endif
491