Use templates for defining int typess

This commit is contained in:
Behdad Esfahbod 2010-04-21 03:11:46 -04:00
parent 2c9fd2adce
commit e032ed9f75
2 changed files with 44 additions and 28 deletions

View File

@ -338,29 +338,51 @@ struct Sanitizer
* Int types
*/
#define DEFINE_INT_TYPE1(NAME, TYPE, BIG_ENDIAN, BYTES) \
struct NAME \
{ \
static inline unsigned int get_size () { return BYTES; } \
inline void set (TYPE i) { BIG_ENDIAN##_put (v, i); } \
inline operator TYPE(void) const { return BIG_ENDIAN##_get (v); } \
inline bool operator == (const NAME &o) const { return BIG_ENDIAN##_cmp (v, o.v); } \
inline bool sanitize (SANITIZE_ARG_DEF) { \
TRACE_SANITIZE (); \
return SANITIZE_SELF (); \
} \
private: unsigned char v[BYTES]; \
}; \
ASSERT_SIZE (NAME, BYTES)
#define DEFINE_INT_TYPE0(NAME, type, b) DEFINE_INT_TYPE1 (NAME, type##_t, hb_be_##type, b)
#define DEFINE_INT_TYPE(NAME, u, w) DEFINE_INT_TYPE0 (NAME, u##int##w, (w / 8))
template <typename Type, int Bytes> class BEInt;
DEFINE_INT_TYPE (USHORT, u, 16); /* 16-bit unsigned integer. */
DEFINE_INT_TYPE (SHORT, , 16); /* 16-bit signed integer. */
DEFINE_INT_TYPE (ULONG, u, 32); /* 32-bit unsigned integer. */
DEFINE_INT_TYPE (LONG, , 32); /* 32-bit signed integer. */
template <typename Type>
class BEInt<Type, 2>
{
public:
inline void put (Type i) { hb_be_uint16_put (v,i); }
inline Type get () const { return hb_be_uint16_get (v); }
inline bool cmp (const BEInt<Type, 2> o) const { return hb_be_uint16_cmp (v, o.v); }
private: uint8_t v[2];
};
template <typename Type>
class BEInt<Type, 4>
{
public:
inline void put (Type i) { hb_be_uint32_put (v,i); }
inline Type get () const { return hb_be_uint32_get (v); }
inline bool cmp (const BEInt<Type, 4> o) const { return hb_be_uint32_cmp (v, o.v); }
private: uint8_t v[4];
};
template <typename Type>
struct IntType
{
static inline unsigned int get_size () { return sizeof (Type); }
inline void set (Type i) { v.put (i); }
inline operator Type(void) const { return v.get (); }
inline bool operator == (const IntType<Type> &o) const { return v.cmp (o.v); }
inline bool sanitize (SANITIZE_ARG_DEF) {
TRACE_SANITIZE ();
return SANITIZE_SELF ();
}
private: BEInt<Type, sizeof (Type)> v;
};
typedef IntType<uint16_t> USHORT; /* 16-bit unsigned integer. */
typedef IntType<int16_t> SHORT; /* 16-bit signed integer. */
typedef IntType<uint32_t> ULONG; /* 32-bit unsigned integer. */
typedef IntType<int32_t> LONG; /* 32-bit signed integer. */
ASSERT_SIZE (USHORT, 2);
ASSERT_SIZE (SHORT, 2);
ASSERT_SIZE (ULONG, 4);
ASSERT_SIZE (LONG, 4);
/* Array of four uint8s (length = 32 bits) used to identify a script, language
* system, feature, or baseline */

View File

@ -216,19 +216,13 @@ typedef int hb_mutex_t;
#define hb_be_uint16(v) ((uint16_t) ((((const uint8_t *)&(v))[0] << 8) + (((const uint8_t *)&(v))[1])))
#define hb_be_uint16_put(v,V) (v[0] = (V>>8), v[1] = (V), 0)
#define hb_be_uint16_put(v,V) HB_STMT_START { v[0] = (V>>8); v[1] = (V); } HB_STMT_END
#define hb_be_uint16_get(v) (uint16_t) ((v[0] << 8) + v[1])
#define hb_be_uint16_cmp(a,b) (a[0] == b[0] && a[1] == b[1])
#define hb_be_int16_put hb_be_uint16_put
#define hb_be_int16_get (int16_t) hb_be_uint16_get
#define hb_be_int16_cmp hb_be_uint16_cmp
#define hb_be_uint32_put(v,V) (v[0] = (V>>24), v[1] = (V>>16), v[2] = (V>>8), v[3] = (V), 0)
#define hb_be_uint32_put(v,V) HB_STMT_START { v[0] = (V>>24); v[1] = (V>>16); v[2] = (V>>8); v[3] = (V); } HB_STMT_END
#define hb_be_uint32_get(v) (uint32_t) ((v[0] << 24) + (v[1] << 16) + (v[2] << 8) + v[3])
#define hb_be_uint32_cmp(a,b) (a[0] == b[0] && a[1] == b[1] && a[2] == b[2] && a[3] == b[3])
#define hb_be_int32_put hb_be_uint32_put
#define hb_be_int32_get (int32_t) hb_be_uint32_get
#define hb_be_int32_cmp hb_be_uint32_cmp