Something went wrong on our end
vrpn_FixedPoint.h 4.40 KiB
/** @file vrpn_FixedPoint.h
@brief Header
@date 2014
@author
Kevin M. Godby
<kevin@godby.org>
*/
#ifndef VRPN_FIXED_POINT_H_
#define VRPN_FIXED_POINT_H_
// Internal Includes
#include "vrpn_Types.h"
// Library/third-party includes
// - none
// Standard includes
#include <cstddef> // for NULL
namespace vrpn {
namespace detail {
/**
* Set as the type member of vrpn_IntegerOfSize if too many bits are
* required.
* We only support up to 32 bits currently.
*/
struct IntegerOverflow;
/**
* \name Integer types.
*
* In the general case, we'll start adding bits to the required size
*until we
* land on one of the specialized cases below, then return that
*specialized
* case. The end result is that we return an integer type that can
*contain a
* value require NUM_BITS bits.
*/
///@{
template <int NUM_BITS> struct IntegerOfSize {
// An integer requiring n bits can be represented by an integer of
// size n+1 bits.
typedef typename IntegerOfSize<NUM_BITS + 1>::type type;
};
template <> struct IntegerOfSize<8> {
typedef vrpn_int8 type;
};
template <> struct IntegerOfSize<16> {
typedef vrpn_int16 type;
};
template <> struct IntegerOfSize<32> {
typedef vrpn_int32 type;
};
template <> struct IntegerOfSize<64> {
typedef IntegerOfSize type;
};
/// @todo allow for larger types if we can establish VRPN versions of
/// them (e.g.,
/// equivalents to int64_t).
///@}
} // namespace detail
/**
* A fixed-point value class. All values are signed, two's-complement.
*
* @tparam INTEGER_BITS The number of bits devoted to the integer part.
* @tparam FRACTIONAL_BITS The number of bits devoted to the fractioal part.
*/
template <int INTEGER_BITS, int FRACTIONAL_BITS> class FixedPoint {
public:
/**
* Find an integer type large enough to hold INTEGER_BITS.
*/
typedef typename detail::IntegerOfSize<INTEGER_BITS>::type IntegerType;
typedef typename detail::IntegerOfSize<INTEGER_BITS +
FRACTIONAL_BITS>::type RawType;
/**
* \name Constructors.
*
* The bits of an integral type passed to the constructor will be
* interpreted as as fixed-point value. A floating-point type passed to
*the
* constructor will be converted to a fixed-point value.
*/
//@{
FixedPoint()
: value_(0)
{
}
explicit FixedPoint(vrpn_int8 x)
: value_(x)
{
}
explicit FixedPoint(vrpn_int16 x)
: value_(x)
{
}
explicit FixedPoint(vrpn_int32 x)
: value_(x)
{
}
explicit FixedPoint(vrpn_uint8 x)
: value_(x)
{
}
explicit FixedPoint(vrpn_uint16 x)
: value_(x)
{
}
explicit FixedPoint(vrpn_uint32 x)
: value_(x)
{
}
explicit FixedPoint(double x)
: value_(x * (1 << FRACTIONAL_BITS))
{
}
explicit FixedPoint(float x)
: value_(x * (1 << FRACTIONAL_BITS))
{
}
//@}
/// @todo add operators, lots and lots of operators?
/**
* Returns a floating-point representation of this
* fixed-point value.
*/
template <typename T> T get() const
{
return get(reinterpret_cast<TypeWrapper<T> *>(NULL));
}
/** \name Debugging functions. */
///@{
/// @todo remove these functions after debugging
RawType value() const { return value_; }
///@}
private:
template <typename T> struct TypeWrapper;
vrpn_float32 get(TypeWrapper<vrpn_float32> *) const
{
return static_cast<vrpn_float32>(value_) / (1 << FRACTIONAL_BITS);
}
vrpn_float64 get(TypeWrapper<vrpn_float64> *) const
{
return static_cast<vrpn_float64>(value_) / (1 << FRACTIONAL_BITS);
}
RawType value_;
};
} // namespace vrpn
#endif // VRPN_FIXED_POINT_H_