/* Copyright 2008 Intel Corporation Use, modification and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). */ #ifndef BOOST_POLYGON_POLYGON_SET_VIEW_HPP #define BOOST_POLYGON_POLYGON_SET_VIEW_HPP namespace boost { namespace polygon{ template inline void polygon_set_data::clean() const { if(dirty_) { polygon_45_set_data tmp; if(downcast(tmp) ) { tmp.clean(); data_.clear(); is_45_ = true; polygon_set_data tmp2; tmp2.insert(tmp); data_.swap(tmp2.data_); dirty_ = false; sort(); } else { sort(); arbitrary_boolean_op abo; polygon_set_data tmp2; abo.execute(tmp2, begin(), end(), end(), end(), 0); data_.swap(tmp2.data_); is_45_ = tmp2.is_45_; dirty_ = false; } } } template <> inline void polygon_set_data::clean() const { if(dirty_) { sort(); arbitrary_boolean_op abo; polygon_set_data tmp2; abo.execute(tmp2, begin(), end(), end(), end(), 0); data_.swap(tmp2.data_); is_45_ = tmp2.is_45_; dirty_ = false; } } template inline void insert_into_view_arg(value_type& dest, const arg_type& arg); template class polygon_set_view; template struct polygon_set_traits > { typedef typename polygon_set_view::coordinate_type coordinate_type; typedef typename polygon_set_view::iterator_type iterator_type; typedef typename polygon_set_view::operator_arg_type operator_arg_type; static inline iterator_type begin(const polygon_set_view& polygon_set); static inline iterator_type end(const polygon_set_view& polygon_set); static inline bool clean(const polygon_set_view& polygon_set); static inline bool sort(const polygon_set_view& polygon_set); }; //template //void execute_boolean_op(value_type& output_, const geometry_type_1& lvalue_, const geometry_type_2& rvalue_, // double coord) { // typedef geometry_type_1 ltype; // typedef geometry_type_2 rtype; // typedef typename polygon_set_traits::coordinate_type coordinate_type; // value_type linput_; // value_type rinput_; // insert_into_view_arg(linput_, lvalue_); // insert_into_view_arg(rinput_, rvalue_); // arbitrary_boolean_op abo; // abo.execute(output_, linput_.begin(), linput_.end(), // rinput_.begin(), rinput_.end(), op_type); //} template void execute_boolean_op(value_type& output_, const geometry_type_1& lvalue_, const geometry_type_2& rvalue_) { typedef geometry_type_1 ltype; typedef geometry_type_2 rtype; typedef typename polygon_set_traits::coordinate_type coordinate_type; value_type linput_; value_type rinput_; insert_into_view_arg(linput_, lvalue_); insert_into_view_arg(rinput_, rvalue_); polygon_45_set_data l45, r45, o45; if(linput_.downcast(l45) && rinput_.downcast(r45)) { //the op codes are screwed up between 45 and arbitrary #ifdef BOOST_POLYGON_MSVC #pragma warning (disable: 4127) #endif if(op_type < 2) l45.template applyAdaptiveBoolean_(o45, r45); else if(op_type == 2) l45.template applyAdaptiveBoolean_<3>(o45, r45); else l45.template applyAdaptiveBoolean_<2>(o45, r45); #ifdef BOOST_POLYGON_MSVC #pragma warning (default: 4127) #endif output_.insert(o45); } else { arbitrary_boolean_op abo; abo.execute(output_, linput_.begin(), linput_.end(), rinput_.begin(), rinput_.end(), op_type); } } template class polygon_set_view { public: typedef typename polygon_set_traits::coordinate_type coordinate_type; typedef polygon_set_data value_type; typedef typename value_type::iterator_type iterator_type; typedef polygon_set_view operator_arg_type; private: const ltype& lvalue_; const rtype& rvalue_; mutable value_type output_; mutable bool evaluated_; polygon_set_view& operator=(const polygon_set_view&); public: polygon_set_view(const ltype& lvalue, const rtype& rvalue ) : lvalue_(lvalue), rvalue_(rvalue), output_(), evaluated_(false) {} // get iterator to begin vertex data public: const value_type& value() const { if(!evaluated_) { evaluated_ = true; execute_boolean_op(output_, lvalue_, rvalue_); } return output_; } public: iterator_type begin() const { return value().begin(); } iterator_type end() const { return value().end(); } bool dirty() const { return false; } //result of a boolean is clean bool sorted() const { return true; } //result of a boolean is sorted void sort() const {} //is always sorted }; template typename polygon_set_traits >::iterator_type polygon_set_traits >:: begin(const polygon_set_view& polygon_set) { return polygon_set.begin(); } template typename polygon_set_traits >::iterator_type polygon_set_traits >:: end(const polygon_set_view& polygon_set) { return polygon_set.end(); } template bool polygon_set_traits >:: clean(const polygon_set_view& ) { return true; } template bool polygon_set_traits >:: sort(const polygon_set_view& ) { return true; } template inline void insert_into_view_arg(value_type& dest, const arg_type& arg) { typedef typename polygon_set_traits::iterator_type literator; literator itr1, itr2; itr1 = polygon_set_traits::begin(arg); itr2 = polygon_set_traits::end(arg); dest.insert(itr1, itr2); } template geometry_type_1& self_assignment_boolean_op(geometry_type_1& lvalue_, const geometry_type_2& rvalue_) { typedef geometry_type_1 ltype; typedef typename polygon_set_traits::coordinate_type coordinate_type; typedef polygon_set_data value_type; value_type output_; execute_boolean_op(output_, lvalue_, rvalue_); polygon_set_mutable_traits::set(lvalue_, output_.begin(), output_.end()); return lvalue_; } // copy constructor template template polygon_set_data::polygon_set_data(const polygon_set_view& that) : data_(that.value().data_), dirty_(that.value().dirty_), unsorted_(that.value().unsorted_), is_45_(that.value().is_45_) {} template struct geometry_concept > { typedef polygon_set_concept type; }; } } #endif