From e40a5d631c7f6531b99c9feccc48102d8af24910 Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Thu, 1 Sep 2022 12:16:47 +0200 Subject: [PATCH] feat: solid angle support added --- src/core/CMakeLists.txt | 2 + src/core/include/units/generic/solid_angle.h | 104 +++++++++++++++++++ test/unit_test/static/angle_test.cpp | 11 +- 3 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 src/core/include/units/generic/solid_angle.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 431f258a..56f462af 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -45,6 +45,7 @@ add_library( include/units/exponent.h include/units/generic/angle.h include/units/generic/dimensionless.h + include/units/generic/solid_angle.h include/units/kind.h include/units/magnitude.h include/units/math.h @@ -83,6 +84,7 @@ endif() if(DEFINED ${projectPrefix}DOWNCAST_MODE) set(downcast_mode_options OFF ON AUTO) list(FIND downcast_mode_options "${${projectPrefix}DOWNCAST_MODE}" downcast_mode) + if(downcast_mode EQUAL -1) message(FATAL_ERROR "'${projectPrefix}DOWNCAST_MODE' should be one of ${downcast_mode_options} ('${${projectPrefix}DOWNCAST_MODE}' received)" diff --git a/src/core/include/units/generic/solid_angle.h b/src/core/include/units/generic/solid_angle.h new file mode 100644 index 00000000..eff9d388 --- /dev/null +++ b/src/core/include/units/generic/solid_angle.h @@ -0,0 +1,104 @@ +// 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 + +// IWYU pragma: begin_exports +#include +#include +#include +#include +// IWYU pragma: end_exports + +#include + +namespace units { + +struct steradian : named_unit {}; + +template +struct dim_solid_angle : derived_dimension, U, exponent, 2>> {}; + +struct square_degree : derived_scaled_unit, degree> {}; + +template +concept SolidAngle = QuantityOfT; + +template> U, Representation Rep = double> +using solid_angle = quantity, U, Rep>; + +#ifndef UNITS_NO_LITERALS + +inline namespace literals { + +// sr +constexpr auto operator"" _q_sr(unsigned long long l) +{ + gsl_ExpectsAudit(std::in_range(l)); + return solid_angle(static_cast(l)); +} +constexpr auto operator"" _q_sr(long double l) { return solid_angle(l); } + +// deg2 +constexpr auto operator"" _q_deg2(unsigned long long l) +{ + gsl_ExpectsAudit(std::in_range(l)); + return solid_angle(static_cast(l)); +} +constexpr auto operator"" _q_deg2(long double l) { return solid_angle(l); } + +} // namespace literals + +#endif // UNITS_NO_LITERALS + +#ifndef UNITS_NO_REFERENCES + +namespace solid_angle_references { + +inline constexpr auto sr = reference, steradian>{}; +inline constexpr auto deg2 = reference, square_degree>{}; + +} // namespace solid_angle_references + +namespace references { + +using namespace solid_angle_references; + +} // namespace references + +#endif // UNITS_NO_REFERENCES + +} // namespace units + +#ifndef UNITS_NO_ALIASES + +namespace units::aliases::inline solid_angle { + +template +using sr = units::solid_angle; + +template +using deg2 = units::solid_angle; + +} // namespace units::aliases::inline solid_angle + +#endif // UNITS_NO_ALIASES diff --git a/test/unit_test/static/angle_test.cpp b/test/unit_test/static/angle_test.cpp index ccbd692c..4abc679e 100644 --- a/test/unit_test/static/angle_test.cpp +++ b/test/unit_test/static/angle_test.cpp @@ -21,18 +21,20 @@ // SOFTWARE. #include +#include #include namespace { +// plane angle + using namespace units::references; +using namespace units::literals; static_assert(360 * deg == 1 * rot); static_assert(400 * grad == 1 * rot); static_assert(std::numbers::pi * 2 * rad == 1. * rot); -using namespace units::literals; - static_assert(360_q_deg == 1_q_rot); static_assert(400_q_grad == 1_q_rot); static_assert(std::numbers::pi * quantity_cast(2._q_rad) == quantity_cast(1._q_rot)); @@ -42,4 +44,9 @@ static_assert(units::aliases::deg(360) == units::aliases::rot(1)); static_assert(units::aliases::grad(400) == units::aliases::rot(1)); static_assert(std::numbers::pi * units::aliases::rad<>(2.) == units::aliases::rot<>(1.)); +// solid angle + +static_assert(1_q_rad * 1_q_rad == 1_q_sr); +static_assert(1_q_deg * 1_q_deg == 1_q_deg2); + } // namespace