Skip to content

Commit

Permalink
refactor: 💥 is_XXX customization points for representation types re…
Browse files Browse the repository at this point in the history
…moved
  • Loading branch information
mpusz committed Nov 26, 2024
1 parent 083ef6a commit 465f88d
Show file tree
Hide file tree
Showing 21 changed files with 154 additions and 208 deletions.
3 changes: 0 additions & 3 deletions example/include/ranged_representation.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ class ranged_representation : public validated_type<T, is_in_range_t<T, Min, Max
}
};

template<typename T, auto Min, auto Max>
constexpr bool mp_units::is_scalar<ranged_representation<T, Min, Max>> = mp_units::is_scalar<T>;

template<typename T, auto Min, auto Max, typename Char>
struct MP_UNITS_STD_FMT::formatter<ranged_representation<T, Min, Max>, Char> : formatter<T, Char> {
template<typename FormatContext>
Expand Down
3 changes: 0 additions & 3 deletions example/include/validated_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,6 @@ class validated_type {
= default;
};

template<typename T, typename Validator>
constexpr bool mp_units::is_scalar<validated_type<T, Validator>> = mp_units::is_scalar<T>;


template<typename CharT, typename Traits, typename T, typename Validator>
std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os,
Expand Down
4 changes: 0 additions & 4 deletions example/kalman_filter/kalman_filter-example_2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ import mp_units;

// Based on: https://www.kalmanfilter.net/alphabeta.html#ex2

template<class T>
requires mp_units::is_scalar<T>
constexpr bool mp_units::is_vector<T> = true;

using namespace mp_units;

void print_header(const kalman::SystemState auto& initial)
Expand Down
4 changes: 0 additions & 4 deletions example/kalman_filter/kalman_filter-example_3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ import mp_units;

// Based on: https://www.kalmanfilter.net/alphabeta.html#ex3

template<class T>
requires mp_units::is_scalar<T>
constexpr bool mp_units::is_vector<T> = true;

using namespace mp_units;

void print_header(const kalman::SystemState auto& initial)
Expand Down
4 changes: 0 additions & 4 deletions example/kalman_filter/kalman_filter-example_4.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ import mp_units;

// Based on: https://www.kalmanfilter.net/alphabeta.html#ex4

template<class T>
requires mp_units::is_scalar<T>
constexpr bool mp_units::is_vector<T> = true;

using namespace mp_units;

void print_header(const kalman::SystemState auto& initial)
Expand Down
13 changes: 8 additions & 5 deletions example/measurement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,19 +124,22 @@ class measurement {
return os << v.value() << " ± " << v.uncertainty();
}

[[nodiscard]] friend constexpr measurement abs(const measurement& v)
requires requires { abs(v.value()); } || requires { std::abs(v.value()); }
{
using std::abs;
return measurement(abs(v.value()), v.uncertainty());
}

private:
value_type value_{};
value_type uncertainty_{};
};

} // namespace

template<typename T>
constexpr bool mp_units::is_scalar<measurement<T>> = true;
template<typename T>
constexpr bool mp_units::is_vector<measurement<T>> = true;

static_assert(mp_units::RepresentationOf<measurement<double>, mp_units::quantity_character::scalar>);
static_assert(mp_units::RepresentationOf<measurement<double>, mp_units::quantity_character::vector>);

