using   i8                      = char;

using   u8                      = unsigned char;

using   i16                     = short;

using   u16                     = unsigned short;

using   i32                     = int;

using   u32                     = unsigned int;

using   i64                     = long long;

using   u64                     = unsigned long long;


using   f32                     = float;

using   f64                     = double;


#define rigid                   constexpr


//---------------------------------------------------------------------------------------


rigid   u32 CHAR_BITS           = 8;


// 특정 타입의 most significant bit의 위치를 리턴

// ex ) 32bit type -> 31

template< typename T >

inline  rigid   auto    msb()

{

    return  sizeof( T ) * CHAR_BITS - 1;

}


// 특정 타입의 most significant bit를 1로 둔 값을 리턴

// ex ) 32bit type -> 0x80000000

template< typename T >

inline  rigid   auto    msb_value()

{

    return  (T)1 << msb< T >();

}


// 특정 타입의 most significant bit를 제외시키는 마스크를 리턴

// ex ) 32bit type -> 0x7FFFFFFF

template< typename T >

inline  rigid   auto    msb_mask()

{

    return  (T)~msb_value< T >();

}


// 편하게 쓰자

#define msb_pos( var ) msb< decltype( var ) >()

#define msb_val( var ) msb_value< decltype( var ) >()


// dst 의 가장 큰값 위치에 bits 값을 얹음

template< typename T0, typename T1 >

inline  void    set_msbs( T0& dst, const T1 bits )

{

    *( (T1*)&dst + ( sizeof dst / sizeof bits - 1 ) ) |= bits;

}

//---------------------------------------------------------------------------------------


// 문자열로부터 부호없는 연속한 숫자를 리턴

// 포인터를 숫자의 끝 다음으로 이동시킴

inline  u32     atou32( char*& s )

{

    u32 value;

    for( value = 0; *s <= '9' && *s >= '0'; ++s )

        value = value * 10 + ( *s - '0' );

    return  value;

}


// 문자열로부터 부호있는 연속한 숫자를 리턴

// 포인터를 숫자의 끝 다음으로 이동시킴

inline  i32     atoi32( char*& s )

{

    if( *s == '-' )

        return  -(i32)atou32( ++s );

    return  atou32( s );

}


// 문자열로부터 부호처리된 부동소수 및 지수값을 리턴

// 포인터를 숫자의 끝 다음으로 이동시킴

template< typename T = f64 >

inline  T       atof( char*& s )

{

    char* p     = s;

    u32 sign    = 0;

    T   digit   = 0.;

    T   base    = 1.;

    T   step    = 1.;


    for( i8 token; token = *p++; )

    {

        switch( token )

        {

        case '-':

            sign = msb_val( sign );

            break;

        case '.':

            step = 10;

            break;

        case 'E':

        case 'e':

            digit *= (T)std::pow( 10., (f64)atof< T >( s = p ) );

            goto exit;

        default:

            if( token <= '9' && token >= '0' )

            {

                digit = digit * (T)10. + ( token & 0xF );

                base *= step;

                continue;

            }

            goto exit;

        }

    }

    exit:

    if( s < p - 1 ) s = p - 1;

    set_msbs( digit, sign );

    return  T( digit / base );

}


// 편하게 쓰자

inline  auto    atof32( char*& s )

{

    return  atof< f32 >( s );

}


inline  auto    atof64( char*& s )

{

    return  atof< f64 >( s );

}

//---------------------------------------------------------------------------------------


#include <type_traits>

// 타입에 맞게 문자열의 숫자를 해독해서 param 에 넣음

template< typename T >

inline  char*   parse_number( const char* string, T& param )

{

    char* s = (char*)string;

    while( *s == ' ' || *s == ' ' || *s == ' ' ) s++;


    if( std::is_same< T, i32 >::value )

        param = (T)atoi32( s );

    if( std::is_same< T, u32 >::value )

        param = (T)atou32( s );

    if( std::is_same< T, f32 >::value )

        param = (T)atof32( s );

    if( std::is_same< T, f64 >::value )

        param = (T)atof64( s );


    return  s;

}


// 복수 params

template< typename T, typename... Ts >

inline  char*   parse_number( const char* string, T& param1, Ts&... rest )

{

    return  parse_number( parse_number( string, param1 ), rest... );

}

//---------------------------------------------------------------------------------------


#include <iostream>

using namespace std;


int main()

{

    i32 a, b;

    u32 c, d;

    f64 e;

    f32 f;


    parse_number( "-1 0 1 2 1.23e2 1.23456", a, b, c, d, e, f );

    cout << a << " " << b << " " << c << " " << d << " " << e << " " << f << endl;


    getchar();

    return 0;

}


실행 결과 :

-1 0 1 2 123 1.23456


나답지않게 짱 친절한 주석. 데헷~