@ Dionne, это не стандартизированные типы. Ваша реализация должна выбрать набор типов, которые, как известно, имеют разные размеры.

сто изучаю основы метапрограммирования в C ++, и я подумал, что было бы неплохо увидеть, как другие вопросы решат следующий вопрос. Также было бы очень приятно увидеть решение, использующее библиотеки метапрограммирования Boost, потому что я считаю их темным углом для себя. Итак, вопрос в том, можно ли это переписать более элегантно?

Предположим, что у нас есть следующая структура:

template <std::size_t size>
struct type_factory
{
  typedef typename type_factory_impl<size>::type type;
};

Эта структура должнаtypedef typeв зависимости от стоимостиsize. type_factory_impl это реализацияtype_factory, Алгоритм, который используется для определенияtype является:

if(size % bits<unsigned long long>::value == 0)
  typedef unsigned long long type;
else if(size % bits<unsigned long>::value == 0)
  typedef unsigned long type;
else if(size % bits<unsigned int>::value == 0)
  typedef unsigned int type;
else if(size % bits<unsigned short int>::value == 0)
  typedef unsigned short int type;
else if(size % bits<unsigned char>::value == 0)
  typedef unsigned char type;
else
  static_assert(false, "The type should be multiple of 'unsigned char' size");

Я решил эту метапрограмму двумя способами. Первый использует сопоставление с образцом напрямую, а второй используетmeta if-else, Рассмотрим следующее как общий код для обоих решений:

#include <cstddef>
#include <climits>

typedef unsigned char      uchar;
typedef unsigned short int usint;
typedef unsigned int       uint;
typedef unsigned long      ulong;
typedef unsigned long long ulonglong;

// Returns how many bits in Unsigned_Type
template <typename Unsigned_Type>
struct bits
{ enum { value = sizeof(Unsigned_Type)*CHAR_BIT }; };

// struct type_factory_impl ...

template <std::size_t size>
struct type_factory
{
  typedef typename type_factory_impl<size>::type type;
};

int main()
{
  auto a = type_factory<8>::type(0);  // unsigned char
  auto b = type_factory<16>::type(0); // unsigned short int
  auto c = type_factory<24>::type(0); // unsigned char
  auto d = type_factory<32>::type(0); // unsigned long
  auto e = type_factory<40>::type(0); // unsigned char
  auto f = type_factory<48>::type(0); // unsigned short int
  auto g = type_factory<56>::type(0); // unsigned char
  auto h = type_factory<64>::type(0); // unsigned long long
}
Первое решение:
template <bool is_uchar>
struct unsigned_char
{
  typedef unsigned char type;
  static_assert(is_uchar,
     "error: size must be multiple of 'unsigned char' size"); 
};
template <>
struct unsigned_char <true>
{ typedef uchar type; };

template <bool is_usint, std::size_t size>
struct unsigned_short_int
{ typedef typename
   unsigned_char<size % bits<uchar>::value == 0>::type type; };
template <std::size_t size>
struct unsigned_short_int <true, size>
{ typedef usint type; };

template <bool is_uint, std::size_t size>
struct unsigned_int
{ typedef typename
   unsigned_short_int<size % bits<usint>::value == 0, size>::type type; };
template <std::size_t size>
struct unsigned_int <true, size>
{ typedef uint type; };

template <bool is_ulong, std::size_t size>
struct unsigned_long
{ typedef typename
   unsigned_int<size % bits<uint>::value == 0, size>::type type; };
template <std::size_t size>
struct unsigned_long <true, size>
{ typedef ulong type; };

template <bool is_ulonglong, std::size_t size>
struct unsigned_long_long
{ typedef typename 
   unsigned_long<size % bits<ulong>::value == 0, size>::type type; };
template <std::size_t size>
struct unsigned_long_long <true, size>
{ typedef ulonglong type; };

template <std::size_t size>
struct type_factory_impl
{ typedef typename 
   unsigned_long_long<size % bits<ulonglong>::value == 0, size>::type type; };
Второе решение:
template <bool condition, typename Then, typename Else>
struct IF
{ typedef Else type; };
template <typename Then, typename Else>
struct IF <true, Then, Else>
{ typedef Then type; };

template <std::size_t size>
struct type_factory_impl
{
  typedef typename
    IF<size % bits<ulonglong>::value == 0, ulonglong,
      typename IF<size % bits<ulong>::value == 0, ulong,
        typename IF<size % bits<uint>::value == 0, uint,
          typename IF<size % bits<usint>::value == 0, usint,
            typename IF<size % bits<uchar>::value == 0, uchar, uchar>::type
          >::type
        >::type
      >::type
    >::type type;
};

Ответы на вопрос(2)

Ваш ответ на вопрос