From 6065aa9933c07ee9669810d41d6c99e5617f6b50 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Mon, 19 Jun 2017 15:28:10 +1000 Subject: [PATCH] comparator: add comparator for indexed compound types compares each index of the two parameters in sequence, returning true if the first parameter has the first value that compares less than the second. --- CMakeLists.txt | 1 + test/comparator.cpp | 24 ++++++++++++++++++++++++ types/comparator.hpp | 33 ++++++++++++++++++++++++++++++--- types/comparator.ipp | 4 ++-- 4 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 test/comparator.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a275ad1..cf4cdf4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -451,6 +451,7 @@ if (TESTS) bitwise cmdopt colour + comparator coord crypto/arc4 crypto/ice diff --git a/test/comparator.cpp b/test/comparator.cpp new file mode 100644 index 00000000..c163f2dc --- /dev/null +++ b/test/comparator.cpp @@ -0,0 +1,24 @@ +#include "tap.hpp" + +#include "types/comparator.hpp" + +int +main (int, char**) +{ + util::TAP::logger tap; + + const auto a = { 1, 2, 3 }; + const auto b = { 1, 2, 4 }; + + tap.expect ( + util::comparator::indexed ()(a, b), + "compare initializer_list as a coordinate, success" + ); + + tap.expect ( + !util::comparator::indexed ()(b, a), + "compare initializer_list as a coordinate, failure" + ); + + return tap.status (); +} \ No newline at end of file diff --git a/types/comparator.hpp b/types/comparator.hpp index deb39eb1..934bd970 100644 --- a/types/comparator.hpp +++ b/types/comparator.hpp @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * Copyright 2012 Danny Robson + * Copyright 2012-2017 Danny Robson */ #ifndef __UTIL_TYPES_COMPARATOR_HPP @@ -19,14 +19,41 @@ #include -namespace util { +#include "./iterator.hpp" + +namespace util::comparator { template struct pointer_comparator { bool operator() (const std::unique_ptr &lhs, const std::unique_ptr &rhs); bool operator() (const T *lhs, const std::unique_ptr &rhs); bool operator() (const std::unique_ptr &lhs, const T *rhs); }; + + + /////////////////////////////////////////////////////////////////////////// + /// Provides a comparison interface for types exposing an index operator. + /// + /// Will return true if the first parameter has the first index that + /// compares less than the second parameter. Useful for providing a total + /// order of coordinate types where this doesn't make sense by default. + /// + /// \tparam T The container data type to compare. Must provide an index + /// operator. + template + struct indexed { + constexpr + bool operator() (const T &a, const T &b) + { + for (auto x: util::zip (a, b)) { + const auto &[i,j] = x; // clang-4.0: workaround for segfault. + if (i < j) return true; + if (i != j) return false; + } + + return false; + } + }; } -#include "util/types/comparator.ipp" +#include "./comparator.ipp" #endif diff --git a/types/comparator.ipp b/types/comparator.ipp index 86d6020a..f9a52ee2 100644 --- a/types/comparator.ipp +++ b/types/comparator.ipp @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * Copyright 2012 Danny Robson + * Copyright 2012-2017 Danny Robson */ #ifdef __UTIL_TYPES_COMPARATOR_IPP @@ -22,7 +22,7 @@ //----------------------------------------------------------------------------- -namespace util { +namespace util::comparator { template bool pointer_comparator::operator() (const std::unique_ptr &lhs,