stream_cast fails with case insensitive string

Discussion in 'C++' started by aaragon, May 6, 2011.

  1. aaragon

    aaragon Guest

    HI all,

    The following function stream_cast works perfectly with a std::string,
    but fails when I try to use my custom case insensitive string and I
    don't understand why:


    template <typename T, class string_type>
    T stream_cast_impl(string_type& s) {

    typedef typename string_type::value_type char_type;
    typedef typename string_type::traits_type traits_type;

    T x;
    static typename std::basic_istringstream<char_type,
    traits_type> iss;
    iss.clear();
    iss.str(s);
    iss>>x;
    if (!iss || iss.peek() >= 0) {
    std::string err("*** ERROR *** ");
    err += s.c_str();
    err += " cannot be converted to expected type
    with type id:\n";
    err += typeid(x).name();
    throw std::runtime_error(err);
    }
    return x;
    }


    template <typename T>
    T stream_cast(std::string& s)
    { return stream_cast_impl<T,std::string>(s); }

    template <typename T>
    T stream_cast(const std::string& s)
    { return
    stream_cast_impl<T,std::string>(const_cast<std::string&>(s)); }



    struct ci_char_traits : public std::char_traits<char> {

    static bool eq( char c1, char c2 )
    { return toupper(c1) == toupper(c2); }

    static bool ne( char c1, char c2 )
    { return toupper(c1) != toupper(c2); }

    static bool lt( char c1, char c2 )
    { return toupper(c1) < toupper(c2); }

    static int compare(const char* s1, const char* s2, size_t n )
    { return memicmp( s1, s2, n ); }

    private:
    static int memicmp(const void *s1, const void *s2, size_t n) {

    if (n != 0) {
    const unsigned char *p1 = (const unsigned char *)s1,
    *p2 = (const unsigned char *)s2;
    do {
    if (toupper(*p1) != toupper(*p2))
    return (*p1 - *p2);
    p1++;
    p2++;
    } while (--n != 0);
    }
    return 0;
    }
    };


    typedef std::basic_string<char, ci_char_traits> ci_string;

    template <typename T>
    T stream_cast(ci_string& s)
    { return stream_cast_impl<T,ci_string>(s); }

    template <typename T>
    T stream_cast(const ci_string& s)
    { return
    stream_cast_impl<T,ci_string>(const_cast<ci_string&>(s)); }



    Does anyone have an idea what's happening? I get the following error
    when I try to do this on an integer:


    terminate called after throwing an instance of 'std::runtime_error'
    what(): *** ERROR *** -1 cannot be converted to expected type with
    type id:
    i


    Thank you all...

    a^2
    aaragon, May 6, 2011
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tee
    Replies:
    3
    Views:
    7,766
    Herfried K. Wagner [MVP]
    Jun 23, 2004
  2. Guoqi Zheng

    string.indexof case insensitive

    Guoqi Zheng, Jul 9, 2004, in forum: ASP .Net
    Replies:
    4
    Views:
    12,879
    bentangle
    Jan 25, 2009
  3. Andrew
    Replies:
    2
    Views:
    1,590
    Mike Schilling
    Aug 15, 2004
  4. Replies:
    1
    Views:
    2,456
    Mark P
    Apr 6, 2007
  5. Xah Lee
    Replies:
    4
    Views:
    930
Loading...

Share This Page