forked from mpusz/mp-units
merge_dimension added
This commit is contained in:
53
README.md
53
README.md
@@ -117,29 +117,13 @@ So for example to create a `dimension_velocity` type we have to do:
|
|||||||
struct dimension_velocity : make_dimension_t<exp<base_dim_length, 1>, exp<base_dim_time, -1>> {};
|
struct dimension_velocity : make_dimension_t<exp<base_dim_length, 1>, exp<base_dim_time, -1>> {};
|
||||||
```
|
```
|
||||||
|
|
||||||
Also for example to return the result of multiplying two different dimensions we have to
|
|
||||||
create a final dimension type using:
|
|
||||||
|
|
||||||
```cpp
|
|
||||||
template<Dimension D1, Dimension D2>
|
|
||||||
struct dimension_multiply;
|
|
||||||
|
|
||||||
template<Exponent... E1, Exponent... E2>
|
|
||||||
struct dimension_multiply<dimension<E1...>, dimension<E2...>> {
|
|
||||||
using type = upcasting_traits_t<make_dimension_t<E1..., E2...>>;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<Dimension D1, Dimension D2>
|
|
||||||
using dimension_multiply_t = typename dimension_multiply<typename D1::base_type, typename D2::base_type>::type;
|
|
||||||
```
|
|
||||||
|
|
||||||
In order to make `make_dimension_t` work as expected it has to provide unique ordering for
|
In order to make `make_dimension_t` work as expected it has to provide unique ordering for
|
||||||
contained base dimensions. Beside providing ordering to base dimensions it also has to:
|
contained base dimensions. Beside providing ordering to base dimensions it also has to:
|
||||||
- aggregate two arguments of the same base dimension but different exponents
|
- aggregate two arguments of the same base dimension but different exponents
|
||||||
- eliminate two arguments of the same base dimension and with opposite equal exponents
|
- eliminate two arguments of the same base dimension and with opposite equal exponents
|
||||||
|
|
||||||
Additionally, it would be good if the final type produced by `make_dimension_t` would be easy to
|
Additionally, it would be good if the final type produced by `make_dimension_t` would be easy to
|
||||||
understand by the user. For example we may decide to order base dimensions with decreasing order of
|
understand for the user. For example we may decide to order base dimensions with decreasing order of
|
||||||
their exponents. That is why second sorting of a type list may be required. For example:
|
their exponents. That is why second sorting of a type list may be required. For example:
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
@@ -149,6 +133,39 @@ struct make_dimension {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
#### `merge_dimension`
|
||||||
|
|
||||||
|
`units::merge_dimension` is similar to `make_dimension` but instead of sorting the whole list
|
||||||
|
of base dimensions from scratch it assumes that provided input `dimension` types are already
|
||||||
|
sorted as a result of `make_dimension`.
|
||||||
|
|
||||||
|
Typical use case for `merge_dimension` is to produce final `dimension` return type of multiplying
|
||||||
|
two different dimensions:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template<Dimension D1, Dimension D2>
|
||||||
|
struct dimension_multiply;
|
||||||
|
|
||||||
|
template<Exponent... E1, Exponent... E2>
|
||||||
|
struct dimension_multiply<dimension<E1...>, dimension<E2...>> {
|
||||||
|
using type = upcasting_traits_t<merge_dimension_t<E1..., E2...>>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<Dimension D1, Dimension D2>
|
||||||
|
using dimension_multiply_t = typename dimension_multiply<typename D1::base_type, typename D2::base_type>::type;
|
||||||
|
```
|
||||||
|
|
||||||
|
Example implementation of `merge_dimension` may look like:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
template<Exponent... Es>
|
||||||
|
struct merge_dimension {
|
||||||
|
using type = mp::type_list_sort_t<detail::dim_consolidate_t<mp::type_list_merge_sorted_t<dimension<Es...>, exp_dim_id_less>>, exp_greater_equal>;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
### `Units`
|
### `Units`
|
||||||
|
|
||||||
`units::unit` is a class template that expresses the unit of a specific physical dimension:
|
`units::unit` is a class template that expresses the unit of a specific physical dimension:
|
||||||
@@ -414,7 +431,7 @@ Additionally, it should make the error logs even shorter thus easier to understa
|
|||||||
|
|
||||||
In such a case all the operators have to be provided to a child class. Or maybe use CRTP?
|
In such a case all the operators have to be provided to a child class. Or maybe use CRTP?
|
||||||
|
|
||||||
3. What to do with time which ia ambiguous?
|
3. What to do with `time` which is ambiguous?
|
||||||
|
|
||||||
4. What to do with `std::chrono::duration`?
|
4. What to do with `std::chrono::duration`?
|
||||||
|
|
||||||
|
@@ -162,13 +162,21 @@ namespace units {
|
|||||||
template<Exponent... Es>
|
template<Exponent... Es>
|
||||||
using make_dimension_t = typename make_dimension<Es...>::type;
|
using make_dimension_t = typename make_dimension<Es...>::type;
|
||||||
|
|
||||||
|
template<Exponent... Es>
|
||||||
|
struct merge_dimension {
|
||||||
|
using type = mp::type_list_sort_t<detail::dim_consolidate_t<mp::type_list_merge_sorted_t<dimension<Es...>, exp_dim_id_less>>, exp_greater_equal>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<Exponent... Es>
|
||||||
|
using merge_dimension_t = typename merge_dimension<Es...>::type;
|
||||||
|
|
||||||
// dimension_multiply
|
// dimension_multiply
|
||||||
|
|
||||||
template<Dimension D1, Dimension D2>
|
template<Dimension D1, Dimension D2>
|
||||||
struct dimension_multiply;
|
struct dimension_multiply;
|
||||||
|
|
||||||
template<Exponent... E1, Exponent... E2>
|
template<Exponent... E1, Exponent... E2>
|
||||||
struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<upcasting_traits_t<make_dimension_t<E1..., E2...>>> {};
|
struct dimension_multiply<dimension<E1...>, dimension<E2...>> : std::type_identity<upcasting_traits_t<merge_dimension_t<E1..., E2...>>> {};
|
||||||
|
|
||||||
template<Dimension D1, Dimension D2>
|
template<Dimension D1, Dimension D2>
|
||||||
using dimension_multiply_t = typename dimension_multiply<typename D1::base_type, typename D2::base_type>::type;
|
using dimension_multiply_t = typename dimension_multiply<typename D1::base_type, typename D2::base_type>::type;
|
||||||
|
Reference in New Issue
Block a user