Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / polygon / example / gtl_custom_point.cpp
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 #include <boost/polygon/polygon.hpp>
9 #include <cassert>
10 namespace gtl = boost::polygon;
11 using namespace boost::polygon::operators;
12
13 //lets make the body of main from point_usage.cpp
14 //a generic function parameterized by point type
15 template <typename Point>
16 void test_point() {
17   //constructing a gtl point
18   int x = 10;
19   int y = 20;
20   //Point pt(x, y);
21   Point pt = gtl::construct<Point>(x, y);
22   assert(gtl::x(pt) == 10);
23   assert(gtl::y(pt) == 20);
24     
25   //a quick primer in isotropic point access
26   typedef gtl::orientation_2d O;
27   using gtl::HORIZONTAL;
28   using gtl::VERTICAL;
29   O o = HORIZONTAL;
30   assert(gtl::x(pt) == gtl::get(pt, o));
31     
32   o = o.get_perpendicular();
33   assert(o == VERTICAL);
34   assert(gtl::y(pt) == gtl::get(pt, o));
35     
36   gtl::set(pt, o, 30);
37   assert(gtl::y(pt) == 30);
38     
39   //using some of the library functions
40   //Point pt2(10, 30);
41   Point pt2 = gtl::construct<Point>(10, 30);
42   assert(gtl::equivalence(pt, pt2));
43     
44   gtl::transformation<int> tr(gtl::axis_transformation::SWAP_XY);
45   gtl::transform(pt, tr);
46   assert(gtl::equivalence(pt, gtl::construct<Point>(30, 10)));
47     
48   gtl::transformation<int> tr2 = tr.inverse();
49   assert(tr == tr2); //SWAP_XY is its own inverse transform
50     
51   gtl::transform(pt, tr2);
52   assert(gtl::equivalence(pt, pt2)); //the two points are equal again
53     
54   gtl::move(pt, o, 10); //move pt 10 units in y
55   assert(gtl::euclidean_distance(pt, pt2) == 10.0f);
56     
57   gtl::move(pt, o.get_perpendicular(), 10); //move pt 10 units in x
58   assert(gtl::manhattan_distance(pt, pt2) == 20);
59 }
60     
61 //Now lets declare our own point type
62 //Bjarne says that if a class doesn't maintain an
63 //invariant just use a struct.
64 struct CPoint {
65   int x;
66   int y;
67 };
68     
69 //There, nice a simple...but wait, it doesn't do anything
70 //how do we use it to do all the things a point needs to do?
71     
72     
73 //First we register it as a point with boost polygon
74 namespace boost { namespace polygon {
75     template <>
76     struct geometry_concept<CPoint> { typedef point_concept type; };
77  
78     
79     //Then we specialize the gtl point traits for our point type
80     template <>
81     struct point_traits<CPoint> {
82       typedef int coordinate_type;
83     
84       static inline coordinate_type get(const CPoint& point, 
85                                         orientation_2d orient) {
86         if(orient == HORIZONTAL)
87           return point.x;
88         return point.y;
89       }
90     };
91     
92     template <>
93     struct point_mutable_traits<CPoint> {
94       typedef int coordinate_type;
95
96
97       static inline void set(CPoint& point, orientation_2d orient, int value) {
98         if(orient == HORIZONTAL)
99           point.x = value;
100         else
101           point.y = value;
102       }
103       static inline CPoint construct(int x_value, int y_value) {
104         CPoint retval;
105         retval.x = x_value;
106         retval.y = y_value; 
107         return retval;
108       }
109     };
110   } }
111     
112 //Now lets see if the CPoint works with the library functions
113 int main() {
114   test_point<CPoint>(); //yay! All your testing is done for you.
115   return 0;
116 }
117     
118 //Now you know how to map a user type to the library point concept
119 //and how to write a generic function parameterized by point type
120 //using the library interfaces to access it.