Listing 2: Partial implementation of money_get

        // TEMPLATE CLASS money_get
template<class _E,
    class _II = istreambuf_iterator<_E, char_traits<_E> > >
    class money_get : public locale::facet {
    typedef moneypunct<_E, false> _Mypunct0;
    typedef moneypunct<_E, true> _Mypunct1;
public:
    typedef _E char_type;
    typedef _II iter_type;
    typedef basic_string<_E, char_traits<_E>, allocator<_E> >
        string_type;
    _II get(_II _F, _II _L, bool _Intl, ios_base& _X,
        ios_base::iostate& _St, long double& _V) const
        {return (do_get(_F, _L, _Intl, _X, _St, _V)); }
    _II get(_II _F, _II _L, bool _Intl, ios_base& _X,
        ios_base::iostate& _St, string_type& _D) const
        {return (do_get(_F, _L, _Intl, _X, _St, _D)); }
    static locale::id id;
    explicit money_get(size_t _R = 0);
protected:
    virtual ~money_get();
    virtual _II do_get(_II _F, _II _L, bool _Intl, ios_base& _X,
        ios_base::iostate& _St, long double& _V) const
        {string_type _Str = _Getmfld(_F, _L, _Intl, _X);
        if (_F == _L)
            _St |= ios_base::eofbit;
        if (_Str.size() == 0)
            _St |= ios_base::failbit;
        else
            {string _Str2;
            _Str2.reserve(_Str.size());
            for (size_t _I = 0; _I < _Str.size(); ++_I)
                _Str2 += _NARROW(_E, _Str[_I]);
            const char *_Eb = _Str2.c_str();
            char *_Ep;
            errno = 0;
            const long double _Ans = _Stold(_Eb, &_Ep, 0);
            if (_Ep == _Eb || errno != 0)
                _St |= ios_base::failbit;
            else
                _V = _Ans; }
        return (_F); }
    virtual _II do_get(_II _F, _II _L, bool _Intl, ios_base& _X,
        ios_base::iostate& _St, string_type& _D) const
        {string_type _Str = _Getmfld(_F, _L, _Intl, _X);
        if (_F == _L)
            _St |= ios_base::eofbit;
        if (_Str.size() == 0)
            _St |= ios_base::failbit;
        else
            _D = _Str;
        return (_F); }
private:
    string_type _Getmfld(_II& _F, _II& _L, bool _Intl,
        ios_base& _X) const
        {const _Mpunct<_E> *_Pfac;
        if (_Intl)
            _Pfac = &_USE(_X.getloc(), _Mypunct1);
        else
            _Pfac = &_USE(_X.getloc(), _Mypunct0);
        const ctype<_E>& _Fac2 = _USE(_X.getloc(), ctype<_E>);
        bool _Bad = false, _Neg = false;
        string_type _Sg, _Str;
        const money_base::pattern _Pat = _Pfac->neg_format();
        for (size_t _N = 0; !_Bad && _N < 4; ++_N)
            switch (_Pat.field[_N])
        {case money_base::symbol:
            {string_type _Cs = _Pfac->curr_symbol();
            string_type::const_iterator _S;
            if (_X.flags() & ios_base::showbase)
                ;
            else if (_N == 3 && _Sg.size() == 0
                || _F == _L || *_F != *_Cs.c_str())
                _Cs.erase();
            for (_S = _Cs.begin(); _F != _L && _S != _Cs.end()
                && *_F == *_S; ++_S, ++_F)
                ;
            if (_S != _Cs.end())
                _Bad = true; }
            break;
        case money_base::sign:
            {if (_F == _L)
                ;
            else if (0 < (_Pfac->positive_sign()).size()
                && _Pfac->positive_sign()[0] == *_F)
                ++_F, _Sg = _Pfac->positive_sign();
            else if (0 < (_Pfac->negative_sign()).size()
                && _Pfac->negative_sign()[0] == *_F)
                ++_F, _Sg = _Pfac->negative_sign(), _Neg = true;
            if (_Sg.size() == 1)
                _Sg.erase(); }
            break;
        case money_base::value:
            {int _Nfd = 0;
            int _Fd = _Pfac->frac_digits();

const string _Gr = _Pfac->grouping();

            if (*_Gr.c_str() <= '\0')
                while (_F != _L
                    && _Fac2.is(ctype_base::digit, *_F))
                    _Str += *_F++;
            else
                {const _E _Ks = _Pfac->thousands_sep();
                string _Grin((size_t)1, '\0');
                size_t _I = 0;
                for (; _F != _L; ++_F)
                    if (_Fac2.is(ctype_base::digit, *_F))
                        {_Str += *_F;
                        if (_Grin[_I] != CHAR_MAX)
                            ++_Grin[_I]; }
                    else if (_Grin[_I] == '\0' || *_F != _Ks)
                        break;
                    else
                        _Grin.append((size_t)1, '\0'), ++_I;
                if (_I == 0)
                    ;
                else if ('\0' < _Grin[_I])
                    ++_I;
                else
                    _Bad = true;
                for (const char *_Pg = _Gr.c_str();
                    !_Bad && 0 < _I; --_I)
                    if (*_Pg == CHAR_MAX)
                        break;
                    else if (0 < --_I && *_Pg != _Grin[_I]
                        || 0 == _I && *_Pg < _Grin[_I])
                        _Bad = true;
                    else if ('\0' < _Pg[1])
                        ++_Pg;
                if (_Bad)
                    break; }
            if (_F != _L && *_F == _Pfac->decimal_point())
                {while (++_F != _L
                    && _Fac2.is(ctype_base::digit, *_F))
                    if (_Nfd < _Fd)
                        _Str += *_F, ++_Nfd; }
            if (_Str.size() == 0)
                _Bad = true;
            else
                for (; _Nfd < _Fd; ++_Nfd)
                    _Str += _WIDEN(_E, '0'); }
            break;
        default:
            {if (_N == 3)
                break;
            while (_F != _L && _Fac2.is(ctype_base::space, *_F))
                ++_F; }}
        if (!_Bad && 0 < _Sg.size())
            {string_type::const_iterator _S;
            for (_S = _Sg.begin(); _F != _L
                && ++_S != _Sg.end() && *_F == *_S; ++_F)
                ;
            if (_S != _Sg.end())
                _Bad = true; }
        if (_Bad)
            _Str.erase();
        else if (_Neg)
            _Str.insert((size_t)0, (size_t)1, _WIDEN(_E, '-'));
        return (_Str); }
    };
template<class _E, class _II>
    locale::id money_get<_E, _II>::id;
//End of File