diff --git a/src/include/units/math.h b/src/include/units/math.h new file mode 100644 index 00000000..377b1615 --- /dev/null +++ b/src/include/units/math.h @@ -0,0 +1,46 @@ +// 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 std::experimental::units { + + template + inline Quantity pow(const quantity& q) noexcept + { + using dim = dimension_pow_t; + using r = ratio_pow; + return quantity>, Rep>(std::pow(q.count(), N)); + } + + template + inline Quantity sqrt(const quantity& q) noexcept + { + using dim = dimension_sqrt_t; + using r = ratio_sqrt; + return quantity>, Rep>(std::sqrt(q.count())); + } + +} // namespace std::experimental::units diff --git a/src/include/units/ratio.h b/src/include/units/ratio.h index 157841f9..8a8a0a7f 100644 --- a/src/include/units/ratio.h +++ b/src/include/units/ratio.h @@ -118,6 +118,52 @@ namespace std::experimental::units { template using ratio_divide = detail::ratio_divide_impl::type; + // ratio_pow + + namespace detail { + + template + struct ratio_pow_impl { + using type = ratio_multiply::type, R>; + }; + + template + struct ratio_pow_impl { + using type = R; + }; + + } + + template + using ratio_pow = detail::ratio_pow_impl::type; + + // ratio_sqrt + + namespace detail { + + constexpr std::intmax_t sqrt_impl(std::intmax_t v, std::intmax_t l, std::intmax_t r) + { + if(l == r) + return r; + + const auto mid = (r + l) / 2; + if(mid * mid >= v) + return sqrt_impl(v, l, mid); + else + return sqrt_impl(v, mid + 1, r); + } + + static constexpr std::intmax_t sqrt_impl(std::intmax_t v) + { + return sqrt_impl(v, 1, v); + } + + } + + template + using ratio_sqrt = ratio; + + // common_ratio namespace detail { diff --git a/test/unit_test/test_custom_units.cpp b/test/unit_test/test_custom_units.cpp index f8991953..0e5f5c79 100644 --- a/test/unit_test/test_custom_units.cpp +++ b/test/unit_test/test_custom_units.cpp @@ -22,7 +22,7 @@ #include #include - +#include /* ************** DERIVED DIMENSIONS THAT INCLUDE UNITS WITH SPECIAL NAMES **************** */ @@ -68,11 +68,11 @@ namespace { using namespace stde::units; // power spectral density - struct power_spectral_density : make_dimension_t, exp> {}; + struct power_spectral_density : make_dimension_t, units::exp> {}; struct sq_volt_per_hertz : unit {}; // amplitude spectral density - struct amplitude_spectral_density : make_dimension_t, exp> {}; + struct amplitude_spectral_density : make_dimension_t, units::exp> {}; // todo: add support for derived_unit //struct volt_per_sq_hertz : derived_unit {}; struct volt_per_sqrt_hertz : unit {}; @@ -93,6 +93,7 @@ namespace { static_assert(std::is_same_v, amplitude_spectral_density>); static_assert(std::is_same_v, power_spectral_density>); - //static_assert(sqrt(quantity(4)) = quantity(2)); + static_assert(std::is_same_v(quantity(4))), decltype(quantity(16))>); + static_assert(std::is_same_v(16))), decltype(quantity(4))>); }