Commit 0d099868 authored by Dennis Gläser's avatar Dennis Gläser
Browse files

[geom][point] pull out base class from impl namespace

parent c9e84d43
......@@ -36,84 +36,78 @@ namespace Frackit {
// Forwad declaration
template<class CT, int wd> class Vector;
// Hide implementation from Doxygen
#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace Impl {
/*!
* \brief Base class for Point implementations.
* \tparam Impl The actual vector class implementation
* \tparam CT The type used for coordinates
* \tparam wd The dimension of the space
*/
template<class Impl, class CT, int wd>
class PointBase
{
public:
//! export dimensionality
static constexpr int myDimension() { return 0; };
static constexpr int worldDimension() { return wd; };
//! export type used for coordinates
using ctype = CT;
/*!
* \brief Base class for Point implementations.
* \tparam Impl The actual vector class implementation
* \tparam CT The type used for coordinates
* \tparam wd The dimension of the space
* \brief Default constructor. Creates a point at the origin.
*/
template<class Impl, class CT, int wd>
class PointBase
PointBase()
{
std::fill(coordinates_.begin(), coordinates_.end(), 0.0);
}
public:
//! export dimensionality
static constexpr int myDimension() { return 0; };
static constexpr int worldDimension() { return wd; };
//! export type used for coordinates
using ctype = CT;
/*!
* \brief Default constructor. Creates a point at the origin.
*/
PointBase()
{
std::fill(coordinates_.begin(), coordinates_.end(), 0.0);
}
/*!
* \brief Construction from an initializer list.
* \param l The initializer list containing the coordinates
*/
PointBase(const std::initializer_list<CT>& l)
{
const auto minDim = std::min(static_cast<std::size_t>(wd), l.size());
std::copy_n( l.begin(), minDim, coordinates_.begin());
}
//! Return the name of this geometry class
static std::string name()
{ return "Point"; }
//! Returns true if the given point is equal to this one
bool isEqual(const Impl& other, ctype eps) const
{ return Vector<ctype, wd>(asImp_(), other).squaredLength() < eps*eps; }
//! Returns true if the given point is equal to this one (default eps)
bool isEqual(const Impl& other) const
{
const auto scale = Vector<ctype, wd>(Impl(), asImp_()).length();
const auto eps = Precision<ctype>::confusion()*scale;
return isEqual(other, eps);
}
protected:
//! Provide access to the underlying coordinates
ctype operator[] (unsigned int i) const
{
assert(i < coordinates_.size());
return coordinates_[i];
}
//! Provide access to the coordinate storage
std::array<ctype, wd>& coordinates()
{ return coordinates_; }
//! Returns the implementation (static polymorphism)
Impl &asImp_() { return *static_cast<Impl*>(this); }
//! \copydoc asImp_()
const Impl &asImp_() const { return *static_cast<const Impl*>(this); }
private:
std::array<ctype, wd> coordinates_;
};
} // end namespace Impl
#endif // DOXYGEN_SHOULD_SKIP_THIS
/*!
* \brief Construction from an initializer list.
* \param l The initializer list containing the coordinates
*/
PointBase(const std::initializer_list<CT>& l)
{
const auto minDim = std::min(static_cast<std::size_t>(wd), l.size());
std::copy_n( l.begin(), minDim, coordinates_.begin());
}
//! Return the name of this geometry class
static std::string name()
{ return "Point"; }
//! Returns true if the given point is equal to this one
bool isEqual(const Impl& other, ctype eps) const
{ return Vector<ctype, wd>(asImp_(), other).squaredLength() < eps*eps; }
//! Returns true if the given point is equal to this one (default eps)
bool isEqual(const Impl& other) const
{
const auto scale = Vector<ctype, wd>(Impl(), asImp_()).length();
const auto eps = Precision<ctype>::confusion()*scale;
return isEqual(other, eps);
}
protected:
//! Provide access to the underlying coordinates
ctype operator[] (unsigned int i) const
{
assert(i < coordinates_.size());
return coordinates_[i];
}
//! Provide access to the coordinate storage
std::array<ctype, wd>& coordinates()
{ return coordinates_; }
//! Returns the implementation (static polymorphism)
Impl &asImp_() { return *static_cast<Impl*>(this); }
//! \copydoc asImp_()
const Impl &asImp_() const { return *static_cast<const Impl*>(this); }
private:
std::array<ctype, wd> coordinates_;
};
/*!
* \brief Point class implementation.
......@@ -128,10 +122,10 @@ class Point;
*/
template<class CT>
class Point<CT, 1>
: public Impl::PointBase< Point<CT, 1>, CT, 1 >
: public PointBase< Point<CT, 1>, CT, 1 >
{
using ThisType = Point<CT, 1>;
using ParentType = Impl::PointBase<ThisType, CT, 1>;
using ParentType = PointBase<ThisType, CT, 1>;
public:
//! pull up base class' constructors
......@@ -185,10 +179,10 @@ public:
*/
template<class CT>
class Point<CT, 2>
: public Impl::PointBase< Point<CT, 2>, CT, 2 >
: public PointBase< Point<CT, 2>, CT, 2 >
{
using ThisType = Point<CT, 2>;
using ParentType = Impl::PointBase<ThisType, CT, 2>;
using ParentType = PointBase<ThisType, CT, 2>;
public:
//! pull up base class' constructors
......@@ -247,10 +241,10 @@ public:
*/
template<class CT>
class Point<CT, 3>
: public Impl::PointBase< Point<CT, 3>, CT, 3 >
: public PointBase< Point<CT, 3>, CT, 3 >
{
using ThisType = Point<CT, 3>;
using ParentType = Impl::PointBase<ThisType, CT, 3>;
using ParentType = PointBase<ThisType, CT, 3>;
public:
//! pull up base class' constructors
......
......@@ -55,7 +55,7 @@ template<class CT, int wd> class Direction;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
// namespace with implementation details
namespace Impl {
namespace VectorImpl {
/*!
* \brief Computes the scalar product between two 1d vectors.
......@@ -127,123 +127,123 @@ namespace Impl {
template<class CT1, class CT2>
Vector<CT1, 3> subtractVectors(const Vector<CT1, 3>& v1, const Vector<CT2, 3>& v2)
{ return {v1.x()-v2.x(), v1.y()-v2.y(), v1.z()-v2.z()}; }
} // end namespace VectorImpl
#endif // DOXYGEN_SHOULD_SKIP_THIS
/*!
* \brief Base class of the dimension-specific Vector implementations.
* \tparam Impl The actual vector class implementation
* \tparam CT The type used for coordinates
* \tparam wd The dimension of the space
*/
template<class Impl, class CoordType, int wd>
class VectorBase
{
public:
//! export dimensionality
static constexpr int myDimension() { return 1; };
static constexpr int worldDimension() { return wd; };
//! export type used for coordinates
using ctype = CoordType;
//! export underlying point type
using Point = typename Frackit::Point<ctype, wd>;
using Vector = typename Frackit::Vector<ctype, wd>;
using Direction = typename Frackit::Direction<ctype, wd>;
/*!
* \brief Base class of the dimension-specific Vector implementations.
* \tparam Impl The actual vector class implementation
* \tparam CT The type used for coordinates
* \tparam wd The dimension of the space
* \brief Constructs a vector from a single scalar value
* assigning this value to each coordinate direction.
* \param value The coordinate value
*/
template<class Impl, class CoordType, int wd>
class VectorBase
VectorBase(ctype value = 0.0)
{
std::fill(coordinates_.begin(), coordinates_.end(), value);
}
public:
//! export dimensionality
static constexpr int myDimension() { return 1; };
static constexpr int worldDimension() { return wd; };
//! export type used for coordinates
using ctype = CoordType;
//! export underlying point type
using Point = typename Frackit::Point<ctype, wd>;
using Vector = typename Frackit::Vector<ctype, wd>;
using Direction = typename Frackit::Direction<ctype, wd>;
/*!
* \brief Constructs a vector from a single scalar value
* assigning this value to each coordinate direction.
* \param value The coordinate value
*/
VectorBase(ctype value = 0.0)
{
std::fill(coordinates_.begin(), coordinates_.end(), value);
}
/*!
* \brief Constructs a vector from an initializer list.
* \param l The initializer list containing the coordinates
*/
VectorBase(const std::initializer_list<ctype>& l)
{
const auto minSize = std::min(static_cast<std::size_t>(wd), l.size());
std::copy_n( l.begin(), minSize, coordinates_.begin() );
}
//! Return the name of this geometry class
static std::string name()
{ return "Vector"; }
//! Return the squared length of the vector
ctype squaredLength() const
{
ctype result = 0;
for (unsigned int i = 0; i < wd; ++i)
result += coordinates_[i]*coordinates_[i];
return result;
}
//! Return the length of the vector
ctype length() const
{
using std::sqrt;
return sqrt(squaredLength());
}
//! Scalar product with another vector
template<class CT>
ctype operator*(const Frackit::Vector<CT, wd>& other) const
{ return scalarProduct(asImp_(), other); }
//! Add vector to this one
template<class CT>
Impl operator+(const Frackit::Vector<CT, wd>& other) const
{ return sumVectors(asImp_(), other); }
//! Subtract vector from this one
template<class CT>
Impl operator-(const Frackit::Vector<CT, wd>& other) const
{ return subtractVectors(asImp_(), other); }
//! Product of this vector with a scalar
template<class CT>
Impl& operator*=(CT value)
{
for (auto& coord : coordinates_)
coord *= value;
return asImp_();
}
//! Division of this vector with a scalar
template<class CT>
Impl& operator/=(CT value)
{
for (auto& coord : coordinates_)
coord /= value;
return asImp_();
}
protected:
//! Provide access to the coordinates of the vector
ctype operator[] (unsigned int coordIdx) const
{ return coordinates_[coordIdx]; }
//! Provide access to the coordinates of the vector
std::array<ctype, wd>& data()
{ return coordinates_; }
//! Returns the implementation (static polymorphism)
Impl &asImp_() { return *static_cast<Impl*>(this); }
//! \copydoc asImp_()
const Impl &asImp_() const { return *static_cast<const Impl*>(this); }
private:
// storage of the coordinates
std::array<ctype, wd> coordinates_;
};
} // end namespace Impl
#endif // DOXYGEN_SHOULD_SKIP_THIS
/*!
* \brief Constructs a vector from an initializer list.
* \param l The initializer list containing the coordinates
*/
VectorBase(const std::initializer_list<ctype>& l)
{
const auto minSize = std::min(static_cast<std::size_t>(wd), l.size());
std::copy_n( l.begin(), minSize, coordinates_.begin() );
}
//! Return the name of this geometry class
static std::string name()
{ return "Vector"; }
//! Return the squared length of the vector
ctype squaredLength() const
{
ctype result = 0;
for (unsigned int i = 0; i < wd; ++i)
result += coordinates_[i]*coordinates_[i];
return result;
}
//! Return the length of the vector
ctype length() const
{
using std::sqrt;
return sqrt(squaredLength());
}
//! Scalar product with another vector
template<class CT>
ctype operator*(const Frackit::Vector<CT, wd>& other) const
{ return VectorImpl::scalarProduct(asImp_(), other); }
//! Add vector to this one
template<class CT>
Impl operator+(const Frackit::Vector<CT, wd>& other) const
{ return VectorImpl::sumVectors(asImp_(), other); }
//! Subtract vector from this one
template<class CT>
Impl operator-(const Frackit::Vector<CT, wd>& other) const
{ return VectorImpl::subtractVectors(asImp_(), other); }
//! Product of this vector with a scalar
template<class CT>
Impl& operator*=(CT value)
{
for (auto& coord : coordinates_)
coord *= value;
return asImp_();
}
//! Division of this vector with a scalar
template<class CT>
Impl& operator/=(CT value)
{
for (auto& coord : coordinates_)
coord /= value;
return asImp_();
}
protected:
//! Provide access to the coordinates of the vector
ctype operator[] (unsigned int coordIdx) const
{ return coordinates_[coordIdx]; }
//! Provide access to the coordinates of the vector
std::array<ctype, wd>& data()
{ return coordinates_; }
//! Returns the implementation (static polymorphism)
Impl &asImp_() { return *static_cast<Impl*>(this); }
//! \copydoc asImp_()
const Impl &asImp_() const { return *static_cast<const Impl*>(this); }
private:
// storage of the coordinates
std::array<ctype, wd> coordinates_;
};
/*!
* \brief Vector class implementation.
......@@ -258,10 +258,10 @@ class Vector;
*/
template<class CT>
class Vector<CT, 1>
: public Impl::VectorBase< Vector<CT, 1>, CT, 1 >
: public VectorBase< Vector<CT, 1>, CT, 1 >
{
using ThisType = Vector<CT, 1>;
using ParentType = Impl::VectorBase<ThisType, CT, 1>;
using ParentType = VectorBase<ThisType, CT, 1>;
public:
//! pull up base class' constructors
......@@ -305,10 +305,10 @@ public:
*/
template<class CT>
class Vector<CT, 2>
: public Impl::VectorBase< Vector<CT, 2>, CT, 2 >
: public VectorBase< Vector<CT, 2>, CT, 2 >
{
using ThisType = Vector<CT, 2>;
using ParentType = Impl::VectorBase<ThisType, CT, 2>;
using ParentType = VectorBase<ThisType, CT, 2>;
public:
//! pull up base class' constructors
......@@ -356,10 +356,10 @@ public:
*/
template<class CT>
class Vector<CT, 3>
: public Impl::VectorBase< Vector<CT, 3>, CT, 3 >
: public VectorBase< Vector<CT, 3>, CT, 3 >
{
using ThisType = Vector<CT, 3>;
using ParentType = Impl::VectorBase<ThisType, CT, 3>;
using ParentType = VectorBase<ThisType, CT, 3>;
public:
//! pull up base class' constructors
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment