Imported Upstream version 1.57.0
[platform/upstream/boost.git] / boost / polygon / detail / polygon_set_view.hpp
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_SET_VIEW_HPP
9 #define BOOST_POLYGON_POLYGON_SET_VIEW_HPP
10 namespace boost { namespace polygon{
11
12
13   template <typename coordinate_type>
14   inline void polygon_set_data<coordinate_type>::clean() const {
15     if(dirty_) {
16       //polygon_45_set_data<coordinate_type> tmp;
17       //very important:
18       //the 45 degree algorithm does not satisfy
19       //the precondition of arbitrary polygon formation
20       //that vertices be "linearly consistent"
21       //therefore it doesn't work to fall back on 45-degree
22       //booleans for arbitrary angle polygons
23       //if(0) { //downcast(tmp) ) {
24       //  tmp.clean();
25       //  data_.clear();
26       //  is_45_ = true;
27       //  polygon_set_data<coordinate_type> tmp2;
28       //  tmp2.insert(tmp);
29       //  data_.swap(tmp2.data_);
30       //  dirty_ = false;
31       //  sort();
32       //} else {
33       sort();
34       arbitrary_boolean_op<coordinate_type> abo;
35       polygon_set_data<coordinate_type> tmp2;
36       abo.execute(tmp2, begin(), end(), end(), end(), 0);
37       data_.swap(tmp2.data_);
38       is_45_ = tmp2.is_45_;
39       dirty_ = false;
40       //}
41     }
42   }
43
44   template <>
45   inline void polygon_set_data<double>::clean() const {
46     if(dirty_) {
47       sort();
48       arbitrary_boolean_op<double> abo;
49       polygon_set_data<double> tmp2;
50       abo.execute(tmp2, begin(), end(), end(), end(), 0);
51       data_.swap(tmp2.data_);
52       is_45_ = tmp2.is_45_;
53       dirty_ = false;
54     }
55   }
56
57   template <typename value_type, typename arg_type>
58   inline void insert_into_view_arg(value_type& dest, const arg_type& arg);
59
60   template <typename ltype, typename rtype, int op_type>
61   class polygon_set_view;
62
63   template <typename ltype, typename rtype, int op_type>
64   struct polygon_set_traits<polygon_set_view<ltype, rtype, op_type> > {
65     typedef typename polygon_set_view<ltype, rtype, op_type>::coordinate_type coordinate_type;
66     typedef typename polygon_set_view<ltype, rtype, op_type>::iterator_type iterator_type;
67     typedef typename polygon_set_view<ltype, rtype, op_type>::operator_arg_type operator_arg_type;
68
69     static inline iterator_type begin(const polygon_set_view<ltype, rtype, op_type>& polygon_set);
70     static inline iterator_type end(const polygon_set_view<ltype, rtype, op_type>& polygon_set);
71
72     static inline bool clean(const polygon_set_view<ltype, rtype, op_type>& polygon_set);
73
74     static inline bool sort(const polygon_set_view<ltype, rtype, op_type>& polygon_set);
75   };
76
77   //template <typename value_type, typename geometry_type_1, typename geometry_type_2, int op_type>
78   //void execute_boolean_op(value_type& output_, const geometry_type_1& lvalue_, const geometry_type_2& rvalue_,
79   //                        double coord) {
80   //  typedef geometry_type_1 ltype;
81   //  typedef geometry_type_2 rtype;
82   //  typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type;
83   //  value_type linput_;
84   //  value_type rinput_;
85   //  insert_into_view_arg(linput_, lvalue_);
86   //  insert_into_view_arg(rinput_, rvalue_);
87   //  arbitrary_boolean_op<coordinate_type> abo;
88   //  abo.execute(output_, linput_.begin(), linput_.end(),
89   //              rinput_.begin(), rinput_.end(), op_type);
90   //}
91
92   template <typename value_type, typename geometry_type_1, typename geometry_type_2, int op_type>
93   void execute_boolean_op(value_type& output_, const geometry_type_1& lvalue_, const geometry_type_2& rvalue_) {
94     typedef geometry_type_1 ltype;
95     //typedef geometry_type_2 rtype;
96     typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type;
97     value_type linput_;
98     value_type rinput_;
99     insert_into_view_arg(linput_, lvalue_);
100     insert_into_view_arg(rinput_, rvalue_);
101     polygon_45_set_data<coordinate_type> l45, r45, o45;
102 //    if(linput_.downcast(l45) && rinput_.downcast(r45)) {
103 //      //the op codes are screwed up between 45 and arbitrary
104 //#ifdef BOOST_POLYGON_MSVC
105 //#pragma warning (push)
106 //#pragma warning (disable: 4127)
107 //#endif
108 //      if(op_type < 2)
109 //        l45.template applyAdaptiveBoolean_<op_type>(o45, r45);
110 //      else if(op_type == 2)
111 //        l45.template applyAdaptiveBoolean_<3>(o45, r45);
112 //      else
113 //        l45.template applyAdaptiveBoolean_<2>(o45, r45);
114 //#ifdef BOOST_POLYGON_MSVC
115 //#pragma warning (pop)
116 //#endif
117 //      output_.insert(o45);
118 //    } else {
119       arbitrary_boolean_op<coordinate_type> abo;
120       abo.execute(output_, linput_.begin(), linput_.end(),
121                   rinput_.begin(), rinput_.end(), op_type);
122 //    }
123   }
124
125   template <typename ltype, typename rtype, int op_type>
126   class polygon_set_view {
127   public:
128     typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type;
129     typedef polygon_set_data<coordinate_type> value_type;
130     typedef typename value_type::iterator_type iterator_type;
131     typedef polygon_set_view operator_arg_type;
132   private:
133     const ltype& lvalue_;
134     const rtype& rvalue_;
135     mutable value_type output_;
136     mutable bool evaluated_;
137     polygon_set_view& operator=(const polygon_set_view&);
138   public:
139     polygon_set_view(const ltype& lvalue,
140                      const rtype& rvalue ) :
141       lvalue_(lvalue), rvalue_(rvalue), output_(), evaluated_(false) {}
142
143     // get iterator to begin vertex data
144   public:
145     const value_type& value() const {
146       if(!evaluated_) {
147         evaluated_ = true;
148         execute_boolean_op<value_type, ltype, rtype, op_type>(output_, lvalue_, rvalue_);
149       }
150       return output_;
151     }
152   public:
153     iterator_type begin() const { return value().begin(); }
154     iterator_type end() const { return value().end(); }
155
156     bool dirty() const { return false; } //result of a boolean is clean
157     bool sorted() const { return true; } //result of a boolean is sorted
158
159     void sort() const {} //is always sorted
160   };
161
162   template <typename ltype, typename rtype, int op_type>
163   typename polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::iterator_type
164   polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::
165   begin(const polygon_set_view<ltype, rtype, op_type>& polygon_set) {
166     return polygon_set.begin();
167   }
168   template <typename ltype, typename rtype, int op_type>
169   typename polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::iterator_type
170   polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::
171   end(const polygon_set_view<ltype, rtype, op_type>& polygon_set) {
172     return polygon_set.end();
173   }
174   template <typename ltype, typename rtype, int op_type>
175   bool polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::
176   clean(const polygon_set_view<ltype, rtype, op_type>& ) {
177     return true; }
178   template <typename ltype, typename rtype, int op_type>
179   bool polygon_set_traits<polygon_set_view<ltype, rtype, op_type> >::
180   sort(const polygon_set_view<ltype, rtype, op_type>& ) {
181     return true; }
182
183   template <typename value_type, typename arg_type>
184   inline void insert_into_view_arg(value_type& dest, const arg_type& arg) {
185     typedef typename polygon_set_traits<arg_type>::iterator_type literator;
186     literator itr1, itr2;
187     itr1 = polygon_set_traits<arg_type>::begin(arg);
188     itr2 = polygon_set_traits<arg_type>::end(arg);
189     dest.insert(itr1, itr2);
190   }
191
192   template <typename geometry_type_1, typename geometry_type_2, int op_type>
193   geometry_type_1& self_assignment_boolean_op(geometry_type_1& lvalue_, const geometry_type_2& rvalue_) {
194     typedef geometry_type_1 ltype;
195     typedef typename polygon_set_traits<ltype>::coordinate_type coordinate_type;
196     typedef polygon_set_data<coordinate_type> value_type;
197     value_type output_;
198     execute_boolean_op<value_type, geometry_type_1, geometry_type_2, op_type>(output_, lvalue_, rvalue_);
199     polygon_set_mutable_traits<geometry_type_1>::set(lvalue_, output_.begin(), output_.end());
200     return lvalue_;
201   }
202
203   // copy constructor
204   template <typename coordinate_type>
205   template <typename ltype, typename rtype, int op_type>
206   polygon_set_data<coordinate_type>::polygon_set_data(const polygon_set_view<ltype, rtype, op_type>& that) :
207     data_(that.value().data_), dirty_(that.value().dirty_), unsorted_(that.value().unsorted_), is_45_(that.value().is_45_) {}
208
209     // equivalence operator
210   template <typename coordinate_type>
211   inline bool polygon_set_data<coordinate_type>::operator==(const polygon_set_data<coordinate_type>& p) const {
212     typedef polygon_set_data<coordinate_type> value_type;
213     value_type output_;
214     execute_boolean_op<value_type, value_type, value_type, 2>(output_, (*this), p);  
215     return output_.data_.empty();
216   }
217
218   template <typename ltype, typename rtype, int op_type>
219   struct geometry_concept<polygon_set_view<ltype, rtype, op_type> > { typedef polygon_set_concept type; };
220 }
221 }
222 #endif