nholthaus / units

a compile-time, header-only, dimensional analysis and unit conversion library built on c++14 with no dependencies.
http://nholthaus.github.io/units/
MIT License
938 stars 134 forks source link

Swap pow()s #261

Closed ts826848 closed 3 years ago

ts826848 commented 3 years ago

The pow() overload taking an unsigned second parameter was declared/defined after it was used in the other pow() implementation. This results in compilation errors [0]. Moving the unsigned overload above the signed overload fixes the issue.

[0]:

awang@rp units % cat test.cpp

int main() {}
awang@rp units % clang++ -I include/ -std=c++17 test.cpp
In file included from test.cpp:1:
In file included from include/units.h:50:
In file included from include/units/acceleration.h:49:
In file included from include/units/length.h:49:
include/units/core.h:1710:64: error: call to function 'pow' that is neither visible in the template definition nor
      found by argument-dependent lookup
                return y == 0 ? 1.0 : (y < 0 ? 1.0 / x * pow(x, y + 1) : x * pow(x, static_cast<unsigned lon...
                                                                             ^
include/units/core.h:1803:36: note: in instantiation of function template specialization
      'units::pow<double, long, 0>' requested here
                                        static_cast<CommonUnderlying>(pow(detail::PI_VAL, PiRatio::num / PiR...
                                                                      ^
include/units/core.h:1894:17: note: in instantiation of function template specialization
      'units::convert<units::detail::PI, units::conversion_factor<std::__1::ratio<1, 1>, units::dimension_t<>,
      std::__1::ratio<0, 1>, std::__1::ratio<0, 1> >, double, double, 0>' requested here
                return UnitTo(convert<typename UnitFrom::conversion_factor, typename UnitTo::conversion_factor,
                              ^
include/units/core.h:2440:18: note: in instantiation of function template specialization
      'units::convert<units::unit<units::conversion_factor<std::__1::ratio<1, 1>, units::dimension_t<>,
      std::__1::ratio<0, 1>, std::__1::ratio<0, 1> >, double, units::linear_scale>, units::unit<units::detail::PI,
      double, units::linear_scale>, 0>' requested here
                        return units::convert<units::unit<units::conversion_factor<std::ratio<1>, units::dim...
                                      ^
include/units/core.h:3045:71: note: in instantiation of function template specialization
      'units::unit<units::detail::PI, double, units::linear_scale>::operator double<double, 0>' requested here
                return CommonUnit(static_cast<typename CommonUnit::underlying_type>(lhs) * CommonUnit(rhs).value());
                                                                                    ^
include/units.h:118:123: note: in instantiation of function template specialization
      'units::operator*<units::unit<units::detail::PI, double, units::linear_scale>,
      units::unit<units::force::newtons_, double, units::linear_scale>, 0>' requested here
  ...mu0(pi * 4.0e-7 * newtons<>(1) / pow<2>(amperes<>(1)));    ///< vacuum permeability.
                     ^
include/units/core.h:1715:51: note: 'pow' should be declared prior to the call site
        constexpr detail::floating_point_promotion_t<T1> pow(T1 x, T2 y)
                                                         ^
include/units/core.h:1710:64: error: call to function 'pow' that is neither visible in the template definition nor
      found by argument-dependent lookup
                return y == 0 ? 1.0 : (y < 0 ? 1.0 / x * pow(x, y + 1) : x * pow(x, static_cast<unsigned lon...
                                                                             ^
include/units/core.h:3357:45: note: in instantiation of function template specialization
      'units::pow<double, int, 0>' requested here
                return decltype(units::pow<power>(value))(pow(value.value(), power));
                                                          ^
include/units.h:118:140: note: in instantiation of function template specialization 'units::pow<2,
      units::unit<units::current::amperes_, double, units::linear_scale>, 0>' requested here
  ...mu0(pi * 4.0e-7 * newtons<>(1) / pow<2>(amperes<>(1)));    ///< vacuum permeability.
                                      ^
include/units/core.h:1715:51: note: 'pow' should be declared prior to the call site
        constexpr detail::floating_point_promotion_t<T1> pow(T1 x, T2 y)
                                                         ^
2 errors generated.
ts826848 commented 3 years ago

Also, is it worth using an exponentiation-by-squares approach to pow() instead of the current linear approach? Don't think it'll make a huge difference, but it should be a fairly easy change, too.

coveralls commented 3 years ago

Coverage Status

Coverage remained the same at 0.0% when pulling e5d011e0d5bed6d086ee7d828606240ca18cf7ad on ts826848:fix-pows into f394648193e612754e1548b2c5628b7d4af5aabf on nholthaus:v3.x.

coveralls commented 3 years ago

Coverage Status

Coverage remained the same at 0.0% when pulling e5d011e0d5bed6d086ee7d828606240ca18cf7ad on ts826848:fix-pows into f394648193e612754e1548b2c5628b7d4af5aabf on nholthaus:v3.x.

nholthaus commented 3 years ago

Also, is it worth using an exponentiation-by-squares approach to pow() instead of the current linear approach? Don't think it'll make a huge difference, but it should be a fairly easy change, too.

Probably. I'd certainly take a PR for it.