This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: strtoul etc.



Below a sample of the simplest (base == 10) conversion
from a string to an integer. 

I think we should decide if we want to go this way.
I suppose it depends on the answer to the question:

Does somebody want to implement the necessary functions?


Ryszard Kabatek
Martin-Luther University Halle-Wittenberg, Department of Physical Chemistry
Geusaer Str. 88, 06217 Merseburg, Germany
Tel. +49 3461 46 2487 Fax. +49 3461 46 2129

template<class Iter>
class AtoN {
public:
  static bool
    toi10(Iter first, Iter last, short& val)
    {
      return _S_a2i10(first, last, SHRT_MAX, val);
    }

  static bool
    toi10(Iter first, Iter last, int& val)
    {
      return _S_a2i10(first, last, INT_MAX, val);
    }

  static bool
    toi10(Iter first, Iter last, long& val)
    {
      return _S_a2i10(first, last, LONG_MAX, val);
    }

  static bool
    toi10(Iter first, Iter last, long long& val)
    {
      return _S_a2i10(first, last, LONG_LONG_MAX, val);
    }

  static bool
    toui10(Iter first, Iter last, unsigned short& val)
    {
      return _S_a2ui10(first, last, USHRT_MAX, val);
    }

  static bool
    toui10(Iter first, Iter last, unsigned int& val)
    {
      return _S_a2ui10(first, last, UINT_MAX, val);
    }

  static bool
    toui10(Iter first, Iter last, unsigned long& val)
    {
      return _S_a2ui10(first, last, ULONG_MAX, val);
    }

  static bool
    toui10(Iter first, Iter last, unsigned long long& val)
    {
      return _S_a2ui10(first, last, ULONG_LONG_MAX, val);
    }

protected:
  template<class Int_type>
  static bool
  _S_a2i10(Iter first, Iter last, Int_type max_val, Int_type& value)
  {
    const Int_type base = 10;
    const Int_type cutoff = max_val / base;
    const Int_type cutlim = max_val % base;

    value = 0;
    char c;
    int sign = 1;
    // Check the sign
    if (first != last && !isdigit(c = *first)) {
       if (c == '-') {
          sign = -1;
         ++first;
       }
       else if (c == '+')
          ++first;
       else
          return false;
    }
    if (first == last)
       return false;

    // Skip leading zeroes
    while (first != last && isdigit(c = *first) && c == '0')
       ++first;

    while (first != last && isdigit(c = *first)) {
       Int_type n = c - '0';
       if (value > cutoff || (value == cutoff && n > cutlim))
          return false;
       value *= base;
       value += n;
       ++first;
    }
    value *= sign;
    if (first != last)
       return false;

    return true;
  }

  template<class Int_type>
  static bool
  _S_a2ui10(Iter first, Iter last, Int_type max_val, Int_type& value)
  {
    const Int_type base = 10;
    const Int_type cutoff = max_val / base;
    const Int_type cutlim = max_val % base;

    value = 0;
    char c;
    // Check the sign
    if (first != last && !isdigit(c = *first)) {
       if (c == '+')
         ++first;
       else
          return false;
    }
    if (first == last)
       return false;

    // Skip leading zeroes
    while (first != last && isdigit(c = *first) && c == '0')
       ++first;

    while (first != last && isdigit(c = *first)) {
       Int_type n = c - '0';
       if (value > cutoff || (value == cutoff && n > cutlim))
          return false;
       value *= base;
       value += n;
       ++first;
    }
    if (first != last)
       return false;

    return true;
  }
};



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]