/***************************************************************************
 *
 * wctype.cpp - source for the C++ Standard Library ctype<wchar_t> facets
 *
 * $Id$
 *
 ***************************************************************************
 *
 * Licensed to the Apache Software  Foundation (ASF) under one or more
 * contributor  license agreements.  See  the NOTICE  file distributed
 * with  this  work  for  additional information  regarding  copyright
 * ownership.   The ASF  licenses this  file to  you under  the Apache
 * License, Version  2.0 (the  "License"); you may  not use  this file
 * except in  compliance with the License.   You may obtain  a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the  License is distributed on an  "AS IS" BASIS,
 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY  KIND, either  express or
 * implied.   See  the License  for  the  specific language  governing
 * permissions and limitations under the License.
 *
 * Copyright 2001-2005 Rogue Wave Software, Inc.
 * 
 **************************************************************************/

#define _RWSTD_LIB_SRC

#include <rw/_defs.h>

#ifndef _RWSTD_NO_WCHAR_T

#include <ctype.h>
#include <limits.h>
#include <locale.h>

#ifndef _RWSTD_NO_WCHAR_H
#  include <wchar.h>   // for wctob()
#endif   // _RWSTD_NO_WCHAR_H

#include <stdlib.h>   // for wctomb()
#include <string.h>   // for memset()
#include <wctype.h>   // for iswspace(), ...

#include <loc/_ctype.h>
#include <loc/_locale.h>
#include <loc/_localedef.h>

#include "setlocale.h"
#include "use_facet.h"

#ifdef _RWSTD_NO_EQUAL_CTYPE_MASK
#  include "once.h"   // for __rw_once()
#endif   // _RWSTD_NO_EQUAL_CTYPE_MASK

// utf8 encoding maximum size
#undef  _UTF8_MB_CUR_MAX
#define _UTF8_MB_CUR_MAX   6


