Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:55:26

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_RECTANGLE_CONCEPT_HPP
0009 #define BOOST_POLYGON_RECTANGLE_CONCEPT_HPP
0010 
0011 #include "isotropy.hpp"
0012 
0013 //point
0014 #include "point_data.hpp"
0015 #include "point_traits.hpp"
0016 #include "point_concept.hpp"
0017 
0018 //interval
0019 #include "interval_data.hpp"
0020 #include "interval_traits.hpp"
0021 #include "interval_concept.hpp"
0022 
0023 #include "rectangle_data.hpp"
0024 #include "rectangle_traits.hpp"
0025 
0026 namespace boost { namespace polygon{
0027   struct rectangle_concept {};
0028 
0029   template <typename T>
0030   struct is_rectangle_concept { typedef gtl_no type; };
0031   template <>
0032   struct is_rectangle_concept<rectangle_concept> { typedef gtl_yes type; };
0033 
0034   template <typename T>
0035   struct is_mutable_rectangle_concept { typedef gtl_no type; };
0036   template <>
0037   struct is_mutable_rectangle_concept<rectangle_concept> { typedef gtl_yes type; };
0038 
0039   template <>
0040   struct geometry_domain<rectangle_concept> { typedef manhattan_domain type; };
0041 
0042   template <typename T, typename CT>
0043   struct rectangle_interval_type_by_concept { typedef void type; };
0044   template <typename T>
0045   struct rectangle_interval_type_by_concept<T, gtl_yes> { typedef typename rectangle_traits<T>::interval_type type; };
0046 
0047   template <typename T>
0048   struct rectangle_interval_type {
0049       typedef typename rectangle_interval_type_by_concept<T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type;
0050   };
0051 
0052   template <typename T, typename CT>
0053   struct rectangle_coordinate_type_by_concept { typedef void type; };
0054   template <typename T>
0055   struct rectangle_coordinate_type_by_concept<T, gtl_yes> { typedef typename rectangle_traits<T>::coordinate_type type; };
0056 
0057   template <typename T>
0058   struct rectangle_coordinate_type {
0059       typedef typename rectangle_coordinate_type_by_concept<T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type;
0060   };
0061 
0062   template <typename T, typename CT>
0063   struct rectangle_difference_type_by_concept { typedef void type; };
0064   template <typename T>
0065   struct rectangle_difference_type_by_concept<T, gtl_yes> {
0066      typedef typename coordinate_traits<typename rectangle_traits<T>::coordinate_type>::coordinate_difference type; };
0067 
0068   template <typename T>
0069   struct rectangle_difference_type {
0070     typedef typename rectangle_difference_type_by_concept<
0071       T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type;
0072   };
0073 
0074   template <typename T, typename CT>
0075   struct rectangle_distance_type_by_concept { typedef void type; };
0076   template <typename T>
0077   struct rectangle_distance_type_by_concept<T, gtl_yes> {
0078     typedef typename coordinate_traits<typename rectangle_coordinate_type<T>::type>::coordinate_distance type; };
0079 
0080   template <typename T>
0081   struct rectangle_distance_type {
0082     typedef typename rectangle_distance_type_by_concept<
0083       T, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type type;
0084   };
0085 
0086   struct y_r_get_interval : gtl_yes {};
0087 
0088   template <typename T>
0089   typename enable_if< typename gtl_and<y_r_get_interval, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type,
0090                       typename rectangle_interval_type<T>::type>::type
0091   get(const T& rectangle, orientation_2d orient) {
0092     return rectangle_traits<T>::get(rectangle, orient);
0093   }
0094 
0095   struct y_r_h : gtl_yes {};
0096 
0097   template <typename T>
0098   typename enable_if< typename gtl_and<y_r_h, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type,
0099                        typename rectangle_interval_type<T>::type>::type
0100   horizontal(const T& rectangle) {
0101     return rectangle_traits<T>::get(rectangle, HORIZONTAL);
0102   }
0103 
0104   struct y_r_v : gtl_yes {};
0105 
0106   template <typename T>
0107   typename enable_if< typename gtl_and<y_r_v, typename is_rectangle_concept<typename geometry_concept<T>::type>::type>::type,
0108                        typename rectangle_interval_type<T>::type>::type
0109   vertical(const T& rectangle) {
0110     return rectangle_traits<T>::get(rectangle, VERTICAL);
0111   }
0112 
0113   struct y_r_set : gtl_yes {};
0114 
0115   template <orientation_2d_enum orient, typename T, typename T2>
0116   typename enable_if< typename gtl_and_3<y_r_set, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type,
0117                                         typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type,
0118                        void>::type
0119   set(T& rectangle, const T2& interval) {
0120     rectangle_mutable_traits<T>::set(rectangle, orient, interval);
0121   }
0122 
0123   struct y_r_set2 : gtl_yes {};
0124 
0125   template <typename T, typename T2>
0126   typename enable_if< typename gtl_and_3<y_r_set2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type,
0127                                         typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type,
0128                        void>::type
0129   set(T& rectangle, orientation_2d orient, const T2& interval) {
0130     rectangle_mutable_traits<T>::set(rectangle, orient, interval);
0131   }
0132 
0133   struct y_r_h2 : gtl_yes {};
0134 
0135   template <typename T, typename T2>
0136   typename enable_if< typename gtl_and_3<y_r_h2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type,
0137                                         typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type,
0138                        void>::type
0139   horizontal(T& rectangle, const T2& interval) {
0140     rectangle_mutable_traits<T>::set(rectangle, HORIZONTAL, interval);
0141   }
0142 
0143   struct y_r_v2 : gtl_yes {};
0144 
0145   template <typename T, typename T2>
0146   typename enable_if<
0147     typename gtl_and_3<y_r_v2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type,
0148                      typename is_interval_concept<typename geometry_concept<T2>::type>::type>::type, void>::type
0149   vertical(T& rectangle, const T2& interval) {
0150     rectangle_mutable_traits<T>::set(rectangle, VERTICAL, interval);
0151   }
0152 
0153   struct y_r_construct : gtl_yes {};
0154 
0155   template <typename T, typename T2, typename T3>
0156   typename enable_if< typename gtl_and<y_r_construct, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type>::type,
0157                        T>::type
0158   construct(const T2& interval_horizontal,
0159             const T3& interval_vertical) {
0160     return rectangle_mutable_traits<T>::construct(interval_horizontal, interval_vertical); }
0161 
0162   struct y_r_construct2 : gtl_yes {};
0163 
0164   template <typename T, typename coord_type>
0165   typename enable_if< typename gtl_and<y_r_construct2, typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type>::type,
0166                        T>::type
0167   construct(coord_type xl, coord_type yl, coord_type xh, coord_type yh) {
0168     return rectangle_mutable_traits<T>::construct(interval_data<coord_type>(xl, xh),
0169                                                   interval_data<coord_type>(yl, yh));
0170   }
0171 
0172   struct y_r_cconstruct : gtl_yes {};
0173 
0174   template <typename T, typename T2>
0175   typename enable_if<
0176     typename gtl_and_3<y_r_cconstruct,
0177       typename is_mutable_rectangle_concept<typename geometry_concept<T>::type>::type,
0178       typename is_rectangle_concept<typename geometry_concept<T2>::type>::type>::type,
0179     T>::type
0180   copy_construct(const T2& rectangle) {
0181     return construct<T> (get(rectangle, HORIZONTAL), get(rectangle, VERTICAL));
0182   }
0183 
0184   struct y_r_assign : gtl_yes {};
0185 
0186   template <typename rectangle_type_1, typename rectangle_type_2>
0187   typename enable_if<
0188     typename gtl_and_3< y_r_assign,
0189       typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0190       typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0191     rectangle_type_1>::type &
0192   assign(rectangle_type_1& lvalue, const rectangle_type_2& rvalue) {
0193     set(lvalue, HORIZONTAL, get(rvalue, HORIZONTAL));
0194     set(lvalue, VERTICAL, get(rvalue, VERTICAL));
0195     return lvalue;
0196   }
0197 
0198   struct y_r_equiv : gtl_yes {};
0199 
0200   template <typename T, typename T2>
0201   typename enable_if<
0202     typename gtl_and_3< y_r_equiv,
0203       typename is_rectangle_concept<typename geometry_concept<T>::type>::type,
0204       typename is_rectangle_concept<typename geometry_concept<T2>::type>::type>::type,
0205     bool>::type
0206   equivalence(const T& rect1, const T2& rect2) {
0207     return equivalence(get(rect1, HORIZONTAL), get(rect2, HORIZONTAL)) &&
0208       equivalence(get(rect1, VERTICAL), get(rect2, VERTICAL));
0209   }
0210 
0211   struct y_r_get : gtl_yes {};
0212 
0213   template <typename rectangle_type>
0214   typename enable_if< typename gtl_and<y_r_get, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0215                        typename rectangle_coordinate_type<rectangle_type>::type>::type
0216   get(const rectangle_type& rectangle, orientation_2d orient, direction_1d dir) {
0217     return get(rectangle_traits<rectangle_type>::get(rectangle, orient), dir);
0218   }
0219 
0220   struct y_r_set3 : gtl_yes {};
0221 
0222   template <typename rectangle_type>
0223   typename enable_if<typename gtl_and<y_r_set3, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type
0224   set(rectangle_type& rectangle, orientation_2d orient, direction_1d dir,
0225       typename rectangle_coordinate_type<rectangle_type>::type value) {
0226     typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
0227     set(ivl, dir, value);
0228     set(rectangle, orient, ivl);
0229   }
0230 
0231   struct y_r_xl : gtl_yes {};
0232 
0233   template <typename rectangle_type>
0234   typename enable_if< typename gtl_and<y_r_xl, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0235                        typename rectangle_coordinate_type<rectangle_type>::type>::type
0236   xl(const rectangle_type& rectangle) {
0237     return get(rectangle, HORIZONTAL, LOW);
0238   }
0239 
0240   struct y_r_xl2 : gtl_yes {};
0241 
0242   template <typename rectangle_type>
0243   typename enable_if<typename gtl_and<y_r_xl2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type
0244       xl(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) {
0245     return set(rectangle, HORIZONTAL, LOW, value);
0246   }
0247 
0248   struct y_r_xh : gtl_yes {};
0249 
0250   template <typename rectangle_type>
0251   typename enable_if< typename gtl_and<y_r_xh, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0252                        typename rectangle_coordinate_type<rectangle_type>::type>::type
0253   xh(const rectangle_type& rectangle) {
0254     return get(rectangle, HORIZONTAL, HIGH);
0255   }
0256 
0257   struct y_r_xh2 : gtl_yes {};
0258 
0259   template <typename rectangle_type>
0260   typename enable_if<typename gtl_and<y_r_xh2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type
0261   xh(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) {
0262     return set(rectangle, HORIZONTAL, HIGH, value);
0263   }
0264 
0265   struct y_r_yl : gtl_yes {};
0266 
0267   template <typename rectangle_type>
0268   typename enable_if< typename gtl_and<y_r_yl, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0269                        typename rectangle_coordinate_type<rectangle_type>::type>::type
0270   yl(const rectangle_type& rectangle) {
0271     return get(rectangle, VERTICAL, LOW);
0272   }
0273 
0274   struct y_r_yl2 : gtl_yes {};
0275 
0276   template <typename rectangle_type>
0277   typename enable_if<typename gtl_and<y_r_yl2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type
0278       yl(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) {
0279     return set(rectangle, VERTICAL, LOW, value);
0280   }
0281 
0282   struct y_r_yh : gtl_yes {};
0283 
0284   template <typename rectangle_type>
0285   typename enable_if< typename gtl_and<y_r_yh, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0286                        typename rectangle_coordinate_type<rectangle_type>::type>::type
0287   yh(const rectangle_type& rectangle) {
0288     return get(rectangle, VERTICAL, HIGH);
0289   }
0290 
0291   struct y_r_yh2 : gtl_yes {};
0292 
0293   template <typename rectangle_type>
0294   typename enable_if<typename gtl_and<y_r_yh2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type, void>::type
0295       yh(rectangle_type& rectangle, typename rectangle_coordinate_type<rectangle_type>::type value) {
0296     return set(rectangle, VERTICAL, HIGH, value);
0297   }
0298 
0299   struct y_r_ll : gtl_yes {};
0300 
0301   template <typename rectangle_type>
0302   typename enable_if<typename gtl_and<y_r_ll,  typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0303                        point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type
0304   ll(const rectangle_type& rectangle) {
0305     return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xl(rectangle), yl(rectangle));
0306   }
0307 
0308   struct y_r_lr : gtl_yes {};
0309 
0310   template <typename rectangle_type>
0311   typename enable_if<typename gtl_and<y_r_lr,  typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0312                        point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type
0313   lr(const rectangle_type& rectangle) {
0314     return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xh(rectangle), yl(rectangle));
0315   }
0316 
0317   struct y_r_ul : gtl_yes {};
0318 
0319   template <typename rectangle_type>
0320   typename enable_if<typename gtl_and<y_r_ul,  typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0321                        point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type
0322   ul(const rectangle_type& rectangle) {
0323     return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xl(rectangle), yh(rectangle));
0324   }
0325 
0326   struct y_r_ur : gtl_yes {};
0327 
0328   template <typename rectangle_type>
0329   typename enable_if<typename gtl_and<y_r_ur,  typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0330                        point_data<typename rectangle_coordinate_type<rectangle_type>::type> >::type
0331   ur(const rectangle_type& rectangle) {
0332     return point_data<typename rectangle_coordinate_type<rectangle_type>::type> (xh(rectangle), yh(rectangle));
0333   }
0334 
0335   struct y_r_contains : gtl_yes {};
0336 
0337   template <typename rectangle_type, typename rectangle_type_2>
0338   typename enable_if< typename gtl_and_3<y_r_contains, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
0339                                          typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0340                        bool>::type
0341   contains(const rectangle_type& rectangle, const rectangle_type_2 rectangle_contained,
0342            bool consider_touch = true) {
0343     return contains(horizontal(rectangle), horizontal(rectangle_contained), consider_touch) &&
0344       contains(vertical(rectangle), vertical(rectangle_contained), consider_touch);
0345   }
0346 
0347   struct y_r_contains2 : gtl_yes {};
0348 
0349   template <typename rectangle_type, typename point_type>
0350   typename enable_if< typename gtl_and_3<y_r_contains2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
0351                                          typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, bool>::type
0352   contains(const rectangle_type& rectangle, const point_type point_contained,
0353            bool consider_touch = true) {
0354     return contains(horizontal(rectangle), x(point_contained), consider_touch) &&
0355       contains(vertical(rectangle), y(point_contained), consider_touch);
0356   }
0357 
0358   struct y_r_set_points : gtl_yes {};
0359 
0360   // set all four coordinates based upon two points
0361   template <typename rectangle_type, typename point_type_1, typename point_type_2>
0362   typename enable_if< typename gtl_and_4< y_r_set_points,
0363     typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
0364     typename is_point_concept<typename geometry_concept<point_type_1>::type>::type,
0365     typename is_point_concept<typename geometry_concept<point_type_2>::type>::type>::type,
0366                        rectangle_type>::type &
0367   set_points(rectangle_type& rectangle, const point_type_1& p1,
0368              const point_type_2& p2) {
0369     typedef typename rectangle_coordinate_type<rectangle_type>::type Unit;
0370     Unit x1(x(p1));
0371     Unit x2(x(p2));
0372     Unit y1(y(p1));
0373     Unit y2(y(p2));
0374     horizontal(rectangle, construct<typename rectangle_interval_type<rectangle_type>::type>(x1, x2));
0375     vertical(rectangle, construct<typename rectangle_interval_type<rectangle_type>::type>(y1, y2));
0376     return rectangle;
0377   }
0378 
0379   struct y_r_move : gtl_yes {};
0380 
0381   // move rectangle by delta in orient
0382   template <typename rectangle_type>
0383   typename enable_if< typename gtl_and<y_r_move, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0384                       rectangle_type>::type &
0385   move(rectangle_type& rectangle, orientation_2d orient,
0386        typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference delta) {
0387     typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
0388     move(ivl, delta);
0389     set(rectangle, orient, ivl);
0390     return rectangle;
0391   }
0392 
0393   struct y_r_convolve : gtl_yes {};
0394 
0395   // convolve this with b
0396   template <typename rectangle_type_1, typename rectangle_type_2>
0397   typename enable_if<
0398     typename gtl_and_3< y_r_convolve,
0399       typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0400       typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0401     rectangle_type_1>::type &
0402   convolve(rectangle_type_1& rectangle,
0403            const rectangle_type_2& convolution_rectangle) {
0404     typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle);
0405     horizontal(rectangle, convolve(ivl, horizontal(convolution_rectangle)));
0406     ivl = vertical(rectangle);
0407     vertical(rectangle, convolve(ivl, vertical(convolution_rectangle)));
0408     return rectangle;
0409   }
0410 
0411   struct y_r_deconvolve : gtl_yes {};
0412 
0413   // deconvolve this with b
0414   template <typename rectangle_type_1, typename rectangle_type_2>
0415   typename enable_if< typename gtl_and_3< y_r_deconvolve,
0416     typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0417     typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0418                        rectangle_type_1>::type &
0419   deconvolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) {
0420     typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle);
0421     horizontal(rectangle, deconvolve(ivl, horizontal(convolution_rectangle)));
0422     ivl = vertical(rectangle);
0423     vertical(rectangle, deconvolve(ivl, vertical(convolution_rectangle)));
0424     return rectangle;
0425   }
0426 
0427   struct y_r_reconvolve : gtl_yes {};
0428 
0429   // reflectedConvolve this with b
0430   template <typename rectangle_type_1, typename rectangle_type_2>
0431   typename enable_if<
0432     typename gtl_and_3<y_r_reconvolve, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0433                       typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0434     rectangle_type_1>::type &
0435   reflected_convolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) {
0436     typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle);
0437     horizontal(rectangle, reflected_convolve(ivl, horizontal(convolution_rectangle)));
0438     ivl = vertical(rectangle);
0439     vertical(rectangle, reflected_convolve(ivl, vertical(convolution_rectangle)));
0440     return rectangle;
0441   }
0442 
0443   struct y_r_redeconvolve : gtl_yes {};
0444 
0445   // reflectedDeconvolve this with b
0446   // deconvolve this with b
0447   template <typename rectangle_type_1, typename rectangle_type_2>
0448   typename enable_if<
0449     typename gtl_and_3<y_r_redeconvolve, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0450                       typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0451     rectangle_type_1>::type &
0452   reflected_deconvolve(rectangle_type_1& rectangle, const rectangle_type_2& convolution_rectangle) {
0453     typename rectangle_interval_type<rectangle_type_1>::type ivl = horizontal(rectangle);
0454     horizontal(rectangle, reflected_deconvolve(ivl, horizontal(convolution_rectangle)));
0455     ivl = vertical(rectangle);
0456     vertical(rectangle, reflected_deconvolve(ivl, vertical(convolution_rectangle)));
0457     return rectangle;
0458   }
0459 
0460   struct y_r_convolve2 : gtl_yes {};
0461 
0462   // convolve with point
0463   template <typename rectangle_type, typename point_type>
0464   typename enable_if< typename gtl_and_3<y_r_convolve2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
0465                                          typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
0466                        rectangle_type>::type &
0467   convolve(rectangle_type& rectangle, const point_type& convolution_point) {
0468     typename rectangle_interval_type<rectangle_type>::type ivl = horizontal(rectangle);
0469     horizontal(rectangle, convolve(ivl, x(convolution_point)));
0470     ivl = vertical(rectangle);
0471     vertical(rectangle, convolve(ivl, y(convolution_point)));
0472     return rectangle;
0473   }
0474 
0475   struct y_r_deconvolve2 : gtl_yes {};
0476 
0477   // deconvolve with point
0478   template <typename rectangle_type, typename point_type>
0479   typename enable_if<
0480     typename gtl_and_3<y_r_deconvolve2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
0481                       typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, rectangle_type>::type &
0482   deconvolve(rectangle_type& rectangle, const point_type& convolution_point) {
0483     typename rectangle_interval_type<rectangle_type>::type ivl = horizontal(rectangle);
0484     horizontal(rectangle, deconvolve(ivl, x(convolution_point)));
0485     ivl = vertical(rectangle);
0486     vertical(rectangle, deconvolve(ivl, y(convolution_point)));
0487     return rectangle;
0488   }
0489 
0490   struct y_r_delta : gtl_yes {};
0491 
0492   // get the magnitude of the interval range depending on orient
0493   template <typename rectangle_type>
0494   typename enable_if< typename gtl_and<y_r_delta, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0495                        typename rectangle_difference_type<rectangle_type>::type>::type
0496   delta(const rectangle_type& rectangle, orientation_2d orient) {
0497     return delta(get(rectangle, orient));
0498   }
0499 
0500   struct y_r_area : gtl_yes {};
0501 
0502   // get the area of the rectangle
0503   template <typename rectangle_type>
0504   typename enable_if< typename gtl_and<y_r_area, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0505                        typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::manhattan_area_type>::type
0506   area(const rectangle_type& rectangle) {
0507     typedef typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::manhattan_area_type area_type;
0508     return (area_type)delta(rectangle, HORIZONTAL) * (area_type)delta(rectangle, VERTICAL);
0509   }
0510 
0511   struct y_r_go : gtl_yes {};
0512 
0513   // returns the orientation of the longest side
0514   template <typename rectangle_type>
0515   typename enable_if<typename gtl_and<y_r_go, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0516                       orientation_2d>::type
0517   guess_orientation(const rectangle_type& rectangle) {
0518     return delta(rectangle, HORIZONTAL) >= delta(rectangle, VERTICAL) ?
0519       HORIZONTAL : VERTICAL;
0520   }
0521 
0522   struct y_r_half_p : gtl_yes {};
0523 
0524   // get the half perimeter of the rectangle
0525   template <typename rectangle_type>
0526   typename enable_if< typename gtl_and<y_r_half_p, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0527                        typename rectangle_difference_type<rectangle_type>::type>::type
0528   half_perimeter(const rectangle_type& rectangle) {
0529     return delta(rectangle, HORIZONTAL) + delta(rectangle, VERTICAL);
0530   }
0531 
0532   struct y_r_perimeter : gtl_yes {};
0533 
0534   // get the perimeter of the rectangle
0535   template <typename rectangle_type>
0536   typename enable_if< typename gtl_and<y_r_perimeter, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0537                       typename rectangle_difference_type<rectangle_type>::type>::type
0538   perimeter(const rectangle_type& rectangle) {
0539     return 2 * half_perimeter(rectangle);
0540   }
0541 
0542   struct y_r_intersects : gtl_yes {};
0543 
0544   // check if Rectangle b intersects `this` Rectangle
0545   //  [in]     b         Rectangle that will be checked
0546   //  [in]     considerTouch If true, return true even if b touches the boundary
0547   //  [ret]    .         true if `t` intersects b
0548   template <typename rectangle_type_1, typename rectangle_type_2>
0549   typename enable_if<
0550     typename gtl_and_3<y_r_intersects, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0551                       typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0552     bool>::type
0553   intersects(const rectangle_type_1& rectangle, const rectangle_type_2& b, bool consider_touch = true) {
0554     return intersects(horizontal(rectangle), horizontal(b), consider_touch) &&
0555       intersects(vertical(rectangle), vertical(b), consider_touch);
0556   }
0557 
0558   struct y_r_b_intersect : gtl_yes {};
0559 
0560   // Check if boundaries of Rectangle b and `this` Rectangle intersect
0561   //  [in]     b         Rectangle that will be checked
0562   //  [in]     considerTouch If true, return true even if p is on the foundary
0563   //  [ret]    .         true if `t` contains p
0564   template <typename rectangle_type_1, typename rectangle_type_2>
0565   typename enable_if<
0566     typename gtl_and_3<y_r_b_intersect, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0567                       typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0568     bool>::type
0569   boundaries_intersect(const rectangle_type_1& rectangle, const rectangle_type_2& b,
0570                        bool consider_touch = true) {
0571     return (intersects(rectangle, b, consider_touch) &&
0572             !(contains(rectangle, b, !consider_touch)) &&
0573             !(contains(b, rectangle, !consider_touch)));
0574   }
0575 
0576   struct y_r_b_abuts : gtl_yes {};
0577 
0578   // check if b is touching 'this' on the end specified by dir
0579   template <typename rectangle_type_1, typename rectangle_type_2>
0580   typename enable_if< typename gtl_and_3<y_r_b_abuts, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0581                                          typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0582                        bool>::type
0583   abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b,
0584         direction_2d dir) {
0585     return
0586       abuts(get(rectangle, orientation_2d(dir)),
0587             get(b, orientation_2d(dir)),
0588             direction_1d(dir)) &&
0589       intersects(get(rectangle, orientation_2d(dir).get_perpendicular()),
0590                  get(b, orientation_2d(dir).get_perpendicular()), true);
0591   }
0592 
0593   struct y_r_b_abuts2 : gtl_yes {};
0594 
0595   // check if they are touching in the given orientation
0596   template <typename rectangle_type_1, typename rectangle_type_2>
0597   typename enable_if< typename gtl_and_3<y_r_b_abuts2, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0598                                          typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0599                        bool>::type
0600   abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b,
0601         orientation_2d orient) {
0602     return
0603       abuts(get(rectangle, orient), get(b, orient)) &&
0604       intersects(get(rectangle, orient.get_perpendicular()),
0605                  get(b, orient.get_perpendicular()), true);
0606   }
0607 
0608   struct y_r_b_abuts3 : gtl_yes {};
0609 
0610   // check if they are touching but not overlapping
0611   template <typename rectangle_type_1, typename rectangle_type_2>
0612   typename enable_if< typename gtl_and_3<y_r_b_abuts3, typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0613                                          typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0614                        bool>::type
0615   abuts(const rectangle_type_1& rectangle, const rectangle_type_2& b) {
0616     return abuts(rectangle, b, HORIZONTAL) || abuts(rectangle, b, VERTICAL);
0617   }
0618 
0619   struct y_r_b_intersect2 : gtl_yes {};
0620 
0621   // intersect rectangle with interval on orient
0622   template <typename rectangle_type, typename interval_type>
0623   typename enable_if<
0624     typename gtl_and_3<y_r_b_intersect2, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
0625                       typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
0626     bool>::type
0627   intersect(rectangle_type& rectangle, const interval_type& b,
0628             orientation_2d orient, bool consider_touch = true) {
0629     typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
0630     if(intersect(ivl, b, consider_touch)) {
0631       set(rectangle, orient, ivl);
0632       return true;
0633     }
0634     return false;
0635   }
0636 
0637   struct y_r_b_intersect3 : gtl_yes {};
0638 
0639   // clip rectangle to b
0640   template <typename rectangle_type_1, typename rectangle_type_2>
0641   typename enable_if< typename gtl_and_3<y_r_b_intersect3, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0642                                          typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0643                        bool>::type
0644   intersect(rectangle_type_1& rectangle, const rectangle_type_2& b, bool consider_touch = true) {
0645     if(intersects(rectangle, b)) {
0646       intersect(rectangle, horizontal(b), HORIZONTAL, consider_touch);
0647       intersect(rectangle, vertical(b), VERTICAL, consider_touch);
0648       return true;
0649     }
0650     return false;
0651   }
0652 
0653   struct y_r_g_intersect : gtl_yes {};
0654 
0655   // Sets this to the generalized intersection of this and the given rectangle
0656   template <typename rectangle_type_1, typename rectangle_type_2>
0657   typename enable_if< typename gtl_and_3<y_r_g_intersect,
0658     typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0659     typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0660                        rectangle_type_1>::type &
0661   generalized_intersect(rectangle_type_1& rectangle, const rectangle_type_2& b) {
0662     typename rectangle_interval_type<rectangle_type_1>::type ivl = get(rectangle, HORIZONTAL);
0663     generalized_intersect(ivl, horizontal(b));
0664     horizontal(rectangle, ivl);
0665     ivl = vertical(rectangle);
0666     generalized_intersect(ivl, vertical(b));
0667     vertical(rectangle, ivl);
0668     return rectangle;
0669   }
0670 
0671   struct y_r_bloat : gtl_yes {};
0672 
0673   // bloat the interval specified by orient by bloating
0674   template <typename rectangle_type>
0675   typename enable_if<typename gtl_and<y_r_bloat, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0676                       rectangle_type>::type &
0677   bloat(rectangle_type& rectangle, orientation_2d orient,
0678         typename rectangle_coordinate_type<rectangle_type>::type bloating) {
0679     typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
0680     bloat(ivl, bloating);
0681     set(rectangle, orient, ivl);
0682     return rectangle;
0683   }
0684 
0685   struct y_r_bloat2 : gtl_yes {};
0686 
0687   // bloat the Rectangle by bloating
0688   template <typename rectangle_type>
0689   typename enable_if<typename gtl_and<y_r_bloat2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0690                       rectangle_type>::type &
0691   bloat(rectangle_type& rectangle,
0692         typename rectangle_coordinate_type<rectangle_type>::type bloating) {
0693     bloat(rectangle, HORIZONTAL, bloating);
0694     return bloat(rectangle, VERTICAL, bloating);
0695   }
0696 
0697   struct y_r_bloat3 : gtl_yes {};
0698 
0699   // bloat the interval cooresponding to orient by bloating in dir direction
0700   template <typename rectangle_type>
0701   typename enable_if<typename gtl_and<y_r_bloat3, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0702                       rectangle_type>::type &
0703   bloat(rectangle_type& rectangle, direction_2d dir,
0704         typename rectangle_coordinate_type<rectangle_type>::type bloating) {
0705     typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orientation_2d(dir));
0706     bloat(ivl, direction_1d(dir), bloating);
0707     set(rectangle, orientation_2d(dir), ivl);
0708     return rectangle;
0709   }
0710 
0711   struct y_r_shrink : gtl_yes {};
0712 
0713   // shrink the interval specified by orient by bloating
0714   template <typename rectangle_type>
0715   typename enable_if<typename gtl_and<y_r_shrink, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0716                       rectangle_type>::type &
0717   shrink(rectangle_type& rectangle, orientation_2d orient,
0718          typename rectangle_coordinate_type<rectangle_type>::type shrinking) {
0719     return bloat(rectangle, orient, -shrinking);
0720   }
0721 
0722   struct y_r_shrink2 : gtl_yes {};
0723 
0724   // shrink the Rectangle by bloating
0725   template <typename rectangle_type>
0726   typename enable_if<typename gtl_and<y_r_shrink2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0727                       rectangle_type>::type &
0728   shrink(rectangle_type& rectangle,
0729          typename rectangle_coordinate_type<rectangle_type>::type shrinking) {
0730     return bloat(rectangle, -shrinking);
0731   }
0732 
0733   struct y_r_shrink3 : gtl_yes {};
0734 
0735   // shrink the interval cooresponding to orient by bloating in dir direction
0736   template <typename rectangle_type>
0737   typename enable_if<typename gtl_and<y_r_shrink3, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0738                       rectangle_type>::type &
0739   shrink(rectangle_type& rectangle, direction_2d dir,
0740          typename rectangle_coordinate_type<rectangle_type>::type shrinking) {
0741     return bloat(rectangle, dir, -shrinking);
0742   }
0743 
0744   struct y_r_encompass : gtl_yes {};
0745 
0746   // encompass interval on orient
0747   template <typename rectangle_type, typename interval_type>
0748   typename enable_if<typename gtl_and_3<
0749         y_r_encompass,
0750         typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
0751         typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type,
0752       bool>::type
0753   encompass(rectangle_type& rectangle, const interval_type& b, orientation_2d orient) {
0754     typename rectangle_interval_type<rectangle_type>::type ivl = get(rectangle, orient);
0755     if(encompass(ivl, b)) {
0756       set(rectangle, orient, ivl);
0757       return true;
0758     }
0759     return false;
0760   }
0761 
0762  struct y_r_encompass2 : gtl_yes {};
0763 
0764   // enlarge rectangle to encompass the Rectangle b
0765   template <typename rectangle_type_1, typename rectangle_type_2>
0766   typename enable_if< typename gtl_and_3<
0767         y_r_encompass2,
0768         typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0769         typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type >::type,
0770       bool>::type
0771   encompass(rectangle_type_1& rectangle, const rectangle_type_2& b) {
0772     //note that operator | is intentional because both should be called regardless
0773     return encompass(rectangle, horizontal(b), HORIZONTAL) |
0774       encompass(rectangle, vertical(b), VERTICAL);
0775   }
0776 
0777   struct y_r_encompass3 : gtl_yes {};
0778 
0779   // enlarge rectangle to encompass the point b
0780   template <typename rectangle_type_1, typename point_type>
0781   typename enable_if<typename gtl_and_3<
0782         y_r_encompass3,
0783         typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0784         typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
0785       bool>::type
0786   encompass(rectangle_type_1& rectangle, const point_type& b) {
0787     typename rectangle_interval_type<rectangle_type_1>::type hivl, vivl;
0788     hivl = horizontal(rectangle);
0789     vivl = vertical(rectangle);
0790     //note that operator | is intentional because both should be called regardless
0791     bool retval = encompass(hivl, x(b)) | encompass(vivl, y(b));
0792     if(retval) {
0793       horizontal(rectangle, hivl);
0794       vertical(rectangle, vivl);
0795     }
0796     return retval;
0797   }
0798 
0799   struct y_r_center : gtl_yes {};
0800 
0801   // returns the center of the rectangle
0802   template <typename point_type, typename rectangle_type>
0803   typename enable_if<
0804     typename gtl_and_3<y_r_center, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type,
0805                       typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0806     bool>::type
0807   center(point_type& center_point, const rectangle_type& rectangle) {
0808     center_point = construct<point_type>(center(horizontal(rectangle)),
0809                                          center(vertical(rectangle)));
0810     return true;
0811   }
0812 
0813   struct y_r_get_corner : gtl_yes {};
0814 
0815   template <typename point_type, typename rectangle_type>
0816   typename enable_if<
0817     typename gtl_and_3<y_r_get_corner, typename is_mutable_point_concept<typename geometry_concept<point_type>::type>::type,
0818                       typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0819     bool>::type
0820   get_corner(point_type& corner_point, const rectangle_type& rectangle, direction_2d direction_facing, direction_1d direction_turning) {
0821     typedef typename rectangle_coordinate_type<rectangle_type>::type Unit;
0822     Unit u1 = get(rectangle, direction_facing);
0823     Unit u2 = get(rectangle, direction_facing.turn(direction_turning));
0824     if(orientation_2d(direction_facing).to_int()) std::swap(u1, u2);
0825     corner_point = construct<point_type>(u1, u2);
0826     return true;
0827   }
0828 
0829   struct y_r_get_half : gtl_yes {};
0830 
0831   template <typename rectangle_type>
0832   typename enable_if<typename gtl_and<y_r_get_half, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0833                      rectangle_type>::type
0834   get_half(const rectangle_type& rectangle, direction_2d dir) {
0835     rectangle_type retval(rectangle);
0836     set(retval, orientation_2d(dir), get_half(get(rectangle, orientation_2d(dir)), direction_1d(dir)));
0837     return retval;
0838   }
0839 
0840   struct y_r_join_with : gtl_yes {};
0841 
0842   template <typename rectangle_type_1, typename rectangle_type_2>
0843   typename enable_if< typename gtl_and_3<y_r_join_with, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
0844                                          typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0845                        bool>::type
0846   join_with(rectangle_type_1& rectangle, const rectangle_type_2& b) {
0847     typedef typename rectangle_interval_type<rectangle_type_1>::type Interval1;
0848     typedef typename rectangle_interval_type<rectangle_type_2>::type Interval2;
0849     Interval1 hi1 = get(rectangle, HORIZONTAL);
0850     Interval1 vi1 = get(rectangle, VERTICAL);
0851     Interval2 hi2 = get(b, HORIZONTAL), vi2 = get(b, VERTICAL);
0852     Interval1 temp;
0853     if (equivalence(hi1, hi2) && join_with(vi1, vi2)) {
0854       vertical(rectangle, vi1);
0855       return true;
0856     }
0857     if (equivalence(vi1, vi2) && join_with(hi1, hi2)) {
0858       horizontal(rectangle, hi1);
0859       return true;
0860     }
0861     return false;
0862   }
0863 
0864   struct y_r_eda2 : gtl_yes {};
0865 
0866   template <typename rectangle_type, typename point_type>
0867   typename enable_if< typename gtl_and_3<y_r_eda2,
0868     typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
0869     typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
0870                       typename rectangle_difference_type<rectangle_type>::type>::type
0871   euclidean_distance(const rectangle_type& lvalue, const point_type& rvalue, orientation_2d orient) {
0872     return euclidean_distance(get(lvalue, orient), get(rvalue, orient));
0873   }
0874 
0875   struct y_r_eda : gtl_yes {};
0876 
0877   template <typename rectangle_type, typename rectangle_type_2>
0878   typename enable_if<
0879     typename gtl_and_3<y_r_eda,
0880       typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
0881                        typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0882     typename rectangle_difference_type<rectangle_type>::type>::type
0883   euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue, orientation_2d orient) {
0884     return euclidean_distance(get(lvalue, orient), get(rvalue, orient));
0885   }
0886 
0887   struct y_r_sed : gtl_yes {};
0888 
0889   template <typename rectangle_type, typename point_type>
0890   typename enable_if< typename gtl_and_3<y_r_sed,
0891     typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
0892     typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
0893                        typename rectangle_difference_type<rectangle_type>::type>::type
0894   square_euclidean_distance(rectangle_type& lvalue, const point_type& rvalue) {
0895     typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist;
0896     xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL);
0897     ydist = euclidean_distance(lvalue, rvalue, VERTICAL);
0898     return (xdist * xdist) + (ydist * ydist);
0899   }
0900 
0901   struct y_r_sed2 : gtl_yes {};
0902 
0903   template <typename rectangle_type, typename rectangle_type_2>
0904   typename enable_if<
0905     typename gtl_and_3<y_r_sed2, typename is_rectangle_concept< typename geometry_concept<rectangle_type>::type>::type,
0906                                        typename is_rectangle_concept< typename geometry_concept<rectangle_type_2>::type>::type>::type,
0907     typename rectangle_difference_type<rectangle_type>::type>::type
0908   square_euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) {
0909     typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist;
0910     xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL);
0911     ydist = euclidean_distance(lvalue, rvalue, VERTICAL);
0912     return (xdist * xdist) + (ydist * ydist);
0913   }
0914 
0915   struct y_r_edist : gtl_yes {};
0916 
0917   template <typename rectangle_type, typename point_type>
0918   typename enable_if< typename gtl_and_3<y_r_edist, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
0919                                                           typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
0920                        typename rectangle_distance_type<rectangle_type>::type>::type
0921   euclidean_distance(rectangle_type& lvalue, const point_type& rvalue) {
0922     return std::sqrt((double)(square_euclidean_distance(lvalue, rvalue)));
0923   }
0924 
0925   struct y_r_edist2 : gtl_yes {};
0926 
0927   template <typename rectangle_type, typename rectangle_type_2>
0928   typename enable_if< typename gtl_and_3<y_r_edist2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
0929                                                           typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0930                        typename rectangle_distance_type<rectangle_type>::type>::type
0931   euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) {
0932     double val = (int)square_euclidean_distance(lvalue, rvalue);
0933     return std::sqrt(val);
0934   }
0935 
0936   struct y_r_mdist : gtl_yes {};
0937 
0938   template <typename rectangle_type, typename point_type>
0939   typename enable_if<
0940     typename gtl_and_3<y_r_mdist, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
0941                                        typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type,
0942     typename rectangle_difference_type<rectangle_type>::type>::type
0943   manhattan_distance(rectangle_type& lvalue, const point_type& rvalue) {
0944     typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist;
0945     xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL);
0946     ydist = euclidean_distance(lvalue, rvalue, VERTICAL);
0947     return xdist + ydist;
0948   }
0949 
0950   struct y_r_mdist2 : gtl_yes {};
0951 
0952   template <typename rectangle_type, typename rectangle_type_2>
0953   typename enable_if<
0954     typename gtl_and_3<y_r_mdist2, typename is_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type,
0955                                        typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
0956     typename rectangle_difference_type<rectangle_type>::type>::type
0957   manhattan_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) {
0958     typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::coordinate_difference xdist, ydist;
0959     xdist = euclidean_distance(lvalue, rvalue, HORIZONTAL);
0960     ydist = euclidean_distance(lvalue, rvalue, VERTICAL);
0961     return xdist + ydist;
0962   }
0963 
0964   struct y_r_scale_up : gtl_yes {};
0965 
0966   template <typename rectangle_type>
0967   typename enable_if<typename gtl_and<y_r_scale_up, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0968                      rectangle_type>::type &
0969   scale_up(rectangle_type& rectangle,
0970            typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::unsigned_area_type factor) {
0971     typename rectangle_interval_type<rectangle_type>::type h = horizontal(rectangle);
0972     horizontal(rectangle, scale_up(h, factor));
0973     typename rectangle_interval_type<rectangle_type>::type v = vertical(rectangle);
0974     vertical(rectangle, scale_up(v, factor));
0975     return rectangle;
0976   }
0977 
0978   struct y_r_scale_down : gtl_yes {};
0979 
0980   template <typename rectangle_type>
0981   typename enable_if<typename gtl_and<y_r_scale_down, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0982                      rectangle_type>::type &
0983   scale_down(rectangle_type& rectangle,
0984              typename coordinate_traits<typename rectangle_coordinate_type<rectangle_type>::type>::unsigned_area_type factor) {
0985     typename rectangle_interval_type<rectangle_type>::type h = horizontal(rectangle);
0986     horizontal(rectangle, scale_down(h, factor));
0987     typename rectangle_interval_type<rectangle_type>::type v = vertical(rectangle);
0988     vertical(rectangle, scale_down(v, factor));
0989     return rectangle;
0990   }
0991 
0992   struct y_r_scale : gtl_yes {};
0993 
0994   template <typename rectangle_type, typename scaling_type>
0995   typename enable_if<typename gtl_and<y_r_scale, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
0996                      rectangle_type>::type &
0997   scale(rectangle_type& rectangle, const scaling_type& scaling) {
0998     point_data<typename rectangle_coordinate_type<rectangle_type>::type> llp(xl(rectangle), yl(rectangle));
0999     point_data<typename rectangle_coordinate_type<rectangle_type>::type> urp(xl(rectangle), yl(rectangle));
1000     scale(llp, scaling);
1001     scale(urp, scaling);
1002     set_points(rectangle, llp, urp);
1003     return rectangle;
1004   }
1005 
1006   struct y_r_transform : gtl_yes {};
1007 
1008   template <typename rectangle_type, typename transformation_type>
1009   typename enable_if<typename gtl_and<y_r_transform, typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type>::type,
1010                      rectangle_type>::type &
1011   transform(rectangle_type& rectangle, const transformation_type& transformation) {
1012     point_data<typename rectangle_coordinate_type<rectangle_type>::type> llp(xl(rectangle), yl(rectangle));
1013     point_data<typename rectangle_coordinate_type<rectangle_type>::type> urp(xh(rectangle), yh(rectangle));
1014     transform(llp, transformation);
1015     transform(urp, transformation);
1016     set_points(rectangle, llp, urp);
1017     return rectangle;
1018   }
1019 
1020   template <typename rectangle_type_1, typename rectangle_type_2>
1021   class less_rectangle_concept {
1022   private:
1023     orientation_2d orient_;
1024   public:
1025     inline less_rectangle_concept(orientation_2d orient = VERTICAL) : orient_(orient) {}
1026     typename enable_if<
1027       typename gtl_and< typename is_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type,
1028                         typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type,
1029       bool>::type
1030     operator () (const rectangle_type_1& a,
1031                  const rectangle_type_2& b) const {
1032       typedef typename rectangle_coordinate_type<rectangle_type_1>::type Unit;
1033       Unit vl1 = get(get(a, orient_), LOW);
1034       Unit vl2 = get(get(b, orient_), LOW);
1035       if(vl1 > vl2) return false;
1036       if(vl1 == vl2) {
1037         orientation_2d perp = orient_.get_perpendicular();
1038         Unit hl1 = get(get(a, perp), LOW);
1039         Unit hl2 = get(get(b, perp), LOW);
1040         if(hl1 > hl2) return false;
1041         if(hl1 == hl2) {
1042           Unit vh1 = get(get(a, orient_), HIGH);
1043           Unit vh2 = get(get(b, orient_), HIGH);
1044           if(vh1 > vh2) return false;
1045           if(vh1 == vh2) {
1046             Unit hh1 = get(get(a, perp), HIGH);
1047             Unit hh2 = get(get(b, perp), HIGH);
1048             return hh1 < hh2;
1049           }
1050         }
1051       }
1052       return true;
1053     }
1054 
1055   };
1056 
1057   template <typename T>
1058   template <typename interval_type_1>
1059   inline void rectangle_data<T>::set(orientation_2d orient, const interval_type_1& interval) {
1060     assign(ranges_[orient.to_int()], interval);
1061   }
1062 
1063   template <class T>
1064   template <class T2>
1065   rectangle_data<T>& rectangle_data<T>::operator=(const T2& rvalue) {
1066     assign(*this, rvalue);
1067     return *this;
1068   }
1069 
1070   template <class T>
1071   template <class T2>
1072   bool rectangle_data<T>::operator==(const T2& rvalue) const {
1073     return equivalence(*this, rvalue);
1074   }
1075 
1076   template <typename T>
1077   struct geometry_concept<rectangle_data<T> > {
1078     typedef rectangle_concept type;
1079   };
1080 }
1081 }
1082 #endif