feat: degrees and rotations support added

Resolves #370
This commit is contained in:
Mateusz Pusz
2022-08-31 12:56:08 +02:00
parent 1a29726d34
commit 8b534c8d8b
3 changed files with 91 additions and 1 deletions

View File

@@ -32,7 +32,9 @@
namespace units {
struct radian : named_unit<radian, "rad"> {};
struct degree : named_unit<degree, "deg"> {};
struct rotation : named_scaled_unit<rotation, "rot", mag<360>(), degree> {};
struct radian : named_scaled_unit<radian, "rad", mag<ratio(1, 2)>() / pi, rotation> {};
template<Unit U = radian>
struct dim_angle : base_dimension<"A", U> {};
@@ -55,6 +57,22 @@ constexpr auto operator"" _q_rad(unsigned long long l)
}
constexpr auto operator"" _q_rad(long double l) { return angle<radian, long double>(l); }
// rot
constexpr auto operator"" _q_rot(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return angle<rotation, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_rot(long double l) { return angle<rotation, long double>(l); }
// deg
constexpr auto operator"" _q_deg(unsigned long long l)
{
gsl_ExpectsAudit(std::in_range<std::int64_t>(l));
return angle<degree, std::int64_t>(static_cast<std::int64_t>(l));
}
constexpr auto operator"" _q_deg(long double l) { return angle<degree, long double>(l); }
} // namespace literals
#endif // UNITS_NO_LITERALS
@@ -64,6 +82,8 @@ constexpr auto operator"" _q_rad(long double l) { return angle<radian, long doub
namespace angle_references {
inline constexpr auto rad = reference<dim_angle<>, radian>{};
inline constexpr auto rot = reference<dim_angle<>, rotation>{};
inline constexpr auto deg = reference<dim_angle<>, degree>{};
} // namespace angle_references
@@ -76,3 +96,18 @@ using namespace angle_references;
#endif // UNITS_NO_REFERENCES
} // namespace units
#ifndef UNITS_NO_ALIASES
namespace units::aliases::inline angle {
template<Representation Rep = double>
using rad = units::angle<units::radian, Rep>;
template<Representation Rep = double>
using rot = units::angle<units::rotation, Rep>;
template<Representation Rep = double>
using deg = units::angle<units::degree, Rep>;
} // namespace units::aliases::inline angle
#endif // UNITS_NO_ALIASES

View File

@@ -23,9 +23,11 @@
cmake_minimum_required(VERSION 3.2)
add_library(unit_tests_static_truncating quantity_test.cpp)
if(NOT ${projectPrefix}LIBCXX)
target_sources(unit_tests_static_truncating PRIVATE quantity_kind_test.cpp quantity_point_kind_test.cpp)
endif()
target_link_libraries(unit_tests_static_truncating PRIVATE mp-units::mp-units)
target_compile_options(
unit_tests_static_truncating PRIVATE $<IF:$<CXX_COMPILER_ID:MSVC>,/wd4242 /wd4244,-Wno-conversion>
@@ -33,6 +35,7 @@ target_compile_options(
add_library(
unit_tests_static
angle_test.cpp
cgs_test.cpp
chrono_test.cpp
concepts_test.cpp

View File

@@ -0,0 +1,52 @@
// 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 <units/generic/angle.h>
#include <numbers>
namespace {
using namespace units::references;
static_assert(360. * deg == 1. * rot);
static_assert(360 * deg == 1 * rot);
static_assert(std::numbers::pi * 2 * rad == 1. * rot);
} // namespace
namespace {
using namespace units::literals;
static_assert(360._q_deg == 1._q_rot);
static_assert(360_q_deg == 1_q_rot);
static_assert(std::numbers::pi * quantity_cast<double>(2._q_rad) == quantity_cast<double>(1._q_rot));
} // namespace
namespace {
static_assert(units::aliases::deg<>(360.) == units::aliases::rot<>(1.));
static_assert(units::aliases::deg<int>(360) == units::aliases::rot<int>(1));
static_assert(std::numbers::pi * units::aliases::rad<>(2.) == units::aliases::rot<>(1.));
} // namespace