diff --git a/doc/DESIGN.md b/doc/DESIGN.md index 3330fe6d..723a40f2 100644 --- a/doc/DESIGN.md +++ b/doc/DESIGN.md @@ -39,7 +39,7 @@ static_assert(10_km / 5_km == 2); 3. No macros in the user interface 4. Easy extensibility 5. No external dependencies -6. Possibility to be standardized as a part of the C++ Standard Library +6. Possibility to be standardized as a freestanding part of the C++ Standard Library ## Basic Concepts @@ -111,7 +111,7 @@ However, such an approach have some challenges: constexpr Velocity auto v1 = 1_m / 1_s; constexpr Velocity auto v2 = 2 / 2_s * 1_m; -static_assert(Same); +static_assert(std::Same); static_assert(v1 == v2); ``` @@ -215,7 +215,7 @@ expressed in a specific unit of that dimension: ```cpp template - requires Same + requires std::Same class quantity; ``` @@ -233,7 +233,7 @@ member types and functions as below: ```cpp template - requires Same + requires std::Same class quantity { public: using dimension = D; @@ -248,13 +248,13 @@ public: template quantity, upcasting_traits_t, std::ratio>>, std::common_type_t> constexpr operator/(const Rep1& v, - const quantity& q); + const quantity& q) [[expects: q != quantity(0)]]; template requires treat_as_floating_point> || std::ratio_divide::den == 1 quantity, upcasting_traits_t, std::ratio_divide>>, std::common_type_t> constexpr operator/(const quantity& lhs, - const quantity& rhs); + const quantity& rhs) [[expects: rhs != quantity(0)]]; }; ``` @@ -285,14 +285,14 @@ C:\repos\units\example\example.cpp:39:22: error: deduced initializer does not sa ^~~~ In file included from C:\repos\units\example\example.cpp:23: C:/repos/units/src/include/units/si/velocity.h:41:16: note: within 'template concept const bool units::Velocity [with T = units::quantity >, units::unit >, std::ratio<1> >, long long int>]' - concept Velocity = Quantity && Same; + concept Velocity = Quantity && std::Same; ^~~~~~~~ In file included from C:/repos/units/src/include/units/bits/tools.h:25, from C:/repos/units/src/include/units/dimension.h:25, from C:/repos/units/src/include/units/si/base_dimensions.h:25, from C:/repos/units/src/include/units/si/velocity.h:25, from C:\repos\units\example\example.cpp:23: -C:/repos/units/src/include/units/bits/stdconcepts.h:33:18: note: within 'template concept const bool mp::std_concepts::Same [with T = units::dimension >; U = units::dimension, units::exp >]' +C:/repos/units/src/include/units/bits/stdconcepts.h:33:18: note: within 'template concept const bool std::Same [with T = units::dimension >; U = units::dimension, units::exp >]' concept Same = std::is_same_v; ^~~~ C:/repos/units/src/include/units/bits/stdconcepts.h:33:18: note: 'std::is_same_v' evaluated to false @@ -322,14 +322,14 @@ C:\repos\units\example\example.cpp:40:22: error: deduced initializer does not sa ^~~~ In file included from C:\repos\units\example\example.cpp:23: C:/repos/units/src/include/units/si/velocity.h:48:16: note: within 'template concept const bool units::Velocity [with T = units::quantity]' - concept Velocity = Quantity && Same; + concept Velocity = Quantity && std::Same; ^~~~~~~~ In file included from C:/repos/units/src/include/units/bits/tools.h:25, from C:/repos/units/src/include/units/dimension.h:25, from C:/repos/units/src/include/units/si/base_dimensions.h:25, from C:/repos/units/src/include/units/si/velocity.h:25, from C:\repos\units\example\example.cpp:23: -C:/repos/units/src/include/units/bits/stdconcepts.h:33:18: note: within 'template concept const bool mp::std_concepts::Same [with T = units::dimension_time; U = units::dimension_velocity]' +C:/repos/units/src/include/units/bits/stdconcepts.h:33:18: note: within 'template concept const bool std::Same [with T = units::dimension_time; U = units::dimension_velocity]' concept Same = std::is_same_v; ^~~~ C:/repos/units/src/include/units/bits/stdconcepts.h:33:18: note: 'std::is_same_v' evaluated to false @@ -379,36 +379,50 @@ template<> struct upcasting_traits> : upcast_to, exp> {}; template<> struct upcasting_traits> : upcast_to {}; ``` -2. Define the base unit (`std::ratio<1>`) and secondary ones and provide upcasting traits for them via: +2. Provide `quantity` class template partial specialization for new dimension and provide its base type: ```cpp -struct meter_per_second : unit> {}; -template<> struct upcasting_traits> : upcast_to {}; +template +using velocity = quantity; ``` 3. Define a concept that will match a new dimension: ```cpp template -concept Velocity = Quantity && Same; +concept Velocity = Quantity && std::Same; ``` -4. Provide user-defined literals for the most important units: +4. Define the base and secondary units and provide upcasting traits for them: + +```cpp +struct meter_per_second : derived_unit {}; +template<> struct upcasting_traits> : upcast_to {}; + +struct kilometer_per_hour : derived_unit {}; +template<> struct upcasting_traits> : upcast_to {}; +``` + +5. Provide user-defined literals for the most important units: ```cpp inline namespace literals { constexpr auto operator""_mps(unsigned long long l) { return velocity(l); } constexpr auto operator""_mps(long double l) { return velocity(l); } + + constexpr auto operator""_kmph(unsigned long long l) { return velocity(l); } + constexpr auto operator""_kmph(long double l) { return velocity(l); } } ``` @@ -507,7 +521,7 @@ Additionally, it should make the error logs even shorter thus easier to understa 17. Should we leave `quantity` and specific dimensions as ```cpp template - requires std::experimental::ranges::Same + requires std::Same class quantity; template