_RWSTD_NAMESPACE (__rw) {

typedef _STD::ctype_base::mask MaskT;

extern const MaskT         __rw_classic_tab [];
extern const unsigned char __rw_upper_tab [];
extern const unsigned char __rw_lower_tab [];


static const wchar_t*
__rw_get_mask (__rw_ctype_t    *impl,
               const wchar_t   *beg,
               const wchar_t   *end,
               MaskT            mask,
               MaskT           *vec,
               bool             scan_is,
               bool             use_libstd,
               const char      *locname)
{
    _RWSTD_ASSERT (!end || beg <= end);

    if (use_libstd && impl != 0) {

        for (; beg != end; ++beg) {

            // using binary search look up the character and its mask
            size_t low  = 0;
            size_t high = size_t (impl->wmask_s);

            if (vec)
                *vec = MaskT ();

            while (low <= high) {

                const size_t cur = (low + high) / 2;
                const __rw_mask_elm next_elm = impl->wmask_tab (cur);

                if (next_elm.ch == *beg) {

                    // character found
                    // if vec is non-0, fill it with the character's mask
                    // otherwise, if scanning for a match and the char's
                    // mask matches, or if scanning for a mismatch and
                    // the char's mask does not match, return the pointer
                    // to the current character; otherwise continue
                    if (vec)
                        *vec = MaskT (next_elm.mask & mask);
                    else if (    (scan_is && next_elm.mask & mask)
                             || (!scan_is && !(next_elm.mask & mask)))
                        return beg;

                    break;
                }

                // convert both sides to a sufficiently large type
                // with the same signedness
                if (  _RWSTD_STATIC_CAST (_RWSTD_UINT32_T, next_elm.ch)
                    < _RWSTD_STATIC_CAST (_RWSTD_UINT32_T, *beg))
                    low = cur + 1;
                else
                    high = cur - 1;
            }

            if (vec)
                ++vec;
        }

        return beg;
    }

    const __rw_setlocale clocale (locname, LC_CTYPE);

    for (; beg != end; ++beg) {

        int m = 0;

        // does the value of *beg fit into the range of an unsigned char?
        const bool fits_char =
            _RWSTD_STATIC_CAST (size_t, *beg) <= _RWSTD_UCHAR_MAX;

        // `fits_char' is not used if all wide character
        // classification functions use below are present
        _RWSTD_UNUSED (fits_char);

        if (mask & __rw_space) {
#ifndef _RWSTD_NO_ISWSPACE
            if ((::iswspace)(*beg))
#else
            if (fits_char && (::isspace)(*beg))
#endif   // _RWSTD_NO_ISWSPACE
                m |= __rw_space;
        }

        if (mask & __rw_print) {
#ifndef _RWSTD_NO_ISWPRINT
            if ((::iswprint)(*beg))
#else
            if (fits_char && (::isprint)(*beg))
#endif   // _RWSTD_NO_ISWPRINT
                m |= __rw_print;
        }

        if (mask & __rw_cntrl) {
#ifndef _RWSTD_NO_ISWCNTRL
            if ((::iswcntrl)(*beg))
#else
            if (fits_char && (::iscntrl)(*beg))
#endif   // _RWSTD_NO_ISWCNTRL
                m |= __rw_cntrl;
        }

        if (mask & __rw_upper) {
#ifndef _RWSTD_NO_ISWUPPER
            if ((::iswupper)(*beg))
#else
            if (fits_char && (::isupper)(*beg))
#endif   // _RWSTD_NO_ISWUPPER
                m |= __rw_upper;
        }

        if (mask & __rw_lower) {
#ifndef _RWSTD_NO_ISWLOWER
            if ((::iswlower)(*beg))
#else
            if (fits_char && (::islower)(*beg))
#endif   // _RWSTD_NO_ISWLOWER
                m |= __rw_lower;
        }

        if (mask & __rw_alpha) {
#ifndef _RWSTD_NO_ISWALPHA
            if ((::iswalpha)(*beg))
#else
            if (fits_char && (::isalpha)(*beg))
#endif   // _RWSTD_NO_ISWALPHA
                m |= __rw_alpha;
        }

        if (mask & __rw_digit) {
#ifndef _RWSTD_NO_ISWDIGIT
            if ((::iswdigit)(*beg))
#else
            if (fits_char && (::isdigit)(*beg))
#endif
                m |= __rw_digit;
        }

        if (mask & __rw_punct) {
#ifndef _RWSTD_NO_ISWPUNCT
            if ((::iswpunct)(*beg))
#else
            if (fits_char && (::ispunct)(*beg))
#endif   // _RWSTD_NO_ISWPUNCT
                m |= __rw_punct;
        }

        if (mask & __rw_xdigit) {
#ifndef _RWSTD_NO_ISWXDIGIT
            if ((::iswxdigit)(*beg))
#else
            if (fits_char && (::isxdigit) (*beg))
#endif   // _RWSTD_NO_ISWXDIGIT
                m |= __rw_xdigit;
        }

        if (mask & __rw_graph) {
#ifndef _RWSTD_NO_ISWGRAPH
            if ((::iswgraph)(*beg))
#else
            if (fits_char && (::isgraph)(*beg))
#endif   // _RWSTD_NO_ISWGRAPH
                m |= __rw_graph;
        }

        if (vec)
            *vec++ = MaskT (m);
        else if ((scan_is && m & mask) || (!scan_is && !(m & mask)))
            break;
    }

    return beg;
}


static _STD::ctype_byname<wchar_t>::char_type
__rw_toupper (__rw_ctype_t* impl,
              wchar_t c, bool use_libstd,
              const char* locname)
{
    if (use_libstd && impl != 0) {

        size_t low  = 0;
        size_t high = size_t (impl->wtoupper_s ());
        size_t cur;

        __rw_upper_elm next_elm;

        while (low <= high) {
            cur = (low + high) / 2;
            next_elm = impl->wtoupper_tab(cur);
            if (next_elm.lower == c) {
                c = next_elm.upper;
                break;
            }

            // convert both sides to a sufficiently large type
            // with the same signedness
            if (  _RWSTD_STATIC_CAST (_RWSTD_UINT32_T, next_elm.lower)
                < _RWSTD_STATIC_CAST (_RWSTD_UINT32_T, c))
                low = cur + 1;
            else
                high = cur - 1;
        }
    }
    else {

#ifndef _RWSTD_NO_TOWUPPER

        const __rw_setlocale clocale (locname, LC_CTYPE);

        c = (::towupper)(c);

#else   // if defined (_RWSTD_NO_TOWUPPER)

        if (_RWSTD_STATIC_CAST (size_t, c) <= _RWSTD_UCHAR_MAX) {

            const __rw_setlocale clocale (locname, LC_CTYPE);

            c = (::toupper)(c);
        }

#endif   // _RWSTD_NO_TOWUPPER

    }

    return c;
}


static _STD::ctype_byname<wchar_t>::char_type
__rw_tolower (__rw_ctype_t* impl,
              wchar_t c, bool use_libstd,
              const char* locname)
{
    if (use_libstd && impl != 0) {

        size_t low  = 0;
        size_t high = size_t (impl->wtolower_s ());
        size_t cur;

        __rw_lower_elm next_elm;

        while (low <= high) {
            cur = (low + high) / 2;
            next_elm = impl->wtolower_tab(cur);
            if (next_elm.upper == c) {
                c = next_elm.lower;
                break;
            }

            // convert both sides to a sufficiently large type
            // with the same signedness
            if (  _RWSTD_STATIC_CAST (_RWSTD_UINT32_T, next_elm.upper)
                < _RWSTD_STATIC_CAST (_RWSTD_UINT32_T, c))
                low = cur + 1;
            else
                high = cur - 1;
        }
    }
    else {

#ifndef _RWSTD_NO_TOWLOWER

        const __rw_setlocale clocale (locname, LC_CTYPE);

        c = (::towlower)(c);

#else   // if defined (_RWSTD_NO_TOWLOWER)

        if (_RWSTD_STATIC_CAST (size_t, c) <= _RWSTD_UCHAR_MAX) {

            const __rw_setlocale clocale (locname, LC_CTYPE);

            c = (::tolower)(c);
        }

#endif   // _RWSTD_NO_TOWLOWER

    }

    return c;
}


#if 0   // FIXME: implement analogously to the above

static void
__rw_narrow (const __rw_codecvt_t *cvt, bool use_libstd,
             const wchar_t *lo, const wchar_t *hi, char dfault, char *dst)
{
}


static void
__rw_widen (const __rw_codecvt_t *cvt, bool use_libstd,
            const char *lo, const char *hi, wchar_t *dst)
{
}

#endif   // 0/1

#ifdef _RWSTD_NO_EQUAL_CTYPE_MASK

// table of wide character classes
static _STD::ctype_base::mask
__rw_classic_wide_tab [_STD::ctype<char>::table_size];

// init-once flag for the classic wide tab
static __rw_once_t
__rw_classic_wide_tab_once_init = _RWSTD_ONCE_INIT;

extern "C" {

// one-time initializer for the classic wide_tab
static void
__rw_init_classic_wide_tab ()
{
#  ifdef _RWSTDDEBUG

    static int init;

    // paranoid check: verify that one-time initialization works
    _RWSTD_ASSERT (0 == init);

    ++init;

#  endif   // _RWSTDDEBUG

    // init the classic wide tab
    wchar_t wc_array [_STD::ctype<char>::table_size];

    for (wchar_t wc = 0; wc < _STD::ctype<char>::table_size; ++wc)
        wc_array [wc] = wc;

    __rw_get_mask (0, wc_array, wc_array + _STD::ctype<char>::table_size,
                   __rw_all, __rw_classic_wide_tab, false, false, "C");
}

}   // extern "C"

#endif   // _RWSTD_NO_EQUAL_CTYPE_MASK

}   // namespace __rw


