|
Boost : |
Subject: [boost] Library proposal: binconst, constant of the binary form.
From: TaeKyeong Wang (bugiii_at_[hidden])
Date: 2009-01-14 22:14:36
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;
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk