Listing 3: Class codecvt<wchar_t, wchar, mbstate_t>

        // CLASS codecvt<wchar_t, char, mbstate_t>
template<>
    class codecvt<wchar_t, char, mbstate_t>
    : public codecvt_base {
public:
    typedef wchar_t _E;
    typedef char _To;
    typedef mbstate_t _St;
    typedef _E intern_type;
    typedef _To extern_type;
    typedef _St state_type;
    result in(_St& _State,
        const _To *_F1, const _To *_L1, const _To *& _Mid1,
        _E *_F2, _E *_L2, _E *& _Mid2) const
        {return (do_in(_State,
            _F1, _L1, _Mid1, _F2, _L2, _Mid2)); }
    result out(_St& _State,
        const _E *_F1, const _E *_L1, const _E *& _Mid1,
        _To *_F2, _To *_L2, _To *& _Mid2) const
        {return (do_out(_State,
            _F1, _L1, _Mid1, _F2, _L2, _Mid2)); }
    result unshift(_St& _State,
        _To *_F2, _To *_L2, _To *& _Mid2) const
        {return (do_unshift(_State,
            _F2, _L2, _Mid2)); }
    int length(_St& _State, const _E *_F1,
        const _E *_L1, size_t _N2) const throw ()
        {return (do_length(_State, _F1, _L1, _N2)); }
    static locale::id id;
    explicit codecvt(size_t _R = 0)
        : codecvt_base(_R) {_Init(_Locinfo()); }
    codecvt(const _Locinfo& _Lobj, size_t _R = 0)
        : codecvt_base(_R) {_Init(_Lobj); }
    static size_t _CDECL _Getcat()
        {return (_X_CTYPE); }
protected:
    virtual ~codecvt()
        {};
    void _Init(const _Locinfo& _Lobj)
        {_Cvt = _Lobj._Getcvt(); }
    virtual result do_in(_St& _State,
        const _To *_F1, const _To *_L1, const _To *& _Mid1,
        _E *_F2, _E *_L2, _E *& _Mid2) const
        {_Mid1 = _F1, _Mid2 = _F2;
        result _Ans = _Mid1 == _L1 ? ok : partial;
        int _N;
        while (_Mid1 != _L1 && _Mid2 != _L2)
            switch (_N = _Mbrtowc(_Mid2, _Mid1, _L1 - _Mid1,
                &_State, &_Cvt))
            {case -2:
                _Mid1 = _L1;
                return (_Ans);
            case -1:
                return (error);
            case 0:
                _N = strlen(_Mid1) + 1;
            default:    // fall through
                _Mid1 += _N, ++_Mid2, _Ans = ok; }
        return (_Ans); }
    virtual result do_out(_St& _State,
        const _E *_F1, const _E *_L1, const _E *& _Mid1,
        _To *_F2, _To *_L2, _To *& _Mid2) const
        {_Mid1 = _F1, _Mid2 = _F2;
        result _Ans = _Mid1 == _L1 ? ok : partial;
        int _N;
        while (_Mid1 != _L1 && _Mid2 != _L2)
            if (MB_CUR_MAX <= _L2 - _Mid2)
                if ((_N = _Wcrtomb(_Mid2, *_Mid1,
                    &_State, &_Cvt)) <= 0)
                    return (error);
                else
                    ++_Mid1, _Mid2 += _N, _Ans = ok;
            else
                {_To _Buf[MB_LEN_MAX];
                _St _Stsave = _State;
                if ((_N = _Wcrtomb(_Buf, *_Mid1,
                    &_State, &_Cvt)) <= 0)
                    return (error);
                else if (_L2 - _Mid2 < _N)
                    {_State = _Stsave;
                    return (_Ans); }
                else
                    {memcpy(_Mid2, _Buf, _N);
                    ++_Mid1, _Mid2 += _N, _Ans = ok; }}
        return (_Ans); }
    virtual result do_unshift(_St& _State,
        _To *_F2, _To *_L2, _To *& _Mid2) const
        {_Mid2 = _F2;
        result _Ans = ok;
        int _N;
        _To _Buf[MB_LEN_MAX];
        _St _Stsave = _State;
        if ((_N = _Wcrtomb(_Buf, L'\0', &_State, &_Cvt)) <= 0)
            _Ans = error;
        else if (_L2 - _Mid2 < --_N)
            {_State = _Stsave;
            _Ans = partial; }
        else if (0 < _N)
            {memcpy(_Mid2, _Buf, _N);
            _Mid2 += _N; }
        return (_Ans); }
    virtual int do_length(_St& _State, const _E *_F1,
        const _E *_L1, size_t _N2) const throw ()
        {const _E *_Mid1;
        _To _Buf[MB_LEN_MAX];
        int _N;
        for (_Mid1 = _F1; _Mid1 != _L1 && 0 < _N2;
            ++_Mid1, _N2 -= _N)
            if ((_N = _Wcrtomb(_Buf, *_Mid1,
                &_State, &_Cvt)) <= 0 || _N2 < _N)
                break;
        return (_Mid1 - _F1); }
    virtual bool do_always_noconv() const throw ()
        {return (false); }
    virtual int do_max_length() const throw ()
        {return (MB_LEN_MAX); }
    virtual int do_encoding() const throw ()
        {return (0); }
private:
    _Locinfo::_Cvtvec _Cvt;
    };
// must define id in an object file as follows:
//template<>
//    locale::id codecvt<wchar_t, char, mbstate_t>::id = 0;
//End of File