extent: derive from generic coord class

This commit is contained in:
Danny Robson 2015-03-03 19:43:09 +11:00
parent 31d1d741e9
commit 872499360f
5 changed files with 55 additions and 116 deletions

View File

@ -209,6 +209,8 @@ namespace util {
using coord_init<S,T,tags...>::coord_init; using coord_init<S,T,tags...>::coord_init;
coord () = default; coord () = default;
size_t size (void) const { return S; }
explicit coord (T v) explicit coord (T v)
{ std::fill (std::begin (this->data), std::end (this->data), v); } { std::fill (std::begin (this->data), std::end (this->data), v); }

View File

@ -24,59 +24,27 @@
#include <cmath> #include <cmath>
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
template <size_t S, typename T> template <size_t S, typename T>
util::extent<S,T>::extent (const T _width, const T _height):
w (_width),
h (_height)
{
static_assert (S == 2, "extents currently only support 2 dimensions");
CHECK_GE (w, 0);
CHECK_GE (h, 0);
}
//-----------------------------------------------------------------------------
template <size_t S, typename T>
util::extent<S,T>::extent (T t):
extent (t, t)
{ ; }
//-----------------------------------------------------------------------------
template <size_t S, typename T>
util::extent<S,T>::extent (vector<S,T> _v): util::extent<S,T>::extent (vector<S,T> _v):
extent (_v.x, _v.y) extent (_v.x, _v.y)
{ ; } { ; }
//-----------------------------------------------------------------------------
template <size_t S, typename T>
util::extent<S,T>::extent (const util::extent<S,T> &rhs):
w (rhs.w),
h (rhs.h)
{ ; }
//-----------------------------------------------------------------------------
template <size_t S, typename T>
util::extent<S,T>&
util::extent<S,T>::operator= (extent<S,T> rhs)
{
w = rhs.w;
h = rhs.h;
return *this;
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
template <size_t S, typename T> template <size_t S, typename T>
T T
util::extent<S,T>::diameter (void) const util::extent<S,T>::diameter (void) const
{ {
return static_cast<T> (sqrt (w * w + h * h)); return static_cast<T> (
std::sqrt (
std::accumulate (std::begin (this->data),
std::end (this->data),
T {0},
[] (auto a, auto b) { return a + b * b; })
)
);
} }
@ -85,7 +53,10 @@ template <size_t S, typename T>
T T
util::extent<S,T>::area (void) const util::extent<S,T>::area (void) const
{ {
return w * h; return std::accumulate (std::begin (this->data),
std::end (this->data),
T {1},
std::multiplies<T> ());
} }
@ -94,10 +65,7 @@ template <size_t S, typename T>
util::extent<S,T> util::extent<S,T>
util::extent<S,T>::expanded (util::vector<S,T> mag) const util::extent<S,T>::expanded (util::vector<S,T> mag) const
{ {
return { return *this + mag;
w + mag.x,
h + mag.y
};
} }
@ -110,15 +78,6 @@ util::extent<S,T>::expanded (T t) const
} }
///////////////////////////////////////////////////////////////////////////////
template <size_t S, typename T>
float
util::extent<S,T>::aspect (void) const
{
return static_cast<float> (w) / static_cast<float> (h);
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
template <size_t S, typename T> template <size_t S, typename T>
bool bool
@ -130,40 +89,15 @@ util::extent<S,T>::empty (void) const
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
template <size_t S, typename T> template <size_t S, typename T>
T& util::extent<S,T>
util::extent<S,T>::operator[] (size_t idx) util::extent<S,T>::operator+ (vector<S,T> rhs) const
{ {
switch (idx) { extent<S,T> out;
case 0: return w; std::adjacent_difference (std::begin (this->data),
case 1: return h; std::end (this->data),
std::begin (rhs.data),
default: std::plus<T> ());
unreachable (); return out;
}
}
//-----------------------------------------------------------------------------
template <size_t S, typename T>
const T&
util::extent<S,T>::operator[] (size_t idx) const
{
switch (idx) {
case 0: return w;
case 1: return h;
default:
unreachable ();
}
}
//-----------------------------------------------------------------------------
template <size_t S, typename T>
size_t
util::extent<S,T>::size (void) const
{
return S;
} }
@ -172,22 +106,21 @@ template <size_t S, typename T>
bool bool
util::extent<S,T>::operator ==(const extent& rhs) const util::extent<S,T>::operator ==(const extent& rhs) const
{ {
return almost_equal (w, rhs.w) && return std::equal (std::begin (this->data),
almost_equal (h, rhs.h); std::end (this->data),
std::begin (rhs.data),
almost_equal<T>);
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
template <size_t S, typename T> template <size_t S, typename T>
const util::extent<S,T> util::extent<S,T>::MIN { const util::extent<S,T> util::extent<S,T>::MIN { 0 };
0, 0
};
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <size_t S, typename T> template <size_t S, typename T>
const util::extent<S,T> util::extent<S,T>::MAX { const util::extent<S,T> util::extent<S,T>::MAX {
std::numeric_limits<T>::max (),
std::numeric_limits<T>::max () std::numeric_limits<T>::max ()
}; };

View File

@ -20,8 +20,8 @@
#ifndef __UTIL_EXTENT_HPP #ifndef __UTIL_EXTENT_HPP
#define __UTIL_EXTENT_HPP #define __UTIL_EXTENT_HPP
#include "detail/coord.hpp"
#include "vector.hpp" #include "vector.hpp"
#include <iostream> #include <iostream>
@ -30,15 +30,10 @@ namespace util {
* A pure two-dimensional size, without positioning * A pure two-dimensional size, without positioning
*/ */
template <size_t S, typename T> template <size_t S, typename T>
struct extent { struct extent : public detail::coord<S,T,detail::whd> {
T w, h; using detail::coord<S,T,detail::whd>::coord;
extent (const T _width, const T _height);
extent (T);
extent (vector<S,T>);
extent (const extent&);
extent& operator= (extent);
extent () = default; extent () = default;
extent (vector<S,T>);
T area (void) const; T area (void) const;
T diameter (void) const; T diameter (void) const;
@ -46,14 +41,9 @@ namespace util {
extent expanded (vector<S,T>) const; extent expanded (vector<S,T>) const;
extent expanded (T) const; extent expanded (T) const;
float aspect (void) const;
bool empty (void) const; bool empty (void) const;
T& operator[] (size_t idx); extent<S,T> operator+ (vector<S,T>) const;
const T& operator[] (size_t idx) const;
size_t size (void) const;
bool operator ==(const extent& rhs) const; bool operator ==(const extent& rhs) const;
bool operator !=(const extent& rhs) const bool operator !=(const extent& rhs) const
@ -66,6 +56,10 @@ namespace util {
static const extent MIN; static const extent MIN;
}; };
template <typename U, typename T>
U
aspect (extent<2,T>);
typedef extent<2,int> extent2i; typedef extent<2,int> extent2i;
typedef extent<2,size_t> extent2u; typedef extent<2,size_t> extent2u;
typedef extent<2,float> extent2f; typedef extent<2,float> extent2f;

View File

@ -19,19 +19,29 @@
#ifdef __UTIL_EXTENT_IPP #ifdef __UTIL_EXTENT_IPP
#error "twice included ipp" #error
#endif #endif
#define __UTIL_EXTENT_IPP #define __UTIL_EXTENT_IPP
#include <algorithm>
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <size_t S, typename T> template <size_t S, typename T>
template <typename U> template <typename U>
util::extent<S,U> util::extent<S,U>
util::extent<S,T>::cast (void) const util::extent<S,T>::cast (void) const
{ {
return { util::extent<S,U> out;
static_cast<U> (w), std::copy (std::begin (this->data), std::end (this->data), std::begin (out.data));
static_cast<U> (h) return out;
}; }
//-----------------------------------------------------------------------------
template <typename U, typename T>
U
util::aspect (util::extent<2,T> e)
{
return static_cast<U> (e.w) / e.h;
} }

View File

@ -37,7 +37,7 @@ util::region<S,T>::region (extent_t _extent):
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <size_t S, typename T> template <size_t S, typename T>
util::region<S,T>::region (point_t _point, util::region<S,T>::region (point_t _point,
extent_t _size): extent_t _size):
x (_point.x), x (_point.x),
y (_point.y), y (_point.y),
w (_size.w), w (_size.w),
@ -48,7 +48,7 @@ util::region<S,T>::region (point_t _point,
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <size_t S, typename T> template <size_t S, typename T>
util::region<S,T>::region (point_t _a, util::region<S,T>::region (point_t _a,
point_t _b): point_t _b):
region (_a, _b - _a) region (_a, _b - _a)
{ {
CHECK_GE (_b.x, _a.x); CHECK_GE (_b.x, _a.x);