i create class template takes unsigned integer parameter , has member u_ type smallest unsigned integer type hold integer parameter.
so:
template <uint64_t k> class { ??? u_; }; for a<0>, u_ should of type uint8_t. same a<255>. a<256>, u_ should of type uint16_t, etc.
how implement this?
this piece of metaprogramming trickery achieves it:
template<unsigned int y> struct typed { typedef typename typed<(y & (y - 1)) == 0 ? y / 2 : (y & (y - 1))>::type type; }; template<> struct typed<0> { typedef std::uint8_t type; }; template<> struct typed<256> { typedef std::uint16_t type; }; template<> struct typed<65536> { typedef std::uint32_t type; }; /* todo - add more specialisations necessary*/ template<unsigned k> class { public: unsigned static const k_ = k; /*constexpr if compiler supports it*/ typename typed<k>::type u_; }; the usage in question.
the unspecialised template version takes previous type. typed<0> blocks static recursion. other specialisations act anchoring points appropriate types.
the compile-time evaluable (y & (y - 1)) == 0 ? y / 2 : (y & (y - 1)) reduces number of instantiations removing rightmost bit of y until power of 2 reached, , divides 2 subsequently that. (acknowledge @jarod42).
Comments
Post a Comment