namespace {

Expand Down
6 changes: 0 additions & 6 deletions example/storage_tank.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,6 @@ import mp_units;
#include <mp-units/systems/si.h>
#endif

// allows standard gravity (acceleration) and weight (force) to be expressed with scalar representation
// types instead of requiring the usage of Linear Algebra library for this simple example
template<class T>
requires mp_units::is_scalar<T>
constexpr bool mp_units::is_vector<T> = true;

namespace {

using namespace mp_units;
Expand Down
4 changes: 0 additions & 4 deletions example/strong_angular_quantities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@ import mp_units;
#include <mp-units/systems/si.h>
#endif

template<class T>
requires mp_units::is_scalar<T>
constexpr bool mp_units::is_vector<T> = true;

int main()
{
using namespace mp_units;
Expand Down
4 changes: 0 additions & 4 deletions example/total_energy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ import mp_units;
#include <mp-units/systems/si.h>
#endif

template<class T>
requires mp_units::is_scalar<T>
constexpr bool mp_units::is_vector<T> = true;

namespace {

using namespace mp_units;
Expand Down
5 changes: 1 addition & 4 deletions src/core/include/mp-units/cartesian_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ class cartesian_vector {
lhs._coordinates_[2] == rhs._coordinates_[2];
}

[[nodiscard]] friend constexpr T norm(const cartesian_vector& vec)
[[nodiscard]] friend constexpr T magnitude(const cartesian_vector& vec)
requires treat_as_floating_point<T>
{
return vec.magnitude();
Expand Down Expand Up @@ -263,9 +263,6 @@ template<typename Arg, typename... Args>
requires(sizeof...(Args) <= 2) && requires { typename std::common_type_t<Arg, Args...>; }
cartesian_vector(Arg, Args...) -> cartesian_vector<std::common_type_t<Arg, Args...>>;

template<class T>
constexpr bool is_vector<cartesian_vector<T>> = true;

} // namespace mp_units

#if MP_UNITS_HOSTED
Expand Down
4 changes: 2 additions & 2 deletions src/core/include/mp-units/complex.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ import std;
namespace mp_units {

template<typename T>
constexpr bool is_complex<std::complex<T>> = true;
constexpr bool disable_scalar<std::complex<T>> = true;

}
} // namespace mp_units
39 changes: 5 additions & 34 deletions src/core/include/mp-units/framework/customization_points.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,49 +60,20 @@ constexpr bool treat_as_floating_point =
std::is_floating_point_v<value_type_t<Rep>>;
#endif

/**
* @brief Specifies a type to have a scalar character
*
* A scalar is a physical quantity that has magnitude but no direction.
*/
template<typename Rep>
constexpr bool is_scalar = std::is_floating_point_v<Rep> || (std::is_integral_v<Rep> && !is_same_v<Rep, bool>);
[[deprecated("`is_scalar` is no longer necessary and can simply be removed")]]
constexpr bool is_scalar = false;

/**
* @brief Specifies a type to have a complex character
*
* A complex is a physical quantity that has a complex representation type.
*/
template<typename Rep>
[[deprecated("`is_complex` is no longer necessary and can simply be removed")]]
constexpr bool is_complex = false;

/**
* @brief Specifies a type to have a vector character
*
* Vectors are physical quantities that possess both magnitude and direction
* and whose operations obey the axioms of a vector space.
*
* In specific cases a scalar can represent a vector with the default direction.
* If that is the intent, a user should provide a partial specialization:
*
* @code{.cpp}
* template<class T>
* requires mp_units::is_scalar<T>
* constexpr bool mp_units::is_vector<T> = true;
* @endcode
*/
template<typename Rep>
[[deprecated("`is_vector` is no longer necessary and can simply be removed")]]
constexpr bool is_vector = false;

/**
* @brief Specifies a type to have a tensor character
*
* Tensors can be used to describe more general physical quantities.
*
* A vector is a tensor of the first order and a scalar is a tensor of order zero.
* Similarly to `is_vector` a partial specialization is needed in such cases.
*/
template<typename Rep>
[[deprecated("`is_tensor` is no longer necessary and can simply be removed")]]
constexpr bool is_tensor = false;

/**
Expand Down
4 changes: 4 additions & 0 deletions src/core/include/mp-units/framework/quantity_concepts.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ template<typename T>
constexpr bool is_derived_from_specialization_of_quantity =
requires(T* type) { to_base_specialization_of_quantity(type); };

template<typename T>
requires is_derived_from_specialization_of_quantity<T>
constexpr bool is_quantity<T> = true;

} // namespace detail

/**
Expand Down
Loading

2 comments on commit 465f88d

@JohelEGP
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current hierarchy of concepts seems a bit backwards to me.
For example, Scalar is refined by ScalarRepresentation.
The refinement rejects specializations of quantity
and also requires scaling with long double/std::intmax_t.

The rejection part of the refinement is smelly.
A cleaner solution would be to have a more general ScalarWith concept.
You can then have a Scalar concept which defaults the scalar type (which you'll need in the CPOs).
Representation should be the concept to reject specializations of quantity.

@mpusz
Copy link
Owner Author

@mpusz mpusz commented on 465f88d Nov 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if I follow you here. I provide the rejection first to prevent recursive concepts calls. Please try to refactor according to your ideas and check if it works.

P.S. Until the end of the next week, I will need to back off a bit due to work and family constraints.

Please sign in to comment.