diff --git a/detail/coord.hpp b/detail/coord.hpp
index d842a3f7..f3157b37 100644
--- a/detail/coord.hpp
+++ b/detail/coord.hpp
@@ -5,16 +5,16 @@
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
- *
+ *
* libgim is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with libgim. If not, see .
*
- * Copyright 2012 Danny Robson
+ * Copyright 2012-2015 Danny Robson
*/
#ifndef __UTIL_COORD_HPP
@@ -39,173 +39,120 @@ namespace util {
#if defined(COMPILER_CLANG)
#pragma GCC diagnostic ignored "-Wgnu"
#endif
+
+ //---------------------------------------------------------------------
+ // coord types are not really intended to have arbitrary dimension, so
+ // don't add specialisations (or a general case) without a decent
+ // reason.
template
- struct coord {
- typedef T value_type;
-
- coord () { ; }
-
- explicit coord (T v)
- { std::fill (std::begin (data), std::end (data), v); }
-
- template
- coord (U ..._u): data{_u...}
- { ; }
-
- coord (const coord &rhs) = default;
- coord& operator= (const coord &rhs) = default;
-
- T data[S];
-
- static constexpr size_t dimension = S;
-
- T& operator[] (size_t i) { return data[i]; }
- T operator[] (size_t i) const { return data[i]; }
- };
+ struct coord_data;
+ //---------------------------------------------------------------------
template
- struct coord<1,T> {
- typedef T value_type;
-
- coord () { ; }
-
- explicit coord (T v)
- { std::fill (std::begin (data), std::end (data), v); }
-
- template
- coord (U ..._u): data{_u...}
+ struct coord_data<1, T>
+ {
+ coord_data () = default;
+ coord_data (T v0):
+ data { v0 }
{ ; }
- coord (const coord<1,T> &rhs) = default;
- coord& operator= (const coord<1,T> &rhs) = default;
-
union {
T data[1];
T x;
};
-
- static constexpr size_t dimension = 1;
-
- T& operator[] (size_t i) { return data[i]; }
- T operator[] (size_t i) const { return data[i]; }
};
+
+ //---------------------------------------------------------------------
template
- struct coord<2,T> {
- typedef T value_type;
-
- coord () { ; }
-
- explicit coord (T v)
- { std::fill (std::begin (data), std::end (data), v); }
-
- template
- coord (U ..._u): data{_u...}
+ struct coord_data<2,T>
+ {
+ coord_data () = default;
+ coord_data (T v0, T v1):
+ data { v0, v1 }
{ ; }
- coord (const coord<2,T> &rhs) = default;
- coord& operator= (const coord<2,T> &rhs) = default;
-
union {
T data[2];
- struct {
- T x;
- T y;
- };
- struct {
- T s;
- T t;
- };
+
+ struct { T x, y; };
+ struct { T s, t; };
};
-
- static constexpr size_t dimension = 2;
-
- T& operator[] (size_t i) { return data[i]; }
- T operator[] (size_t i) const { return data[i]; }
};
+
+ //---------------------------------------------------------------------
template
- struct coord<3,T> {
- typedef T value_type;
+ struct coord_data<3,T>
+ {
+ coord_data () = default;
+ coord_data (T v0, T v1, T v2):
+ data { v0, v1, v2 }
+ { ; }
union {
T data[3];
- struct {
- T x;
- T y;
- T z;
- };
- struct {
- T r;
- T g;
- T b;
- };
+
+ struct { T x, y, z; };
+ struct { T s, t, p; };
+ struct { T r, g, b; };
};
-
- static constexpr size_t dimension = 3;
-
- coord () { ; }
-
- explicit coord (T v)
- { std::fill (std::begin (data), std::end (data), v); }
-
- template
- coord (U... u): data{u...}
- { ; }
-
- coord (const coord<3,T> &rhs) = default;
- coord& operator= (const coord<3,T> &rhs) = default;
-
- T& operator[] (size_t i) { return data[i]; }
- T operator[] (size_t i) const { return data[i]; }
};
- template
- T dot (const coord &a, const coord &b)
- {
- T sum { 0 };
- for (size_t i = 0; i < S; ++i)
- sum += a.data[i] * b.data[i];
- return sum;
- }
+ //---------------------------------------------------------------------
template
- struct coord<4,T> {
- typedef T value_type;
+ struct coord_data<4,T>
+ {
+ coord_data () = default;
+ coord_data (T v0, T v1, T v2, T v3):
+ data { v0, v1, v2, v3 }
+ { ; }
union {
T data[4];
- struct {
- T x;
- T y;
- T z;
- T w;
- };
- struct {
- T r;
- T g;
- T b;
- T a;
- };
+
+ struct { T x, y, z, w; };
+ struct { T s, t, p, q; };
+ struct { T r, g, b, a; };
};
+ };
- static constexpr size_t dimension = 4;
- coord () { ; }
+ //---------------------------------------------------------------------
+ template
+ struct coord : public coord_data {
+ static_assert (S > 0, "coord dimensions must be strictly positive");
+
+ typedef T value_type;
+ static constexpr size_t dimension = S;
+
+ using coord_data::coord_data;
+ coord () = default;
explicit coord (T v)
- { std::fill (std::begin (data), std::end (data), v); }
+ { std::fill (std::begin (this->data), std::end (this->data), v); }
- template
- coord (U... u): data{u...}
- { ; }
+ coord (const coord &rhs) = default;
+ coord& operator= (const coord &rhs) = default;
- coord (const coord<4,T> &rhs) = default;
- coord& operator= (const coord<4,T> &rhs) = default;
-
- T& operator[] (size_t i) { return data[i]; }
- T operator[] (size_t i) const { return data[i]; }
+ T& operator[] (size_t i) { return this->data[i]; }
+ T operator[] (size_t i) const { return this->data[i]; }
};
+
+
+ //---------------------------------------------------------------------
+ // XXX: Unsure whether this should really be defined for arbitrary
+ // types in a semantic sense, but practicality suggestes this is the
+ // best option; point/vector dot product is too useful.
+ template
+ T dot (const coord &a, const coord &b)
+ {
+ return std::inner_product (std::begin (a.data),
+ std::end (a.data),
+ std::begin (b.data),
+ T {0});
+ }
#pragma GCC diagnostic pop
}
}
diff --git a/point.hpp b/point.hpp
index ba3dab8a..a3137a09 100644
--- a/point.hpp
+++ b/point.hpp
@@ -32,8 +32,6 @@ namespace util {
/// An n-dimensional position in space.
template
struct point : public detail::coord {
- static_assert (S > 0, "point dimensions must be strictly positive.");
-
using detail::coord::coord;
// point operators
diff --git a/vector.hpp b/vector.hpp
index 9f6f72db..8bf86c32 100644
--- a/vector.hpp
+++ b/vector.hpp
@@ -30,8 +30,6 @@
namespace util {
template
struct vector : public detail::coord {
- static_assert (S > 0, "vector dimensions must be strictly positive");
-
using detail::coord::coord;
// arithmetic operators