From cbcc6f46271c5ddd1d072625080ef8bbb7683df6 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Wed, 13 Sep 2023 08:55:06 +0200 Subject: [PATCH] feat: `compare.h` header added with checks against zero Resolves #487 --- example/include/geographic.h | 13 ++-- src/utility/include/mp-units/compare.h | 95 ++++++++++++++++++++++++++ test/unit_test/static/compare_test.cpp | 54 +++++++++++++++ 3 files changed, 156 insertions(+), 6 deletions(-) create mode 100644 src/utility/include/mp-units/compare.h create mode 100644 test/unit_test/static/compare_test.cpp diff --git a/example/include/geographic.h b/example/include/geographic.h index 07ce60f4..e24a0aab 100644 --- a/example/include/geographic.h +++ b/example/include/geographic.h @@ -24,6 +24,7 @@ #include "ranged_representation.h" #include +#include #include #include #include @@ -78,7 +79,7 @@ using longitude = mp_units::quantity_point std::basic_ostream& operator<<(std::basic_ostream& os, const latitude& lat) { - if (lat > latitude::zero()) + if (is_gt_zero(lat)) return os << lat.quantity_from_origin() << " N"; else return os << -lat.quantity_from_origin() << " S"; @@ -87,7 +88,7 @@ std::basic_ostream& operator<<(std::basic_ostream& template std::basic_ostream& operator<<(std::basic_ostream& os, const longitude& lon) { - if (lon > longitude::zero()) + if (is_gt_zero(lon)) return os << lon.quantity_from_origin() << " E"; else return os << -lon.quantity_from_origin() << " W"; @@ -137,8 +138,8 @@ struct MP_UNITS_STD_FMT::formatter> : auto format(geographic::latitude lat, FormatContext& ctx) { formatter::quantity_type>::format( - lat > geographic::latitude::zero() ? lat.quantity_from_origin() : -lat.quantity_from_origin(), ctx); - MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", lat > geographic::latitude::zero() ? " N" : "S"); + is_gt_zero(lat) ? lat.quantity_from_origin() : -lat.quantity_from_origin(), ctx); + MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", is_gt_zero(lat) ? " N" : "S"); return ctx.out(); } }; @@ -150,8 +151,8 @@ struct MP_UNITS_STD_FMT::formatter> : auto format(geographic::longitude lon, FormatContext& ctx) { formatter::quantity_type>::format( - lon > geographic::longitude::zero() ? lon.quantity_from_origin() : -lon.quantity_from_origin(), ctx); - MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", lon > geographic::longitude::zero() ? " E" : " W"); + is_gt_zero(lon) ? lon.quantity_from_origin() : -lon.quantity_from_origin(), ctx); + MP_UNITS_STD_FMT::format_to(ctx.out(), "{}", is_gt_zero(lon) ? " E" : " W"); return ctx.out(); } }; diff --git a/src/utility/include/mp-units/compare.h b/src/utility/include/mp-units/compare.h new file mode 100644 index 00000000..d94645b5 --- /dev/null +++ b/src/utility/include/mp-units/compare.h @@ -0,0 +1,95 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#pragma once + +#include + +namespace mp_units { + +template + requires requires { + { + T::zero() + } -> std::equality_comparable_with; + } +[[nodiscard]] constexpr bool is_eq_zero(T v) +{ + return v == T::zero(); +} + +template + requires requires { + { + T::zero() + } -> std::equality_comparable_with; + } +[[nodiscard]] constexpr bool is_neq_zero(T v) +{ + return v != T::zero(); +} + +template + requires requires { + { + T::zero() + } -> std::three_way_comparable_with; + } +[[nodiscard]] constexpr bool is_lt_zero(T v) +{ + return v < T::zero(); +} + +template + requires requires { + { + T::zero() + } -> std::three_way_comparable_with; + } +[[nodiscard]] constexpr bool is_gt_zero(T v) +{ + return v > T::zero(); +} + +template + requires requires { + { + T::zero() + } -> std::three_way_comparable_with; + } +[[nodiscard]] constexpr bool is_lteq_zero(T v) +{ + return v <= T::zero(); +} + +template + requires requires { + { + T::zero() + } -> std::three_way_comparable_with; + } +[[nodiscard]] constexpr bool is_gteq_zero(T v) +{ + return v >= T::zero(); +} + +} // namespace mp_units diff --git a/test/unit_test/static/compare_test.cpp b/test/unit_test/static/compare_test.cpp new file mode 100644 index 00000000..5de812d9 --- /dev/null +++ b/test/unit_test/static/compare_test.cpp @@ -0,0 +1,54 @@ +// The MIT License (MIT) +// +// Copyright (c) 2018 Mateusz Pusz +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include +#include + +namespace { + +using namespace mp_units::si::unit_symbols; + +static_assert(is_eq_zero(0 * m)); +static_assert(!is_eq_zero(1 * m)); +static_assert(!is_eq_zero(-1 * m)); + +static_assert(!is_neq_zero(0 * m)); +static_assert(is_neq_zero(1 * m)); +static_assert(is_neq_zero(-1 * m)); + +static_assert(!is_lt_zero(0 * m)); +static_assert(!is_lt_zero(1 * m)); +static_assert(is_lt_zero(-1 * m)); + +static_assert(!is_gt_zero(0 * m)); +static_assert(is_gt_zero(1 * m)); +static_assert(!is_gt_zero(-1 * m)); + +static_assert(is_lteq_zero(0 * m)); +static_assert(!is_lteq_zero(1 * m)); +static_assert(is_lteq_zero(-1 * m)); + +static_assert(is_gteq_zero(0 * m)); +static_assert(is_gteq_zero(1 * m)); +static_assert(!is_gteq_zero(-1 * m)); + +} // namespace