From: Mikko Rasa Date: Wed, 22 May 2013 13:14:16 +0000 (+0300) Subject: Rewrite composite shape vector constructors with iterator ranges X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=f7dcf3f0be55316bf20ac0c318dd90cb78a75c80;p=libs%2Fmath.git Rewrite composite shape vector constructors with iterator ranges Besides the issue of favoring one container type over others, constness of the contents causes it to be a different, incompatible type. Iterators solve this in an elegant way. --- diff --git a/source/geometry/compositeshape.h b/source/geometry/compositeshape.h index 9476f99..50075d9 100644 --- a/source/geometry/compositeshape.h +++ b/source/geometry/compositeshape.h @@ -1,6 +1,7 @@ #ifndef MSP_GEOMETRY_COMPOSITESHAPE_H_ #define MSP_GEOMETRY_COMPOSITESHAPE_H_ +#include #include #include "shape.h" @@ -19,10 +20,12 @@ protected: ShapeArray shapes; + CompositeShape() { } CompositeShape(const Shape &, const Shape &); - CompositeShape(const ShapeArray &); CompositeShape(const CompositeShape &); CompositeShape &operator=(const CompositeShape &); + template + void init_from_iter_range(const Iter &, const Iter &); public: virtual ~CompositeShape(); @@ -41,13 +44,21 @@ inline CompositeShape::CompositeShape(const Shape &s1, const Shap } template -inline CompositeShape::CompositeShape(const ShapeArray &s) +template +inline void CompositeShape::init_from_iter_range(const Iter &begin, const Iter &end) { - if(s.empty()) - throw std::invalid_argument("CompositeShape::CompositeShape"); + if(begin==end) + throw std::invalid_argument("CompositeShape::init_from_iter_range"); - shapes.reserve(s.size()); - for(typename ShapeArray::const_iterator i=s.begin(); i!=s.end(); ++i) + for(Iter i=begin; i!=end; ++i) + shapes.push_back((*i)->clone()); +} + +template +inline CompositeShape::CompositeShape(const CompositeShape &other) +{ + shapes.reserve(other.shapes.size()); + for(typename ShapeArray::const_iterator i=other.shapes.begin(); i!=other.shapes.end(); ++i) shapes.push_back((*i)->clone()); } diff --git a/source/geometry/intersection.h b/source/geometry/intersection.h index 53c25c2..c20aae1 100644 --- a/source/geometry/intersection.h +++ b/source/geometry/intersection.h @@ -23,27 +23,35 @@ struct IntersectionOps template class Intersection: public CompositeShape > { +private: + Intersection() { } public: Intersection(const Shape &, const Shape &); - Intersection(const std::vector *> &); + + template + static Intersection from_iterator_range(const Iter &, const Iter &); virtual Intersection *clone() const; }; template -Intersection::Intersection(const Shape &s1, const Shape &s2): +inline Intersection::Intersection(const Shape &s1, const Shape &s2): CompositeShape >(s1, s2) { } template -Intersection::Intersection(const std::vector *> &s): - CompositeShape >(s) -{ } +template +inline Intersection Intersection::from_iterator_range(const Iter &begin, const Iter &end) +{ + Intersection shape; + shape.init_from_iter_range(begin, end); + return shape; +} template -Intersection *Intersection::clone() const +inline Intersection *Intersection::clone() const { - return new Intersection(this->shapes); + return new Intersection(*this); } diff --git a/source/geometry/union.h b/source/geometry/union.h index fadeff2..13eb708 100644 --- a/source/geometry/union.h +++ b/source/geometry/union.h @@ -23,9 +23,13 @@ struct UnionOps template class Union: public CompositeShape > { +private: + Union() { } public: Union(const Shape &, const Shape &); - Union(const std::vector *> &); + + template + static Union from_iterator_range(const Iter &, const Iter &); virtual Union *clone() const; }; @@ -36,14 +40,18 @@ inline Union::Union(const Shape &s1, const Shape &s2): { } template -inline Union::Union(const std::vector *> &s): - CompositeShape >(s) -{ } +template +inline Union Union::from_iterator_range(const Iter &begin, const Iter &end) +{ + Union shape; + shape.init_from_iter_range(begin, end); + return shape; +} template inline Union *Union::clone() const { - return new Union(this->shapes); + return new Union(*this); }