It is not the first time I hit it. This time I was playing with the "binary angle" class (unsigned integer is mapped into a 0-360deg or 0-180deg circle). Different object span on different ranges. Some times it is 0-360 and some objects angles are -180 - +180 . I want it be done automatically when the object is cast to "arithmetic" values in degrees0 or radians. I am storing the type of the "span" as an enum attribute of the class and it works, but I think it is wrong. There should be way to statically test that template parameter.
I know how to use static checks like "is_arithmetic", "is_unsigned", etc. But I can not find what I am looking for.
enum declaration:
enum cycle {
FULL, ///< 0 to 360deg
HALF, ///< 0 to 180deg
FULL_SYMMETRIC, ///< -180deg to 180deg
HALF_SYMMETRIC ///< -90deg to 90deg
};
class declaration:
/// Binary angle representation with conversion to/from DEG and RAD
template<typename U = uint32_t, enum cycle c = FULL>
class angle {
U bin_angle;
static const enum cycle type = c;
public:
and the degree/radians extraction member function
/// Get current value in degrees or, optionally, in radians represented
/// by the floating point type D
template<typename D>
D get(enum angle_units au = DEG) const {
static_assert(std::is_arithmetic<D>::value,
"The angle can only be requested as an arithmetic type");
D circle_ang = cycle_span<D>(type);
D ang = D(0);
if (bin_angle != U(0)) {
// XXX there must be a better way than to use long double
long double ratio =
(long double) (maxU()) / (long double) (bin_angle);
ang = (circle_ang) / D(ratio);
}
if (ang > cycle_end<D>(type)) {
ang -= circle_ang;
}
if (au == RAD) {
ang = deg2rad<D>(ang);
}
return ang;
}
is there a better way?
Aucun commentaire:
Enregistrer un commentaire