Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:48:01

0001 /*
0002   Copyright 2008 Intel Corporation
0003 
0004   Use, modification and distribution are subject to the Boost Software License,
0005   Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0006   http://www.boost.org/LICENSE_1_0.txt).
0007 */
0008 #ifndef BOOST_POLYGON_POLYGON_SET_CONCEPT_HPP
0009 #define BOOST_POLYGON_POLYGON_SET_CONCEPT_HPP
0010 #include "polygon_set_data.hpp"
0011 #include "detail/polygon_simplify.hpp"
0012 namespace boost { namespace polygon{
0013 
0014   template <typename T, typename T2>
0015   struct is_either_polygon_set_type {
0016     typedef typename gtl_or<typename is_polygon_set_type<T>::type, typename is_polygon_set_type<T2>::type >::type type;
0017   };
0018 
0019   template <typename T>
0020   struct is_any_polygon_set_type {
0021     typedef typename gtl_or<typename is_polygon_45_or_90_set_type<T>::type, typename is_polygon_set_type<T>::type >::type type;
0022   };
0023 
0024   template <typename polygon_set_type>
0025   typename enable_if< typename is_any_polygon_set_type<polygon_set_type>::type,
0026                        typename polygon_set_traits<polygon_set_type>::iterator_type>::type
0027   begin_polygon_set_data(const polygon_set_type& polygon_set) {
0028     return polygon_set_traits<polygon_set_type>::begin(polygon_set);
0029   }
0030 
0031   template <typename polygon_set_type>
0032   typename enable_if< typename is_any_polygon_set_type<polygon_set_type>::type,
0033                        typename polygon_set_traits<polygon_set_type>::iterator_type>::type
0034   end_polygon_set_data(const polygon_set_type& polygon_set) {
0035     return polygon_set_traits<polygon_set_type>::end(polygon_set);
0036   }
0037 
0038   template <typename polygon_set_type>
0039   typename enable_if< typename is_polygon_set_type<polygon_set_type>::type,
0040                        bool>::type
0041   clean(const polygon_set_type& polygon_set) {
0042     return polygon_set_traits<polygon_set_type>::clean(polygon_set);
0043   }
0044 
0045   //assign
0046   template <typename polygon_set_type_1, typename polygon_set_type_2>
0047   typename enable_if< typename gtl_and<
0048     typename is_mutable_polygon_set_type<polygon_set_type_1>::type,
0049     typename is_any_polygon_set_type<polygon_set_type_2>::type>::type,
0050                        polygon_set_type_1>::type &
0051   assign(polygon_set_type_1& lvalue, const polygon_set_type_2& rvalue) {
0052     if(clean(rvalue))
0053       polygon_set_mutable_traits<polygon_set_type_1>::set(lvalue, begin_polygon_set_data(rvalue), end_polygon_set_data(rvalue));
0054     else {
0055       polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps;
0056       ps.insert(begin_polygon_set_data(rvalue), end_polygon_set_data(rvalue));
0057       ps.clean();
0058       polygon_set_mutable_traits<polygon_set_type_1>::set(lvalue, ps.begin(), ps.end());
0059     }
0060     return lvalue;
0061   }
0062 
0063   //get trapezoids
0064   template <typename output_container_type, typename polygon_set_type>
0065   typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
0066                       void>::type
0067   get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set) {
0068     polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps;
0069     assign(ps, polygon_set);
0070     ps.get_trapezoids(output);
0071   }
0072 
0073   //get trapezoids
0074   template <typename output_container_type, typename polygon_set_type>
0075   typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
0076                       void>::type
0077   get_trapezoids(output_container_type& output, const polygon_set_type& polygon_set,
0078                  orientation_2d orient) {
0079     polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps;
0080     assign(ps, polygon_set);
0081     ps.get_trapezoids(output, orient);
0082   }
0083 
0084   //equivalence
0085   template <typename polygon_set_type_1, typename polygon_set_type_2>
0086   typename enable_if< typename gtl_and_3 <
0087     typename is_any_polygon_set_type<polygon_set_type_1>::type,
0088     typename is_any_polygon_set_type<polygon_set_type_2>::type,
0089     typename is_either_polygon_set_type<polygon_set_type_1, polygon_set_type_2>::type>::type,
0090                        bool>::type
0091   equivalence(const polygon_set_type_1& lvalue,
0092               const polygon_set_type_2& rvalue) {
0093     polygon_set_data<typename polygon_set_traits<polygon_set_type_1>::coordinate_type> ps1;
0094     assign(ps1, lvalue);
0095     polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps2;
0096     assign(ps2, rvalue);
0097     return ps1 == ps2;
0098   }
0099 
0100   //clear
0101   template <typename polygon_set_type>
0102   typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
0103                        void>::type
0104   clear(polygon_set_type& polygon_set) {
0105     polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps;
0106     assign(polygon_set, ps);
0107   }
0108 
0109   //empty
0110   template <typename polygon_set_type>
0111   typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
0112                        bool>::type
0113   empty(const polygon_set_type& polygon_set) {
0114     if(clean(polygon_set)) return begin_polygon_set_data(polygon_set) == end_polygon_set_data(polygon_set);
0115     polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps;
0116     assign(ps, polygon_set);
0117     ps.clean();
0118     return ps.empty();
0119   }
0120 
0121   //extents
0122   template <typename polygon_set_type, typename rectangle_type>
0123   typename enable_if< typename gtl_and<
0124     typename is_mutable_polygon_set_type<polygon_set_type>::type,
0125     typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0126                        bool>::type
0127   extents(rectangle_type& extents_rectangle,
0128           const polygon_set_type& polygon_set) {
0129     clean(polygon_set);
0130     polygon_set_data<typename polygon_set_traits<polygon_set_type>::coordinate_type> ps;
0131     assign(ps, polygon_set);
0132     return ps.extents(extents_rectangle);
0133   }
0134 
0135   //area
0136   template <typename polygon_set_type>
0137   typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
0138                        typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type>::type
0139   area(const polygon_set_type& polygon_set) {
0140     typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit;
0141     typedef polygon_with_holes_data<Unit> p_type;
0142     typedef typename coordinate_traits<Unit>::area_type area_type;
0143     std::vector<p_type> polys;
0144     assign(polys, polygon_set);
0145     area_type retval = (area_type)0;
0146     for(std::size_t i = 0; i < polys.size(); ++i) {
0147       retval += area(polys[i]);
0148     }
0149     return retval;
0150   }
0151 
0152   template <typename polygon_set_type>
0153   typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
0154                       std::size_t>::type
0155   simplify(polygon_set_type& polygon_set, typename coordinate_traits<
0156            typename polygon_set_traits<polygon_set_type>::coordinate_type
0157            >::coordinate_distance threshold) {
0158     typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit;
0159     typedef polygon_with_holes_data<Unit> p_type;
0160     std::vector<p_type> polys;
0161     assign(polys, polygon_set);
0162     std::size_t retval = 0;
0163     for(std::size_t i = 0; i < polys.size(); ++i) {
0164       retval += detail::simplify_detail::simplify(polys[i].self_.coords_,
0165                                                   polys[i].self_.coords_, threshold);
0166       for(typename std::list<polygon_data<Unit> >::iterator itrh =
0167             polys[i].holes_.begin(); itrh != (polys[i].holes_.end()); ++itrh) {
0168         retval += detail::simplify_detail::simplify((*itrh).coords_,
0169                                                     (*itrh).coords_, threshold);
0170       }
0171     }
0172     assign(polygon_set, polys);
0173     return retval;
0174   }
0175 
0176   template <typename polygon_set_type, typename coord_type>
0177   typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
0178                        polygon_set_type>::type &
0179   resize(polygon_set_type& polygon_set, coord_type resizing, bool corner_fill_arcs = false, int num_circle_segments = 0) {
0180     typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit;
0181     clean(polygon_set);
0182     polygon_set_data<Unit> ps;
0183     assign(ps, polygon_set);
0184     ps.resize(resizing, corner_fill_arcs,num_circle_segments);
0185     assign(polygon_set, ps);
0186     return polygon_set;
0187   }
0188 
0189   template <typename polygon_set_type>
0190   typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
0191                        polygon_set_type>::type &
0192   bloat(polygon_set_type& polygon_set,
0193         typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type bloating) {
0194     return resize(polygon_set, bloating);
0195   }
0196 
0197   template <typename polygon_set_type>
0198   typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
0199                        polygon_set_type>::type &
0200   shrink(polygon_set_type& polygon_set,
0201         typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type shrinking) {
0202     return resize(polygon_set, -(typename polygon_set_traits<polygon_set_type>::coordinate_type)shrinking);
0203   }
0204 
0205   //interact
0206   template <typename polygon_set_type_1, typename polygon_set_type_2>
0207   typename enable_if< typename gtl_and_3 <
0208     typename is_any_polygon_set_type<polygon_set_type_1>::type,
0209     typename is_any_polygon_set_type<polygon_set_type_2>::type,
0210     typename is_either_polygon_set_type<polygon_set_type_1, polygon_set_type_2>::type>::type,
0211     polygon_set_type_1>::type&
0212   interact(polygon_set_type_1& polygon_set_1, const polygon_set_type_2& polygon_set_2) {
0213     polygon_set_data<typename polygon_set_traits<polygon_set_type_1>::coordinate_type> ps1;
0214     assign(ps1, polygon_set_1);
0215     polygon_set_data<typename polygon_set_traits<polygon_set_type_2>::coordinate_type> ps2;
0216     assign(ps2, polygon_set_2);
0217     ps1.interact(ps2);
0218     assign(polygon_set_1, ps1);
0219     return polygon_set_1;
0220   }
0221 
0222   template <typename polygon_set_type>
0223   typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
0224                        polygon_set_type>::type &
0225   scale_up(polygon_set_type& polygon_set,
0226            typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) {
0227     typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit;
0228     clean(polygon_set);
0229     polygon_set_data<Unit> ps;
0230     assign(ps, polygon_set);
0231     ps.scale_up(factor);
0232     assign(polygon_set, ps);
0233     return polygon_set;
0234   }
0235 
0236   template <typename polygon_set_type>
0237   typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
0238                        polygon_set_type>::type &
0239   scale_down(polygon_set_type& polygon_set,
0240              typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type factor) {
0241     typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit;
0242     clean(polygon_set);
0243     polygon_set_data<Unit> ps;
0244     assign(ps, polygon_set);
0245     ps.scale_down(factor);
0246     assign(polygon_set, ps);
0247     return polygon_set;
0248   }
0249 
0250   //transform
0251   template <typename polygon_set_type, typename transformation_type>
0252   typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
0253                        polygon_set_type>::type &
0254   transform(polygon_set_type& polygon_set,
0255             const transformation_type& transformation) {
0256     typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit;
0257     clean(polygon_set);
0258     polygon_set_data<Unit> ps;
0259     assign(ps, polygon_set);
0260     ps.transform(transformation);
0261     assign(polygon_set, ps);
0262     return polygon_set;
0263   }
0264 
0265   //keep
0266   template <typename polygon_set_type>
0267   typename enable_if< typename is_mutable_polygon_set_type<polygon_set_type>::type,
0268                        polygon_set_type>::type &
0269   keep(polygon_set_type& polygon_set,
0270        typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type min_area,
0271        typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::area_type max_area,
0272        typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_width,
0273        typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_width,
0274        typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type min_height,
0275        typename coordinate_traits<typename polygon_set_traits<polygon_set_type>::coordinate_type>::unsigned_area_type max_height) {
0276     typedef typename polygon_set_traits<polygon_set_type>::coordinate_type Unit;
0277     typedef typename coordinate_traits<Unit>::unsigned_area_type uat;
0278     std::list<polygon_with_holes_data<Unit> > polys;
0279     assign(polys, polygon_set);
0280     typename std::list<polygon_with_holes_data<Unit> >::iterator itr_nxt;
0281     for(typename std::list<polygon_with_holes_data<Unit> >::iterator itr = polys.begin(); itr != polys.end(); itr = itr_nxt){
0282       itr_nxt = itr;
0283       ++itr_nxt;
0284       rectangle_data<Unit> bbox;
0285       extents(bbox, *itr);
0286       uat pwidth = delta(bbox, HORIZONTAL);
0287       if(pwidth > min_width && pwidth <= max_width){
0288         uat pheight = delta(bbox, VERTICAL);
0289         if(pheight > min_height && pheight <= max_height){
0290           typename coordinate_traits<Unit>::area_type parea = area(*itr);
0291           if(parea <= max_area && parea >= min_area) {
0292             continue;
0293           }
0294         }
0295       }
0296       polys.erase(itr);
0297     }
0298     assign(polygon_set, polys);
0299     return polygon_set;
0300   }
0301 
0302   namespace operators {
0303 
0304   struct yes_ps_ob : gtl_yes {};
0305 
0306   template <typename geometry_type_1, typename geometry_type_2>
0307   typename enable_if< typename gtl_and_4 < yes_ps_ob, typename is_any_polygon_set_type<geometry_type_1>::type,
0308                                             typename is_any_polygon_set_type<geometry_type_2>::type,
0309                                             typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type,
0310                        polygon_set_view<geometry_type_1, geometry_type_2, 0> >::type
0311   operator|(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
0312     return polygon_set_view<geometry_type_1, geometry_type_2, 0>
0313       (lvalue, rvalue);
0314   }
0315 
0316   struct yes_ps_op : gtl_yes {};
0317 
0318   template <typename geometry_type_1, typename geometry_type_2>
0319   typename enable_if< typename gtl_and_4 < yes_ps_op,
0320     typename gtl_if<typename is_any_polygon_set_type<geometry_type_1>::type>::type,
0321     typename gtl_if<typename is_any_polygon_set_type<geometry_type_2>::type>::type,
0322     typename gtl_if<typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type>
0323     ::type, polygon_set_view<geometry_type_1, geometry_type_2, 0> >::type
0324   operator+(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
0325     return polygon_set_view<geometry_type_1, geometry_type_2, 0>
0326       (lvalue, rvalue);
0327   }
0328 
0329   struct yes_ps_os : gtl_yes {};
0330 
0331   template <typename geometry_type_1, typename geometry_type_2>
0332   typename enable_if< typename gtl_and_4 < yes_ps_os,
0333     typename is_any_polygon_set_type<geometry_type_1>::type,
0334     typename is_any_polygon_set_type<geometry_type_2>::type,
0335     typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type,
0336                        polygon_set_view<geometry_type_1, geometry_type_2, 1> >::type
0337   operator*(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
0338     return polygon_set_view<geometry_type_1, geometry_type_2, 1>
0339       (lvalue, rvalue);
0340   }
0341 
0342   struct yes_ps_oa : gtl_yes {};
0343 
0344   template <typename geometry_type_1, typename geometry_type_2>
0345   typename enable_if< typename gtl_and_4 < yes_ps_oa,
0346     typename is_any_polygon_set_type<geometry_type_1>::type,
0347     typename is_any_polygon_set_type<geometry_type_2>::type,
0348     typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type,
0349                        polygon_set_view<geometry_type_1, geometry_type_2, 1> >::type
0350   operator&(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
0351     return polygon_set_view<geometry_type_1, geometry_type_2, 1>
0352       (lvalue, rvalue);
0353   }
0354 
0355   struct yes_ps_ox : gtl_yes {};
0356 
0357   template <typename geometry_type_1, typename geometry_type_2>
0358   typename enable_if< typename gtl_and_4 < yes_ps_ox,
0359     typename is_any_polygon_set_type<geometry_type_1>::type,
0360     typename is_any_polygon_set_type<geometry_type_2>::type,
0361     typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type,
0362                        polygon_set_view<geometry_type_1, geometry_type_2, 2> >::type
0363   operator^(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
0364     return polygon_set_view<geometry_type_1, geometry_type_2, 2>
0365       (lvalue, rvalue);
0366   }
0367 
0368   struct yes_ps_om : gtl_yes {};
0369 
0370   template <typename geometry_type_1, typename geometry_type_2>
0371     typename enable_if< typename gtl_and_4 < yes_ps_om,
0372     typename gtl_if<typename is_any_polygon_set_type<geometry_type_1>::type>::type,
0373     typename gtl_if<typename is_any_polygon_set_type<geometry_type_2>::type>::type,
0374     typename gtl_if<typename is_either_polygon_set_type<geometry_type_1, geometry_type_2>::type>::type>
0375     ::type, polygon_set_view<geometry_type_1, geometry_type_2, 3> >::type
0376   operator-(const geometry_type_1& lvalue, const geometry_type_2& rvalue) {
0377     return polygon_set_view<geometry_type_1, geometry_type_2, 3>
0378       (lvalue, rvalue);
0379   }
0380 
0381   struct yes_ps_ope : gtl_yes {};
0382 
0383   template <typename geometry_type_1, typename geometry_type_2>
0384   typename enable_if< typename gtl_and_4< yes_ps_ope, gtl_yes, typename is_mutable_polygon_set_type<geometry_type_1>::type,
0385                                          typename is_any_polygon_set_type<geometry_type_2>::type>::type,
0386                        geometry_type_1>::type &
0387   operator+=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
0388     return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 0>(lvalue, rvalue);
0389   }
0390 
0391   struct yes_ps_obe : gtl_yes {};
0392 
0393   template <typename geometry_type_1, typename geometry_type_2>
0394   typename enable_if< typename gtl_and_3< yes_ps_obe, typename is_mutable_polygon_set_type<geometry_type_1>::type,
0395                                          typename is_any_polygon_set_type<geometry_type_2>::type>::type,
0396                        geometry_type_1>::type &
0397   operator|=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
0398     return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 0>(lvalue, rvalue);
0399   }
0400 
0401   struct yes_ps_ose : gtl_yes {};
0402 
0403   template <typename geometry_type_1, typename geometry_type_2>
0404   typename enable_if< typename gtl_and_3< yes_ps_ose, typename is_mutable_polygon_set_type<geometry_type_1>::type,
0405                                          typename is_any_polygon_set_type<geometry_type_2>::type>::type,
0406                        geometry_type_1>::type &
0407   operator*=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
0408     return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 1>(lvalue, rvalue);
0409   }
0410 
0411   struct yes_ps_oae : gtl_yes {};
0412 
0413   template <typename geometry_type_1, typename geometry_type_2>
0414   typename enable_if<
0415     typename gtl_and_3< yes_ps_oae, typename is_mutable_polygon_set_type<geometry_type_1>::type,
0416                       typename is_any_polygon_set_type<geometry_type_2>::type>::type,
0417     geometry_type_1>::type &
0418   operator&=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
0419     return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 1>(lvalue, rvalue);
0420   }
0421 
0422   struct yes_ps_oxe : gtl_yes {};
0423 
0424   template <typename geometry_type_1, typename geometry_type_2>
0425   typename enable_if< typename gtl_and_3< yes_ps_oxe, typename is_mutable_polygon_set_type<geometry_type_1>::type,
0426                                          typename is_any_polygon_set_type<geometry_type_2>::type>::type,
0427                        geometry_type_1>::type &
0428   operator^=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
0429     return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 2>(lvalue, rvalue);
0430   }
0431 
0432   struct yes_ps_ome : gtl_yes {};
0433 
0434   template <typename geometry_type_1, typename geometry_type_2>
0435   typename enable_if<
0436     typename gtl_and_3< yes_ps_ome, typename is_mutable_polygon_set_type<geometry_type_1>::type,
0437                       typename is_any_polygon_set_type<geometry_type_2>::type>::type,
0438     geometry_type_1>::type &
0439   operator-=(geometry_type_1& lvalue, const geometry_type_2& rvalue) {
0440     return self_assignment_boolean_op<geometry_type_1, geometry_type_2, 3>(lvalue, rvalue);
0441   }
0442 
0443   // TODO: Dafna, test these four resizing operators
0444   struct y_ps_rpe : gtl_yes {};
0445 
0446   template <typename geometry_type_1, typename coordinate_type_1>
0447   typename enable_if< typename gtl_and_3< y_ps_rpe, typename is_mutable_polygon_set_type<geometry_type_1>::type,
0448                                          typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type,
0449                                                                 coordinate_concept>::type>::type,
0450                        geometry_type_1>::type &
0451   operator+=(geometry_type_1& lvalue, coordinate_type_1 rvalue) {
0452     return resize(lvalue, rvalue);
0453   }
0454 
0455   struct y_ps_rme : gtl_yes {};
0456 
0457   template <typename geometry_type_1, typename coordinate_type_1>
0458   typename enable_if< typename gtl_and_3<y_ps_rme, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type,
0459                                          typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type,
0460                                                                 coordinate_concept>::type>::type,
0461                        geometry_type_1>::type &
0462   operator-=(geometry_type_1& lvalue, coordinate_type_1 rvalue) {
0463     return resize(lvalue, -rvalue);
0464   }
0465 
0466   struct y_ps_rp : gtl_yes {};
0467 
0468   template <typename geometry_type_1, typename coordinate_type_1>
0469   typename enable_if< typename gtl_and_3<y_ps_rp, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type,
0470                                         typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type,
0471                                                                coordinate_concept>::type>
0472   ::type, geometry_type_1>::type
0473   operator+(const geometry_type_1& lvalue, coordinate_type_1 rvalue) {
0474     geometry_type_1 retval(lvalue);
0475     retval += rvalue;
0476     return retval;
0477   }
0478 
0479   struct y_ps_rm : gtl_yes {};
0480 
0481   template <typename geometry_type_1, typename coordinate_type_1>
0482   typename enable_if< typename gtl_and_3<y_ps_rm, typename gtl_if<typename is_mutable_polygon_set_type<geometry_type_1>::type>::type,
0483                                         typename gtl_same_type<typename geometry_concept<coordinate_type_1>::type,
0484                                                                coordinate_concept>::type>
0485   ::type, geometry_type_1>::type
0486   operator-(const geometry_type_1& lvalue, coordinate_type_1 rvalue) {
0487     geometry_type_1 retval(lvalue);
0488     retval -= rvalue;
0489     return retval;
0490   }
0491 
0492 
0493   } //end operators namespace
0494 
0495   template <typename T>
0496   struct view_of<polygon_45_set_concept, T> {
0497     typedef typename get_coordinate_type<T, typename geometry_concept<T>::type >::type coordinate_type;
0498     T* tp;
0499     std::vector<polygon_45_with_holes_data<coordinate_type> > polys;
0500     view_of(const T& obj) : tp(), polys() {
0501       std::vector<polygon_with_holes_data<coordinate_type> > gpolys;
0502       assign(gpolys, obj);
0503       for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin();
0504           itr != gpolys.end(); ++itr) {
0505         polys.push_back(polygon_45_with_holes_data<coordinate_type>());
0506         assign(polys.back(), view_as<polygon_45_with_holes_concept>(*itr));
0507       }
0508     }
0509     view_of(T& obj) : tp(&obj), polys() {
0510       std::vector<polygon_with_holes_data<coordinate_type> > gpolys;
0511       assign(gpolys, obj);
0512       for(typename std::vector<polygon_with_holes_data<coordinate_type> >::iterator itr = gpolys.begin();
0513           itr != gpolys.end(); ++itr) {
0514         polys.push_back(polygon_45_with_holes_data<coordinate_type>());
0515         assign(polys.back(), view_as<polygon_45_with_holes_concept>(*itr));
0516       }
0517     }
0518 
0519     typedef typename std::vector<polygon_45_with_holes_data<coordinate_type> >::const_iterator iterator_type;
0520     typedef view_of operator_arg_type;
0521 
0522     inline iterator_type begin() const {
0523       return polys.begin();
0524     }
0525 
0526     inline iterator_type end() const {
0527       return polys.end();
0528     }
0529 
0530     inline orientation_2d orient() const { return HORIZONTAL; }
0531 
0532     inline bool clean() const { return false; }
0533 
0534     inline bool sorted() const { return false; }
0535 
0536     inline T& get() { return *tp; }
0537   };
0538 
0539   template <typename T>
0540   struct polygon_45_set_traits<view_of<polygon_45_set_concept, T> > {
0541     typedef typename view_of<polygon_45_set_concept, T>::coordinate_type coordinate_type;
0542     typedef typename view_of<polygon_45_set_concept, T>::iterator_type iterator_type;
0543     typedef view_of<polygon_45_set_concept, T> operator_arg_type;
0544 
0545     static inline iterator_type begin(const view_of<polygon_45_set_concept, T>& polygon_set) {
0546       return polygon_set.begin();
0547     }
0548 
0549     static inline iterator_type end(const view_of<polygon_45_set_concept, T>& polygon_set) {
0550       return polygon_set.end();
0551     }
0552 
0553     static inline orientation_2d orient(const view_of<polygon_45_set_concept, T>& polygon_set) {
0554       return polygon_set.orient(); }
0555 
0556     static inline bool clean(const view_of<polygon_45_set_concept, T>& polygon_set) {
0557       return polygon_set.clean(); }
0558 
0559     static inline bool sorted(const view_of<polygon_45_set_concept, T>& polygon_set) {
0560       return polygon_set.sorted(); }
0561 
0562   };
0563 
0564   template <typename T>
0565   struct geometry_concept<view_of<polygon_45_set_concept, T> > {
0566     typedef polygon_45_set_concept type;
0567   };
0568 
0569   template <typename T>
0570   struct get_coordinate_type<view_of<polygon_45_set_concept, T>, polygon_45_set_concept> {
0571     typedef typename view_of<polygon_45_set_concept, T>::coordinate_type type;
0572   };
0573   template <typename T>
0574   struct get_iterator_type_2<view_of<polygon_45_set_concept, T>, polygon_45_set_concept> {
0575     typedef typename view_of<polygon_45_set_concept, T>::iterator_type type;
0576     static type begin(const view_of<polygon_45_set_concept, T>& t) { return t.begin(); }
0577     static type end(const view_of<polygon_45_set_concept, T>& t) { return t.end(); }
0578   };
0579 }
0580 }
0581 #endif