Skip to content

Instantly share code, notes, and snippets.

@rpav
Created July 14, 2016 15:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rpav/2dc0eb8a73e6a18be50bd4605d8f5423 to your computer and use it in GitHub Desktop.
Save rpav/2dc0eb8a73e6a18be50bd4605d8f5423 to your computer and use it in GitHub Desktop.
Better COERCE. Pick and return a function which we can reuse. Considerably faster.
#include <stdint.h>
#include "cpk++/log.hpp"
typedef int8_t i8;
typedef uint8_t u8;
typedef int16_t i16;
typedef uint16_t u16;
typedef int32_t i32;
typedef uint32_t u32;
typedef int64_t i64;
typedef uint64_t u64;
enum NumberTypeHeader : int8_t {
I8 = 0x0,
I16 = 0x1,
I32 = 0x2,
I64 = 0x3,
U8 = 0x4,
U16 = 0x5,
U32 = 0x6,
U64 = 0x7,
FLOAT = 0x8,
DOUBLE = 0x9,
I128 = 0xA,
U128 = 0xB,
COMPLEX = 0xC,
RATIONAL = 0xF
};
template<typename T, typename V>
void coerce(void *to, void *from) { *(T*)to = *(V*)from; }
typedef void CoerceFun(void*,void*);
template <typename V>
static CoerceFun* pickTo(NumberTypeHeader to) {
switch(to) {
case I8:
case U8: return reinterpret_cast<CoerceFun*>(&coerce<i8, V>);
case I16:
case U16: return reinterpret_cast<CoerceFun*>(&coerce<i16, V>);
case I32:
case U32: return reinterpret_cast<CoerceFun*>(&coerce<i32, V>);
case I64:
case U64: return reinterpret_cast<CoerceFun*>(&coerce<i64, V>);
case FLOAT: return reinterpret_cast<CoerceFun*>(&coerce<float, V>);
case DOUBLE: return reinterpret_cast<CoerceFun*>(&coerce<double, V>);
}
}
static CoerceFun* pickCoercion(NumberTypeHeader to, NumberTypeHeader from) {
switch(from) {
case I8: return pickTo<i8>(to);
case U8: return pickTo<u8>(to);
case I16: return pickTo<i16>(to);
case U16: return pickTo<u16>(to);
case I32: return pickTo<i32>(to);
case U32: return pickTo<u32>(to);
case I64: return pickTo<i64>(to);
case U64: return pickTo<u64>(to);
case FLOAT: return pickTo<float>(to);
case DOUBLE: return pickTo<double>(to);
}
}
int main() {
u32 to = 0;
float from = -1.1;
auto fun = pickCoercion(U32, FLOAT);
for(u64 i = 0; i < 999999990; ++i) {
fun(&to, &from);
}
LOG(to);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment