c++ - std::array compile time deduction -


i have piece of code tried automatically decode buffer given awaited data types. data represented tuples:

std::tuple<uint8_t, int32_t> data; size_t bufferindex; iobuffer::constsptr buffer( std::make_shared<iobuffer>(5) ); 

i have tuple heplers iterate on tuples , execute functor each one:

//------------------------------------------------------------------------- // template <typename function, typename ...tuples, typename ...args> void iterateovertuple( function& f, std::tuple<tuples...>& t,                        args&... args ) {     impl::iterateovertupleimpl<0, sizeof...(tuples),         std::tuple<tuples...>>()( f, t, args... ); } //--------------------------------------------------------------------- // template <int i, size_t tsize, typename tuple> struct iterateovertupleimpl     : public iterateovertupleimpl<i + 1, tsize, tuple> {     template <typename function, typename ...args>     void operator()( function& f, tuple& t, args&... args )     {         f( std::get<i>(t), args... );         iterateovertupleimpl<i + 1, tsize, tuple>::operator()( f, t,             args... );     } };  //--------------------------------------------------------------------- // template <int i, typename tuple> struct iterateovertupleimpl<i, i, tuple> {     template <typename function, typename ...args>     void operator()( function& f, tuple& t, args&... )     {         cl::ignore(f);         cl::ignore(t);     } }; 

and here decoder functor:

struct decoderfunctor {     template <typename x>     void decodeintegral( x& x, const iobuffer::constsptr& buffer, size_t& index )     {         if( std::is_same<x, uint8_t>::value )         {             x = buffer->at(index);         }         else if( std::is_same<x,  int8_t>::value )         {             x = static_cast<int8_t>( buffer->at(index) );         }         else if( std::is_same<x, uint16_t>::value )         {             x = cl::byteconversion::ubytestouint16( ubytearray<2>{{                 buffer->at(index + 0),                 buffer->at(index + 1) }}             );         }         else if( std::is_same<x, int16_t>::value )         {             x = cl::byteconversion::ubytestoint16( ubytearray<2>{{                 buffer->at(index + 0),                 buffer->at(index + 1) }}             );         }         else if( std::is_same<x, uint32_t>::value )         {             x = cl::byteconversion::ubytestouint32( ubytearray<4>{{                 buffer->at(index + 0),                 buffer->at(index + 1),                 buffer->at(index + 2),                 buffer->at(index + 3) }}             );         }         else if( std::is_same<x, int32_t>::value )         {             x = cl::byteconversion::ubytestoint32( ubytearray<4>{{                 buffer->at(index + 0),                 buffer->at(index + 1),                 buffer->at(index + 2),                 buffer->at(index + 3) }}             );         }         else if( std::is_same<x, uint64_t>::value )         {             x = cl::byteconversion::ubytestouint64( ubytearray<8>{{                 buffer->at(index + 0),                 buffer->at(index + 1),                 buffer->at(index + 2),                 buffer->at(index + 3),                 buffer->at(index + 4),                 buffer->at(index + 5),                 buffer->at(index + 6),                 buffer->at(index + 7) }}             );         }         else if( std::is_same<x, int64_t>::value )         {             x = cl::byteconversion::ubytestoint64( ubytearray<8>{{                 buffer->at(index + 0),                 buffer->at(index + 1),                 buffer->at(index + 2),                 buffer->at(index + 3),                 buffer->at(index + 4),                 buffer->at(index + 5),                 buffer->at(index + 6),                 buffer->at(index + 7) }}             );         }          // increment index in buffer         index += sizeof(x);     }      template <typename x>     void operator()( x& x, const iobuffer::constsptr& buffer, size_t& index )     {         if( std::is_integral<x>::value )         {             decodeintegral( x, buffer, index );         }     } }; 

and code called:

decoderfunctor func; iterateovertuple( func, data, buffer, index ); 

so works fine integral types , decoded perfectly. when wanted try implement new decoding method (for arrays), didn't compile:

std::tuple<std::array<uint16_t, 100>, std::array<uint8_t, 100>> data; 

here error (gcc-4.9).

so don't understand why error. because of test std::is_integral<x>::value data should not evaluated in decodeintegral( x, buffer, index ); right ?

please not work in progress there few mistakes , improvements make. , thank !

i admit haven't gone through of code, believe issue runtime vs. compile-time conditions. cannot use run-time condition (like if (std::is_integral<:::>::value>) prevent compile-time errors.

i understand decodeintegral compilable when x indeed integral. therefore, must make sure call decodeintegral non-integral x never seen compiler (i.e. instantiated), , not never occurs @ runtime.

seeing function decodeintegral static member without change in semantics, can use "delegate class" trick achieve this. move decodeintegral helper class:

template <bool integral> struct helper;  template <> struct helper<true> {   template <class x>   static void decode( x& x, const iobuffer::constsptr& buffer, size_t& index )   {     // old code of decodeintegral() goes here   }   };  template <> struct helper<false> {   template <class x>   static void decode( x& x, const iobuffer::constsptr& buffer, size_t& index )   {     // code non-integral decoding goes here   } };  struct decoderfunctor {     template <typename x>     void operator()( x& x, const iobuffer::constsptr& buffer, size_t& index )     {         helper<std::is_integral<x>::value>::decode(x, buffer, index);     } }; 

added based on request in comment

if need more 1 discriminator, add more bool template parameters helper. if there no standard predicate discriminator need, can write own.

(the example below assumes discriminators exclusive - @ 1 true):

// two-discriminator helper template <bool integral, bool array> struct helper;  template <> struct helper<true, false> {   void decode() { /* integral decode */ } };  template <> struct helper<false, true> {   void decode() { /* array decode */ } };   // custom predicate template <class t> struct isstdarray : std::false_type {};  template <class t, size_t n> struct isstdarray<std::array<t, n>> : std::true_type {};  // usage struct decoderfunctor {     template <typename x>     void operator()( x& x, const iobuffer::constsptr& buffer, size_t& index )     {         helper<             std::is_integral<x>::value,             isstdarray<x>::value         >::decode(x, buffer, index);     } }; 

Comments

Popular posts from this blog

google api - Incomplete response from Gmail API threads.list -

Installing Android SQLite Asset Helper -

Qt Creator - Searching files with Locator including folder -