
C++ programmers want to input a constant of the binary form, like following. But, this is illegal in C++ world. unsigned char value = 0b10001010; There are some solutions of this lack. But, I can't find the gratifying answer. This proposal has following features. - whether digits is binary form - whether digits is octal or decimal of binary form - range of input octal or decimal number detection - output value is absolutely constant, no charge of resource (code, memory) at a run-time Usage: unsigned int td = BD_( 10101010, 00101100, 11110000, 00001111 ); // OK unsigned short tw = BW_( 00011000, 12345678 ); // Compile Error - invalid binary digit unsigned char tb1 = BB_( 0101 ); // OK. from octal unsigned char tb2 = BB_( 1010 ); // OK. from decimal unsigned char tb3 = BB_( 0111100001 ); // Compile Error - out of octal range unsigned char tb4 = BB_( 111100001 ); // Compile Error - out of decimal range Thanks. ---------- binconst.h template<int> struct CompileTimeCheck; template<> struct CompileTimeCheck<true> { }; /** Determines whether N is octal digits of the binary form. ex 1) octal_test< 0101 > == octal_test< 65 >, 65 % 8 == 1 octal_test< 0010 > == octal_test< 8 >, 8 % 8 == 1 octal_test< 0001 > == octal_test< 1 >, 1 % 8 == 1 octal_test< 0000 > == octal_test< 0 >, 0 % 8 == 0 ex 2) octal_test< 0120 > == octal_test< 80 >, 80 % 8 == 0 octal_test< 0012 > == octal_test< 10 >, 10 % 8 == 2 <--- invalid digit detected!!! octal_test< 0001 > == octal_test< 1 >, 1 % 8 == 1 octal_test< 0000 > == octal_test< 0 >, 0 % 8 == 0 */ template< unsigned int N > struct octal_test { enum { is_octal = (N % 8 <= 1) & octal_test< N / 8 >::is_octal }; }; /** end recursive */ template<> struct octal_test< 0 > { enum { is_octal = 1 }; }; /** Determines whether N is decimal digits of the binary form. */ template< unsigned int N > struct decimal_test { enum { is_decimal = (N % 10 <= 1) & decimal_test< N / 10 >::is_decimal, }; }; /** end recursive */ template<> struct decimal_test< 0 > { enum { is_decimal = 1 }; }; /** Convert octal digits of the binary form to a binary number. */ template< unsigned int N > struct binary_octal { enum { value = N % 8 + 2 * binary_octal< N / 8 >::value }; }; /** end recursive */ template<> struct binary_octal< 0 > { enum { value = 0 }; }; /** Convert decimal digits of the binary form to a binary number. */ template< unsigned int N > struct binary_decimal { enum { value = N % 10 + 2 * binary_decimal< N / 10 >::value }; }; /** end recursive */ template<> struct binary_decimal< 0 > { enum { value = 0 }; }; /** one byte */ template< unsigned int B0 > struct binary_byte { enum { is_octal = octal_test< B0 >::is_octal, is_decimal = decimal_test< B0 >::is_decimal }; static const unsigned int value = is_decimal ? binary_decimal< B0 >::value : binary_octal< B0 >::value; CompileTimeCheck< is_octal * B0 <= 011111111 > Out_Of_Range_Octal; CompileTimeCheck< is_decimal * B0 <= 11111111 > Out_Of_Range_Decimal; CompileTimeCheck< is_octal | is_decimal > Invalid_Binary_Digit; }; /** two bytes */ template< unsigned int B1, unsigned int B0 > struct binary_word { static const unsigned int value = (binary_byte< B1 >::value << 8) + (binary_byte< B0 >::value); }; /** four bytes */ template< unsigned int B3, unsigned int B2, unsigned int B1, unsigned int B0 > struct binary_dword { static const unsigned int value = (binary_word< B3, B2>::value << 16) + binary_word< B1, B0 >::value; }; #define BB_( b0 ) \ binary_byte< b0 >::value #define BW_( b1, b0 ) \ binary_word< b1, b0 >::value #define BD_( b3, b2, b1, b0 ) \ binary_dword< b3, b2, b1, b0 >::value ---------- binconst_test.cpp #include "binconst.h" const unsigned int testd = BD_( 11111111, 00000000, 00000000, 00000101 ); #define CHECK( c ) \ { \ CompileTimeCheck< (c) > error; \ (void)error; \ } int main() { /* Generated assembly code Visual C++ 2008 Express Edition mov DWORD PTR _bd$[ebp], -16777211 ; ff000005H g++ (GCC) 4.2.1 20070719 [FreeBSD] movl $-16777211, -4(%ebp) */ dword bd = BD_( 11111111, 00000000, 00000000, 00000101 ); CHECK( BD_( 11111111, 00000000, 00000000, 00000101 ) == 0XFF000005 ); CHECK( BB_( 0 ) == 0x0 ); CHECK( BB_( 1 ) == 0x1 ); CHECK( BB_( 00 ) == 0x0 ); CHECK( BB_( 01 ) == 0x1 ); CHECK( BB_( 10 ) == 0x2 ); CHECK( BB_( 11 ) == 0x3 ); CHECK( BB_( 000 ) == 0x0 ); CHECK( BB_( 001 ) == 0x1 ); CHECK( BB_( 010 ) == 0x2 ); CHECK( BB_( 011 ) == 0x3 ); CHECK( BB_( 100 ) == 0x4 ); CHECK( BB_( 101 ) == 0x5 ); CHECK( BB_( 110 ) == 0x6 ); CHECK( BB_( 111 ) == 0x7 ); CHECK( BB_( 0000 ) == 0x0 ); CHECK( BB_( 0001 ) == 0x1 ); CHECK( BB_( 0010 ) == 0x2 ); CHECK( BB_( 0011 ) == 0x3 ); CHECK( BB_( 0100 ) == 0x4 ); CHECK( BB_( 0101 ) == 0x5 ); CHECK( BB_( 0110 ) == 0x6 ); CHECK( BB_( 0111 ) == 0x7 ); CHECK( BB_( 1000 ) == 0x8 ); CHECK( BB_( 1001 ) == 0x9 ); CHECK( BB_( 1010 ) == 0xA ); CHECK( BB_( 1011 ) == 0xB ); CHECK( BB_( 1100 ) == 0xC ); CHECK( BB_( 1101 ) == 0xD ); CHECK( BB_( 1110 ) == 0xE ); CHECK( BB_( 1111 ) == 0xF ); CHECK( BB_( 00000000 ) == 0x00 ); CHECK( BB_( 00000001 ) == 0x01 ); CHECK( BB_( 00000010 ) == 0x02 ); CHECK( BB_( 00000011 ) == 0x03 ); CHECK( BB_( 00000100 ) == 0x04 ); CHECK( BB_( 00000101 ) == 0x05 ); CHECK( BB_( 00000110 ) == 0x06 ); CHECK( BB_( 00000111 ) == 0x07 ); CHECK( BB_( 00001000 ) == 0x08 ); CHECK( BB_( 00001001 ) == 0x09 ); CHECK( BB_( 00001010 ) == 0x0A ); CHECK( BB_( 00001011 ) == 0x0B ); CHECK( BB_( 00001100 ) == 0x0C ); CHECK( BB_( 00001101 ) == 0x0D ); CHECK( BB_( 00001110 ) == 0x0E ); CHECK( BB_( 00001111 ) == 0x0F ); CHECK( BB_( 00010000 ) == 0x10 ); CHECK( BB_( 00010001 ) == 0x11 ); CHECK( BB_( 00010010 ) == 0x12 ); CHECK( BB_( 00010011 ) == 0x13 ); CHECK( BB_( 00010100 ) == 0x14 ); CHECK( BB_( 00010101 ) == 0x15 ); CHECK( BB_( 00010110 ) == 0x16 ); CHECK( BB_( 00010111 ) == 0x17 ); CHECK( BB_( 00011000 ) == 0x18 ); CHECK( BB_( 00011001 ) == 0x19 ); CHECK( BB_( 00011010 ) == 0x1A ); CHECK( BB_( 00011011 ) == 0x1B ); CHECK( BB_( 00011100 ) == 0x1C ); CHECK( BB_( 00011101 ) == 0x1D ); CHECK( BB_( 00011110 ) == 0x1E ); CHECK( BB_( 00011111 ) == 0x1F ); CHECK( BB_( 00100000 ) == 0x20 ); CHECK( BB_( 00100001 ) == 0x21 ); CHECK( BB_( 00100010 ) == 0x22 ); CHECK( BB_( 00100011 ) == 0x23 ); CHECK( BB_( 00100100 ) == 0x24 ); CHECK( BB_( 00100101 ) == 0x25 ); CHECK( BB_( 00100110 ) == 0x26 ); CHECK( BB_( 00100111 ) == 0x27 ); CHECK( BB_( 00101000 ) == 0x28 ); CHECK( BB_( 00101001 ) == 0x29 ); CHECK( BB_( 00101010 ) == 0x2A ); CHECK( BB_( 00101011 ) == 0x2B ); CHECK( BB_( 00101100 ) == 0x2C ); CHECK( BB_( 00101101 ) == 0x2D ); CHECK( BB_( 00101110 ) == 0x2E ); CHECK( BB_( 00101111 ) == 0x2F ); CHECK( BB_( 00110000 ) == 0x30 ); CHECK( BB_( 00110001 ) == 0x31 ); CHECK( BB_( 00110010 ) == 0x32 ); CHECK( BB_( 00110011 ) == 0x33 ); CHECK( BB_( 00110100 ) == 0x34 ); CHECK( BB_( 00110101 ) == 0x35 ); CHECK( BB_( 00110110 ) == 0x36 ); CHECK( BB_( 00110111 ) == 0x37 ); CHECK( BB_( 00111000 ) == 0x38 ); CHECK( BB_( 00111001 ) == 0x39 ); CHECK( BB_( 00111010 ) == 0x3A ); CHECK( BB_( 00111011 ) == 0x3B ); CHECK( BB_( 00111100 ) == 0x3C ); CHECK( BB_( 00111101 ) == 0x3D ); CHECK( BB_( 00111110 ) == 0x3E ); CHECK( BB_( 00111111 ) == 0x3F ); CHECK( BB_( 01000000 ) == 0x40 ); CHECK( BB_( 01000001 ) == 0x41 ); CHECK( BB_( 01000010 ) == 0x42 ); CHECK( BB_( 01000011 ) == 0x43 ); CHECK( BB_( 01000100 ) == 0x44 ); CHECK( BB_( 01000101 ) == 0x45 ); CHECK( BB_( 01000110 ) == 0x46 ); CHECK( BB_( 01000111 ) == 0x47 ); CHECK( BB_( 01001000 ) == 0x48 ); CHECK( BB_( 01001001 ) == 0x49 ); CHECK( BB_( 01001010 ) == 0x4A ); CHECK( BB_( 01001011 ) == 0x4B ); CHECK( BB_( 01001100 ) == 0x4C ); CHECK( BB_( 01001101 ) == 0x4D ); CHECK( BB_( 01001110 ) == 0x4E ); CHECK( BB_( 01001111 ) == 0x4F ); CHECK( BB_( 01010000 ) == 0x50 ); CHECK( BB_( 01010001 ) == 0x51 ); CHECK( BB_( 01010010 ) == 0x52 ); CHECK( BB_( 01010011 ) == 0x53 ); CHECK( BB_( 01010100 ) == 0x54 ); CHECK( BB_( 01010101 ) == 0x55 ); CHECK( BB_( 01010110 ) == 0x56 ); CHECK( BB_( 01010111 ) == 0x57 ); CHECK( BB_( 01011000 ) == 0x58 ); CHECK( BB_( 01011001 ) == 0x59 ); CHECK( BB_( 01011010 ) == 0x5A ); CHECK( BB_( 01011011 ) == 0x5B ); CHECK( BB_( 01011100 ) == 0x5C ); CHECK( BB_( 01011101 ) == 0x5D ); CHECK( BB_( 01011110 ) == 0x5E ); CHECK( BB_( 01011111 ) == 0x5F ); CHECK( BB_( 01100000 ) == 0x60 ); CHECK( BB_( 01100001 ) == 0x61 ); CHECK( BB_( 01100010 ) == 0x62 ); CHECK( BB_( 01100011 ) == 0x63 ); CHECK( BB_( 01100100 ) == 0x64 ); CHECK( BB_( 01100101 ) == 0x65 ); CHECK( BB_( 01100110 ) == 0x66 ); CHECK( BB_( 01100111 ) == 0x67 ); CHECK( BB_( 01101000 ) == 0x68 ); CHECK( BB_( 01101001 ) == 0x69 ); CHECK( BB_( 01101010 ) == 0x6A ); CHECK( BB_( 01101011 ) == 0x6B ); CHECK( BB_( 01101100 ) == 0x6C ); CHECK( BB_( 01101101 ) == 0x6D ); CHECK( BB_( 01101110 ) == 0x6E ); CHECK( BB_( 01101111 ) == 0x6F ); CHECK( BB_( 01110000 ) == 0x70 ); CHECK( BB_( 01110001 ) == 0x71 ); CHECK( BB_( 01110010 ) == 0x72 ); CHECK( BB_( 01110011 ) == 0x73 ); CHECK( BB_( 01110100 ) == 0x74 ); CHECK( BB_( 01110101 ) == 0x75 ); CHECK( BB_( 01110110 ) == 0x76 ); CHECK( BB_( 01110111 ) == 0x77 ); CHECK( BB_( 01111000 ) == 0x78 ); CHECK( BB_( 01111001 ) == 0x79 ); CHECK( BB_( 01111010 ) == 0x7A ); CHECK( BB_( 01111011 ) == 0x7B ); CHECK( BB_( 01111100 ) == 0x7C ); CHECK( BB_( 01111101 ) == 0x7D ); CHECK( BB_( 01111110 ) == 0x7E ); CHECK( BB_( 01111111 ) == 0x7F ); CHECK( BB_( 10000000 ) == 0x80 ); CHECK( BB_( 10000001 ) == 0x81 ); CHECK( BB_( 10000010 ) == 0x82 ); CHECK( BB_( 10000011 ) == 0x83 ); CHECK( BB_( 10000100 ) == 0x84 ); CHECK( BB_( 10000101 ) == 0x85 ); CHECK( BB_( 10000110 ) == 0x86 ); CHECK( BB_( 10000111 ) == 0x87 ); CHECK( BB_( 10001000 ) == 0x88 ); CHECK( BB_( 10001001 ) == 0x89 ); CHECK( BB_( 10001010 ) == 0x8A ); CHECK( BB_( 10001011 ) == 0x8B ); CHECK( BB_( 10001100 ) == 0x8C ); CHECK( BB_( 10001101 ) == 0x8D ); CHECK( BB_( 10001110 ) == 0x8E ); CHECK( BB_( 10001111 ) == 0x8F ); CHECK( BB_( 10010000 ) == 0x90 ); CHECK( BB_( 10010001 ) == 0x91 ); CHECK( BB_( 10010010 ) == 0x92 ); CHECK( BB_( 10010011 ) == 0x93 ); CHECK( BB_( 10010100 ) == 0x94 ); CHECK( BB_( 10010101 ) == 0x95 ); CHECK( BB_( 10010110 ) == 0x96 ); CHECK( BB_( 10010111 ) == 0x97 ); CHECK( BB_( 10011000 ) == 0x98 ); CHECK( BB_( 10011001 ) == 0x99 ); CHECK( BB_( 10011010 ) == 0x9A ); CHECK( BB_( 10011011 ) == 0x9B ); CHECK( BB_( 10011100 ) == 0x9C ); CHECK( BB_( 10011101 ) == 0x9D ); CHECK( BB_( 10011110 ) == 0x9E ); CHECK( BB_( 10011111 ) == 0x9F ); CHECK( BB_( 10100000 ) == 0xA0 ); CHECK( BB_( 10100001 ) == 0xA1 ); CHECK( BB_( 10100010 ) == 0xA2 ); CHECK( BB_( 10100011 ) == 0xA3 ); CHECK( BB_( 10100100 ) == 0xA4 ); CHECK( BB_( 10100101 ) == 0xA5 ); CHECK( BB_( 10100110 ) == 0xA6 ); CHECK( BB_( 10100111 ) == 0xA7 ); CHECK( BB_( 10101000 ) == 0xA8 ); CHECK( BB_( 10101001 ) == 0xA9 ); CHECK( BB_( 10101010 ) == 0xAA ); CHECK( BB_( 10101011 ) == 0xAB ); CHECK( BB_( 10101100 ) == 0xAC ); CHECK( BB_( 10101101 ) == 0xAD ); CHECK( BB_( 10101110 ) == 0xAE ); CHECK( BB_( 10101111 ) == 0xAF ); CHECK( BB_( 10110000 ) == 0xB0 ); CHECK( BB_( 10110001 ) == 0xB1 ); CHECK( BB_( 10110010 ) == 0xB2 ); CHECK( BB_( 10110011 ) == 0xB3 ); CHECK( BB_( 10110100 ) == 0xB4 ); CHECK( BB_( 10110101 ) == 0xB5 ); CHECK( BB_( 10110110 ) == 0xB6 ); CHECK( BB_( 10110111 ) == 0xB7 ); CHECK( BB_( 10111000 ) == 0xB8 ); CHECK( BB_( 10111001 ) == 0xB9 ); CHECK( BB_( 10111010 ) == 0xBA ); CHECK( BB_( 10111011 ) == 0xBB ); CHECK( BB_( 10111100 ) == 0xBC ); CHECK( BB_( 10111101 ) == 0xBD ); CHECK( BB_( 10111110 ) == 0xBE ); CHECK( BB_( 10111111 ) == 0xBF ); CHECK( BB_( 11000000 ) == 0xC0 ); CHECK( BB_( 11000001 ) == 0xC1 ); CHECK( BB_( 11000010 ) == 0xC2 ); CHECK( BB_( 11000011 ) == 0xC3 ); CHECK( BB_( 11000100 ) == 0xC4 ); CHECK( BB_( 11000101 ) == 0xC5 ); CHECK( BB_( 11000110 ) == 0xC6 ); CHECK( BB_( 11000111 ) == 0xC7 ); CHECK( BB_( 11001000 ) == 0xC8 ); CHECK( BB_( 11001001 ) == 0xC9 ); CHECK( BB_( 11001010 ) == 0xCA ); CHECK( BB_( 11001011 ) == 0xCB ); CHECK( BB_( 11001100 ) == 0xCC ); CHECK( BB_( 11001101 ) == 0xCD ); CHECK( BB_( 11001110 ) == 0xCE ); CHECK( BB_( 11001111 ) == 0xCF ); CHECK( BB_( 11010000 ) == 0xD0 ); CHECK( BB_( 11010001 ) == 0xD1 ); CHECK( BB_( 11010010 ) == 0xD2 ); CHECK( BB_( 11010011 ) == 0xD3 ); CHECK( BB_( 11010100 ) == 0xD4 ); CHECK( BB_( 11010101 ) == 0xD5 ); CHECK( BB_( 11010110 ) == 0xD6 ); CHECK( BB_( 11010111 ) == 0xD7 ); CHECK( BB_( 11011000 ) == 0xD8 ); CHECK( BB_( 11011001 ) == 0xD9 ); CHECK( BB_( 11011010 ) == 0xDA ); CHECK( BB_( 11011011 ) == 0xDB ); CHECK( BB_( 11011100 ) == 0xDC ); CHECK( BB_( 11011101 ) == 0xDD ); CHECK( BB_( 11011110 ) == 0xDE ); CHECK( BB_( 11011111 ) == 0xDF ); CHECK( BB_( 11100000 ) == 0xE0 ); CHECK( BB_( 11100001 ) == 0xE1 ); CHECK( BB_( 11100010 ) == 0xE2 ); CHECK( BB_( 11100011 ) == 0xE3 ); CHECK( BB_( 11100100 ) == 0xE4 ); CHECK( BB_( 11100101 ) == 0xE5 ); CHECK( BB_( 11100110 ) == 0xE6 ); CHECK( BB_( 11100111 ) == 0xE7 ); CHECK( BB_( 11101000 ) == 0xE8 ); CHECK( BB_( 11101001 ) == 0xE9 ); CHECK( BB_( 11101010 ) == 0xEA ); CHECK( BB_( 11101011 ) == 0xEB ); CHECK( BB_( 11101100 ) == 0xEC ); CHECK( BB_( 11101101 ) == 0xED ); CHECK( BB_( 11101110 ) == 0xEE ); CHECK( BB_( 11101111 ) == 0xEF ); CHECK( BB_( 11110000 ) == 0xF0 ); CHECK( BB_( 11110001 ) == 0xF1 ); CHECK( BB_( 11110010 ) == 0xF2 ); CHECK( BB_( 11110011 ) == 0xF3 ); CHECK( BB_( 11110100 ) == 0xF4 ); CHECK( BB_( 11110101 ) == 0xF5 ); CHECK( BB_( 11110110 ) == 0xF6 ); CHECK( BB_( 11110111 ) == 0xF7 ); CHECK( BB_( 11111000 ) == 0xF8 ); CHECK( BB_( 11111001 ) == 0xF9 ); CHECK( BB_( 11111010 ) == 0xFA ); CHECK( BB_( 11111011 ) == 0xFB ); CHECK( BB_( 11111100 ) == 0xFC ); CHECK( BB_( 11111101 ) == 0xFD ); CHECK( BB_( 11111110 ) == 0xFE ); CHECK( BB_( 11111111 ) == 0xFF ); return 0; }