From bce17a8476b9c42468aa25765cfc2af29f81026a Mon Sep 17 00:00:00 2001 From: Mateusz Pusz Date: Tue, 10 Sep 2019 21:20:32 +0200 Subject: [PATCH] Fractional dimension exponents support added --- src/include/units/dimension.h | 30 ++++++++----- src/include/units/unit.h | 16 +++---- test/unit_test/CMakeLists.txt | 1 + test/unit_test/test_custom_units.cpp | 64 ++++++++++++++++++++++++++++ test/unit_test/test_dimension.cpp | 3 ++ 5 files changed, 95 insertions(+), 19 deletions(-) create mode 100644 test/unit_test/test_custom_units.cpp diff --git a/src/include/units/dimension.h b/src/include/units/dimension.h index 47039cae..d78f8177 100644 --- a/src/include/units/dimension.h +++ b/src/include/units/dimension.h @@ -24,6 +24,8 @@ #include #include +#include +#include namespace std::experimental::units { @@ -60,10 +62,11 @@ namespace std::experimental::units { // exp - template + template struct exp { static constexpr const base_dimension& dimension = BaseDimension; - static constexpr int value = Value; + static constexpr int num = Num; + static constexpr int den = Den; }; // is_exp @@ -71,8 +74,8 @@ namespace std::experimental::units { template inline constexpr bool is_exp = false; - template - inline constexpr bool is_exp> = true; + template + inline constexpr bool is_exp> = true; } // namespace detail template @@ -89,9 +92,9 @@ namespace std::experimental::units { template struct exp_invert; - template - struct exp_invert> { - using type = exp; + template + struct exp_invert> { + using type = exp; }; template @@ -131,6 +134,7 @@ namespace std::experimental::units { using dim_invert_t = dim_invert::type; + // todo: force as the only user interface to create dimensions through modules // make_dimension namespace detail { @@ -157,10 +161,14 @@ namespace std::experimental::units { using type = conditional>, dimension, type_list_push_front>; }; - template - struct dim_consolidate, exp, ERest...>> { - using type = conditional>, - dim_consolidate_t, ERest...>>>; + template + struct dim_consolidate, exp, ERest...>> { + // todo: provide custom implementation for ratio_add + using r1 = std::ratio; + using r2 = std::ratio; + using r = std::ratio_add; + using type = conditional>, + dim_consolidate_t, ERest...>>>; }; } // namespace detail diff --git a/src/include/units/unit.h b/src/include/units/unit.h index c9ccb3d5..15e69e61 100644 --- a/src/include/units/unit.h +++ b/src/include/units/unit.h @@ -78,20 +78,20 @@ namespace std::experimental::units { typename get_ratio::ratio>; }; - template + template struct ratio_op; - template - struct ratio_op { + template + struct ratio_op { using ratio = Result; }; - template + template struct ratio_op { - using calc_ratio = conditional<(UnitExpValue > 0), ratio_multiply, + using calc_ratio = conditional<(UnitExpNum * UnitExpDen > 0), ratio_multiply, ratio_divide>; - static constexpr int value = UnitExpValue > 0 ? UnitExpValue - 1 : UnitExpValue + 1; - using ratio = ratio_op::ratio; + static constexpr int value = (UnitExpNum * UnitExpDen > 0) ? (UnitExpNum - UnitExpDen) : (UnitExpNum + UnitExpDen); + using ratio = ratio_op::ratio; }; template @@ -106,7 +106,7 @@ namespace std::experimental::units { struct derived_ratio, Us...> { using rest_ratio = derived_ratio, Us...>::ratio; using e_ratio = get_ratio::ratio; - using ratio = ratio_op::ratio; + using ratio = ratio_op::ratio; }; } diff --git a/test/unit_test/CMakeLists.txt b/test/unit_test/CMakeLists.txt index 9637450e..cbb5f987 100644 --- a/test/unit_test/CMakeLists.txt +++ b/test/unit_test/CMakeLists.txt @@ -22,6 +22,7 @@ # unit tests add_library(unit_tests + test_custom_units.cpp test_dimension.cpp test_quantity.cpp test_tools.cpp diff --git a/test/unit_test/test_custom_units.cpp b/test/unit_test/test_custom_units.cpp new file mode 100644 index 00000000..a7c8c77b --- /dev/null +++ b/test/unit_test/test_custom_units.cpp @@ -0,0 +1,64 @@ +// 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 + + +/* ************** DERIVED DIMENSIONS THAT INCLUDE UNITS WITH SPECIAL NAMES **************** */ + +namespace { + +using namespace std::experimental::units; + + // power spectral density + // todo: add support for make_dimension_t of non base units + // struct power_spectral_density : make_dimension_t, exp> {}; + struct power_spectral_density + : make_dimension_t, exp, exp, exp> { + }; + struct sq_volt_per_hertz : unit {}; + + // amplitude spectral density + // struct dimension_amplitude_spectral_density : make_dimension_t, exp> {}; + struct amplitude_spectral_density + : make_dimension_t, exp, exp, exp, exp> { + }; + // todo: add support for derived_unit + //struct volt_per_sq_hertz : derived_unit {}; + struct volt_per_sqrt_hertz : unit {}; +} + +namespace std::experimental::units { + +template<> struct downcasting_traits> : downcast_to {}; +template<> struct downcasting_traits> : downcast_to {}; + +template<> struct downcasting_traits> : downcast_to {}; +template<> struct downcasting_traits> : downcast_to {}; + +} + +namespace { + + //static_assert(sqrt(quantity(4)) = quantity(2)); + +} diff --git a/test/unit_test/test_dimension.cpp b/test/unit_test/test_dimension.cpp index 8f4bb9bb..182c54b5 100644 --- a/test/unit_test/test_dimension.cpp +++ b/test/unit_test/test_dimension.cpp @@ -44,6 +44,9 @@ namespace { static_assert(std::is_same_v, exp>, dimension, exp>>); static_assert(std::is_same_v, exp>, dimension>>); static_assert(std::is_same_v, exp>, dimension<>>); + static_assert(std::is_same_v, exp>, dimension>>); + static_assert(std::is_same_v, exp>, dimension>>); + static_assert(std::is_same_v, exp>, dimension>>); static_assert(std::is_same_v, exp, exp, exp>, dimension, exp>>); static_assert(