build_info
{
- standard CXX "c++11";
+ standard CXX "c++14";
};
if_arch "linux"
class RayTracer: public RegisteredApplication<RayTracer>
{
private:
- Geometry::Shape<double, 3> *shape;
+ std::unique_ptr<Geometry::Shape<double, 3>> shape;
unsigned width;
unsigned height;
string filename;
RayTracer::RayTracer(int argc, char **argv):
- shape(0),
width(500),
height(500),
pixels(new UInt8[width*height])
RayTracer::~RayTracer()
{
- delete shape;
delete[] pixels;
}
DataFile::Parser parser(in, filename);
Geometry::Loader<double, 3> loader;
loader.load(parser);
- shape = loader.get_shape().clone();
+ shape = loader.take_shape();
}
#define MSP_GEOMETRY_COMPOSITESHAPE_H_
#include <algorithm>
+#include <memory>
#include <stdexcept>
#include <vector>
#include "shape.h"
{
protected:
typedef O Ops;
- typedef std::vector<Shape<T, D> *> ShapeArray;
+ typedef std::vector<std::unique_ptr<Shape<T, D>>> ShapeArray;
ShapeArray shapes;
unsigned max_isect;
protected:
CompositeShape(const CompositeShape &);
CompositeShape &operator=(const CompositeShape &);
-public:
- ~CompositeShape() override;
+public:
BoundingBox<T, D> get_axis_aligned_bounding_box(unsigned = 0) const override;
bool contains(const LinAl::Vector<T, D> &) const override;
unsigned get_max_ray_intersections() const override { return max_isect; }
inline void CompositeShape<T, D, O>::init()
{
max_isect = 0;
- for(Shape<T, D> *s: shapes)
+ for(const std::unique_ptr<Shape<T, D>> &s: shapes)
max_isect += s->get_max_ray_intersections();
}
template<typename T, unsigned D, typename O>
inline CompositeShape<T, D, O>::CompositeShape(const CompositeShape<T, D, O> &other):
- shapes(other.shapes),
max_isect(other.max_isect)
{
- for(Shape<T, D> *&s: shapes)
- s = s->clone();
+ for(const std::unique_ptr<Shape<T, D>> &s: other.shapes)
+ shapes.push_back(s->clone());
}
template<typename T, unsigned D, typename O>
inline CompositeShape<T, D, O> &CompositeShape<T, D, O>::operator=(const CompositeShape<T, D, O> &other)
{
- for(Shape<T, D> *s: shapes)
- delete s;
-
- shapes = other.shapes;
- for(Shape<T, D> *&s: shapes)
- s = s->clone();
+ shapes.clear();
+ for(const std::unique_ptr<Shape<T, D>> &s: shapes)
+ shapes.push_back(s->clone());
max_isect = other.max_isect;
}
-template<typename T, unsigned D, typename O>
-inline CompositeShape<T, D, O>::~CompositeShape()
-{
- for(Shape<T, D> *s: shapes)
- delete s;
-}
-
template<typename T, unsigned D, typename O>
inline BoundingBox<T, D> CompositeShape<T, D, O>::get_axis_aligned_bounding_box(unsigned detail) const
{
inline bool CompositeShape<T, D, O>::contains(const LinAl::Vector<T, D> &point) const
{
bool inside = false;
- for(Shape<T, D> *s: shapes)
+ for(const std::unique_ptr<Shape<T, D>> &s: shapes)
{
inside = s->contains(point);
if(Ops::shortcircuit(inside))
class ExtrudedShape: public Shape<T, D>
{
private:
- Shape<T, D-1> *base = nullptr;
+ std::unique_ptr<Shape<T, D-1>> base;
T length = T(1);
public:
ExtrudedShape(const Shape<T, D-1> &, T);
ExtrudedShape(const ExtrudedShape &);
ExtrudedShape &operator=(const ExtrudedShape &);
- ~ExtrudedShape() override;
- ExtrudedShape *clone() const override;
+ std::unique_ptr<Shape<T, D>> clone() const override;
const Shape<T, D-1> &get_base() const { return *base; }
T get_length() const { return length; }
template<typename T, unsigned D>
inline ExtrudedShape<T, D> &ExtrudedShape<T, D>::operator=(const ExtrudedShape<T, D> &other)
{
- delete base;
base = other.base->clone();
length = other.length;
}
template<typename T, unsigned D>
-inline ExtrudedShape<T, D>::~ExtrudedShape()
+inline std::unique_ptr<Shape<T, D>> ExtrudedShape<T, D>::clone() const
{
- delete base;
-}
-
-template<typename T, unsigned D>
-inline ExtrudedShape<T, D> *ExtrudedShape<T, D>::clone() const
-{
- return new ExtrudedShape<T, D>(*base, length);
+ return std::make_unique<ExtrudedShape<T, D>>(*base, length);
}
template<typename T, unsigned D>
HalfSpace();
HalfSpace(const LinAl::Vector<T, D> &);
- HalfSpace *clone() const override;
+ std::unique_ptr<Shape<T, D>> clone() const override;
const LinAl::Vector<T, D> &get_normal() const { return normal; }
{ }
template<typename T, unsigned D>
-inline HalfSpace<T, D> *HalfSpace<T, D>::clone() const
+inline std::unique_ptr<Shape<T, D>> HalfSpace<T, D>::clone() const
{
- return new HalfSpace<T, D>(normal);
+ return std::make_unique<HalfSpace<T, D>>(normal);
}
template<typename T, unsigned D>
HyperBox();
explicit HyperBox(const LinAl::Vector<T, D> &);
- HyperBox *clone() const override;
+ std::unique_ptr<Shape<T, D>> clone() const override;
const LinAl::Vector<T, D> &get_dimensions() const { return dimensions; }
T get_dimension(unsigned) const;
}
template<typename T, unsigned D>
-inline HyperBox<T, D> *HyperBox<T, D>::clone() const
+inline std::unique_ptr<Shape<T, D>> HyperBox<T, D>::clone() const
{
- return new HyperBox<T, D>(dimensions);
+ return std::make_unique<HyperBox<T, D>>(dimensions);
}
template<typename T, unsigned D>
HyperSphere() = default;
explicit HyperSphere(T);
- HyperSphere *clone() const override;
+ std::unique_ptr<Shape<T, D>> clone() const override;
T get_radius() const { return radius; }
}
template<typename T, unsigned D>
-inline HyperSphere<T, D> *HyperSphere<T, D>::clone() const
+inline std::unique_ptr<Shape<T, D>> HyperSphere<T, D>::clone() const
{
- return new HyperSphere<T, D>(radius);
+ return std::make_unique<HyperSphere<T, D>>(radius);
}
template<typename T, unsigned D>
template<typename Iter>
static Intersection from_iterator_range(const Iter &, const Iter &);
- Intersection *clone() const override;
+ std::unique_ptr<Shape<T, D>> clone() const override;
};
template<typename T, unsigned D>
}
template<typename T, unsigned D>
-inline Intersection<T, D> *Intersection<T, D>::clone() const
+inline std::unique_ptr<Shape<T, D>> Intersection<T, D>::clone() const
{
- return new Intersection<T, D>(*this);
+ return std::make_unique<Intersection<T, D>>(*this);
}
} // namespace Geometry
{
protected:
bool single = true;
- std::list<Shape<T, D> *> shapes;
+ std::list<std::unique_ptr<Shape<T, D>>> shapes;
DimensionIndependentLoader(bool = true);
-public:
- ~DimensionIndependentLoader() override;
- const Shape<T, D> &get_shape() const;
+public:
+ std::unique_ptr<Shape<T, D>> take_shape();
protected:
template<typename S>
public:
ShapeLoader();
- ExtrudedShape<T, D> *create() const;
+ std::unique_ptr<ExtrudedShape<T, D>> create() const;
private:
void length(T);
public:
ShapeLoader();
- HalfSpace<T, D> *create() const;
+ std::unique_ptr<Shape<T, D>> create() const;
private:
void normal(const std::vector<T> &);
public:
ShapeLoader();
- HyperBox<T, D> *create() const;
+ std::unique_ptr<Shape<T, D>> create() const;
private:
void dimensions(const std::vector<T> &);
public:
ShapeLoader();
- HyperSphere<T, D> *create() const;
+ std::unique_ptr<Shape<T, D>> create() const;
private:
void radius(T);
public:
CompositeLoader();
- S *create() const;
+ std::unique_ptr<Shape<T, D>> create() const;
};
template<typename T, unsigned D>
class ShapeLoader<Negation<T, D> >: public Loader<T, D>
{
public:
- Negation<T, D> *create() const;
+ std::unique_ptr<Shape<T, D>> create() const;
};
template<typename T, unsigned D>
public:
TransformationLoader();
- TransformedShape<T, D> *create() const;
+ std::unique_ptr<Shape<T, D>> create() const;
void translate(const std::vector<T> &);
void scale(const std::vector<T> &);
}
template<typename T, unsigned D>
-inline DimensionIndependentLoader<T, D>::~DimensionIndependentLoader()
-{
- for(Shape<T, D> *s: shapes)
- delete s;
-}
-
-template<typename T, unsigned D>
-inline const Shape<T, D> &DimensionIndependentLoader<T, D>::get_shape() const
+inline std::unique_ptr<Shape<T, D>> DimensionIndependentLoader<T, D>::take_shape()
{
if(shapes.empty())
throw std::runtime_error("no shape");
- return *shapes.front();
+ return std::move(shapes.front());
}
template<typename T, unsigned D>
}
template<typename T, unsigned D>
-inline ExtrudedShape<T, D> *ShapeLoader<ExtrudedShape<T, D> >::create() const
+inline std::unique_ptr<ExtrudedShape<T, D>> ShapeLoader<ExtrudedShape<T, D> >::create() const
{
- return new ExtrudedShape<T, D>(*this->shapes.front(), length_);
+ return std::make_unique<ExtrudedShape<T, D>>(*this->shapes.front(), length_);
}
template<typename T, unsigned D>
}
template<typename T, unsigned D>
-inline HalfSpace<T, D> *ShapeLoader<HalfSpace<T, D> >::create() const
+inline std::unique_ptr<Shape<T, D>> ShapeLoader<HalfSpace<T, D> >::create() const
{
- return new HalfSpace<T, D>(normal_);
+ return std::make_unique<HalfSpace<T, D>>(normal_);
}
template<typename T, unsigned D>
}
template<typename T, unsigned D>
-inline HyperBox<T, D> *ShapeLoader<HyperBox<T, D> >::create() const
+inline std::unique_ptr<Shape<T, D>> ShapeLoader<HyperBox<T, D> >::create() const
{
- return new HyperBox<T, D>(dimensions_);
+ return std::make_unique<HyperBox<T, D>>(dimensions_);
}
template<typename T, unsigned D>
}
template<typename T, unsigned D>
-inline HyperSphere<T, D> *ShapeLoader<HyperSphere<T, D> >::create() const
+inline std::unique_ptr<Shape<T, D>> ShapeLoader<HyperSphere<T, D> >::create() const
{
- return new HyperSphere<T, D>(radius_);
+ return std::make_unique<HyperSphere<T, D>>(radius_);
}
template<typename T, unsigned D>
template<typename T, unsigned D>
-inline Negation<T, D> *ShapeLoader<Negation<T, D> >::create() const
+inline std::unique_ptr<Shape<T, D>> ShapeLoader<Negation<T, D> >::create() const
{
- return new Negation<T, D>(*this->shapes.front());
+ return std::make_unique<Negation<T, D>>(*this->shapes.front());
}
}
template<typename T, unsigned D>
-inline TransformedShape<T, D> *TransformationLoader<T, D>::create() const
+inline std::unique_ptr<Shape<T, D>> TransformationLoader<T, D>::create() const
{
- return new TransformedShape<T, D>(*this->shapes.front(), transformation);
+ return std::make_unique<TransformedShape<T, D>>(*this->shapes.front(), transformation);
}
template<typename T, unsigned D>
{ }
template<typename T, unsigned D, typename S>
-inline S *CompositeLoader<T, D, S>::create() const
+inline std::unique_ptr<Shape<T, D>> CompositeLoader<T, D, S>::create() const
{
if(this->shapes.empty())
throw std::runtime_error("no shapes");
class Negation: public Shape<T, D>
{
private:
- Shape<T, D> *shape = nullptr;
+ std::unique_ptr<Shape<T, D>> shape;
public:
Negation(const Shape<T, D> &);
Negation(const Negation &);
Negation &operator=(const Negation &);
- ~Negation();
- Negation *clone() const override;
+ std::unique_ptr<Shape<T, D>> clone() const override;
const Shape<T, D> &get_shape() const { return *shape; }
template<typename T, unsigned D>
inline Negation<T, D> &Negation<T, D>::operator=(const Negation<T, D> &other)
{
- delete shape;
shape = other.shape->clone();
return *this;
}
template<typename T, unsigned D>
-inline Negation<T, D>::~Negation()
+inline std::unique_ptr<Shape<T, D>> Negation<T, D>::clone() const
{
- delete shape;
-}
-
-template<typename T, unsigned D>
-inline Negation<T, D> *Negation<T, D>::clone() const
-{
- return new Negation<T, D>(*shape);
+ return std::make_unique<Negation<T, D>>(*shape);
}
template<typename T, unsigned D>
#define MSP_GEOMETRY_SHAPE_H_
#include <list>
+#include <memory>
#include <vector>
#include <msp/linal/vector.h>
#include "boundingbox.h"
public:
virtual ~Shape() = default;
- virtual Shape *clone() const = 0;
+ virtual std::unique_ptr<Shape> 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. */
class TransformedShape: public Shape<T, D>
{
private:
- Shape<T, D> *shape = nullptr;
+ std::unique_ptr<Shape<T, D>> shape;
AffineTransform<T, D> transformation;
AffineTransform<T, D> inverse_trans;
TransformedShape(const Shape<T, D> &, const AffineTransform<T, D> &);
TransformedShape(const TransformedShape &);
TransformedShape &operator=(const TransformedShape &);
- ~TransformedShape();
- TransformedShape *clone() const override;
+ std::unique_ptr<Shape<T, D>> clone() const override;
const Shape<T, D> &get_shape() const { return *shape; }
const AffineTransform<T, D> &get_transformation() const { return transformation; }
template<typename T, unsigned D>
inline TransformedShape<T, D> &TransformedShape<T, D>::operator=(const TransformedShape<T, D> &other)
{
- delete shape;
shape = other.shape->clone();
transformation = other.transformation;
inverse_trans = other.inverse_trans;
}
template<typename T, unsigned D>
-inline TransformedShape<T, D>::~TransformedShape()
+inline std::unique_ptr<Shape<T, D>> TransformedShape<T, D>::clone() const
{
- delete shape;
-}
-
-template<typename T, unsigned D>
-inline TransformedShape<T, D> *TransformedShape<T, D>::clone() const
-{
- return new TransformedShape<T, D>(*this);
+ return std::make_unique<TransformedShape<T, D>>(*this);
}
template<typename T, unsigned D>
template<typename Iter>
static Union from_iterator_range(const Iter &, const Iter &);
- Union *clone() const override;
+ std::unique_ptr<Shape<T, D>> clone() const override;
};
template<typename T, unsigned D>
}
template<typename T, unsigned D>
-inline Union<T, D> *Union<T, D>::clone() const
+inline std::unique_ptr<Shape<T, D>> Union<T, D>::clone() const
{
- return new Union<T, D>(*this);
+ return std::make_unique<Union<T, D>>(*this);
}
} // namespace Geometry