-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plain and system-specific dimensions #281
Comments
It may also help to address #211. |
If I understand correctly the problem you are referring to, You can use a metafunction (traits class) rather than embed the unit in dimension template parameters. see #187 (comment) |
Thanks, @kwikius. Yes, I know I can use more definitions (type traits, template variables, functions...) to provide additional information about each dimension. However, one of the goals of this library to be able to specify stuff as simple as possible and I believe that one definition like we had until now is the way to go (also based on the feedback of my users). Otherwise, we will invent macros as most other libs do... Actually, the problem I am referring to is not to change the definition of existing dimensions. Hopefully, they will remain as close as possible to: What I want to achieve with this change is to improve the ISQ part: The ISQ is about quantities and not specific units. Right now it is solved with template templates is the system definition. I would prefer it to be an inherent part of the library's framework and not use template templates to work around the fact that system dimensions are specified in terms of their coherent units. As a result, I would like to have:
|
You'll probably need to start by making the systems explicit. See https://godbolt.org/z/ajfrsajK1. #include <type_traits>
consteval auto sysof(auto v) { return system(v); }
namespace units {
struct generic_system {};
consteval generic_system system(auto) { return {}; }
struct dim_angle {};
namespace isq {
struct isq_system {};
consteval isq_system system(auto) { return {}; }
namespace si {
struct si_system {};
consteval si_system system(auto) { return {}; }
struct dim_length {};
}
}
}
static_assert(std::is_same_v<decltype(sysof(units::dim_angle{})), units::generic_system>);
static_assert(std::is_same_v<decltype(sysof(units::isq::si::dim_length{})), units::isq::si::si_system>); IIRC, you want non-system units for what's in code currently called equivalent dimensions, right? Because the indirection ensures that equivalent base dimensions have the same symbols and that equivalent derived dimensions have equivalent exponents. You could look at https://godbolt.org/z/hfqja1 from #248 for inspiration. With system in hand, you are be able to make base dimensions downcastable in conjunction with its symbol too. However, you can't use You'll probably want a struct dim_speed : isq::dim_speed<dim_speed, metre_per_second, dim_length, dim_time> {};
struct dim_speed : isq::dim_speed<dim_speed, metre_per_second> {}; But first, you need to deal with namespace units::isq {
template<typename Child, Unit U, DimensionOfT<dim_length> L, DimensionOfT<dim_time> T>
struct dim_speed<Child, U, L, T> : derived_dimension<Child, U, exponent<L, 1>, exponent<T, -1>> {}; You know Then you might end up with something like this: namespace units::isq {
template<typename Child, Unit U>
struct dim_speed<Child, U, L, T> : derived_dimension<Child, U, exponent<downcast_base_dimension<symbol-of-length-dimension, sysof<Child>()>, 1>, exponent<downcast_base_dimension<symbol-of-time-dimension, sysof<Child>()>, -1>> {}; Does that last line looks like what you want to achieve? |
Yes, I would like the "plain" dimension to scope only on the dimensional equation definition (symbol + exponents). With this, two system dimensions would be equivalent if they would have the same plain dimension. System dimension would add system-specific units to it. Note that the exponents may differ (i.e. area in some systems may be defined as "length[m] * length[mm]"). |
I am not so sure about it and would prefer to not introduce yet another dedicated abstraction.
Simplifying a definition could be nice but also can be limiting. For example, let's assume that we move dimensions based on angle to |
What's stopping you from doing just that?
You want to decouple things that are inherently coupled here, because they carry more information that necessary. I don't see a portable way around this without reflection. However, I believe you might be able to do away with it, too, once you've refactored enough that you don't need the dimensions in
Are you pointing out that this might break |
Lack of time 😉 I didn't work on it too much yet but hopefully I will start soon. I like your suggestions and maybe we will go this way. I need some time to experiment... |
Makes sense, considering that everything can be solved with another level of indirection (or so they say, don't quote me on that). I was wondering if you had run into problems implementing that, actually. |
Done in V2 |
Split the design to provide:
base_dimension
andderived_dimension
defined without the associated unitsystem_base_dimension
andsystem_derived_dimension
defined in the terms of the previous ones and a system-specific base/coherent unit.The text was updated successfully, but these errors were encountered: