Tuesday, 15 June 2010

Preprocessor-style concatenation with C++ templates? -



Preprocessor-style concatenation with C++ templates? -

suppose sake of question implementing betoh16(), etc., methods in c++ class called opsys. while doing notice 12 or of these functions identical, , don't wish duplicate much source.

i opt next using preprocessor...

typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; #define betoh_xx(nbits) \ u##nbits opsys::betoh##nbits, u##nbits val) \ { \ if (cpu_is_big_endian) \ homecoming val; \ \ homecoming bswap##nbits(val); \ } betoh_xx(16) betoh_xx(32) betoh_xx(64)

... wonder if there way accomplish same thing templates, calls like

u16 hval = betoh<16>(beval);

i see few other questions on concerning templates constant values, nil seems employ concatenation of templatized value adjacent text.

is possible?

i not believe concatenating arbitrary template values form new identifiers possible(or should be, kind of break additional safety templates provide). is, however, (as mentioned in comments) possible archive similiar specific example.

to desired syntax

u16 hval = betoh<16>(beval);

it first of necessary obtain 1 of fixed size integer types bitsize. in video http://www.youtube.com/watch?v=mvfj8qo1iua, andrei alexandrescu showed nice way of doing @ 19:45. declare template struct typedef type fellow member , specialize types available, whilst leaving undefined others:

template <size_t bitsize> struct uint_bits; template<> struct uint_bits<8>{typedef uint8_t type;}; template<> struct uint_bits<16>{typedef uint16_t type;}; template<> struct uint_bits<32>{typedef uint32_t type;};

with in place, need template betoh bswap:

template <size_t bitsize> typename uint_bits<bitsize>::type bswap(typename uint_bits<bitsize>::type value) { typename uint_bits<bitsize>::type ret_val=0; for(size_t b=0;b<sizeof(value);++b) { ret_val<<=8; ret_val|=(value&0xff); value>>=8; } homecoming ret_val; } template <size_t bitsize> typename uint_bits<bitsize>::type betoh(typename uint_bits<bitsize>::type value) { if(cpu_is_big_endian) homecoming value; homecoming bswap<bitsize>(value); }

this can used proposed explicitly stating number of bits, is, imho, kind of verbose, complicates implementation , restricts functions known types, although work arbitrary unsigned integers:

template <typename t> t bswap(t value) { t ret_val=0; for(size_t b=0;b<sizeof(value);++b) { ret_val<<=8; ret_val|=(value&0xff); value>>=8; } homecoming ret_val; } template <typename t> t betoh(t value) { if(cpu_is_big_endian) homecoming value; homecoming bswap(value); }

this not require uint_bits struct , allow above phone call rewritten simply

u16 hval = betoh(beval);

i not sure of practical and/or efficient ;-).

c++ templates

No comments:

Post a Comment