From 385709d739bf6cc29c933d533868f011ebc9fd73 Mon Sep 17 00:00:00 2001 From: mental Date: Fri, 9 Mar 2007 00:25:51 +0000 Subject: [PATCH] specialize MaybeStorage for Rect, and start using reference maybes to avoid some copies --- src/libnr/nr-rect.cpp | 4 +- src/libnr/nr-rect.h | 81 ++++++++++++++++++++-------------- src/selection-chemistry.cpp | 2 +- src/selection.cpp | 2 +- src/ui/view/edit-widget.cpp | 2 +- src/widgets/desktop-widget.cpp | 2 +- 6 files changed, 55 insertions(+), 38 deletions(-) diff --git a/src/libnr/nr-rect.cpp b/src/libnr/nr-rect.cpp index 21d3f470a..9047e4e1c 100644 --- a/src/libnr/nr-rect.cpp +++ b/src/libnr/nr-rect.cpp @@ -284,7 +284,7 @@ void Rect::expandTo(Point p) { } /** Returns the set of points shared by both rectangles. */ -Maybe Rect::intersection(Maybe const &a, Maybe const &b) { +Maybe intersection(Maybe a, Maybe b) { if ( !a || !b ) { return Nothing(); } else { @@ -301,7 +301,7 @@ Maybe Rect::intersection(Maybe const &a, Maybe const &b) { } /** returns the smallest rectangle containing both rectangles */ -Rect Rect::union_bounds(Rect const &a, Rect const &b) { +Rect union_bounds(Rect const &a, Rect const &b) { Rect r; for ( int i=0 ; i < 2 ; i++ ) { r._min[i] = MIN(a._min[i], b._min[i]); diff --git a/src/libnr/nr-rect.h b/src/libnr/nr-rect.h index dd7caa897..5e2332bf2 100644 --- a/src/libnr/nr-rect.h +++ b/src/libnr/nr-rect.h @@ -125,36 +125,6 @@ public: _max[NR::Y] += by; } - /** Returns the set of points shared by both rectangles. */ - static Maybe intersection(Maybe const &a, Maybe const &b); - - /** Returns the smallest rectangle that encloses both rectangles. */ - static Maybe union_bounds(Maybe const &a, Maybe const &b) - { - if (!a) { - return b; - } else if (!b) { - return a; - } else { - return union_bounds(*a, *b); - } - } - static Rect union_bounds(Maybe const &a, Rect const &b) { - if (a) { - return union_bounds(*a, b); - } else { - return b; - } - } - static Rect union_bounds(Rect const &a, Maybe const &b) { - if (b) { - return union_bounds(a, *b); - } else { - return a; - } - } - static Rect union_bounds(Rect const &a, Rect const &b); - /** Scales the rect by s, with origin at 0, 0 */ inline Rect operator*(double const s) const { return Rect(s * min(), s * max()); @@ -172,6 +142,8 @@ public: friend inline std::ostream &operator<<(std::ostream &out_file, NR::Rect const &in_rect); private: + Rect(Nothing) : _min(1, 1), _max(-1, -1) {} + static double _inf() { return std::numeric_limits::infinity(); } @@ -203,10 +175,55 @@ private: Point _min, _max; - /* evil, but temporary */ - friend class Maybe; + friend class MaybeStorage; }; +template <> +class MaybeStorage { +public: + MaybeStorage() : _rect(Nothing()) {} + MaybeStorage(Rect const &rect) : _rect(rect) {} + + bool is_nothing() const { + return _rect._min[X] > _rect._max[X]; + } + Rect const &value() const { return _rect; } + Rect &value() { return _rect; } + +private: + Rect _rect; +}; + +/** Returns the set of points shared by both rectangles. */ +Maybe intersection(Maybe a, Maybe b); + +/** Returns the smallest rectangle that encloses both rectangles. */ +Rect union_bounds(Rect const &a, Rect const &b); +inline Rect union_bounds(Maybe a, Rect const &b) { + if (a) { + return union_bounds(*a, b); + } else { + return b; + } +} +inline Rect union_bounds(Rect const &a, Maybe b) { + if (b) { + return union_bounds(a, *b); + } else { + return a; + } +} +inline Maybe union_bounds(Maybe a, Maybe b) +{ + if (!a) { + return b; + } else if (!b) { + return a; + } else { + return union_bounds(*a, *b); + } +} + /** A function to print out the rectange if sent to an output stream. */ inline std::ostream diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 57fa6bb84..a65c9b290 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -598,7 +598,7 @@ enclose_items(const GSList *items) NR::Maybe r = NR::Nothing(); for (GSList const *i = items; i; i = i->next) { - r = NR::Rect::union_bounds(r, sp_item_bbox_desktop((SPItem *) i->data)); + r = NR::union_bounds(r, sp_item_bbox_desktop((SPItem *) i->data)); } return r; } diff --git a/src/selection.cpp b/src/selection.cpp index 5c60e5f41..49934cfd3 100644 --- a/src/selection.cpp +++ b/src/selection.cpp @@ -320,7 +320,7 @@ NR::Rect Selection::bounds() const NR::Maybe bbox = NR::Nothing(); for ( GSList const *i = items ; i != NULL ; i = i->next ) { - bbox = NR::Rect::union_bounds(bbox, sp_item_bbox_desktop(SP_ITEM(i->data))); + bbox = NR::union_bounds(bbox, sp_item_bbox_desktop(SP_ITEM(i->data))); } // TODO: return NR::Maybe diff --git a/src/ui/view/edit-widget.cpp b/src/ui/view/edit-widget.cpp index 78e706a25..f386aefcc 100644 --- a/src/ui/view/edit-widget.cpp +++ b/src/ui/view/edit-widget.cpp @@ -1395,7 +1395,7 @@ EditWidget::updateScrollbars (double scale) NR::Rect const viewbox = _svg_canvas.spobj()->getViewbox(); /* Viewbox is always included into scrollable region */ - carea = NR::Rect::union_bounds(carea, viewbox); + carea = NR::union_bounds(carea, viewbox); Gtk::Adjustment *adj = _bottom_scrollbar.get_adjustment(); adj->set_value(viewbox.min()[NR::X]); diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index eb813a2a2..76313f771 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -1289,7 +1289,7 @@ sp_desktop_widget_update_scrollbars (SPDesktopWidget *dtw, double scale) NR::Rect viewbox = dtw->canvas->getViewbox(); /* Viewbox is always included into scrollable region */ - carea = NR::Rect::union_bounds(carea, viewbox); + carea = NR::union_bounds(carea, viewbox); set_adjustment(dtw->hadj, carea.min()[NR::X], carea.max()[NR::X], viewbox.dimensions()[NR::X], -- 2.30.2