Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (c) 1999
      3  * Silicon Graphics Computer Systems, Inc.
      4  *
      5  * Copyright (c) 1999
      6  * Boris Fomitchev
      7  *
      8  * This material is provided "as is", with absolutely no warranty expressed
      9  * or implied. Any use is at your own risk.
     10  *
     11  * Permission to use or copy this software for any purpose is hereby granted
     12  * without fee, provided the above notices are retained on all copies.
     13  * Permission to modify the code and to distribute modified code is granted,
     14  * provided the above notices are retained, and a notice that the code was
     15  * modified is included with the above copyright notice.
     16  *
     17  */
     18 
     19 #include "stlport_prefix.h"
     20 
     21 #include <algorithm>
     22 #include <locale>
     23 #include <functional>
     24 
     25 #include "c_locale.h"
     26 
     27 _STLP_BEGIN_NAMESPACE
     28 
     29 //----------------------------------------------------------------------
     30 // ctype<char>
     31 
     32 // The classic table: static data members.
     33 
     34 #if !defined (_STLP_STATIC_CONST_INIT_BUG) && !defined (_STLP_NO_STATIC_CONST_DEFINITION)
     35 //*TY 02/25/2000 - added workaround for MPW compilers; they confuse on in-class static const
     36 const size_t ctype<char>::table_size;
     37 #endif
     38 
     39 // This macro is specifically for platforms where isprint() relies
     40 // on separate flag
     41 
     42 const ctype_base::mask*
     43 ctype<char>::classic_table() _STLP_NOTHROW {
     44   /* Ctype table for the ASCII character set. */
     45   static const ctype_base::mask _S_classic_table[table_size] = {
     46     cntrl /* null */,
     47     cntrl /* ^A */,
     48     cntrl /* ^B */,
     49     cntrl /* ^C */,
     50     cntrl /* ^D */,
     51     cntrl /* ^E */,
     52     cntrl /* ^F */,
     53     cntrl /* ^G */,
     54     cntrl /* ^H */,
     55     ctype_base::mask(space | cntrl) /* tab */,
     56     ctype_base::mask(space | cntrl) /* LF */,
     57     ctype_base::mask(space | cntrl) /* ^K */,
     58     ctype_base::mask(space | cntrl) /* FF */,
     59     ctype_base::mask(space | cntrl) /* ^M */,
     60     cntrl /* ^N */,
     61     cntrl /* ^O */,
     62     cntrl /* ^P */,
     63     cntrl /* ^Q */,
     64     cntrl /* ^R */,
     65     cntrl /* ^S */,
     66     cntrl /* ^T */,
     67     cntrl /* ^U */,
     68     cntrl /* ^V */,
     69     cntrl /* ^W */,
     70     cntrl /* ^X */,
     71     cntrl /* ^Y */,
     72     cntrl /* ^Z */,
     73     cntrl /* esc */,
     74     cntrl /* ^\ */,
     75     cntrl /* ^] */,
     76     cntrl /* ^^ */,
     77     cntrl /* ^_ */,
     78     ctype_base::mask(space | print) /*  */,
     79     ctype_base::mask(punct | print) /* ! */,
     80     ctype_base::mask(punct | print) /* " */,
     81     ctype_base::mask(punct | print) /* # */,
     82     ctype_base::mask(punct | print) /* $ */,
     83     ctype_base::mask(punct | print) /* % */,
     84     ctype_base::mask(punct | print) /* & */,
     85     ctype_base::mask(punct | print) /* ' */,
     86     ctype_base::mask(punct | print) /* ( */,
     87     ctype_base::mask(punct | print) /* ) */,
     88     ctype_base::mask(punct | print) /* * */,
     89     ctype_base::mask(punct | print) /* + */,
     90     ctype_base::mask(punct | print) /* , */,
     91     ctype_base::mask(punct | print) /* - */,
     92     ctype_base::mask(punct | print) /* . */,
     93     ctype_base::mask(punct | print) /* / */,
     94     ctype_base::mask(digit | print | xdigit) /* 0 */,
     95     ctype_base::mask(digit | print | xdigit) /* 1 */,
     96     ctype_base::mask(digit | print | xdigit) /* 2 */,
     97     ctype_base::mask(digit | print | xdigit) /* 3 */,
     98     ctype_base::mask(digit | print | xdigit) /* 4 */,
     99     ctype_base::mask(digit | print | xdigit) /* 5 */,
    100     ctype_base::mask(digit | print | xdigit) /* 6 */,
    101     ctype_base::mask(digit | print | xdigit) /* 7 */,
    102     ctype_base::mask(digit | print | xdigit) /* 8 */,
    103     ctype_base::mask(digit | print | xdigit) /* 9 */,
    104     ctype_base::mask(punct | print) /* : */,
    105     ctype_base::mask(punct | print) /* ; */,
    106     ctype_base::mask(punct | print) /* < */,
    107     ctype_base::mask(punct | print) /* = */,
    108     ctype_base::mask(punct | print) /* > */,
    109     ctype_base::mask(punct | print) /* ? */,
    110     ctype_base::mask(punct | print) /* ! */,
    111     ctype_base::mask(alpha | print | upper | xdigit) /* A */,
    112     ctype_base::mask(alpha | print | upper | xdigit) /* B */,
    113     ctype_base::mask(alpha | print | upper | xdigit) /* C */,
    114     ctype_base::mask(alpha | print | upper | xdigit) /* D */,
    115     ctype_base::mask(alpha | print | upper | xdigit) /* E */,
    116     ctype_base::mask(alpha | print | upper | xdigit) /* F */,
    117     ctype_base::mask(alpha | print | upper) /* G */,
    118     ctype_base::mask(alpha | print | upper) /* H */,
    119     ctype_base::mask(alpha | print | upper) /* I */,
    120     ctype_base::mask(alpha | print | upper) /* J */,
    121     ctype_base::mask(alpha | print | upper) /* K */,
    122     ctype_base::mask(alpha | print | upper) /* L */,
    123     ctype_base::mask(alpha | print | upper) /* M */,
    124     ctype_base::mask(alpha | print | upper) /* N */,
    125     ctype_base::mask(alpha | print | upper) /* O */,
    126     ctype_base::mask(alpha | print | upper) /* P */,
    127     ctype_base::mask(alpha | print | upper) /* Q */,
    128     ctype_base::mask(alpha | print | upper) /* R */,
    129     ctype_base::mask(alpha | print | upper) /* S */,
    130     ctype_base::mask(alpha | print | upper) /* T */,
    131     ctype_base::mask(alpha | print | upper) /* U */,
    132     ctype_base::mask(alpha | print | upper) /* V */,
    133     ctype_base::mask(alpha | print | upper) /* W */,
    134     ctype_base::mask(alpha | print | upper) /* X */,
    135     ctype_base::mask(alpha | print | upper) /* Y */,
    136     ctype_base::mask(alpha | print | upper) /* Z */,
    137     ctype_base::mask(punct | print) /* [ */,
    138     ctype_base::mask(punct | print) /* \ */,
    139     ctype_base::mask(punct | print) /* ] */,
    140     ctype_base::mask(punct | print) /* ^ */,
    141     ctype_base::mask(punct | print) /* _ */,
    142     ctype_base::mask(punct | print) /* ` */,
    143     ctype_base::mask(alpha | print | lower | xdigit) /* a */,
    144     ctype_base::mask(alpha | print | lower | xdigit) /* b */,
    145     ctype_base::mask(alpha | print | lower | xdigit) /* c */,
    146     ctype_base::mask(alpha | print | lower | xdigit) /* d */,
    147     ctype_base::mask(alpha | print | lower | xdigit) /* e */,
    148     ctype_base::mask(alpha | print | lower | xdigit) /* f */,
    149     ctype_base::mask(alpha | print | lower) /* g */,
    150     ctype_base::mask(alpha | print | lower) /* h */,
    151     ctype_base::mask(alpha | print | lower) /* i */,
    152     ctype_base::mask(alpha | print | lower) /* j */,
    153     ctype_base::mask(alpha | print | lower) /* k */,
    154     ctype_base::mask(alpha | print | lower) /* l */,
    155     ctype_base::mask(alpha | print | lower) /* m */,
    156     ctype_base::mask(alpha | print | lower) /* n */,
    157     ctype_base::mask(alpha | print | lower) /* o */,
    158     ctype_base::mask(alpha | print | lower) /* p */,
    159     ctype_base::mask(alpha | print | lower) /* q */,
    160     ctype_base::mask(alpha | print | lower) /* r */,
    161     ctype_base::mask(alpha | print | lower) /* s */,
    162     ctype_base::mask(alpha | print | lower) /* t */,
    163     ctype_base::mask(alpha | print | lower) /* u */,
    164     ctype_base::mask(alpha | print | lower) /* v */,
    165     ctype_base::mask(alpha | print | lower) /* w */,
    166     ctype_base::mask(alpha | print | lower) /* x */,
    167     ctype_base::mask(alpha | print | lower) /* y */,
    168     ctype_base::mask(alpha | print | lower) /* z */,
    169     ctype_base::mask(punct | print) /* { */,
    170     ctype_base::mask(punct | print) /* | */,
    171     ctype_base::mask(punct | print) /* } */,
    172     ctype_base::mask(punct | print) /* ~ */,
    173     cntrl /* del (0x7f)*/,
    174     /* ASCII is a 7-bit code, so everything else is non-ASCII */
    175     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    176     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    177     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    178     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    179     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    180     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    181     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    182     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    183     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    184     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    185     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    186     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    187     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    188     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    189     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0),
    190     ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0), ctype_base::mask(0),  ctype_base::mask(0)
    191   };
    192   return _S_classic_table;
    193 }
    194 
    195 // For every c in the range 0 <= c < 256, _S_upper[c] is the
    196 // uppercased version of c and _S_lower[c] is the lowercased
    197 // version.  As before, these two tables assume the ASCII character
    198 // set.
    199 
    200 const unsigned char _S_upper[ctype<char>::table_size] =
    201 {
    202   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    203   0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    204   0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    205   0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    206   0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    207   0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
    208   0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
    209   0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
    210   0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
    211   0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
    212   0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
    213   0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
    214   0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
    215   0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
    216   0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
    217   0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
    218   0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
    219   0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
    220   0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
    221   0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
    222   0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
    223   0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
    224   0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
    225   0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
    226   0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
    227   0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
    228   0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
    229   0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
    230   0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
    231   0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
    232   0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
    233   0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
    234 };
    235 
    236 const unsigned char _S_lower[ctype<char>::table_size] =
    237 {
    238   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    239   0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    240   0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    241   0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    242   0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    243   0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
    244   0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
    245   0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
    246   0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
    247   0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
    248   0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
    249   0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
    250   0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
    251   0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
    252   0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
    253   0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
    254   0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
    255   0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
    256   0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
    257   0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
    258   0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
    259   0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
    260   0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
    261   0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
    262   0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
    263   0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
    264   0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
    265   0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
    266   0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
    267   0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
    268   0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
    269   0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
    270 };
    271 
    272 //An helper struct to check wchar_t index without generating warnings
    273 //under some compilers (gcc) because of a limited range of value
    274 //(when wchar_t is unsigned)
    275 template <bool _IsSigned>
    276 struct _WCharIndexT;
    277 
    278 #if !(defined (__BORLANDC__) && !defined(__linux__)) && \
    279     !(defined (__GNUC__) && (defined (__MINGW32__) || defined (__CYGWIN__))) && \
    280     !defined (__ICL)
    281 _STLP_TEMPLATE_NULL
    282 struct _WCharIndexT<true> {
    283   static bool in_range(wchar_t c, size_t upperBound) {
    284     return c >= 0 && size_t(c) < upperBound;
    285   }
    286 };
    287 #endif
    288 
    289 _STLP_TEMPLATE_NULL
    290 struct _WCharIndexT<false> {
    291   static bool in_range(wchar_t c, size_t upperBound) {
    292     return size_t(c) < upperBound;
    293   }
    294 };
    295 
    296 typedef _WCharIndexT<wchar_t(-1) < 0> _WCharIndex;
    297 
    298 // Some helper functions used in ctype<>::scan_is and scan_is_not.
    299 
    300 struct _Ctype_is_mask : public unary_function<char, bool> {
    301   ctype_base::mask _Mask;
    302   const ctype_base::mask* _M_table;
    303 
    304   _Ctype_is_mask(ctype_base::mask __m, const ctype_base::mask* __t) : _Mask(__m), _M_table(__t) {}
    305   bool operator()(char __c) const { return (_M_table[(unsigned char) __c] & _Mask) != 0; }
    306 };
    307 
    308 struct _Ctype_not_mask : public unary_function<char, bool> {
    309   ctype_base::mask _Mask;
    310   const ctype_base::mask* _M_table;
    311 
    312   _Ctype_not_mask(ctype_base::mask __m, const ctype_base::mask* __t) : _Mask(__m), _M_table(__t) {}
    313   bool operator()(char __c) const { return (_M_table[(unsigned char) __c] & _Mask) == 0; }
    314 };
    315 
    316 ctype<char>::ctype(const ctype_base::mask * __tab, bool __del, size_t __refs) :
    317   locale::facet(__refs),
    318   _M_ctype_table(__tab ? __tab : classic_table()),
    319   _M_delete(__tab && __del)
    320 {}
    321 
    322 ctype<char>::~ctype() {
    323   if (_M_delete)
    324     delete[] __CONST_CAST(ctype_base::mask *, _M_ctype_table);
    325 }
    326 
    327 const char*
    328 #if defined (__DMC__)
    329 _STLP_DECLSPEC
    330 #endif
    331 ctype<char>::scan_is(ctype_base::mask  __m, const char* __low, const char* __high) const
    332 { return _STLP_STD::find_if(__low, __high, _Ctype_is_mask(__m, _M_ctype_table)); }
    333 
    334 const char*
    335 #if defined (__DMC__)
    336 _STLP_DECLSPEC
    337 #endif
    338 ctype<char>::scan_not(ctype_base::mask  __m, const char* __low, const char* __high) const
    339 { return _STLP_STD::find_if(__low, __high, _Ctype_not_mask(__m, _M_ctype_table)); }
    340 
    341 char ctype<char>::do_toupper(char __c) const
    342 { return (char) _S_upper[(unsigned char) __c]; }
    343 char ctype<char>::do_tolower(char __c) const
    344 { return (char) _S_lower[(unsigned char) __c]; }
    345 
    346 const char* ctype<char>::do_toupper(char* __low, const char* __high) const {
    347   for ( ; __low < __high; ++__low)
    348     *__low = (char) _S_upper[(unsigned char) *__low];
    349   return __high;
    350 }
    351 const char* ctype<char>::do_tolower(char* __low, const char* __high) const {
    352   for ( ; __low < __high; ++__low)
    353     *__low = (char) _S_lower[(unsigned char) *__low];
    354   return __high;
    355 }
    356 
    357 char
    358 ctype<char>::do_widen(char __c) const { return __c; }
    359 
    360 const char*
    361 ctype<char>::do_widen(const char* __low, const char* __high,
    362                       char* __to) const {
    363   _STLP_PRIV __copy_trivial(__low, __high, __to);
    364   return __high;
    365 }
    366 char
    367 ctype<char>::do_narrow(char __c, char /* dfault */ ) const { return __c; }
    368 const char*
    369 ctype<char>::do_narrow(const char* __low, const char* __high,
    370                        char /* dfault */, char* __to) const {
    371   _STLP_PRIV __copy_trivial(__low, __high, __to);
    372   return __high;
    373 }
    374 
    375 
    376 #if !defined (_STLP_NO_WCHAR_T)
    377 
    378 struct _Ctype_w_is_mask : public unary_function<wchar_t, bool> {
    379   ctype_base::mask M;
    380   const ctype_base::mask* table;
    381 
    382   _Ctype_w_is_mask(ctype_base::mask m, const ctype_base::mask* t)
    383     : M(m), table(t) {}
    384   bool operator()(wchar_t c) const
    385   { return _WCharIndex::in_range(c, ctype<char>::table_size) && (table[c] & M); }
    386 };
    387 
    388 //----------------------------------------------------------------------
    389 // ctype<wchar_t>
    390 
    391 ctype<wchar_t>::~ctype() {}
    392 
    393 
    394 bool ctype<wchar_t>::do_is(ctype_base::mask  m, wchar_t c) const {
    395   const ctype_base::mask * table = ctype<char>::classic_table();
    396   return _WCharIndex::in_range(c, ctype<char>::table_size) && (m & table[c]);
    397 }
    398 
    399 const wchar_t* ctype<wchar_t>::do_is(const wchar_t* low, const wchar_t* high,
    400                                      ctype_base::mask * vec) const {
    401   // boris : not clear if this is the right thing to do...
    402   const ctype_base::mask * table = ctype<char>::classic_table();
    403   wchar_t c;
    404   for ( ; low < high; ++low, ++vec) {
    405     c = *low;
    406     *vec = _WCharIndex::in_range(c, ctype<char>::table_size) ? table[c] : ctype_base::mask(0);
    407   }
    408   return high;
    409 }
    410 
    411 const wchar_t*
    412 ctype<wchar_t>::do_scan_is(ctype_base::mask  m,
    413                            const wchar_t* low, const wchar_t* high) const {
    414   return find_if(low, high, _Ctype_w_is_mask(m, ctype<char>::classic_table()));
    415 }
    416 
    417 
    418 const wchar_t*
    419 ctype<wchar_t>::do_scan_not(ctype_base::mask  m,
    420                             const wchar_t* low, const wchar_t* high) const {
    421   return find_if(low, high, not1(_Ctype_w_is_mask(m, ctype<char>::classic_table())));
    422 }
    423 
    424 wchar_t ctype<wchar_t>::do_toupper(wchar_t c) const {
    425   return _WCharIndex::in_range(c, ctype<char>::table_size) ? (wchar_t)_S_upper[c]
    426                                                            : c;
    427 }
    428 
    429 const wchar_t*
    430 ctype<wchar_t>::do_toupper(wchar_t* low, const wchar_t* high) const {
    431   for ( ; low < high; ++low) {
    432     wchar_t c = *low;
    433     *low = _WCharIndex::in_range(c, ctype<char>::table_size) ? (wchar_t)_S_upper[c]
    434                                                              : c;
    435   }
    436   return high;
    437 }
    438 
    439 wchar_t ctype<wchar_t>::do_tolower(wchar_t c) const {
    440   return _WCharIndex::in_range(c, ctype<char>::table_size) ? (wchar_t)_S_lower[c]
    441                                                            : c;
    442 }
    443 
    444 const wchar_t*
    445 ctype<wchar_t>::do_tolower(wchar_t* low, const wchar_t* high) const {
    446   for ( ; low < high; ++low) {
    447     wchar_t c = *low;
    448     *low = _WCharIndex::in_range(c, ctype<char>::table_size) ? (wchar_t)_S_lower[c]
    449                                                              : c;
    450   }
    451   return high;
    452 }
    453 
    454 wchar_t ctype<wchar_t>::do_widen(char c) const {
    455   return (wchar_t)(unsigned char)c;
    456 }
    457 
    458 const char*
    459 ctype<wchar_t>::do_widen(const char* low, const char* high,
    460                          wchar_t* dest) const {
    461   while (low != high)
    462     *dest++ = (wchar_t)(unsigned char)*low++;
    463   return high;
    464 }
    465 
    466 char ctype<wchar_t>::do_narrow(wchar_t c, char dfault) const
    467 { return (unsigned char)c == c ? (char)c : dfault; }
    468 
    469 const wchar_t* ctype<wchar_t>::do_narrow(const wchar_t* low,
    470                                          const wchar_t* high,
    471                                          char dfault, char* dest) const {
    472   while (low != high) {
    473     wchar_t c = *low++;
    474     *dest++ = (unsigned char)c == c ? (char)c : dfault;
    475   }
    476 
    477   return high;
    478 }
    479 
    480 # endif
    481 _STLP_END_NAMESPACE
    482 
    483 // Local Variables:
    484 // mode:C++
    485 // End:
    486 
    487