_RWSTD_NAMESPACE (std) {


_RW::__rw_facet_id ctype<wchar_t>::id;


ctype<wchar_t>::ctype (size_t ref) _THROWS (())
    : _RW::__rw_facet (ref)
{
#ifndef _RWSTD_NO_EQUAL_CTYPE_MASK
    _C_mask_tab  = _RW::__rw_classic_tab;
#else
    // initialize classic wide tab exactly once
    _RW::__rw_once (&_RW::__rw_classic_wide_tab_once_init,
                    _RW::__rw_init_classic_wide_tab);

    _C_mask_tab  = _RW::__rw_classic_wide_tab;
#endif
    _C_upper_tab = _RWSTD_CONST_CAST (_UChar*, _RW::__rw_upper_tab);
    _C_lower_tab = _RWSTD_CONST_CAST (_UChar*, _RW::__rw_lower_tab);
    _C_delete_it = false;

    memset (_C_narrow_tab, 0, sizeof _C_narrow_tab);
    memset (_C_wide_tab, 0, sizeof _C_wide_tab);
}


ctype<wchar_t>::~ctype ()
{
    if (_C_delete_it) {
        delete[] _RWSTD_CONST_CAST (mask*, _C_mask_tab);

        if (_C_upper_tab != _RW::__rw_upper_tab) {
            // lower_tab is allocated in the same block of memory
            // as upper_tab and must not be deleted
            delete[] _C_upper_tab;
        }
    }
}


bool ctype<wchar_t>::
do_is (mask m, char_type c) const
{
    return    _RWSTD_STATIC_CAST (size_t, c) <= _C_tab_size
           && (_C_mask_tab [_UChar (c)] & m);
}


const ctype<wchar_t>::char_type*
ctype<wchar_t>::
do_is (const char_type *lo, const char_type *hi, mask *mvec) const
{
    _RWSTD_ASSERT (lo <= hi);

    for ( ; lo != hi; ++lo, ++mvec) {
        *mvec = _RWSTD_STATIC_CAST (size_t, *lo) < _C_tab_size ?
            _C_mask_tab [_UChar (*lo)] : mask (0);
    }

    return hi;

}


ctype<wchar_t>::char_type
ctype<wchar_t>::
do_widen (char c) const
{
    // explicitly specifying template argument list to work around
    // HP aCC 3 and 5 bug (STDCXX-445)
    return _RWSTD_CONST_CAST (ctype<wchar_t>*, this)->
        _C_wide_tab [_UChar (c)] = char_type (_UChar (c));
}


const char*
ctype<wchar_t>::
do_widen (const char *lo, const char *hi, char_type *dest) const
{
    _RWSTD_ASSERT (lo <= hi);
    while (lo < hi) {
        // call widen instead of do_widen to take advantage of the
        // table optimization
        *dest++ = widen (*lo++);
    }
    return hi;
}


ctype<wchar_t>::char_type
ctype<wchar_t>::
do_toupper (char_type c) const
{
    return _RWSTD_STATIC_CAST (size_t, c) < _C_tab_size ?
        _C_upper_tab [_UChar (c)] : c;
}


ctype<wchar_t>::char_type
ctype<wchar_t>::
do_tolower (char_type c) const
{
    return _RWSTD_STATIC_CAST (size_t, c) < _C_tab_size ?
        _C_lower_tab [_UChar (c)] : c;
}


const ctype<wchar_t>::char_type*
ctype<wchar_t>::
do_toupper (char_type *lo, const char_type *hi) const
{
    _RWSTD_ASSERT (lo <= hi);

    for ( ; lo < hi; ++lo)
        *lo = _RWSTD_STATIC_CAST (size_t, *lo) < _C_tab_size ?
            _C_upper_tab [_UChar (*lo)] : 0;

    return lo;
}


const ctype<wchar_t>::char_type*
ctype<wchar_t>::
do_tolower (char_type *lo, const char_type *hi) const
{
    _RWSTD_ASSERT (lo <= hi);

    for ( ; lo < hi; ++lo)
        *lo = _RWSTD_STATIC_CAST (size_t, *lo) < _C_tab_size ?
            _C_lower_tab [_UChar (*lo)] : 0;

    return lo;
}


const ctype<wchar_t>::char_type*
ctype<wchar_t>::
do_scan_is (mask m, const char_type *lo, const char_type *hi) const
{
    _RWSTD_ASSERT (lo <= hi);

    for ( ; lo != hi; ++lo) {
        if (   _RWSTD_STATIC_CAST (size_t, *lo) <= _C_tab_size
            && (_C_mask_tab [_UChar (*lo)] & m))
            break;
    }

    return lo;
}


const ctype<wchar_t>::char_type*
ctype<wchar_t>::
do_scan_not (mask m, const char_type *lo, const char_type *hi) const
{
    _RWSTD_ASSERT (lo <= hi);
    for ( ; lo != hi; ++lo) {
        if (   _RWSTD_STATIC_CAST (size_t, *lo) >= _C_tab_size
            || !(_C_mask_tab [_UChar (*lo)] & m))
            break;
    }

    return lo;
}


char
ctype<wchar_t>::
do_narrow (char_type c, char dfault) const
{
    return _RWSTD_STATIC_CAST (size_t, c) <= _RWSTD_SCHAR_MAX ?
        _RWSTD_STATIC_CAST (char, c) : dfault;
}


const ctype<wchar_t>::char_type*
ctype<wchar_t>::
do_narrow (const char_type *lo, const char_type *hi,
           char dfault, char *dest) const
{
    _RWSTD_ASSERT (lo <= hi);
    while (lo != hi) {
        *dest++ = do_narrow (*lo++, dfault);
    }
    return hi;
}


ctype_byname<wchar_t>::
ctype_byname (const char *name, size_t refs)
    : ctype<wchar_t> (refs), _C_cvtimpl (0), _C_cvtsize (0)
{
    this->_C_set_name (name, _C_namebuf, sizeof _C_namebuf);

    if ('C' == name [0] && '\0' == name [1])
        return;

    // delayed initialization not used for efficiency
    _RW::__rw_ctype_t* impl =
        _RWSTD_CONST_CAST (_RW::__rw_ctype_t*,
            _RWSTD_STATIC_CAST (const _RW::__rw_ctype_t*,
                _RW::__rw_get_facet_data (LC_CTYPE, _C_impsize, _C_name)));

    _C_impdata = impl;

    // Memory map the codecvt database and store it for future use
    if (impl)
        _C_cvtimpl = _RW::__rw_get_facet_data (LC_CTYPE, _C_cvtsize, 0, 
                                               impl->codeset_name ());

    if (impl == 0 || (this->_C_opts & this->_C_use_libc)) {

        // set locale first to avoid unnecessary allocation
        // if `name' doesn't refer to a valid locale (and
        // __rw_setlocale throws an exception)
        const _RW::__rw_setlocale clocale (name, LC_CTYPE);

        _C_delete_it = true;

        // casts prevent bogus gcc 2.95.2 warning:
        //     size in array new must have integral type
        _C_mask_tab = new mask [size_t (_C_tab_size)];

        _TRY {
            // avoid doing one extra allocation by allocating
            // both the upper and lower tables in the same space
            _C_upper_tab = new _UChar [size_t (_C_tab_size) * 2];
            _C_lower_tab = _C_upper_tab + _C_tab_size;
        }
        _CATCH (...) {
            delete[] _RWSTD_CONST_CAST (mask*, _C_mask_tab);
            _RETHROW;
        }

        for (char_type i = 0; i <= char_type (_RWSTD_UCHAR_MAX); i++) {

            int m = 0;

#ifndef _RWSTD_NO_ISWSPACE
            if ((::iswspace)(i))
#else
            if ((::isspace)(i))
#endif   // _RWSTD_NO_ISWSPACE
                m |= _RW::__rw_space;

#ifndef _RWSTD_NO_ISWPRINT
            if ((::iswprint)(i))
#else
            if ((::isprint)(i))
#endif   // _RWSTD_NO_ISWPRINT
                m |= _RW::__rw_print;

#ifndef _RWSTD_NO_ISWCNTRL
            if ((::iswcntrl)(i))
#else
            if ((::iscntrl)(i))
#endif   // _RWSTD_NO_ISWCNTRL
                m |= _RW::__rw_cntrl;

#ifndef _RWSTD_NO_ISWUPPER
            if ((::iswupper)(i))
#else
            if ((::isupper)(i))
#endif   // _RWSTD_NO_ISWUPPER
                m |= _RW::__rw_upper;

#ifndef _RWSTD_NO_ISWLOWER
            if ((::iswlower)(i))
#else
            if ((::islower)(i))
#endif   // _RWSTD_NO_ISWLOWER
                m |= _RW::__rw_lower;

#ifndef _RWSTD_NO_ISWALPHA
            if ((::iswalpha)(i))
#else
            if ((::isalpha)(i))
#endif   // _RWSTD_NO_ISWALPHA
                m |= _RW::__rw_alpha;

#ifndef _RWSTD_NO_ISWDIGIT
            if ((::iswdigit)(i))
#else
            if ((::isdigit)(i))
#endif   // _RWSTD_NO_ISWDIGIT
                m |= _RW::__rw_digit;

#ifndef _RWSTD_NO_ISWPUNCT
            if ((::iswpunct)(i))
#else
            if ((::ispunct)(i))
#endif   // _RWSTD_NO_ISWPUNCT
                m |= _RW::__rw_punct;

#ifndef _RWSTD_NO_ISWXDIGIT
            if ((::iswxdigit)(i))
#else
            if ((::isxdigit)(i))
#endif   // _RWSTD_NO_ISWXDIGIT
                m |= _RW::__rw_xdigit;

#ifndef _RWSTD_NO_ISWGRAPH
            if ((::iswgraph)(i))
#else
            if ((::isgraph)(i))
#endif   // _RWSTD_NO_ISWGRAPH
                m |= _RW::__rw_graph;

            _RWSTD_CONST_CAST (mask*, _C_mask_tab) [i]  = mask (m);

#ifndef _RWSTD_NO_TOWUPPER
            const size_t upr = size_t ((::towupper)(i));
#else   // if defined (_RWSTD_NO_TOWUPPER)
            const size_t upr = size_t ((::toupper)(i));
#endif   // _RWSTD_NO_TOWUPPER

#ifndef _RWSTD_NO_TOWLOWER
            const size_t lwr = size_t ((::towlower)(i));
#else   // if defined (_RWSTD_NO_TOWLOWER)
            const size_t lwr = size_t ((::tolower)(i));
#endif   // _RWSTD_NO_TOWLOWER

            // optimize (and avoid warnings) when wint_t is unsigned
            _C_upper_tab [i] = upr <= size_t (_RWSTD_UCHAR_MAX) ?
                _UChar (upr) : _UChar (0);

            _C_lower_tab [i] = lwr <= size_t (_RWSTD_UCHAR_MAX) ?
                _UChar (lwr) : _UChar (0);
        }
    }
    else {

        _C_delete_it = false;

        _C_mask_tab  = (mask*)impl->mask_tab;
        _C_upper_tab = impl->toupper_tab;
        _C_lower_tab = impl->tolower_tab;
    }
}


ctype_byname<wchar_t>::
~ctype_byname ()
{
    // Release the codecvt database at this level
    if (_C_cvtimpl != 0 && _C_cvtsize != 0)
        _RW::__rw_release_facet_data (_C_cvtimpl, _C_cvtsize);
}


bool
ctype_byname<wchar_t>::
do_is (mask m, wchar_t c) const
{
    _RW::__rw_ctype_t* impl =
        _RWSTD_CONST_CAST (_RW::__rw_ctype_t*,
                           _RWSTD_STATIC_CAST (const _RW::__rw_ctype_t*,
                                               _C_data ()));

    const bool libstd = 0 != (this->_C_opts & this->_C_use_libstd);

    mask res = mask ();

    _RW::__rw_get_mask (impl, &c, &c + 1, m, &res, false, libstd, _C_name);

    return res != 0;
}


const ctype_byname<wchar_t>::char_type*
ctype_byname<wchar_t>::
do_is (const char_type *lo, const char_type *hi, mask *mvec) const
{
    _RWSTD_ASSERT (lo <= hi);
    _RW::__rw_ctype_t* impl =
        _RWSTD_CONST_CAST (_RW::__rw_ctype_t*,
                           _RWSTD_STATIC_CAST (const _RW::__rw_ctype_t*,
                                               _C_data ()));

    const bool libstd = 0 != (this->_C_opts & this->_C_use_libstd);

    return _RW::__rw_get_mask (impl, lo, hi, _RW::__rw_all,
                               mvec, false, libstd, _C_name);
}


ctype_byname<wchar_t>::char_type
ctype_byname<wchar_t>::
do_toupper (char_type c) const
{
    _RW::__rw_ctype_t* impl =
        _RWSTD_CONST_CAST (_RW::__rw_ctype_t*,
                           _RWSTD_STATIC_CAST (const _RW::__rw_ctype_t*,
                                               _C_data ()));

    const bool use_libstd = 0 != (this->_C_opts & this->_C_use_libstd);

    return _RW::__rw_toupper (impl, c, use_libstd, _C_name);
}


ctype_byname<wchar_t>::char_type
ctype_byname<wchar_t>::
do_tolower (char_type c) const
{
    _RW::__rw_ctype_t* impl =
        _RWSTD_CONST_CAST (_RW::__rw_ctype_t*,
                           _RWSTD_STATIC_CAST (const _RW::__rw_ctype_t*,
                                               _C_data ()));

    const bool use_libstd = 0 != (this->_C_opts & this->_C_use_libstd);

    return _RW::__rw_tolower (impl, c, use_libstd, _C_name);
}


const ctype_byname<wchar_t>::char_type*
ctype_byname<wchar_t>::
do_toupper (char_type *lo, const char_type *hi) const
{
    _RWSTD_ASSERT (lo <= hi);
    _RW::__rw_ctype_t* impl =
        _RWSTD_CONST_CAST (_RW::__rw_ctype_t*,
                           _RWSTD_STATIC_CAST (const _RW::__rw_ctype_t*,
                                               _C_data ()));

    const bool use_libstd = 0 != (this->_C_opts & this->_C_use_libstd);

    // FIXME: implement efficiently (__rw_toupper() may call setlocale())
    for ( ; lo < hi; ++lo)
        *lo = _RW::__rw_toupper (impl, *lo, use_libstd, _C_name);
    return lo;
}


const ctype_byname<wchar_t>::char_type*
ctype_byname<wchar_t>::
do_tolower (char_type *lo, const char_type *hi) const
{
    _RWSTD_ASSERT (lo <= hi);
    _RW::__rw_ctype_t* impl =
        _RWSTD_CONST_CAST (_RW::__rw_ctype_t*,
                           _RWSTD_STATIC_CAST (const _RW::__rw_ctype_t*,
                                               _C_data ()));

    const bool use_libstd = 0 != (this->_C_opts & this->_C_use_libstd);

    // FIXME: implement efficiently (__rw_tolower() may call setlocale())
    for ( ; lo < hi; ++lo)
        *lo = _RW::__rw_tolower (impl, *lo, use_libstd, _C_name);
    return lo;
}


const ctype_byname<wchar_t>::char_type*
ctype_byname<wchar_t>::
do_scan_is (mask m, const char_type* lo, const char_type* hi) const
{
    _RWSTD_ASSERT (lo <= hi);

    _RW::__rw_ctype_t* impl =
        _RWSTD_CONST_CAST (_RW::__rw_ctype_t*,
                           _RWSTD_STATIC_CAST (const _RW::__rw_ctype_t*,
                                               _C_data ()));
    const bool libstd = 0 != (this->_C_opts & this->_C_use_libstd);

    return _RW::__rw_get_mask (impl, lo, hi, m, 0, true, libstd, _C_name);
}


const ctype_byname<wchar_t>::char_type*
ctype_byname<wchar_t>::
do_scan_not (mask m, const char_type *lo, const char_type *hi) const
{
    _RWSTD_ASSERT (lo <= hi);

    _RW::__rw_ctype_t* impl =
        _RWSTD_CONST_CAST (_RW::__rw_ctype_t*,
                           _RWSTD_STATIC_CAST (const _RW::__rw_ctype_t*,
                                               _C_data ()));
    const bool libstd = 0 != (this->_C_opts & this->_C_use_libstd);

    return _RW::__rw_get_mask (impl, lo, hi, m, 0, false, libstd, _C_name);
}


char
ctype_byname<wchar_t>::
do_narrow (char_type c, char dfault) const
{
#if _RWSTD_WCHAR_MIN < 0

    // wchar_t is a signed type
    if (c > L'\0' && c < SCHAR_MAX)
        return char (c);

#else   // if _RWSTD_WCHAR_MIN >= 0

    // wchar_t is an unsigned type
    if (c < SCHAR_MAX)
        return char (c);

#endif   // _RWSTD_WCHAR_MIN

    const _RW::__rw_codecvt_t* cvt = 
        _RWSTD_STATIC_CAST(const _RW::__rw_codecvt_t*, _C_cvtimpl);

    char ch = 0;
    if (0 == cvt || (this->_C_opts & this->_C_use_libc)) {

#ifndef _RWSTD_NO_WCTOB

        const _RW::__rw_setlocale clocale (_C_name, LC_CTYPE);

        const int tmp = wctob (c);

        ch = tmp < 0 ? dfault : char (tmp);

#elif !defined (_RWSTD_NO_WCTOMB)

        char tmp [_RWSTD_MB_LEN_MAX];
        ch = 1 == wctomb (tmp, c) ? *tmp : dfault;

#else   // if defined (_RWSTD_NO_WCTOMB)

        ch = dfault;

#endif   // _RWSTD_NO_WCTOB, _RWSTD_NO_WCTOMB

    }
    else {
        
#if _RWSTD_WCHAR_MIN < 0
        // For a signed wchar_t test if the character has a negative value
        if (c < 0)
            return dfault;
#endif // _RWSTD_WCHAR_MIN < 0

        // Look up narrow character value in database; be aware that there 
        // is no way to know what the internal representation is for this 
        // wide character; we have to assume that the internal representation 
        // was native and use wide-to-narrow tables for conversion
        char_type wc = 0;

        unsigned int* tbl  = _RWSTD_CONST_CAST(unsigned int*, 
                                               cvt->w_to_n_tab ());
        unsigned int* ptbl = tbl;

        char  tmp [_UTF8_MB_CUR_MAX + 1];
        char* ptmp = tmp;
        size_t utf8_sz = _RW::__rw_itoutf8 (c, tmp);

#if _RWSTD_WCHAR_MIN < 0
        // compute the invalid bit mask (the MSB set)
        const wchar_t imask = wchar_t (~(_RWSTD_WCHAR_MAX));
#else
        const wchar_t imask = wchar_t (~(_RWSTD_WCHAR_MAX >> 1));
#endif // _RWSTD_WCHAR_MIN < 0

        typedef unsigned char UChar;
        
        size_t i = 0;
        wc = ptbl [UChar (*ptmp)];
        while (wc & imask) {
            // check validity of the value
            if (wc == (imask | _RWSTD_WCHAR_MAX)) 
                return dfault;

            ptbl = tbl + 256 * (wc & (~imask));
            ptmp++;

            // check for invalid sequences
            if (++i >= utf8_sz)
                return dfault;

            // fetch next byte
            wc = ptbl [UChar (*ptmp)];
        }

        // the resulting ch value is an index to the storage space of
        // the narrow sequence; for our purposes here, that sequence has
        // to have length of one
        const char* impl_raw = 
            _RWSTD_REINTERPRET_CAST(const char*, cvt);
        size_t offset = wc + sizeof (_RW::__rw_codecvt_t);

        if (impl_raw [offset + 1])
            return dfault;
        else
            ch = impl_raw [offset];
    }

    return ch;
}


const ctype_byname<wchar_t>::char_type*
ctype_byname<wchar_t>::
do_narrow (const char_type *lo, const char_type *hi,
           char dfault, char *dest) const
{
    _RWSTD_ASSERT (lo <= hi);

    // FIXME: implement w/o relying on another virtual function
    while (lo != hi) {
        *dest++ = do_narrow (*lo, dfault);
        lo++;
    }
    return hi;
}


ctype_byname<wchar_t>::char_type
ctype_byname<wchar_t>::
do_widen (char c) const
{
    const unsigned char u_c = _UChar (c);

    if (u_c <= SCHAR_MAX)
        return char_type (u_c);

    // when using the C++ locale database files then we have to do
    // a table lookup to get the wide version of this character
    // otherwise we have to call setlocale() and btowc() to get the
    // corresponding wchar_t
    const _RW::__rw_codecvt_t* cvt = 
        _RWSTD_STATIC_CAST (const _RW::__rw_codecvt_t*, _C_cvtimpl);

    char_type ch;

    if (0 == cvt || (this->_C_opts & this->_C_use_libc)) {

#ifndef _RWSTD_NO_BTOWC

        const _RW::__rw_setlocale clocale (_C_name, LC_CTYPE);

        // prevent sign extension if `c' is negative
        ch = btowc (u_c);

#else   // if defined (_RWSTD_NO_BTOWC)

        ch = char_type (u_c);

#endif   // _RWSTD_NO_BTOWC

    }
    else {

#if _RWSTD_WCHAR_MIN < 0
        // compute the invalid bit mask (the MSB set)
        const char_type imask = char_type (~(_RWSTD_WCHAR_MAX));
#else
        const char_type imask = char_type (~(_RWSTD_WCHAR_MAX >> 1));
#endif   // _RWSTD_WCHAR_MIN < 0

        // Lookup the narrow character in the table; be aware that 
        // the result of the lookup might be the index for another
        // table (i.e., the narrow character may be the first byte
        // of a multibyte character) in which case return an error.
        ch = cvt->n_to_w_tab ()[u_c];
        if (ch & imask)
            return char_type (_RWSTD_WEOF);

        ch = cvt->get_internal_at_offset (ch);
    }

    return ch;
}


const char*
ctype_byname<wchar_t>::
do_widen (const char *lo, const char *hi, char_type *dest) const
{
    _RWSTD_ASSERT (lo <= hi);

    // FIXME: implement w/o relying on another virtual function
    while (lo < hi) {
        *dest++ = widen (*lo++);
    }
    
    return hi;
}


}   // namespace std


_RWSTD_DEFINE_FACET_FACTORY (static, ctype, <wchar_t>, wctype);
_RWSTD_SPECIALIZE_USE_FACET (wctype);

#endif   // _RWSTD_NO_WCHAR_T
