Chris@16: /* Chris@16: Copyright 2008 Intel Corporation Chris@16: Chris@16: Use, modification and distribution are subject to the Boost Software License, Chris@16: Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: http://www.boost.org/LICENSE_1_0.txt). Chris@16: */ Chris@16: #ifndef BOOST_POLYGON_POLYGON_90_SET_VIEW_HPP Chris@16: #define BOOST_POLYGON_POLYGON_90_SET_VIEW_HPP Chris@16: namespace boost { namespace polygon{ Chris@16: struct operator_provides_storage {}; Chris@16: struct operator_requires_copy {}; Chris@16: Chris@16: template Chris@16: inline void insert_into_view_arg(value_type& dest, const arg_type& arg, orientation_2d orient); Chris@16: Chris@16: template Chris@16: class polygon_90_set_view; Chris@16: Chris@16: template Chris@16: struct polygon_90_set_traits > { Chris@16: typedef typename polygon_90_set_view::coordinate_type coordinate_type; Chris@16: typedef typename polygon_90_set_view::iterator_type iterator_type; Chris@16: typedef typename polygon_90_set_view::operator_arg_type operator_arg_type; Chris@16: Chris@16: static inline iterator_type begin(const polygon_90_set_view& polygon_set); Chris@16: static inline iterator_type end(const polygon_90_set_view& polygon_set); Chris@16: Chris@16: static inline orientation_2d orient(const polygon_90_set_view& polygon_set); Chris@16: Chris@16: static inline bool clean(const polygon_90_set_view& polygon_set); Chris@16: Chris@16: static inline bool sorted(const polygon_90_set_view& polygon_set); Chris@16: }; Chris@16: Chris@16: template Chris@16: struct compute_90_set_value { Chris@16: static Chris@16: void value(value_type& output_, const ltype& lvalue_, const rtype& rvalue_, orientation_2d orient_) { Chris@16: value_type linput_(orient_); Chris@16: value_type rinput_(orient_); Chris@16: orientation_2d orient_l = polygon_90_set_traits::orient(lvalue_); Chris@16: orientation_2d orient_r = polygon_90_set_traits::orient(rvalue_); Chris@16: //std::cout << "compute_90_set_value-0 orientations (left, right, out):\t" << orient_l.to_int() Chris@16: // << "," << orient_r.to_int() << "," << orient_.to_int() << std::endl; Chris@16: insert_into_view_arg(linput_, lvalue_, orient_l); Chris@16: insert_into_view_arg(rinput_, rvalue_, orient_r); Chris@16: output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(), Chris@16: rinput_.begin(), rinput_.end(), boolean_op::BinaryCount()); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct compute_90_set_value, polygon_90_set_data, op_type> { Chris@16: static Chris@16: void value(value_type& output_, const polygon_90_set_data& lvalue_, Chris@16: const polygon_90_set_data& rvalue_, orientation_2d orient_) { Chris@16: orientation_2d orient_l = lvalue_.orient(); Chris@16: orientation_2d orient_r = rvalue_.orient(); Chris@16: value_type linput_(orient_); Chris@16: value_type rinput_(orient_); Chris@16: //std::cout << "compute_90_set_value-1 orientations (left, right, out):\t" << orient_l.to_int() Chris@16: // << "," << orient_r.to_int() << "," << orient_.to_int() << std::endl; Chris@16: if((orient_ == orient_l) && (orient_== orient_r)){ // assume that most of the time this condition is met Chris@16: lvalue_.sort(); Chris@16: rvalue_.sort(); Chris@16: output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(), Chris@16: rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount()); Chris@16: }else if((orient_ != orient_l) && (orient_!= orient_r)){ // both the orientations are not equal to input Chris@16: // easier way is to ignore the input orientation and use the input data's orientation, but not done so Chris@16: insert_into_view_arg(linput_, lvalue_, orient_l); Chris@16: insert_into_view_arg(rinput_, rvalue_, orient_r); Chris@16: output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(), Chris@16: rinput_.begin(), rinput_.end(), boolean_op::BinaryCount()); Chris@16: }else if(orient_ != orient_l){ // left hand side orientation is different Chris@16: insert_into_view_arg(linput_, lvalue_, orient_l); Chris@16: rvalue_.sort(); Chris@16: output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(), Chris@16: rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount()); Chris@16: } else if(orient_ != orient_r){ // right hand side orientation is different Chris@16: insert_into_view_arg(rinput_, rvalue_, orient_r); Chris@16: lvalue_.sort(); Chris@16: output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(), Chris@16: rinput_.begin(), rinput_.end(), boolean_op::BinaryCount()); Chris@16: } Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct compute_90_set_value, rtype, op_type> { Chris@16: static Chris@16: void value(value_type& output_, const polygon_90_set_data& lvalue_, Chris@16: const rtype& rvalue_, orientation_2d orient_) { Chris@16: value_type rinput_(orient_); Chris@16: lvalue_.sort(); Chris@16: orientation_2d orient_r = polygon_90_set_traits::orient(rvalue_); Chris@16: //std::cout << "compute_90_set_value-2 orientations (right, out):\t" << orient_r.to_int() Chris@16: // << "," << orient_.to_int() << std::endl; Chris@16: insert_into_view_arg(rinput_, rvalue_, orient_r); Chris@16: output_.applyBooleanBinaryOp(lvalue_.begin(), lvalue_.end(), Chris@16: rinput_.begin(), rinput_.end(), boolean_op::BinaryCount()); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct compute_90_set_value, op_type> { Chris@16: static Chris@16: void value(value_type& output_, const ltype& lvalue_, Chris@16: const polygon_90_set_data& rvalue_, orientation_2d orient_) { Chris@16: value_type linput_(orient_); Chris@16: orientation_2d orient_l = polygon_90_set_traits::orient(lvalue_); Chris@16: insert_into_view_arg(linput_, lvalue_, orient_l); Chris@16: rvalue_.sort(); Chris@16: //std::cout << "compute_90_set_value-3 orientations (left, out):\t" << orient_l.to_int() Chris@16: // << "," << orient_.to_int() << std::endl; Chris@16: Chris@16: output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(), Chris@16: rvalue_.begin(), rvalue_.end(), boolean_op::BinaryCount()); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: class polygon_90_set_view { Chris@16: public: Chris@16: typedef typename polygon_90_set_traits::coordinate_type coordinate_type; Chris@16: typedef polygon_90_set_data value_type; Chris@16: typedef typename value_type::iterator_type iterator_type; Chris@16: typedef polygon_90_set_view operator_arg_type; Chris@16: private: Chris@16: const ltype& lvalue_; Chris@16: const rtype& rvalue_; Chris@16: orientation_2d orient_; Chris@16: op_type op_; Chris@16: mutable value_type output_; Chris@16: mutable bool evaluated_; Chris@16: polygon_90_set_view& operator=(const polygon_90_set_view&); Chris@16: public: Chris@16: polygon_90_set_view(const ltype& lvalue, Chris@16: const rtype& rvalue, Chris@16: orientation_2d orient, Chris@16: op_type op) : Chris@16: lvalue_(lvalue), rvalue_(rvalue), orient_(orient), op_(op), output_(orient), evaluated_(false) {} Chris@16: Chris@16: // get iterator to begin vertex data Chris@16: private: Chris@16: const value_type& value() const { Chris@16: if(!evaluated_) { Chris@16: evaluated_ = true; Chris@16: compute_90_set_value::value(output_, lvalue_, rvalue_, orient_); Chris@16: } Chris@16: return output_; Chris@16: } Chris@16: public: Chris@16: iterator_type begin() const { return value().begin(); } Chris@16: iterator_type end() const { return value().end(); } Chris@16: Chris@16: orientation_2d orient() const { return orient_; } Chris@16: bool dirty() const { return false; } //result of a boolean is clean Chris@16: bool sorted() const { return true; } //result of a boolean is sorted Chris@16: Chris@16: // template Chris@16: // void set(input_iterator_type input_begin, input_iterator_type input_end, Chris@16: // orientation_2d orient) const { Chris@16: // orient_ = orient; Chris@16: // output_.clear(); Chris@16: // output_.insert(output_.end(), input_begin, input_end); Chris@16: // polygon_sort(output_.begin(), output_.end()); Chris@16: // } Chris@16: void sort() const {} //is always sorted Chris@16: }; Chris@16: Chris@16: template Chris@16: struct geometry_concept > { Chris@16: typedef polygon_90_set_concept type; Chris@16: }; Chris@16: Chris@16: template Chris@16: typename polygon_90_set_traits >::iterator_type Chris@16: polygon_90_set_traits >:: Chris@16: begin(const polygon_90_set_view& polygon_set) { Chris@16: return polygon_set.begin(); Chris@16: } Chris@16: template Chris@16: typename polygon_90_set_traits >::iterator_type Chris@16: polygon_90_set_traits >:: Chris@16: end(const polygon_90_set_view& polygon_set) { Chris@16: return polygon_set.end(); Chris@16: } Chris@16: // template Chris@16: // template Chris@16: // void polygon_90_set_traits >:: Chris@16: // set(polygon_90_set_view& polygon_set, Chris@16: // input_iterator_type input_begin, input_iterator_type input_end, Chris@16: // orientation_2d orient) { Chris@16: // polygon_set.set(input_begin, input_end, orient); Chris@16: // } Chris@16: template Chris@16: orientation_2d polygon_90_set_traits >:: Chris@16: orient(const polygon_90_set_view& polygon_set) { Chris@16: return polygon_set.orient(); } Chris@16: template Chris@16: bool polygon_90_set_traits >:: Chris@16: clean(const polygon_90_set_view& polygon_set) { Chris@16: return true; } Chris@16: template Chris@16: bool polygon_90_set_traits >:: Chris@16: sorted(const polygon_90_set_view& polygon_set) { Chris@16: return true; } Chris@16: Chris@16: template Chris@16: inline void insert_into_view_arg(value_type& dest, const arg_type& arg, orientation_2d orient) { Chris@16: typedef typename polygon_90_set_traits::iterator_type literator; Chris@16: literator itr1, itr2; Chris@16: itr1 = polygon_90_set_traits::begin(arg); Chris@16: itr2 = polygon_90_set_traits::end(arg); Chris@16: dest.insert(itr1, itr2, orient); Chris@16: dest.sort(); Chris@16: } Chris@16: Chris@16: template Chris@16: template Chris@16: inline polygon_90_set_data& polygon_90_set_data::operator=(const polygon_90_set_view& that) { Chris@16: set(that.begin(), that.end(), that.orient()); Chris@16: dirty_ = false; Chris@16: unsorted_ = false; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: template Chris@16: template Chris@16: inline polygon_90_set_data::polygon_90_set_data(const polygon_90_set_view& that) : Chris@16: orient_(that.orient()), data_(that.begin(), that.end()), dirty_(false), unsorted_(false) {} Chris@16: Chris@16: template Chris@16: struct self_assign_operator_lvalue { Chris@16: typedef geometry_type_1& type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct by_value_binary_operator { Chris@16: typedef type_1 type; Chris@16: }; Chris@16: Chris@16: template Chris@16: geometry_type_1& self_assignment_boolean_op(geometry_type_1& lvalue_, const geometry_type_2& rvalue_) { Chris@16: typedef geometry_type_1 ltype; Chris@16: typedef geometry_type_2 rtype; Chris@16: typedef typename polygon_90_set_traits::coordinate_type coordinate_type; Chris@16: typedef polygon_90_set_data value_type; Chris@16: orientation_2d orient_ = polygon_90_set_traits::orient(lvalue_); Chris@16: //BM: rvalue_ data set may have its own orientation for scanline Chris@16: orientation_2d orient_r = polygon_90_set_traits::orient(rvalue_); Chris@16: //std::cout << "self-assignment boolean-op (left, right, out):\t" << orient_.to_int() Chris@16: // << "," << orient_r.to_int() << "," << orient_.to_int() << std::endl; Chris@16: value_type linput_(orient_); Chris@16: // BM: the rinput_ set's (that stores the rvalue_ dataset polygons) scanline orientation is *forced* Chris@16: // to be same as linput Chris@16: value_type rinput_(orient_); Chris@16: //BM: The output dataset's scanline orient is set as equal to first input dataset's (lvalue_) orientation Chris@16: value_type output_(orient_); Chris@16: insert_into_view_arg(linput_, lvalue_, orient_); Chris@16: // BM: The last argument orient_r is the user initialized scanline orientation for rvalue_ data set. Chris@16: // But since rinput (see above) is initialized to scanline orientation consistent with the lvalue_ Chris@16: // data set, this insertion operation will change the incoming rvalue_ dataset's scanline orientation Chris@16: insert_into_view_arg(rinput_, rvalue_, orient_r); Chris@16: // BM: boolean operation and output uses lvalue_ dataset's scanline orientation. Chris@16: output_.applyBooleanBinaryOp(linput_.begin(), linput_.end(), Chris@16: rinput_.begin(), rinput_.end(), boolean_op::BinaryCount()); Chris@16: polygon_90_set_mutable_traits::set(lvalue_, output_.begin(), output_.end(), orient_); Chris@16: return lvalue_; Chris@16: } Chris@16: Chris@16: namespace operators { Chris@16: struct y_ps90_b : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3< y_ps90_b, Chris@16: typename is_polygon_90_set_type::type, Chris@16: typename is_polygon_90_set_type::type>::type, Chris@16: polygon_90_set_view >::type Chris@16: operator|(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { Chris@16: return polygon_90_set_view Chris@16: (lvalue, rvalue, Chris@16: polygon_90_set_traits::orient(lvalue), Chris@16: boolean_op::BinaryOr()); Chris@16: } Chris@16: Chris@16: struct y_ps90_p : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< Chris@16: typename gtl_and_3< y_ps90_p, Chris@16: typename gtl_if::type>::type, Chris@16: typename gtl_if::type>::type>::type, Chris@16: polygon_90_set_view >::type Chris@16: operator+(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { Chris@16: return polygon_90_set_view Chris@16: (lvalue, rvalue, Chris@16: polygon_90_set_traits::orient(lvalue), Chris@16: boolean_op::BinaryOr()); Chris@16: } Chris@16: Chris@16: struct y_ps90_s : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3< y_ps90_s, Chris@16: typename is_polygon_90_set_type::type, Chris@16: typename is_polygon_90_set_type::type>::type, Chris@16: polygon_90_set_view >::type Chris@16: operator*(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { Chris@16: return polygon_90_set_view Chris@16: (lvalue, rvalue, Chris@16: polygon_90_set_traits::orient(lvalue), Chris@16: boolean_op::BinaryAnd()); Chris@16: } Chris@16: Chris@16: struct y_ps90_a : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3< y_ps90_a, Chris@16: typename is_polygon_90_set_type::type, Chris@16: typename is_polygon_90_set_type::type>::type, Chris@16: polygon_90_set_view >::type Chris@16: operator&(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { Chris@16: return polygon_90_set_view Chris@16: (lvalue, rvalue, Chris@16: polygon_90_set_traits::orient(lvalue), Chris@16: boolean_op::BinaryAnd()); Chris@16: } Chris@16: Chris@16: struct y_ps90_x : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3< y_ps90_x, Chris@16: typename is_polygon_90_set_type::type, Chris@16: typename is_polygon_90_set_type::type>::type, Chris@16: polygon_90_set_view >::type Chris@16: operator^(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { Chris@16: return polygon_90_set_view Chris@16: (lvalue, rvalue, Chris@16: polygon_90_set_traits::orient(lvalue), Chris@16: boolean_op::BinaryXor()); Chris@16: } Chris@16: Chris@16: struct y_ps90_m : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3< y_ps90_m, Chris@16: typename gtl_if::type>::type, Chris@16: typename gtl_if::type>::type>::type, Chris@16: polygon_90_set_view >::type Chris@16: operator-(const geometry_type_1& lvalue, const geometry_type_2& rvalue) { Chris@16: return polygon_90_set_view Chris@16: (lvalue, rvalue, Chris@16: polygon_90_set_traits::orient(lvalue), Chris@16: boolean_op::BinaryNot()); Chris@16: } Chris@16: Chris@16: struct y_ps90_pe : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and< y_ps90_pe, typename is_polygon_90_set_type::type>::type, Chris@16: polygon_90_set_data >::type & Chris@16: operator+=(polygon_90_set_data& lvalue, const geometry_type_2& rvalue) { Chris@16: lvalue.insert(polygon_90_set_traits::begin(rvalue), polygon_90_set_traits::end(rvalue), Chris@16: polygon_90_set_traits::orient(rvalue)); Chris@16: return lvalue; Chris@16: } Chris@16: Chris@16: struct y_ps90_be : gtl_yes {}; Chris@16: // Chris@16: template Chris@16: typename enable_if< typename gtl_and< y_ps90_be, typename is_polygon_90_set_type::type>::type, Chris@16: polygon_90_set_data >::type & Chris@16: operator|=(polygon_90_set_data& lvalue, const geometry_type_2& rvalue) { Chris@16: return lvalue += rvalue; Chris@16: } Chris@16: Chris@16: struct y_ps90_pe2 : gtl_yes {}; Chris@16: Chris@16: //normal self assignment boolean operations Chris@16: template Chris@16: typename enable_if< typename gtl_and_3< y_ps90_pe2, typename is_mutable_polygon_90_set_type::type, Chris@16: typename is_polygon_90_set_type::type>::type, Chris@16: geometry_type_1>::type & Chris@16: operator+=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { Chris@16: return self_assignment_boolean_op(lvalue, rvalue); Chris@16: } Chris@16: Chris@16: struct y_ps90_be2 : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type, Chris@16: typename is_polygon_90_set_type::type>::type, Chris@16: geometry_type_1>::type & Chris@16: operator|=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { Chris@16: return self_assignment_boolean_op(lvalue, rvalue); Chris@16: } Chris@16: Chris@16: struct y_ps90_se : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type, Chris@16: typename is_polygon_90_set_type::type>::type, Chris@16: geometry_type_1>::type & Chris@16: operator*=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { Chris@16: return self_assignment_boolean_op(lvalue, rvalue); Chris@16: } Chris@16: Chris@16: struct y_ps90_ae : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type, Chris@16: typename is_polygon_90_set_type::type>::type, Chris@16: geometry_type_1>::type & Chris@16: operator&=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { Chris@16: return self_assignment_boolean_op(lvalue, rvalue); Chris@16: } Chris@16: Chris@16: struct y_ps90_xe : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type, Chris@16: typename is_polygon_90_set_type::type>::type, Chris@16: geometry_type_1>::type & Chris@16: operator^=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { Chris@16: return self_assignment_boolean_op(lvalue, rvalue); Chris@16: } Chris@16: Chris@16: struct y_ps90_me : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3< y_ps90_me, typename is_mutable_polygon_90_set_type::type, Chris@16: typename is_polygon_90_set_type::type>::type, Chris@16: geometry_type_1>::type & Chris@16: operator-=(geometry_type_1& lvalue, const geometry_type_2& rvalue) { Chris@16: return self_assignment_boolean_op(lvalue, rvalue); Chris@16: } Chris@16: Chris@16: struct y_ps90_rpe : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type, Chris@16: typename gtl_same_type::type, coordinate_concept>::type>::type, Chris@16: geometry_type_1>::type & Chris@16: operator+=(geometry_type_1& lvalue, coordinate_type_1 rvalue) { Chris@16: return resize(lvalue, rvalue); Chris@16: } Chris@16: Chris@16: struct y_ps90_rme : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type, Chris@16: typename gtl_same_type::type, coordinate_concept>::type>::type, Chris@16: geometry_type_1>::type & Chris@16: operator-=(geometry_type_1& lvalue, coordinate_type_1 rvalue) { Chris@16: return resize(lvalue, -rvalue); Chris@16: } Chris@16: Chris@16: struct y_ps90_rp : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename gtl_if::type, coordinate_concept>::type>::type>::type, Chris@16: geometry_type_1>::type Chris@16: operator+(const geometry_type_1& lvalue, coordinate_type_1 rvalue) { Chris@16: geometry_type_1 retval(lvalue); Chris@16: retval += rvalue; Chris@16: return retval; Chris@16: } Chris@16: Chris@16: struct y_ps90_rm : gtl_yes {}; Chris@16: Chris@16: template Chris@16: typename enable_if< typename gtl_and_3::type>::type, Chris@16: typename gtl_if::type, coordinate_concept>::type>::type>::type, Chris@16: geometry_type_1>::type Chris@16: operator-(const geometry_type_1& lvalue, coordinate_type_1 rvalue) { Chris@16: geometry_type_1 retval(lvalue); Chris@16: retval -= rvalue; Chris@16: return retval; Chris@16: } Chris@16: } Chris@16: } Chris@16: } Chris@16: #endif