From: Mikko Rasa Date: Sun, 26 Jan 2025 00:00:50 +0000 (+0200) Subject: Use unique_ptr for managing memory allocations X-Git-Url: https://git.tdb.fi/?a=commitdiff_plain;h=896e8440e8c32443fc3fa5272abbac264177437c;p=libs%2Fmath.git Use unique_ptr for managing memory allocations --- diff --git a/Build b/Build index 2795c66..c1c5d2e 100644 --- a/Build +++ b/Build @@ -6,7 +6,7 @@ package "mspmath" build_info { - standard CXX "c++11"; + standard CXX "c++14"; }; if_arch "linux" diff --git a/examples/raytrace.cpp b/examples/raytrace.cpp index 7827bd3..bed9b1b 100644 --- a/examples/raytrace.cpp +++ b/examples/raytrace.cpp @@ -11,7 +11,7 @@ using namespace Msp; class RayTracer: public RegisteredApplication { private: - Geometry::Shape *shape; + std::unique_ptr> shape; unsigned width; unsigned height; string filename; @@ -28,7 +28,6 @@ private: RayTracer::RayTracer(int argc, char **argv): - shape(0), width(500), height(500), pixels(new UInt8[width*height]) @@ -42,7 +41,6 @@ RayTracer::RayTracer(int argc, char **argv): RayTracer::~RayTracer() { - delete shape; delete[] pixels; } @@ -89,5 +87,5 @@ void RayTracer::load_shape() DataFile::Parser parser(in, filename); Geometry::Loader loader; loader.load(parser); - shape = loader.get_shape().clone(); + shape = loader.take_shape(); } diff --git a/source/geometry/compositeshape.h b/source/geometry/compositeshape.h index 012c390..8814ce0 100644 --- a/source/geometry/compositeshape.h +++ b/source/geometry/compositeshape.h @@ -2,6 +2,7 @@ #define MSP_GEOMETRY_COMPOSITESHAPE_H_ #include +#include #include #include #include "shape.h" @@ -17,7 +18,7 @@ class CompositeShape: public Shape { protected: typedef O Ops; - typedef std::vector *> ShapeArray; + typedef std::vector>> ShapeArray; ShapeArray shapes; unsigned max_isect; @@ -31,9 +32,8 @@ private: protected: CompositeShape(const CompositeShape &); CompositeShape &operator=(const CompositeShape &); -public: - ~CompositeShape() override; +public: BoundingBox get_axis_aligned_bounding_box(unsigned = 0) const override; bool contains(const LinAl::Vector &) const override; unsigned get_max_ray_intersections() const override { return max_isect; } @@ -66,39 +66,28 @@ template inline void CompositeShape::init() { max_isect = 0; - for(Shape *s: shapes) + for(const std::unique_ptr> &s: shapes) max_isect += s->get_max_ray_intersections(); } template inline CompositeShape::CompositeShape(const CompositeShape &other): - shapes(other.shapes), max_isect(other.max_isect) { - for(Shape *&s: shapes) - s = s->clone(); + for(const std::unique_ptr> &s: other.shapes) + shapes.push_back(s->clone()); } template inline CompositeShape &CompositeShape::operator=(const CompositeShape &other) { - for(Shape *s: shapes) - delete s; - - shapes = other.shapes; - for(Shape *&s: shapes) - s = s->clone(); + shapes.clear(); + for(const std::unique_ptr> &s: shapes) + shapes.push_back(s->clone()); max_isect = other.max_isect; } -template -inline CompositeShape::~CompositeShape() -{ - for(Shape *s: shapes) - delete s; -} - template inline BoundingBox CompositeShape::get_axis_aligned_bounding_box(unsigned detail) const { @@ -120,7 +109,7 @@ template inline bool CompositeShape::contains(const LinAl::Vector &point) const { bool inside = false; - for(Shape *s: shapes) + for(const std::unique_ptr> &s: shapes) { inside = s->contains(point); if(Ops::shortcircuit(inside)) diff --git a/source/geometry/extrudedshape.h b/source/geometry/extrudedshape.h index 027e4f5..f453a9c 100644 --- a/source/geometry/extrudedshape.h +++ b/source/geometry/extrudedshape.h @@ -17,16 +17,15 @@ template class ExtrudedShape: public Shape { private: - Shape *base = nullptr; + std::unique_ptr> base; T length = T(1); public: ExtrudedShape(const Shape &, T); ExtrudedShape(const ExtrudedShape &); ExtrudedShape &operator=(const ExtrudedShape &); - ~ExtrudedShape() override; - ExtrudedShape *clone() const override; + std::unique_ptr> clone() const override; const Shape &get_base() const { return *base; } T get_length() const { return length; } @@ -57,21 +56,14 @@ inline ExtrudedShape::ExtrudedShape(const ExtrudedShape &other): template inline ExtrudedShape &ExtrudedShape::operator=(const ExtrudedShape &other) { - delete base; base = other.base->clone(); length = other.length; } template -inline ExtrudedShape::~ExtrudedShape() +inline std::unique_ptr> ExtrudedShape::clone() const { - delete base; -} - -template -inline ExtrudedShape *ExtrudedShape::clone() const -{ - return new ExtrudedShape(*base, length); + return std::make_unique>(*base, length); } template diff --git a/source/geometry/halfspace.h b/source/geometry/halfspace.h index 5271bd6..8753198 100644 --- a/source/geometry/halfspace.h +++ b/source/geometry/halfspace.h @@ -20,7 +20,7 @@ public: HalfSpace(); HalfSpace(const LinAl::Vector &); - HalfSpace *clone() const override; + std::unique_ptr> clone() const override; const LinAl::Vector &get_normal() const { return normal; } @@ -43,9 +43,9 @@ inline HalfSpace::HalfSpace(const LinAl::Vector &n): { } template -inline HalfSpace *HalfSpace::clone() const +inline std::unique_ptr> HalfSpace::clone() const { - return new HalfSpace(normal); + return std::make_unique>(normal); } template diff --git a/source/geometry/hyperbox.h b/source/geometry/hyperbox.h index 1743251..cb7a661 100644 --- a/source/geometry/hyperbox.h +++ b/source/geometry/hyperbox.h @@ -24,7 +24,7 @@ public: HyperBox(); explicit HyperBox(const LinAl::Vector &); - HyperBox *clone() const override; + std::unique_ptr> clone() const override; const LinAl::Vector &get_dimensions() const { return dimensions; } T get_dimension(unsigned) const; @@ -53,9 +53,9 @@ inline HyperBox::HyperBox(const LinAl::Vector &d): } template -inline HyperBox *HyperBox::clone() const +inline std::unique_ptr> HyperBox::clone() const { - return new HyperBox(dimensions); + return std::make_unique>(dimensions); } template diff --git a/source/geometry/hypersphere.h b/source/geometry/hypersphere.h index 94ccae9..368549b 100644 --- a/source/geometry/hypersphere.h +++ b/source/geometry/hypersphere.h @@ -23,7 +23,7 @@ public: HyperSphere() = default; explicit HyperSphere(T); - HyperSphere *clone() const override; + std::unique_ptr> clone() const override; T get_radius() const { return radius; } @@ -43,9 +43,9 @@ inline HyperSphere::HyperSphere(T r): } template -inline HyperSphere *HyperSphere::clone() const +inline std::unique_ptr> HyperSphere::clone() const { - return new HyperSphere(radius); + return std::make_unique>(radius); } template diff --git a/source/geometry/intersection.h b/source/geometry/intersection.h index 6ea0602..cdf41e9 100644 --- a/source/geometry/intersection.h +++ b/source/geometry/intersection.h @@ -28,7 +28,7 @@ public: template static Intersection from_iterator_range(const Iter &, const Iter &); - Intersection *clone() const override; + std::unique_ptr> clone() const override; }; template @@ -46,9 +46,9 @@ inline Intersection Intersection::from_iterator_range(const Iter &be } template -inline Intersection *Intersection::clone() const +inline std::unique_ptr> Intersection::clone() const { - return new Intersection(*this); + return std::make_unique>(*this); } } // namespace Geometry diff --git a/source/geometry/loader.h b/source/geometry/loader.h index 6b03bbb..c3774b7 100644 --- a/source/geometry/loader.h +++ b/source/geometry/loader.h @@ -21,13 +21,12 @@ class DimensionIndependentLoader: public DataFile::Loader { protected: bool single = true; - std::list *> shapes; + std::list>> shapes; DimensionIndependentLoader(bool = true); -public: - ~DimensionIndependentLoader() override; - const Shape &get_shape() const; +public: + std::unique_ptr> take_shape(); protected: template @@ -65,7 +64,7 @@ private: public: ShapeLoader(); - ExtrudedShape *create() const; + std::unique_ptr> create() const; private: void length(T); @@ -80,7 +79,7 @@ private: public: ShapeLoader(); - HalfSpace *create() const; + std::unique_ptr> create() const; private: void normal(const std::vector &); @@ -95,7 +94,7 @@ private: public: ShapeLoader(); - HyperBox *create() const; + std::unique_ptr> create() const; private: void dimensions(const std::vector &); @@ -110,7 +109,7 @@ private: public: ShapeLoader(); - HyperSphere *create() const; + std::unique_ptr> create() const; private: void radius(T); @@ -122,7 +121,7 @@ class CompositeLoader: public Loader public: CompositeLoader(); - S *create() const; + std::unique_ptr> create() const; }; template @@ -133,7 +132,7 @@ template class ShapeLoader >: public Loader { public: - Negation *create() const; + std::unique_ptr> create() const; }; template @@ -145,7 +144,7 @@ protected: public: TransformationLoader(); - TransformedShape *create() const; + std::unique_ptr> create() const; void translate(const std::vector &); void scale(const std::vector &); @@ -193,18 +192,11 @@ inline DimensionIndependentLoader::DimensionIndependentLoader(bool s): } template -inline DimensionIndependentLoader::~DimensionIndependentLoader() -{ - for(Shape *s: shapes) - delete s; -} - -template -inline const Shape &DimensionIndependentLoader::get_shape() const +inline std::unique_ptr> DimensionIndependentLoader::take_shape() { if(shapes.empty()) throw std::runtime_error("no shape"); - return *shapes.front(); + return std::move(shapes.front()); } template @@ -241,9 +233,9 @@ inline ShapeLoader >::ShapeLoader(): } template -inline ExtrudedShape *ShapeLoader >::create() const +inline std::unique_ptr> ShapeLoader >::create() const { - return new ExtrudedShape(*this->shapes.front(), length_); + return std::make_unique>(*this->shapes.front(), length_); } template @@ -262,9 +254,9 @@ inline ShapeLoader >::ShapeLoader() } template -inline HalfSpace *ShapeLoader >::create() const +inline std::unique_ptr> ShapeLoader >::create() const { - return new HalfSpace(normal_); + return std::make_unique>(normal_); } template @@ -287,9 +279,9 @@ inline ShapeLoader >::ShapeLoader() } template -inline HyperBox *ShapeLoader >::create() const +inline std::unique_ptr> ShapeLoader >::create() const { - return new HyperBox(dimensions_); + return std::make_unique>(dimensions_); } template @@ -310,9 +302,9 @@ inline ShapeLoader >::ShapeLoader(): } template -inline HyperSphere *ShapeLoader >::create() const +inline std::unique_ptr> ShapeLoader >::create() const { - return new HyperSphere(radius_); + return std::make_unique>(radius_); } template @@ -323,9 +315,9 @@ inline void ShapeLoader >::radius(T r) template -inline Negation *ShapeLoader >::create() const +inline std::unique_ptr> ShapeLoader >::create() const { - return new Negation(*this->shapes.front()); + return std::make_unique>(*this->shapes.front()); } @@ -338,9 +330,9 @@ inline TransformationLoader::TransformationLoader() } template -inline TransformedShape *TransformationLoader::create() const +inline std::unique_ptr> TransformationLoader::create() const { - return new TransformedShape(*this->shapes.front(), transformation); + return std::make_unique>(*this->shapes.front(), transformation); } template @@ -411,7 +403,7 @@ inline CompositeLoader::CompositeLoader(): { } template -inline S *CompositeLoader::create() const +inline std::unique_ptr> CompositeLoader::create() const { if(this->shapes.empty()) throw std::runtime_error("no shapes"); diff --git a/source/geometry/negation.h b/source/geometry/negation.h index 4947bbf..9c781e9 100644 --- a/source/geometry/negation.h +++ b/source/geometry/negation.h @@ -14,15 +14,14 @@ template class Negation: public Shape { private: - Shape *shape = nullptr; + std::unique_ptr> shape; public: Negation(const Shape &); Negation(const Negation &); Negation &operator=(const Negation &); - ~Negation(); - Negation *clone() const override; + std::unique_ptr> clone() const override; const Shape &get_shape() const { return *shape; } @@ -46,21 +45,14 @@ inline Negation::Negation(const Negation &other): template inline Negation &Negation::operator=(const Negation &other) { - delete shape; shape = other.shape->clone(); return *this; } template -inline Negation::~Negation() +inline std::unique_ptr> Negation::clone() const { - delete shape; -} - -template -inline Negation *Negation::clone() const -{ - return new Negation(*shape); + return std::make_unique>(*shape); } template diff --git a/source/geometry/shape.h b/source/geometry/shape.h index 543550d..bd90ba6 100644 --- a/source/geometry/shape.h +++ b/source/geometry/shape.h @@ -2,6 +2,7 @@ #define MSP_GEOMETRY_SHAPE_H_ #include +#include #include #include #include "boundingbox.h" @@ -39,7 +40,7 @@ protected: public: virtual ~Shape() = default; - virtual Shape *clone() const = 0; + virtual std::unique_ptr clone() const = 0; /** Returns the bounding box of the shape. The detail parameter controls the tightness of the box. Higher detail will take more time to compute. */ diff --git a/source/geometry/transformedshape.h b/source/geometry/transformedshape.h index 1cab022..7ea7268 100644 --- a/source/geometry/transformedshape.h +++ b/source/geometry/transformedshape.h @@ -14,7 +14,7 @@ template class TransformedShape: public Shape { private: - Shape *shape = nullptr; + std::unique_ptr> shape; AffineTransform transformation; AffineTransform inverse_trans; @@ -22,9 +22,8 @@ public: TransformedShape(const Shape &, const AffineTransform &); TransformedShape(const TransformedShape &); TransformedShape &operator=(const TransformedShape &); - ~TransformedShape(); - TransformedShape *clone() const override; + std::unique_ptr> clone() const override; const Shape &get_shape() const { return *shape; } const AffineTransform &get_transformation() const { return transformation; } @@ -53,22 +52,15 @@ inline TransformedShape::TransformedShape(const TransformedShape &ot template inline TransformedShape &TransformedShape::operator=(const TransformedShape &other) { - delete shape; shape = other.shape->clone(); transformation = other.transformation; inverse_trans = other.inverse_trans; } template -inline TransformedShape::~TransformedShape() +inline std::unique_ptr> TransformedShape::clone() const { - delete shape; -} - -template -inline TransformedShape *TransformedShape::clone() const -{ - return new TransformedShape(*this); + return std::make_unique>(*this); } template diff --git a/source/geometry/union.h b/source/geometry/union.h index 7d77ed1..e25c750 100644 --- a/source/geometry/union.h +++ b/source/geometry/union.h @@ -28,7 +28,7 @@ public: template static Union from_iterator_range(const Iter &, const Iter &); - Union *clone() const override; + std::unique_ptr> clone() const override; }; template @@ -46,9 +46,9 @@ inline Union Union::from_iterator_range(const Iter &begin, const Ite } template -inline Union *Union::clone() const +inline std::unique_ptr> Union::clone() const { - return new Union(*this); + return std::make_unique>(*this); } } // namespace Geometry