// 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 "stdconcepts.h" #include #include namespace std { template struct type_identity { using type = T; }; template using type_identity_t = typename type_identity::type; } namespace units { using namespace mp::std_concepts; // todo Remove when std::concepts will arrive template concept bool Number = requires(T a, T b) { { a + b } -> T; { a - b } -> T; { a * b } -> T; { a / b } -> T; { -a } -> T; { a += b } -> T&; { a -= b } -> T&; { a *= b } -> T&; { a /= b } -> T&; { T{0} };// can construct a T from a zero // … } ; // static_sign template struct static_sign : std::integral_constant { }; // static_abs template struct static_abs : std::integral_constant::value> { }; // static_gcd template struct static_gcd : static_gcd { }; template struct static_gcd : std::integral_constant::value> { }; template struct static_gcd<0, Qn> : std::integral_constant::value> { }; // is_ratio namespace detail { template inline constexpr bool is_ratio = false; template inline constexpr bool is_ratio> = true; } // namespace detail template concept bool Ratio = detail::is_ratio; // common_ratio // todo: simplified template struct common_ratio { using gcd_num = static_gcd; using gcd_den = static_gcd; using type = std::ratio; }; template using common_ratio_t = typename common_ratio::type; // upcastable template struct upcastable { using base_type = BaseType; }; // upcasting_traits template struct upcasting_traits : std::type_identity {}; template using upcasting_traits_t = typename upcasting_traits::type; } // namespace units