coord: add general vector comparison function

This commit is contained in:
Danny Robson 2017-08-27 12:32:00 +10:00
parent e7fe5d044a
commit 3799135236
5 changed files with 87 additions and 27 deletions

View File

@ -185,5 +185,6 @@ namespace util::coord {
};
}
#include "../vector.hpp"
#endif

View File

@ -11,11 +11,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright 2012-2016 Danny Robson <danny@nerdcruft.net>
* Copyright 2012-2017 Danny Robson <danny@nerdcruft.net>
*/
#ifndef __UTIL_COORDS_OPS
#define __UTIL_COORDS_OPS
#ifndef CRUFT_UTIL_COORDS_OPS
#define CRUFT_UTIL_COORDS_OPS
#include "./fwd.hpp"
@ -28,6 +28,7 @@
#include <cmath>
#include <cstdlib>
#include <iterator>
#include <functional>
namespace util {
///////////////////////////////////////////////////////////////////////
@ -293,6 +294,63 @@ namespace util {
///////////////////////////////////////////////////////////////////////////
// logic operators
namespace detail {
template <
std::size_t S,
typename T,
template <std::size_t,typename> class K,
typename FuncT,
typename = std::enable_if_t<
is_coord_v<K<S,T>>,
void
>,
std::size_t ...Indices
>
constexpr auto
compare (FuncT &&func, std::index_sequence<Indices...>, const K<S,T> a, const K<S,T> b)
{
return vector<S,bool> {
std::invoke (func, a[Indices], b[Indices])...
};
}
}
//-------------------------------------------------------------------------
template <
std::size_t S,
typename T,
template <std::size_t,typename> class K,
typename FuncT,
typename = std::enable_if_t<
is_coord_v<K<S,T>>,
void
>,
typename Indices = std::make_index_sequence<S>
>
constexpr auto
compare (const K<S,T> a, const K<S,T> b, FuncT &&func)
{
return detail::compare (std::forward<FuncT> (func), Indices{}, a, b);
}
//-------------------------------------------------------------------------
template <
std::size_t S,
typename T,
template <std::size_t,typename> class K,
typename = std::enable_if_t<
is_coord_v<K<S,T>>,
void
>
>
constexpr auto
compare (const K<S,T> a, const K<S,T> b)
{
return compare (a, b, std::equal_to<T> {});
}
/// elementwise equality operator
template <
@ -303,16 +361,10 @@ namespace util {
is_coord_v<K<S,T>>, void
>
>
constexpr
bool
constexpr bool
operator== (const K<S,T> a, const K<S,T> b)
{
bool (*predicate)(const T&, const T&) = almost_equal;
return std::equal (std::cbegin (a),
std::cend (a),
std::cbegin (b),
predicate);
return all (compare (a, b, std::equal_to<T> {}));
}
///------------------------------------------------------------------------
@ -325,11 +377,10 @@ namespace util {
is_coord_v<K<S,T>>, void
>
>
constexpr
bool
operator!= (K<S,T> a, K<S,T> b)
constexpr bool
operator!= (const K<S,T> a, const K<S,T> b)
{
return !(a == b);
return any (compare (a, b, std::not_equal_to<T> {}));
}
@ -909,6 +960,7 @@ namespace util {
SCALAR_OP(>)
SCALAR_OP(<=)
SCALAR_OP(>=)
SCALAR_OP(==)
SCALAR_OP(&&)
SCALAR_OP(||)
@ -1026,6 +1078,7 @@ namespace util {
return k;
}
///////////////////////////////////////////////////////////////////////////
template <
size_t S,

View File

@ -23,13 +23,6 @@ main (void)
tap.expect_eq (-p, util::point2i { 1, -2 }, "unary point negation");
tap.expect_eq ( p, p, "unary point addition");
tap.expect (
std::is_same<
bool,
decltype(!p)::value_type
>::value,
"unary point boolean negation has type bool"
);
auto vec = util::vector4f (0.5f);
tap.expect_eq (vec, util::normalised (vec), "normalisation of normalised vector");

View File

@ -203,7 +203,14 @@ main (void)
euler = mod (euler + 4 * PI2, PI2);
truth = mod (truth + 4 * PI2, PI2);
tap.expect_eq (truth, euler, "matrix-to-euler, %s", t.msg);
tap.expect (
all (compare (
truth, euler,
[] (auto a, auto b) { return util::almost_equal (a, b); }
)),
"matrix-to-euler, %s",
t.msg
);
}
}

View File

@ -11,15 +11,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright 2011-2016 Danny Robson <danny@nerdcruft.net>
* Copyright 2011-2017 Danny Robson <danny@nerdcruft.net>
*/
#ifndef __UTIL_VECTOR_HPP
#define __UTIL_VECTOR_HPP
#ifndef CRUFT_UTIL_VECTOR_HPP
#define CRUFT_UTIL_VECTOR_HPP
#include "./coord/fwd.hpp"
#include "./coord.hpp"
#include "coord.hpp"
#include "json/fwd.hpp"
#include <cstddef>
///////////////////////////////////////////////////////////////////////////////
namespace util {
template <size_t S, typename T>
struct vector : public coord::base<S,T,vector,coord::xyzw,coord::stpq>