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,