diff --git a/detail/coord.hpp b/detail/coord.hpp index 16d78888..8f051fe7 100644 --- a/detail/coord.hpp +++ b/detail/coord.hpp @@ -209,6 +209,8 @@ namespace util { using coord_init::coord_init; coord () = default; + size_t size (void) const { return S; } + explicit coord (T v) { std::fill (std::begin (this->data), std::end (this->data), v); } diff --git a/extent.cpp b/extent.cpp index ec44ed43..28b78d96 100644 --- a/extent.cpp +++ b/extent.cpp @@ -24,59 +24,27 @@ #include + /////////////////////////////////////////////////////////////////////////////// template -util::extent::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 -util::extent::extent (T t): - extent (t, t) -{ ; } - - -//----------------------------------------------------------------------------- -template util::extent::extent (vector _v): extent (_v.x, _v.y) { ; } -//----------------------------------------------------------------------------- -template -util::extent::extent (const util::extent &rhs): - w (rhs.w), - h (rhs.h) -{ ; } - - -//----------------------------------------------------------------------------- -template -util::extent& -util::extent::operator= (extent rhs) -{ - w = rhs.w; - h = rhs.h; - - return *this; -} - - /////////////////////////////////////////////////////////////////////////////// template T util::extent::diameter (void) const { - return static_cast (sqrt (w * w + h * h)); + return static_cast ( + 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 T util::extent::area (void) const { - return w * h; + return std::accumulate (std::begin (this->data), + std::end (this->data), + T {1}, + std::multiplies ()); } @@ -94,10 +65,7 @@ template util::extent util::extent::expanded (util::vector mag) const { - return { - w + mag.x, - h + mag.y - }; + return *this + mag; } @@ -110,15 +78,6 @@ util::extent::expanded (T t) const } -/////////////////////////////////////////////////////////////////////////////// -template -float -util::extent::aspect (void) const -{ - return static_cast (w) / static_cast (h); -} - - /////////////////////////////////////////////////////////////////////////////// template bool @@ -130,40 +89,15 @@ util::extent::empty (void) const /////////////////////////////////////////////////////////////////////////////// template -T& -util::extent::operator[] (size_t idx) +util::extent +util::extent::operator+ (vector rhs) const { - switch (idx) { - case 0: return w; - case 1: return h; - - default: - unreachable (); - } -} - - -//----------------------------------------------------------------------------- -template -const T& -util::extent::operator[] (size_t idx) const -{ - switch (idx) { - case 0: return w; - case 1: return h; - - default: - unreachable (); - } -} - - -//----------------------------------------------------------------------------- -template -size_t -util::extent::size (void) const -{ - return S; + extent out; + std::adjacent_difference (std::begin (this->data), + std::end (this->data), + std::begin (rhs.data), + std::plus ()); + return out; } @@ -172,22 +106,21 @@ template bool util::extent::operator ==(const extent& rhs) const { - return almost_equal (w, rhs.w) && - almost_equal (h, rhs.h); + return std::equal (std::begin (this->data), + std::end (this->data), + std::begin (rhs.data), + almost_equal); } /////////////////////////////////////////////////////////////////////////////// template -const util::extent util::extent::MIN { - 0, 0 -}; +const util::extent util::extent::MIN { 0 }; //----------------------------------------------------------------------------- template const util::extent util::extent::MAX { - std::numeric_limits::max (), std::numeric_limits::max () }; diff --git a/extent.hpp b/extent.hpp index 0eee6111..1409ada5 100644 --- a/extent.hpp +++ b/extent.hpp @@ -20,8 +20,8 @@ #ifndef __UTIL_EXTENT_HPP #define __UTIL_EXTENT_HPP +#include "detail/coord.hpp" #include "vector.hpp" - #include @@ -30,15 +30,10 @@ namespace util { * A pure two-dimensional size, without positioning */ template - struct extent { - T w, h; - - extent (const T _width, const T _height); - extent (T); - extent (vector); - extent (const extent&); - extent& operator= (extent); + struct extent : public detail::coord { + using detail::coord::coord; extent () = default; + extent (vector); T area (void) const; T diameter (void) const; @@ -46,14 +41,9 @@ namespace util { extent expanded (vector) const; extent expanded (T) const; - float aspect (void) const; - bool empty (void) const; - T& operator[] (size_t idx); - const T& operator[] (size_t idx) const; - - size_t size (void) const; + extent operator+ (vector) const; bool operator ==(const extent& rhs) const; bool operator !=(const extent& rhs) const @@ -66,6 +56,10 @@ namespace util { static const extent MIN; }; + template + U + aspect (extent<2,T>); + typedef extent<2,int> extent2i; typedef extent<2,size_t> extent2u; typedef extent<2,float> extent2f; diff --git a/extent.ipp b/extent.ipp index b01f5cd3..b7d12a05 100644 --- a/extent.ipp +++ b/extent.ipp @@ -19,19 +19,29 @@ #ifdef __UTIL_EXTENT_IPP -#error "twice included ipp" +#error #endif #define __UTIL_EXTENT_IPP +#include + //----------------------------------------------------------------------------- template template util::extent util::extent::cast (void) const { - return { - static_cast (w), - static_cast (h) - }; + util::extent out; + std::copy (std::begin (this->data), std::end (this->data), std::begin (out.data)); + return out; +} + + +//----------------------------------------------------------------------------- +template +U +util::aspect (util::extent<2,T> e) +{ + return static_cast (e.w) / e.h; } diff --git a/region.cpp b/region.cpp index a30f37c1..c72cf0c0 100644 --- a/region.cpp +++ b/region.cpp @@ -37,7 +37,7 @@ util::region::region (extent_t _extent): //----------------------------------------------------------------------------- template util::region::region (point_t _point, - extent_t _size): + extent_t _size): x (_point.x), y (_point.y), w (_size.w), @@ -48,7 +48,7 @@ util::region::region (point_t _point, //----------------------------------------------------------------------------- template util::region::region (point_t _a, - point_t _b): + point_t _b): region (_a, _b - _a) { CHECK_GE (_b.x, _a.x);