diff --git a/src/core/include/units/kind.h b/src/core/include/units/kind.h deleted file mode 100644 index 690dcbd5..00000000 --- a/src/core/include/units/kind.h +++ /dev/null @@ -1,68 +0,0 @@ -// 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 -#include - -namespace units { - -template -struct dynamic_origin; - -namespace detail { - -template -struct _kind_base : downcast_base<_kind_base> { - using base_kind = K; - using dimension = D; -}; - -template -struct _point_kind_base : downcast_base<_point_kind_base> { - using base_kind = K; - using dimension = typename K::dimension; - using origin = O; -}; - -} // namespace detail - -template - requires Kind>> -using downcast_kind = downcast>; - -template> - requires PointKind>> -using downcast_point_kind = downcast>; - -template -struct kind : downcast_dispatch> {}; - -template - requires std::same_as -struct derived_kind : downcast_dispatch> {}; - -template> -struct point_kind : downcast_dispatch> {}; - -} // namespace units diff --git a/src/core/include/units/quantity_kind.h b/src/core/include/units/quantity_kind.h deleted file mode 100644 index a47fd547..00000000 --- a/src/core/include/units/quantity_kind.h +++ /dev/null @@ -1,409 +0,0 @@ - -// 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 -// IWYU pragma: end_exports - -#include -#include -#include - -namespace units { - -namespace detail { - -template -inline constexpr auto make_quantity_kind_fn = [](auto&& q) { - using Q = std::remove_reference_t; - return quantity_kind(std::forward(q)); -}; - -template -inline constexpr auto& make_quantity_kind = make_quantity_kind_fn; - -template -inline constexpr auto downcasted_kind_fn = [](auto q) { - using Q = decltype(q); - return make_quantity_kind_fn>(std::move(q)); -}; - -template -inline constexpr auto& downcasted_kind = downcasted_kind_fn; - -template -concept quantity_kind_one = QuantityKind && equivalent> && - detail::quantity_one; - -} // namespace detail - -/** - * @brief A concept matching two related quantity kinds - * - * Satisfied by quantity kinds having equivalent base kinds. - */ -template -concept QuantityKindRelatedTo = QuantityKind && QuantityKind && - equivalent; - -/** - * @brief A quantity kind - * - * A quantity with more specific usage as determined by its kind. - * See https://jcgm.bipm.org/vim/en/1.2.html and NOTE 1 at https://jcgm.bipm.org/vim/en/1.1.html. - * - * @tparam K the kind of quantity - * @tparam U the measurement unit of the quantity kind - * @tparam Rep the type to be used to represent values of the quantity kind - */ -template U, Representation Rep = double> -class quantity_kind { -public: - using kind_type = K; - using quantity_type = quantity; - using dimension = typename quantity_type::dimension; - using unit = typename quantity_type::unit; - using rep = typename quantity_type::rep; - static constexpr units::reference reference{}; - -private: - quantity_type q_; - -public: - quantity_kind() = default; - quantity_kind(const quantity_kind&) = default; - quantity_kind(quantity_kind&&) = default; - - template - requires(Quantity> || QuantityLike> || - (Dimensionless && !Quantity>)) && - std::constructible_from - constexpr explicit quantity_kind(T&& t) : q_(std::forward(t)) - { - } - - template QK2> - requires std::convertible_to - constexpr explicit(false) quantity_kind(const QK2& qk) : q_(qk.common()) - { - } - - quantity_kind& operator=(const quantity_kind&) = default; - quantity_kind& operator=(quantity_kind&&) = default; - - [[nodiscard]] constexpr quantity_type& common() & noexcept { return q_; } - [[nodiscard]] constexpr const quantity_type& common() const& noexcept { return q_; } - [[nodiscard]] constexpr quantity_type&& common() && noexcept { return std::move(q_); } - [[nodiscard]] constexpr const quantity_type&& common() const&& noexcept { return std::move(q_); } - - [[nodiscard]] static constexpr quantity_kind zero() noexcept - requires requires { quantity_type::zero(); } - { - return quantity_kind(quantity_type::zero()); - } - - [[nodiscard]] static constexpr quantity_kind one() noexcept - requires requires { quantity_type::one(); } - { - return quantity_kind(quantity_type::one()); - } - - [[nodiscard]] static constexpr quantity_kind min() noexcept - requires requires { quantity_type::min(); } - { - return quantity_kind(quantity_type::min()); - } - - [[nodiscard]] static constexpr quantity_kind max() noexcept - requires requires { quantity_type::max(); } - { - return quantity_kind(quantity_type::max()); - } - - [[nodiscard]] constexpr quantity_kind operator+() const - requires requires(quantity_type q) { +q; } - { - return *this; - } - - [[nodiscard]] constexpr QuantityKind auto operator-() const - requires requires(quantity_type q) { -q; } - { - return detail::make_quantity_kind(-q_); - } - - constexpr quantity_kind& operator++() - requires requires(quantity_type q) { ++q; } - { - ++q_; - return *this; - } - - [[nodiscard]] constexpr quantity_kind operator++(int) - requires requires(quantity_type q) { q++; } - { - return quantity_kind(q_++); - } - - constexpr quantity_kind& operator--() - requires requires(quantity_type q) { --q; } - { - --q_; - return *this; - } - - [[nodiscard]] constexpr quantity_kind operator--(int) - requires requires(quantity_type q) { q--; } - { - return quantity_kind(q_--); - } - - constexpr quantity_kind& operator+=(const quantity_kind& qk) - requires requires(quantity_type q) { q += qk.common(); } - { - q_ += qk.common(); - return *this; - } - - constexpr quantity_kind& operator-=(const quantity_kind& qk) - requires requires(quantity_type q) { q -= qk.common(); } - { - q_ -= qk.common(); - return *this; - } - - template - constexpr quantity_kind& operator*=(const Rep2& rhs) - requires requires(quantity_type q) { q *= rhs; } - { - q_ *= rhs; - return *this; - } - template QK> - constexpr quantity_kind& operator*=(const QK& rhs) - requires requires(quantity_type q) { q *= rhs.common(); } - { - q_ *= rhs.common(); - return *this; - } - - template - constexpr quantity_kind& operator/=(const Rep2& rhs) - requires requires(quantity_type q) { q /= rhs; } - { - gsl_ExpectsAudit(rhs != quantity_values::zero()); - q_ /= rhs; - return *this; - } - template QK> - constexpr quantity_kind& operator/=(const QK& rhs) - requires requires(quantity_type q) { q /= rhs.common(); } - { - q_ /= rhs.common(); - return *this; - } - - template - constexpr quantity_kind& operator%=(const Rep2& rhs) - requires(!Quantity || Dimensionless) && requires(quantity_type q, const Rep2 r) { q %= r; } - { - gsl_ExpectsAudit(rhs != quantity_values::zero()); - q_ %= rhs; - return *this; - } - - template - constexpr quantity_kind& operator%=(const QK& rhs) - requires(QuantityKindEquivalentTo || detail::quantity_kind_one) && - requires(quantity_type q) { q %= rhs.common(); } - { - gsl_ExpectsAudit(rhs.common().number() != quantity_values::zero()); - q_ %= rhs.common(); - return *this; - } - - // Hidden Friends - // Below friend functions are to be found via argument-dependent lookup only - template - [[nodiscard]] friend constexpr QuantityKind auto operator*(const quantity_kind& qk, const Value& v) - requires requires(quantity_type q) { - { - q* v - } -> Quantity; - } - { - return detail::make_quantity_kind(qk.common() * v); - } - - template - [[nodiscard]] friend constexpr QuantityKind auto operator*(const Value& v, const quantity_kind& qk) - requires requires(quantity_type q) { - { - v* q - } -> Quantity; - } - { - return detail::make_quantity_kind(v * qk.common()); - } - - template - [[nodiscard]] friend constexpr QuantityKind auto operator/(const quantity_kind& qk, const Value& v) - requires requires(quantity_type q) { - { - q / v - } -> Quantity; - } - { - gsl_ExpectsAudit(v != quantity_values::zero()); - return detail::make_quantity_kind(qk.common() / v); - } - - template - [[nodiscard]] friend constexpr QuantityKind auto operator/(const Value& v, const quantity_kind& qk) - requires requires(quantity_type q) { - { - v / q - } -> Quantity; - } - { - gsl_ExpectsAudit(qk.common().number() != quantity_values::zero()); - return detail::downcasted_kind(v / qk.common()); - } - - template - [[nodiscard]] friend constexpr QuantityKind auto operator%(const quantity_kind& qk, const Value& v) - requires requires(quantity_type q) { q % v; } - { - gsl_ExpectsAudit(v != quantity_values::zero()); - return detail::make_quantity_kind(qk.common() % v); - } - - [[nodiscard]] friend constexpr auto operator<=>(const quantity_kind& lhs, const quantity_kind& rhs) - requires std::three_way_comparable - { - return lhs.common() <=> rhs.common(); - } - - [[nodiscard]] friend constexpr bool operator==(const quantity_kind&, const quantity_kind&) = default; -}; - -template QK2> -[[nodiscard]] constexpr QuantityKind auto operator+(const QK1& lhs, const QK2& rhs) - requires requires { lhs.common() + rhs.common(); } -{ - return detail::make_quantity_kind(lhs.common() + rhs.common()); -} - -template QK2> -[[nodiscard]] constexpr QuantityKind auto operator-(const QK1& lhs, const QK2& rhs) - requires requires { lhs.common() - rhs.common(); } -{ - return detail::make_quantity_kind(lhs.common() - rhs.common()); -} - -template -[[nodiscard]] constexpr QuantityKind auto operator*(const QK& lhs, const Q& rhs) - requires requires { lhs.common() * rhs; } -{ - return detail::downcasted_kind(lhs.common() * rhs); -} - -template -[[nodiscard]] constexpr QuantityKind auto operator*(const Q& lhs, const QK& rhs) - requires requires { lhs* rhs.common(); } -{ - return detail::downcasted_kind(lhs * rhs.common()); -} - -template QK2> -[[nodiscard]] constexpr QuantityKind auto operator*(const QK1& lhs, const QK2& rhs) - requires requires { lhs.common() * rhs.common(); } -{ - return detail::downcasted_kind(lhs.common() * rhs.common()); -} - -template -[[nodiscard]] constexpr QuantityKind auto operator/(const QK& lhs, const Q& rhs) - requires requires { lhs.common() / rhs; } -{ - gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - return detail::downcasted_kind(lhs.common() / rhs); -} - -template -[[nodiscard]] constexpr QuantityKind auto operator/(const Q& lhs, const QK& rhs) - requires requires { lhs / rhs.common(); } -{ - gsl_ExpectsAudit(rhs.common().number() != quantity_values::zero()); - return detail::downcasted_kind(lhs / rhs.common()); -} - -template QK2> -[[nodiscard]] constexpr QuantityKind auto operator/(const QK1& lhs, const QK2& rhs) - requires requires { lhs.common() / rhs.common(); } -{ - return detail::downcasted_kind(lhs.common() / rhs.common()); -} - -template -[[nodiscard]] constexpr QuantityKind auto operator%(const QK& lhs, const D& rhs) - requires requires { lhs.common() % rhs; } -{ - gsl_ExpectsAudit(rhs.number() != quantity_values::zero()); - return detail::make_quantity_kind(lhs.common() % rhs); -} - -template QK2> -[[nodiscard]] constexpr QuantityKind auto operator%(const QK1& lhs, const QK2& rhs) - requires requires { lhs.common() % rhs.common(); } -{ - gsl_ExpectsAudit(rhs.common().number() != quantity_values::zero()); - return detail::make_quantity_kind(lhs.common() % rhs.common()); -} - -template QK2> - requires std::three_way_comparable_with -[[nodiscard]] constexpr auto operator<=>(const QK1& lhs, const QK2& rhs) -{ - return lhs.common() <=> rhs.common(); -} - -template QK2> - requires std::equality_comparable_with -[[nodiscard]] constexpr bool operator==(const QK1& lhs, const QK2& rhs) -{ - return lhs.common() == rhs.common(); -} - -// type traits -namespace detail { - -template -inline constexpr bool is_quantity_kind> = true; - -} // namespace detail - -} // namespace units diff --git a/src/core/include/units/quantity_point_kind.h b/src/core/include/units/quantity_point_kind.h deleted file mode 100644 index 837ab301..00000000 --- a/src/core/include/units/quantity_point_kind.h +++ /dev/null @@ -1,202 +0,0 @@ - -// 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 -// IWYU pragma: end_exports - -namespace units { - -/** - * @brief A quantity point kind - * - * An absolute quantity kind measured from an origin. - * - * @tparam PK the point kind of quantity point - * @tparam U the measurement unit of the quantity point kind - * @tparam Rep the type to be used to represent values of the quantity point kind - */ -template U, Representation Rep = double> -class quantity_point_kind { -public: - using point_kind_type = PK; - using kind_type = typename PK::base_kind; - using origin = typename point_kind_type::origin; - using quantity_kind_type = quantity_kind; - using quantity_type = typename quantity_kind_type::quantity_type; - using dimension = typename quantity_type::dimension; - using unit = typename quantity_type::unit; - using rep = typename quantity_type::rep; - static constexpr units::reference reference{}; - -private: - quantity_kind_type qk_; - -public: - quantity_point_kind() = default; - quantity_point_kind(const quantity_point_kind&) = default; - quantity_point_kind(quantity_point_kind&&) = default; - - template - requires std::constructible_from - constexpr explicit quantity_point_kind(T&& t) : qk_(std::forward(t)) - { - } - - constexpr explicit quantity_point_kind(const quantity_point& qp) : qk_(qp.relative()) {} - constexpr explicit quantity_point_kind(quantity_point&& qp) : qk_(std::move(qp).relative()) {} - - template - requires(std::constructible_from, QP>) - constexpr explicit quantity_point_kind(const QP& qp) : qk_(quantity_point_like_traits::relative(qp)) - { - } - - template QPK2> - requires std::convertible_to - constexpr explicit(false) quantity_point_kind(const QPK2& qpk) : qk_(qpk.relative()) - { - } - - quantity_point_kind& operator=(const quantity_point_kind&) = default; - quantity_point_kind& operator=(quantity_point_kind&&) = default; - - [[nodiscard]] constexpr quantity_kind_type& relative() & noexcept { return qk_; } - [[nodiscard]] constexpr const quantity_kind_type& relative() const& noexcept { return qk_; } - [[nodiscard]] constexpr quantity_kind_type&& relative() && noexcept { return std::move(qk_); } - [[nodiscard]] constexpr const quantity_kind_type&& relative() const&& noexcept { return std::move(qk_); } - - [[nodiscard]] static constexpr quantity_point_kind min() noexcept - requires requires { quantity_kind_type::min(); } - { - return quantity_point_kind(quantity_kind_type::min()); - } - - [[nodiscard]] static constexpr quantity_point_kind max() noexcept - requires requires { quantity_kind_type::max(); } - { - return quantity_point_kind(quantity_kind_type::max()); - } - - constexpr quantity_point_kind& operator++() - requires requires(quantity_kind_type qk) { ++qk; } - { - ++qk_; - return *this; - } - - [[nodiscard]] constexpr quantity_point_kind operator++(int) - requires requires(quantity_kind_type qk) { qk++; } - { - return quantity_point_kind(qk_++); - } - - constexpr quantity_point_kind& operator--() - requires requires(quantity_kind_type qk) { --qk; } - { - --qk_; - return *this; - } - - [[nodiscard]] constexpr quantity_point_kind operator--(int) - requires requires(quantity_kind_type qk) { qk--; } - { - return quantity_point_kind(qk_--); - } - - constexpr quantity_point_kind& operator+=(const quantity_kind_type& qk) - requires requires(quantity_kind_type qk1, const quantity_kind_type qk2) { qk1 += qk2; } - { - qk_ += qk; - return *this; - } - - constexpr quantity_point_kind& operator-=(const quantity_kind_type& qk) - requires requires(quantity_kind_type qk1, const quantity_kind_type qk2) { qk1 -= qk2; } - { - qk_ -= qk; - return *this; - } - - // Hidden Friends - // Below friend functions are to be found via argument-dependent lookup only - - template - [[nodiscard]] friend constexpr QuantityPointKind auto operator+(const quantity_point_kind& lhs, const QK& rhs) - requires requires(quantity_kind_type qk) { qk + rhs; } - { - return units::quantity_point_kind(lhs.relative() + rhs); - } - - template - [[nodiscard]] friend constexpr QuantityPointKind auto operator+(const QK& lhs, const quantity_point_kind& rhs) - requires requires(quantity_kind_type qk) { lhs + qk; } - { - return units::quantity_point_kind(lhs + rhs.relative()); - } - - template - [[nodiscard]] friend constexpr QuantityPointKind auto operator-(const quantity_point_kind& lhs, const QK& rhs) - requires requires(quantity_kind_type qk) { qk - rhs; } - { - return units::quantity_point_kind(lhs.relative() - rhs); - } - - template QPK> - [[nodiscard]] friend constexpr QuantityKind auto operator-(const quantity_point_kind& lhs, const QPK& rhs) - requires requires(quantity_kind_type qk) { qk - qk; } - { - return lhs.relative() - rhs.relative(); - } - - template QPK> - requires std::three_way_comparable_with - [[nodiscard]] friend constexpr auto operator<=>(const quantity_point_kind& lhs, const QPK& rhs) - { - return lhs.relative() <=> rhs.relative(); - } - - template QPK> - requires std::equality_comparable_with - [[nodiscard]] friend constexpr bool operator==(const quantity_point_kind& lhs, const QPK& rhs) - { - return lhs.relative() == rhs.relative(); - } -}; - -template -quantity_point_kind(QK) - -> quantity_point_kind, typename QK::unit, typename QK::rep>; - -namespace detail { - -template -inline constexpr bool is_quantity_point_kind> = true; - -} // namespace detail - -} // namespace units