Mercurial > lbo > hg > ctmp
changeset 10:43e0e42c373d
units: Also make division work
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Wed, 25 Mar 2020 16:52:28 +0100 |
parents | 25fd2f822fd7 |
children | 6461c5c09e5c |
files | src/units.cc |
diffstat | 1 files changed, 36 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/units.cc Wed Mar 25 16:34:54 2020 +0100 +++ b/src/units.cc Wed Mar 25 16:52:28 2020 +0100 @@ -22,6 +22,13 @@ A1::value - A2::value>::type type; }; +template <typename A1> +struct negate { + typedef typename mpl::integral_c< + typename std::make_signed<decltype(A1::value)>::type, -A1::value>::type + type; +}; + /// `quote` template <template <typename A1, typename... Rest> typename Op> struct make_lambda { @@ -79,6 +86,11 @@ typedef typename mpl::transform<U1, U2, make_lambda<minus>>::type type; }; +template <typename U> +struct invert_units { + typedef typename mpl::transform<U, make_lambda<negate>>::type type; +}; + // Quantity template <typename N, typename U> @@ -124,9 +136,9 @@ } }; -// Scalar multiplication +// Scalar multiplication/division template <typename N1, typename N2, typename U, - std::enable_if_t<std::is_arithmetic<N1>::value, int> = 0> + typename std::enable_if<std::is_arithmetic<N1>::value, int>::type = 0> quantity<typename std::common_type<N1, N2>::type, U> operator*( const quantity<N2, U>& second, const N1& first) { auto q = quantity<typename std::common_type<N1, N2>::type, U>(second.value * @@ -134,12 +146,30 @@ return q; } template <typename N1, typename N2, typename U, - std::enable_if_t<std::is_arithmetic<N1>::value, int> = 0> + typename std::enable_if<std::is_arithmetic<N1>::value, int>::type = 0> quantity<typename std::common_type<N1, N2>::type, U> operator*( const N1& first, const quantity<N2, U>& second) { return second * first; } +template <typename N1, typename N2, typename U, + typename std::enable_if<std::is_arithmetic<N1>::value, int>::type = 0> +quantity<typename std::common_type<N1, N2>::type, U> operator/( + const quantity<N1, U>& first, const N2& second) { + auto q = quantity<typename std::common_type<N1, N2>::type, U>(first.value / + second); + return q; +} +template <typename N1, typename N2, typename U, + typename std::enable_if<std::is_arithmetic<N1>::value, int>::type = 0> +quantity<typename std::common_type<N1, N2>::type, + typename mpl::transform<U, make_lambda<negate>>::type> +operator/(const N1& first, const quantity<N2, U>& second) { + typedef typename mpl::transform<U, make_lambda<negate>>::type inverted; + return quantity<typename std::common_type<N1, N2>::type, inverted>( + first / second.value); +} + static const quantity<int, METER> meter(1); static const quantity<int, SECOND> second(1); static const quantity<int, KILOGRAM> kilogram(1); @@ -150,9 +180,9 @@ int main(void) { auto force = 1 * kilogram * meter / (second * second); - auto x = 13.2 * force; - auto y = 2.3; - auto z = (x * x) / (x * y); + auto x = 1 / force; + auto y = 2.3 / x; + auto z = y; std::cout << std::string(z) << std::endl; return 0; }