순수한 C ++ 솔루션에 관심이 있다면 템플릿과 C ++ 표준 코드 만 사용하여 비트 크기에 따라 컴파일 타임에 유형을 정의했습니다. 이 솔루션을 사용하면 컴파일러간에 솔루션을 이식 할 수 있습니다.
뒤에 아이디어는 매우 간단합니다 : char, int, short, long, long long (서명 및 부호없는 버전) 유형을 포함하는 목록을 만들고 목록을 스캔하고 numeric_limits 템플릿을 사용하여 주어진 크기의 유형을 선택하십시오.
이 헤더를 포함하면 8 가지 유형의 stdtype :: int8, stdtype :: int16, stdtype :: int32, stdtype :: int64, stdtype :: uint8, stdtype :: uint16, stdtype :: uint32, stdtype :: uint64입니다.
일부 유형을 나타낼 수없는 경우 해당 헤더에 선언 된 stdtype :: null_type으로 평가됩니다.
아래 코드는 보증없이 제공되며 두 번 확인하십시오.
나는 METAPROGRAMMING TOO에 새로운 소식입니다.이 코드를 수정하고 수정하십시오.
DevC ++로 테스트되었으므로 (3.5 gcc 버전)
#include <limits>
namespace stdtype
{
using namespace std;
/*
* THIS IS THE CLASS USED TO SEMANTICALLY SPECIFY A NULL TYPE.
* YOU CAN USE WHATEVER YOU WANT AND EVEN DRIVE A COMPILE ERROR IF IT IS
* DECLARED/USED.
*
* PLEASE NOTE that C++ std define sizeof of an empty class to be 1.
*/
class null_type{};
/*
* Template for creating lists of types
*
* T is type to hold
* S is the next type_list<T,S> type
*
* Example:
* Creating a list with type int and char:
* typedef type_list<int, type_list<char> > test;
* test::value //int
* test::next::value //char
*/
template <typename T, typename S> struct type_list
{
typedef T value;
typedef S next;
};
/*
* Declaration of template struct for selecting a type from the list
*/
template <typename list, int b, int ctl> struct select_type;
/*
* Find a type with specified "b" bit in list "list"
*
*
*/
template <typename list, int b> struct find_type
{
private:
//Handy name for the type at the head of the list
typedef typename list::value cur_type;
//Number of bits of the type at the head
//CHANGE THIS (compile time) exp TO USE ANOTHER TYPE LEN COMPUTING
enum {cur_type_bits = numeric_limits<cur_type>::digits};
public:
//Select the type at the head if b == cur_type_bits else
//select_type call find_type with list::next
typedef typename select_type<list, b, cur_type_bits>::type type;
};
/*
* This is the specialization for empty list, return the null_type
* OVVERRIDE this struct to ADD CUSTOM BEHAVIOR for the TYPE NOT FOUND case
* (ie search for type with 17 bits on common archs)
*/
template <int b> struct find_type<null_type, b>
{
typedef null_type type;
};
/*
* Primary template for selecting the type at the head of the list if
* it matches the requested bits (b == ctl)
*
* If b == ctl the partial specified templated is evaluated so here we have
* b != ctl. We call find_type on the next element of the list
*/
template <typename list, int b, int ctl> struct select_type
{
typedef typename find_type<typename list::next, b>::type type;
};
/*
* This partial specified templated is used to select top type of a list
* it is called by find_type with the list of value (consumed at each call)
* the bits requested (b) and the current type (top type) length in bits
*
* We specialice the b == ctl case
*/
template <typename list, int b> struct select_type<list, b, b>
{
typedef typename list::value type;
};
/*
* These are the types list, to avoid possible ambiguity (some weird archs)
* we kept signed and unsigned separated
*/
#define UNSIGNED_TYPES type_list<unsigned char, \
type_list<unsigned short, \
type_list<unsigned int, \
type_list<unsigned long, \
type_list<unsigned long long, null_type> > > > >
#define SIGNED_TYPES type_list<signed char, \
type_list<signed short, \
type_list<signed int, \
type_list<signed long, \
type_list<signed long long, null_type> > > > >
/*
* These are acutally typedef used in programs.
*
* Nomenclature is [u]intN where u if present means unsigned, N is the
* number of bits in the integer
*
* find_type is used simply by giving first a type_list then the number of
* bits to search for.
*
* NB. Each type in the type list must had specified the template
* numeric_limits as it is used to compute the type len in (binary) digit.
*/
typedef find_type<UNSIGNED_TYPES, 8>::type uint8;
typedef find_type<UNSIGNED_TYPES, 16>::type uint16;
typedef find_type<UNSIGNED_TYPES, 32>::type uint32;
typedef find_type<UNSIGNED_TYPES, 64>::type uint64;
typedef find_type<SIGNED_TYPES, 7>::type int8;
typedef find_type<SIGNED_TYPES, 15>::type int16;
typedef find_type<SIGNED_TYPES, 31>::type int32;
typedef find_type<SIGNED_TYPES, 63>::type int64;
}