c++ - how do I use type_traits or template function specialization to consolidate template methods -
i trying consolidate number of similar function methods class similar 1 shown below , thought best way efficiently implement this, through use templates coupled either template function specialization or alternatively type-traits. newbie template specialization , type-traits understand basic concepts , why asking guidance on details. anyway starting point class smart buffer class has many similar method signatures listed below.
class oldsafebuffer { public: intmax_t writeat(const intmax_t& rindex, const uint32_t val32); intmax_t writeat(const intmax_t& rindex, const int32_t val32); intmax_t readfrom(const intmax_t& rindex, uint32_t& rval32); intmax_t readfrom(const intmax_t& rindex, int32_t& rval32); intmax_t writeat(const intmax_t& rindex, const uint16_t val16); intmax_t writeat(const intmax_t& rindex, const int16_t val16); intmax_t readfrom(const intmax_t& rindex, uint16_t& rval16); intmax_t readfrom(const intmax_t& rindex, int16_t& rval16); intmax_t read(uint32_t& rval32); intmax_t read(int32_t& rval32); intmax_t read(uint16_t& rval16); intmax_t read(int16_t& rval16); protected: // actual memory storage. std::unique_ptr<char[]> mbuffer; // buffer length intmax_t mbufferlength; // represents largest byte offset referenced. // can used retrieve written length of buffer. intmax_t mhighwatermark; // if set, caller wanted pack data in network-byte-order. bool mpacknbo; // set on construction, determines whether value needs byte-swapped. bool mswapneeded; // used file compatibility intmax_t mposition; };
i thought perfect candidate conversion use template functions these functions similar , had lot of repeated code in each method. difference between methods sign , size of 16 or 32 bit value argument.
anyway consolidate readfrom methods put following method together. did similar things write methods. these shown in compiling live example.
/** * read value (signed or unsigned) buffer @ given byte offset. * * @param rindex [in] * @param rval [out] * * @return bytesread or -1 on error */ template <typename t> inline intmax_t readfrom(const intmax_t& rindex, t& rval) { if ((rindex + static_cast<intmax_t>(sizeof(t))) <= mbufferlength) { t* pval = (t *)&mbuffer[rindex]; rval = *pval; // @jc partial template specialization 16 bit entities? if (sizeof(rval) > sizeof(int16_t)) { swap32(rval); } else { swap16(rval); } mposition = rindex + sizeof(t); return sizeof(rval); } return -1; }
as can seen comment, still need know size of 't& rval' argument in order decide whether swap32 or swap16 on argument. why thought type_traits come in useful rather having put in runtime check compare size of argument.
i think on right track cannot figure out how use type_traits check , things depending on argument type. thought alternatively use template method specialization special things 16 bit arguments, think not save effort have specialize on both signed adn unsigned variants of 16 bit argument type (assuming non specialized version 32 bit value arguments). figuring out appreciated.
you may use like:
template<typename t, std::size_t n = sizeof(t)> struct swap; template<typename t> struct swap<t, 1> { void operator() (t&) const { /* nothing*/ } }; template<typename t> struct swap<t, 2> { void operator() (t& val) const { swap16(val); } }; template<typename t> struct swap<t, 4> { void operator() (t& val) const { swap32(val); } };
and call it:
swap<t>()(rval);
so in context:
if (sizeof(t) > sizeof(int16_t)) { swap32(val); } else { swap16(val); }
can written as
swap<t>()(val);
Comments
Post a Comment