简体   繁体   中英

Metaprogramming for optimizing storage/run time algorithm, C++

I'd like to generalize bitwise operators in C++ without thinking that the underlying structure is an array.

As instance... if I want to represent 86 bits i would use a structure structure/class like:

typedef struct {
 uint64_t x[1];
 uint16_t y[1];
 uint8_t z[1];
} sampleStruct;

Instead if i would like to allocate 160 bits I would use a structure like:

typedef struct {
 uint64_t x[2];
 uint32_t y[1];
} sampleStruct;

I guess a trivial, but not optimal solution for the storage would be to assume all chunks are uniform and allocate the minimum of those st it covers the size I'm implementing, however even for a matter of exercise I prefer the way I exposed.

To me it sounds clear that I should use metaprogramming to solve the problem, so I have to properly define

template <int I>
typedef sampleStruct {
  //something
}

However I'm not a big expert on C++ template metaprogramming so i would like to understand what would be the best way to implement the different kind of sample struct varing I. I know how to decide the best "cover" for my length it would be something like:

N64 = I/64;
RemN = I%64;
if(0 < RemN <= 8) {
  add uint8_t var;
} else if (8 < RemN <= 16) {
  add uint16_t var;
} else if (16 < RemN <= 24) {
  add uint16_t var;
  add uint8_t var;
} else {
  //Similarly handle the other cases from 24 < RemN < 64
}

What can I do to achieve what I want to do?

I also guess that arraging chunks correctly would allow to achieve slightly better performance compared to other possible implementation.

Hoping it is clear enough... (Assume C++11 or more recent versions).

It's possible, but there's a fair amount of typing involved. The problem is that C++ doesn't provide a way to meta-programmatically omit a data member (see eg Conditional Inclusion/Exclusion of Data Members Inside Class Templates ) so you have to specialize on its presence or absence:

template<int N64, bool P32, bool P16, bool P8>
struct sampleStructImpl;

template<int I>
using sampleStruct = sampleStructImpl<I/64, (I%64 >= 32), (I%32 >= 16), (I%16 >= 8)>;

The various partial specializations (8 in total) would look like the following:

template<int N64>
struct sampleStructImpl<N64, true, true, true>
{
  std::uint64_t x[N64];
  std::uint32_t y;
  std::uint16_t z;
  std::uint8_t w;
};

template<int N64>
struct sampleStructImpl<N64, true, true, false>
{
  std::uint64_t x[N64];
  std::uint32_t y;
  std::uint16_t z;
  // omit std::uint8_t w;
};

// 6 more partial specializations...

Also, since zero-length arrays are illegal, if you want to be able to allow values of I less than 64 you'll have to specialize on N64 being zero:

template<>
struct sampleStructImpl<0, true, true, true>
{
  // omit std::uint64_t x[0];
  std::uint32_t y;
  std::uint16_t z;
  std::uint8_t w;
};

// 7 more specializations...

It'd be a lot more straightforward to use std::array<std::uint8_t, (I + 7) / 8> , possibly with an alignas modifier to 64-bit align it.

Wouldn't it be easier to use just an array of uint8_t , for example:

template <int I>
struct sampleStruct {
  std::uint8_t v[(I % 8)? (I / 8) + 1 : (I / 8)];
};

As you mentioned bits, I'm assuming that you don't access the individual members x,y,z , (it's not clear from the question how you would access the underlying bits..)

It's possible to do what you want as well, but you have to use inheritance, as follows:

template <int I>
struct largeBlock {
    std::uint64_t x[I];
};
template <>
struct largeBlock<0> {
};

template <int I>
struct mediumBlock {
    std::uint16_t y[I];
};
template <>
struct mediumBlock<0> {
};

template <int I>
struct smallBlock {
    std::uint8_t z[(I / 8) + ((I % 8) ? 1 : 0) ];
};
template <>
struct smallBlock<0> {
};

template <int I>
struct sampleStruct : largeBlock<I / 64>, mediumBlock<(I % 64) / 16>, smallBlock<(I % 16)> {

};

Now your operations have to be implemented in terms of calls to the base objects...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM