Parse a C++14 integer literal According to http://en.cppreference.com/w/cpp/language/integer_literal, integer literals consist of a decimal/hex/octal/binary literal and a optional integer suffix, that is obviously completely unnecessary, wastes precious bytes and is not used in this challenge.

A decimal literal is a non-zero decimal digit (1, 2, 3, 4, 5, 6, 7, 8, 9), followed by zero or more decimal digits (0, 1, 2, 3, 4, 5, 6, 7, 8, 9).

A octal literal is the digit zero (0) followed by zero or more octal digits (0, 1, 2, 3, 4, 5, 6, 7).

A hexadecimal literal is the character sequence 0x or the character sequence 0X followed by one or more hexadecimal digits (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, A, b, B, c, C, d, D, e, E, f, F) (note the case-insensitivity of abcdefx).

A binary literal is the character sequence 0b or the character sequence 0B followed by one or more binary digits (0, 1).

Additionally, there may optionally be some 's as a digit separator. They have no meaning and can be ignored.

Input

A string that represents a C++14 integer literal or an array of its charcodes.

Output

The number represented by the input string in base 10, with an optional trailing newline. The correct output never will exceed 2*10^9

Winning criteria

The GCC contributors need over 500 lines of code to do this, therefore our code must be as short as possible! 

Test cases:

0                       -&gt;    0
1                       -&gt;    1
12345                   -&gt;    12345
12345'67890             -&gt;    1234567890
0xFF                    -&gt;    255
0XfF                    -&gt;    255
0xAbCdEf                -&gt;    11259375
0xa'bCd'eF              -&gt;    11259375
0b1111'0000             -&gt;    240
0b0                     -&gt;    0
0B1'0                   -&gt;    2
0b1                     -&gt;    1
00                      -&gt;    0
01                      -&gt;    1
012345                  -&gt;    5349
0'123'4'5               -&gt;    5349
x86 (32-bit) machine code, 59 57 bytes

This function takes esi as a pointer to a null-terminated string and returns the value in edx.  (Listing below is GAS input in AT&amp;T syntax.)

        .globl parse_cxx14_int
        .text
parse_cxx14_int:
        push $10
        pop %ecx                # store 10 as base
        xor %eax,%eax           # initialize high bits of digit reader
        cdq                     # also initialize result accumulator edx to 0
        lodsb                   # fetch first character
        cmp $'0', %al
        jne .Lparseloop2
        lodsb
        and $~32, %al           # uppercase letters (and as side effect,
                                # digits are translated to N+16)
        jz .Lend                # "0" string
        cmp $'B', %al           # after '0' have either digit, apostrophe,
                                # 'b'/'B' or 'x'/'X'
        je .Lbin
        jg .Lhex
        dec %ecx
        dec %ecx                # update base to 8
        jmp .Lprocessdigit      # process octal digit that we just read (or
                                # skip ' if that is what we just read)   
.Lbin:
        sub $14, %ecx           # with below will update base to 2
.Lhex:
        add $6, %ecx            # update base to 16
.Lparseloop:
        lodsb                   # fetch next character
.Lparseloop2:
        and $~32, %al           # uppercase letters (and as side effect,
                                # digits are translated to N+16)
        jz .Lend
.Lprocessdigit:
        cmp $7, %al             # skip ' (ASCII 39 which would have been
                                # translated to 7 above)
        je .Lparseloop
        test $64, %al           # distinguish letters and numbers
        jz .Lnum
        sub $39, %al            # with below will subtract 55 so e.g. 'A'==65
                                # will become 10
.Lnum:
        sub $16, %al            # translate digits to numerical value
        imul %ecx, %edx
#        movzbl %al, %eax
        add %eax, %edx          # accum = accum * base + newdigit
        jmp .Lparseloop
.Lend:
        ret


And a disassembly with byte counts - in Intel format this time, in case you prefer that one.

Disassembly of section .text:

00000000 &lt;parse_cxx14_int&gt;:
   0:   6a 0a                   push   0xa
   2:   59                      pop    ecx
   3:   31 c0                   xor    eax,eax
   5:   99                      cdq    
   6:   ac                      lods   al,BYTE PTR ds:[esi]
   7:   3c 30                   cmp    al,0x30
   9:   75 16                   jne    21 &lt;parse_cxx14_int+0x21&gt;
   b:   ac                      lods   al,BYTE PTR ds:[esi]
   c:   24 df                   and    al,0xdf
   e:   74 28                   je     38 &lt;parse_cxx14_int+0x38&gt;
  10:   3c 42                   cmp    al,0x42
  12:   74 06                   je     1a &lt;parse_cxx14_int+0x1a&gt;
  14:   7f 07                   jg     1d &lt;parse_cxx14_int+0x1d&gt;
  16:   49                      dec    ecx
  17:   49                      dec    ecx
  18:   eb 0b                   jmp    25 &lt;parse_cxx14_int+0x25&gt;
  1a:   83 e9 0e                sub    ecx,0xe
  1d:   83 c1 06                add    ecx,0x6
  20:   ac                      lods   al,BYTE PTR ds:[esi]
  21:   24 df                   and    al,0xdf
  23:   74 13                   je     38 &lt;parse_cxx14_int+0x38&gt;
  25:   3c 07                   cmp    al,0x7
  27:   74 f7                   je     20 &lt;parse_cxx14_int+0x20&gt;
  29:   a8 40                   test   al,0x40
  2b:   74 02                   je     2f &lt;parse_cxx14_int+0x2f&gt;
  2d:   2c 27                   sub    al,0x27
  2f:   2c 10                   sub    al,0x10
  31:   0f af d1                imul   edx,ecx
  34:   01 c2                   add    edx,eax
  36:   eb e8                   jmp    20 &lt;parse_cxx14_int+0x20&gt;
  38:   c3                      ret    


And in case you want to try it, here is the C++ test driver code that I linked with it (including the calling convention specification in GCC asm syntax):

#include &lt;cstdio&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;

inline int parse_cxx14_int_wrap(const char *s) {
    int result;
    const char* end;
    __asm__("call parse_cxx14_int" :
            "=d"(result), "=S"(end) :
            "1"(s) :
            "eax", "ecx", "cc");
    return result;
}

int main(int argc, char* argv[]) {
    std::string s;
    while (std::getline(std::cin, s))
        std::printf("%-16s -&gt; %d\n", s.c_str(), parse_cxx14_int_wrap(s.c_str()));
    return 0;
}




-1 byte due to comment by Peter Cordes

-1 byte from updating to use two decrements to change 10 to 8