#include enum orientation_2d_enum { HORIZONTAL = 0, VERTICAL = 1 }; enum direction_1d_enum { LOW = 0, HIGH = 1, }; enum orientation_3d_enum { PROXIMAL = 2 }; class orientation_2d { private: unsigned int val_; explicit orientation_2d(int o); public: orientation_2d() : val_(HORIZONTAL) {} orientation_2d(const orientation_2d& ori) : val_(ori.val_) {} orientation_2d(const orientation_2d_enum val) : val_(val) {} const orientation_2d& operator=(const orientation_2d& ori) { val_ = ori.val_; return * this; } bool operator==(orientation_2d that) const { return (val_ == that.val_); } bool operator!=(orientation_2d that) const { return (val_ != that.val_); } unsigned int to_int() const { return (val_); } }; class direction_1d { private: unsigned int val_; explicit direction_1d(int d); public: direction_1d() { val_ = LOW; } direction_1d(const direction_1d& that) : val_(that.val_) {} direction_1d(const direction_1d_enum val) : val_(val) {} const direction_1d& operator = (const direction_1d& d) { val_ = d.val_; return * this; } bool operator==(direction_1d d) const { return (val_ == d.val_); } bool operator!=(direction_1d d) const { return !((*this) == d); } unsigned int to_int(void) const { return val_; } }; class orientation_3d { private: unsigned int val_; explicit orientation_3d(int o); public: orientation_3d() : val_((int)HORIZONTAL) {} orientation_3d(const orientation_3d& ori) : val_(ori.val_) {} orientation_3d(const orientation_2d& ori) { val_ = ori.to_int(); } orientation_3d(const orientation_2d_enum val) : val_(val) {} orientation_3d(const orientation_3d_enum val) : val_(val) {} ~orientation_3d() { } const orientation_3d& operator=(const orientation_3d& ori) { val_ = ori.val_; return * this; } bool operator==(orientation_3d that) const { return (val_ == that.val_); } bool operator!=(orientation_3d that) const { return (val_ != that.val_); } unsigned int to_int() const { return (val_); } }; template class point_data { public: typedef T coordinate_type; inline point_data(){} inline point_data(coordinate_type x, coordinate_type y) { coords_[HORIZONTAL] = x; coords_[VERTICAL] = y; } inline point_data(const point_data& that) { (*this) = that; } inline point_data& operator=(const point_data& that) { coords_[0] = that.coords_[0]; coords_[1] = that.coords_[1]; return *this; } template inline point_data& operator=(const T2& that); inline coordinate_type get(orientation_2d orient) const { return coords_[orient.to_int()]; } inline void set(orientation_2d orient, coordinate_type value) { coords_[orient.to_int()] = value; } private: coordinate_type coords_[2]; }; template class point_traits { public: typedef typename T::coordinate_type coordinate_type; static inline coordinate_type get(const T& point, orientation_2d orient) { return point.get(orient); } static inline void set(T& point, orientation_2d orient, coordinate_type value) { point.set(orient, value); } static inline T construct(coordinate_type x_value, coordinate_type y_value) { return T(x_value, y_value); } }; template inline bool is_same_point(const T& point1, const T2& point2) { return point_traits::get(point1, HORIZONTAL) == point_traits::get(point2, HORIZONTAL) && point_traits::get(point1, VERTICAL) == point_traits::get(point2, VERTICAL); } template class interval_data { public: typedef T coordinate_type; inline interval_data(){} inline interval_data(coordinate_type low, coordinate_type high) { coords_[LOW] = low; coords_[HIGH] = high; } inline interval_data(const interval_data& that) { (*this) = that; } inline interval_data& operator=(const interval_data& that) { coords_[0] = that.coords_[0]; coords_[1] = that.coords_[1]; return *this; } inline coordinate_type get(direction_1d dir) const { return coords_[dir.to_int()]; } inline void set(direction_1d dir, coordinate_type value) { coords_[dir.to_int()] = value; } private: coordinate_type coords_[2]; }; template class interval_traits { public: typedef typename T::coordinate_type coordinate_type; static inline coordinate_type get(const T& interval, direction_1d dir) { return interval.get(dir); } static inline void set(T& interval, direction_1d dir, coordinate_type value) { interval.set(dir, value); } static inline T construct(coordinate_type low_value, coordinate_type high_value) { return T(low_value, high_value); } }; template class rectangle_data { public: typedef T coordinate_type; inline rectangle_data() {} template inline rectangle_data(const interval_type_1& hrange, const interval_type_2& vrange) { set(HORIZONTAL, hrange); set(VERTICAL, hrange); } inline rectangle_data(const rectangle_data& that) { (*this) = that; } inline rectangle_data& operator=(const rectangle_data& that) { ranges_[0] = that.ranges_[0]; ranges_[1] = that.ranges_[1]; return *this; } inline interval_data get(orientation_2d orient) const { return ranges_[orient.to_int()]; } template inline void set(orientation_2d orient, const interval_type& interval) { ranges_[orient.to_int()].set(LOW, interval_traits::get(interval, LOW)); ranges_[orient.to_int()].set(HIGH, interval_traits::get(interval, HIGH)); } private: interval_data ranges_[2]; }; template T constructIntervalCopy(const T2& interval) { return interval_traits::construct (interval_traits::get(interval, LOW ), interval_traits::get(interval, HIGH)); } template bool is_same_interval(const T& interval1, const T2& interval2) { return interval_traits::get(interval1, LOW) == interval_traits::get(interval2, LOW) && interval_traits::get(interval1, HIGH) == interval_traits::get(interval2, HIGH); } template class rectangle_traits { public: typedef typename T::coordinate_type coordinate_type; typedef interval_data interval_type; static inline interval_type get(const T& rectangle, orientation_2d orient) { return rectangle.get(orient); } template static inline void set(T& rectangle, orientation_2d orient, const T2& interval) { rectangle.set(orient, constructIntervalCopy(interval)); } template static inline T construct(const T2& interval_horizontal, const T3& interval_vertical) { return T(interval_horizontal, interval_vertical); } }; template T constructRectangleCopy(const T2& rectangle) { return rectangle_traits::construct (rectangle_traits::get(rectangle, HORIZONTAL), rectangle_traits::get(rectangle, VERTICAL)); } template bool is_same_rectangle(const T& rect1, const T2& rect2) { return is_same_interval(rectangle_traits::get(rect1, HORIZONTAL), rectangle_traits::get(rect2, HORIZONTAL)) && is_same_interval(rectangle_traits::get(rect1, VERTICAL), rectangle_traits::get(rect2, VERTICAL)); } template class point_3d_data { public: typedef T coordinate_type; inline point_3d_data(){} inline point_3d_data(coordinate_type x, coordinate_type y) { coords_[HORIZONTAL] = x; coords_[VERTICAL] = y; coords_[PROXIMAL] = 0; } inline point_3d_data(coordinate_type x, coordinate_type y, coordinate_type z) { coords_[HORIZONTAL] = x; coords_[VERTICAL] = y; coords_[PROXIMAL] = z; } inline point_3d_data(const point_3d_data& that) { (*this) = that; } inline point_3d_data& operator=(const point_3d_data& that) { coords_[0] = that.coords_[0]; coords_[1] = that.coords_[1]; coords_[2] = that.coords_[2]; return *this; } template inline point_3d_data& operator=(const T2& that); inline coordinate_type get(orientation_3d orient) const { return coords_[orient.to_int()]; } inline void set(orientation_3d orient, coordinate_type value) { coords_[orient.to_int()] = value; } private: coordinate_type coords_[3]; }; template class point_3d_traits { public: typedef typename T::coordinate_type coordinate_type; static inline coordinate_type get(const T& point, orientation_3d orient) { return point.get(orient); } static inline void set(T& point, orientation_3d orient, coordinate_type value) { point.set(orient, value); } static inline T construct(coordinate_type x_value, coordinate_type y_value, coordinate_type z_value) { return T(x_value, y_value, z_value); } }; template template point_data& point_data::operator=(const T2& r_point) { set(HORIZONTAL, point_traits::get(r_point, HORIZONTAL)); set(VERTICAL, point_traits::get(r_point, VERTICAL)); return *this; } template template point_3d_data& point_3d_data::operator=(const T2& r_point) { set(HORIZONTAL, point_3d_traits::get(r_point, HORIZONTAL)); set(VERTICAL, point_3d_traits::get(r_point, VERTICAL)); set(PROXIMAL, point_3d_traits::get(r_point, PROXIMAL)); return *this; } inline bool testPattern() { point_data pt(10, 20); point_data pt2(10, 90); pt = pt2; std::cout << (is_same_point(pt, pt2)) << std::endl; rectangle_data rect1(interval_data(10, 20), interval_data(30, 40)); rectangle_data rect2(interval_data(10, 20), interval_data(30, 40)); rectangle_data rect3 = constructRectangleCopy, rectangle_data >(rect2); point_3d_data pt3d(40, 50, 30); pt = pt3d; pt3d = pt3d; return is_same_point(pt, pt3d); } struct LayoutObject { public: std::string netname; int xl, yl, xh, yh, layer, id; LayoutObject() {} LayoutObject(std::string name, int xl_val, int yl_val, int xh_val, int yh_val, int layer_val, int id_val) : netname(name), xl(xl_val), yl(yl_val), xh(xh_val), yh(yh_val), layer(layer_val), id(id_val) {} LayoutObject& operator=(const LayoutObject& that) { netname = that.netname; xl = that.xl; xh = that.xh; yl = that.yl; yh = that.yh; layer = that.layer; id = that.id; return *this; } }; template <> class rectangle_traits { public: typedef int coordinate_type; typedef interval_data interval_type; static inline interval_type get(const LayoutObject& rectangle, orientation_2d orient) { if(orient == orientation_2d(HORIZONTAL)) return interval_type(rectangle.xl, rectangle.xh); return interval_type(rectangle.yl, rectangle.yh); } template static inline void set(LayoutObject& rectangle, orientation_2d orient, const T2& interval) { if(orient == orientation_2d(HORIZONTAL)) { rectangle.xl = interval_traits::get(LOW); rectangle.xh = interval_traits::get(HIGH); } else { rectangle.yl = interval_traits::get(LOW); rectangle.yh = interval_traits::get(HIGH); } } template static inline LayoutObject construct(const T2& interval_horizontal, const T3& interval_vertical) { return LayoutObject("", interval_traits::get(interval_horizontal, LOW), interval_traits::get(interval_vertical, LOW), interval_traits::get(interval_horizontal, HIGH), interval_traits::get(interval_vertical, HIGH), 0, 0); } }; int main() { std::cout << testPattern() << std::endl; rectangle_data rect(interval_data(10, 20), interval_data(30, 40)); LayoutObject lobj = constructRectangleCopy >(rect); std::cout << (is_same_rectangle(rect, lobj)) << std::endl; std::cout << (is_same_interval(rectangle_traits::get(lobj, HORIZONTAL), rect.get(HORIZONTAL))) << std::endl; return 0; }