File indexing completed on 2024-11-16 09:32:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #ifndef BOOST_W32_REGEX_TRAITS_HPP_INCLUDED
0020 #define BOOST_W32_REGEX_TRAITS_HPP_INCLUDED
0021
0022 #ifndef BOOST_REGEX_NO_WIN32_LOCALE
0023
0024 #include <boost/regex/pattern_except.hpp>
0025 #include <boost/regex/v5/regex_traits_defaults.hpp>
0026 #ifdef BOOST_HAS_THREADS
0027 #include <mutex>
0028 #endif
0029 #include <boost/regex/v5/primary_transform.hpp>
0030 #include <boost/regex/v5/object_cache.hpp>
0031
0032 #if defined(_MSC_VER) && !defined(_WIN32_WCE) && !defined(UNDER_CE)
0033 #pragma comment(lib, "user32.lib")
0034 #endif
0035
0036 #ifdef BOOST_REGEX_MSVC
0037 #pragma warning(push)
0038 #pragma warning(disable:4786)
0039 #if BOOST_REGEX_MSVC < 1910
0040 #pragma warning(disable:4800)
0041 #endif
0042 #endif
0043
0044 #ifndef BASETYPES
0045
0046
0047
0048 #ifndef NO_STRICT
0049 #ifndef STRICT
0050 #define STRICT 1
0051 #endif
0052 #endif
0053
0054 #if defined(STRICT)
0055 #define BOOST_RE_DETAIL_DECLARE_HANDLE(x) struct x##__; typedef struct x##__ *x
0056 #else
0057 #define BOOST_RE_DETAIL_DECLARE_HANDLE(x) typedef void* x
0058 #endif
0059
0060
0061
0062 extern "C" {
0063
0064 BOOST_RE_DETAIL_DECLARE_HANDLE(HINSTANCE);
0065 typedef HINSTANCE HMODULE;
0066 }
0067 #endif
0068
0069 namespace boost{
0070
0071
0072
0073
0074 template <class charT>
0075 class w32_regex_traits;
0076
0077 namespace BOOST_REGEX_DETAIL_NS{
0078
0079
0080
0081
0082 typedef unsigned long lcid_type;
0083 typedef std::shared_ptr<void> cat_type;
0084
0085
0086
0087
0088 lcid_type w32_get_default_locale();
0089 bool w32_is_lower(char, lcid_type);
0090 #ifndef BOOST_NO_WREGEX
0091 bool w32_is_lower(wchar_t, lcid_type);
0092 #endif
0093 bool w32_is_upper(char, lcid_type);
0094 #ifndef BOOST_NO_WREGEX
0095 bool w32_is_upper(wchar_t, lcid_type);
0096 #endif
0097 cat_type w32_cat_open(const std::string& name);
0098 std::string w32_cat_get(const cat_type& cat, lcid_type state_id, int i, const std::string& def);
0099 #ifndef BOOST_NO_WREGEX
0100 std::wstring w32_cat_get(const cat_type& cat, lcid_type state_id, int i, const std::wstring& def);
0101 #endif
0102 std::string w32_transform(lcid_type state_id, const char* p1, const char* p2);
0103 #ifndef BOOST_NO_WREGEX
0104 std::wstring w32_transform(lcid_type state_id, const wchar_t* p1, const wchar_t* p2);
0105 #endif
0106 char w32_tolower(char c, lcid_type);
0107 #ifndef BOOST_NO_WREGEX
0108 wchar_t w32_tolower(wchar_t c, lcid_type);
0109 #endif
0110 char w32_toupper(char c, lcid_type);
0111 #ifndef BOOST_NO_WREGEX
0112 wchar_t w32_toupper(wchar_t c, lcid_type);
0113 #endif
0114 bool w32_is(lcid_type, std::uint32_t mask, char c);
0115 #ifndef BOOST_NO_WREGEX
0116 bool w32_is(lcid_type, std::uint32_t mask, wchar_t c);
0117 #endif
0118
0119 #ifndef BASETYPES
0120
0121
0122
0123
0124 #if !defined(__LP64__)
0125 using dword = unsigned long;
0126 #else
0127 using DWORD = unsigned int;
0128 #endif
0129 using word = unsigned short;
0130 using lctype = dword;
0131
0132 static constexpr dword ct_ctype1 = 0x00000001;
0133 static constexpr dword c1_upper = 0x0001;
0134 static constexpr dword c1_lower = 0x0002;
0135 static constexpr dword c1_digit = 0x0004;
0136 static constexpr dword c1_space = 0x0008;
0137 static constexpr dword c1_punct = 0x0010;
0138 static constexpr dword c1_cntrl = 0x0020;
0139 static constexpr dword c1_blank = 0x0040;
0140 static constexpr dword c1_xdigit = 0x0080;
0141 static constexpr dword c1_alpha = 0x0100;
0142 static constexpr dword c1_defined = 0x0200;
0143 static constexpr unsigned int cp_acp = 0;
0144 static constexpr dword lcmap_lowercase = 0x00000100;
0145 static constexpr dword lcmap_uppercase = 0x00000200;
0146 static constexpr dword lcmap_sortkey = 0x00000400;
0147 static constexpr lctype locale_idefaultansicodepage = 0x00001004;
0148
0149 # ifdef UNDER_CE
0150 # ifndef WINAPI
0151 # ifndef _WIN32_WCE_EMULATION
0152 # define BOOST_RE_STDCALL __cdecl
0153 # else
0154 # define BOOST_RE_STDCALL __stdcall
0155 # endif
0156 # endif
0157 # else
0158 # if defined(_M_IX86) || defined(__i386__)
0159 # define BOOST_RE_STDCALL __stdcall
0160 # else
0161
0162 # define BOOST_RE_STDCALL
0163 # endif
0164 # endif
0165
0166 #if defined (WIN32_PLATFORM_PSPC)
0167 #define BOOST_RE_IMPORT __declspec( dllimport )
0168 #elif defined (_WIN32_WCE)
0169 #define BOOST_RE_IMPORT
0170 #else
0171 #define BOOST_RE_IMPORT __declspec( dllimport )
0172 #endif
0173
0174 extern "C" {
0175
0176 BOOST_RE_IMPORT int BOOST_RE_STDCALL FreeLibrary(HMODULE hLibModule);
0177 BOOST_RE_IMPORT int BOOST_RE_STDCALL LCMapStringA(lcid_type Locale, dword dwMapFlags, const char* lpSrcStr, int cchSrc, char* lpDestStr, int cchDest);
0178 BOOST_RE_IMPORT int BOOST_RE_STDCALL LCMapStringW(lcid_type Locale, dword dwMapFlags, const wchar_t* lpSrcStr, int cchSrc, wchar_t* lpDestStr, int cchDest);
0179 BOOST_RE_IMPORT int BOOST_RE_STDCALL MultiByteToWideChar(unsigned int CodePage, dword dwFlags, const char* lpMultiByteStr, int cbMultiByte, wchar_t* lpWideCharStr, int cchWideChar);
0180 BOOST_RE_IMPORT int BOOST_RE_STDCALL LCMapStringW(lcid_type Locale, dword dwMapFlags, const wchar_t* lpSrcStr, int cchSrc, wchar_t* lpDestStr, int cchDest);
0181 BOOST_RE_IMPORT int BOOST_RE_STDCALL WideCharToMultiByte(unsigned int CodePage, dword dwFlags, const wchar_t* lpWideCharStr, int cchWideChar, char* lpMultiByteStr, int cbMultiByte, const char* lpDefaultChar, int* lpUsedDefaultChar);
0182 BOOST_RE_IMPORT int BOOST_RE_STDCALL GetStringTypeExA(lcid_type Locale, dword dwInfoType, const char* lpSrcStr, int cchSrc, word* lpCharType);
0183 BOOST_RE_IMPORT int BOOST_RE_STDCALL GetStringTypeExW(lcid_type Locale, dword dwInfoType, const wchar_t* lpSrcStr, int cchSrc, word* lpCharType);
0184 BOOST_RE_IMPORT lcid_type BOOST_RE_STDCALL GetUserDefaultLCID();
0185 BOOST_RE_IMPORT int BOOST_RE_STDCALL GetStringTypeExA(lcid_type Locale, dword dwInfoType, const char* lpSrcStr, int cchSrc, word* lpCharType);
0186 BOOST_RE_IMPORT int BOOST_RE_STDCALL GetStringTypeExW(lcid_type Locale, dword dwInfoType, const wchar_t* lpSrcStr, int cchSrc, word* lpCharType);
0187 BOOST_RE_IMPORT HMODULE BOOST_RE_STDCALL LoadLibraryA(const char* lpLibFileName);
0188 BOOST_RE_IMPORT HMODULE BOOST_RE_STDCALL LoadLibraryW(const wchar_t* lpLibFileName);
0189 BOOST_RE_IMPORT int BOOST_RE_STDCALL LoadStringW(HINSTANCE hInstance, unsigned int uID, wchar_t* lpBuffer, int cchBufferMax);
0190 BOOST_RE_IMPORT int BOOST_RE_STDCALL LoadStringA(HINSTANCE hInstance, unsigned int uID, char* lpBuffer, int cchBufferMax);
0191 BOOST_RE_IMPORT int BOOST_RE_STDCALL GetLocaleInfoW(lcid_type Locale, lctype LCType, wchar_t* lpLCData, int cchData);
0192 }
0193
0194 #else
0195
0196
0197
0198 using dword = DWORD;
0199 using word = WORD;
0200 using lctype = LCTYPE;
0201
0202 static constexpr dword ct_ctype1 = 0x00000001;
0203 static constexpr dword c1_upper = 0x0001;
0204 static constexpr dword c1_lower = 0x0002;
0205 static constexpr dword c1_digit = 0x0004;
0206 static constexpr dword c1_space = 0x0008;
0207 static constexpr dword c1_punct = 0x0010;
0208 static constexpr dword c1_cntrl = 0x0020;
0209 static constexpr dword c1_blank = 0x0040;
0210 static constexpr dword c1_xdigit = 0x0080;
0211 static constexpr dword c1_alpha = 0x0100;
0212 static constexpr dword c1_defined = 0x0200;
0213 static constexpr unsigned int cp_acp = 0;
0214 static constexpr dword lcmap_lowercase = 0x00000100;
0215 static constexpr dword lcmap_uppercase = 0x00000200;
0216 static constexpr dword lcmap_sortkey = 0x00000400;
0217 static constexpr lctype locale_idefaultansicodepage = 0x00001004;
0218
0219 using ::FreeLibrary;
0220 using ::LCMapStringA;
0221 using ::LCMapStringW;
0222 using ::MultiByteToWideChar;
0223 using ::LCMapStringW;
0224 using ::WideCharToMultiByte;
0225 using ::GetStringTypeExA;
0226 using ::GetStringTypeExW;
0227 using ::GetUserDefaultLCID;
0228 using ::GetStringTypeExA;
0229 using ::GetStringTypeExW;
0230 using ::LoadLibraryA;
0231 using ::LoadLibraryW;
0232 using ::LoadStringW;
0233 using ::LoadStringA;
0234 using ::GetLocaleInfoW;
0235
0236 #endif
0237
0238
0239
0240
0241 template <class charT>
0242 struct w32_regex_traits_base
0243 {
0244 w32_regex_traits_base(lcid_type l)
0245 { imbue(l); }
0246 lcid_type imbue(lcid_type l);
0247
0248 lcid_type m_locale;
0249 };
0250
0251 template <class charT>
0252 inline lcid_type w32_regex_traits_base<charT>::imbue(lcid_type l)
0253 {
0254 lcid_type result(m_locale);
0255 m_locale = l;
0256 return result;
0257 }
0258
0259
0260
0261
0262
0263 template <class charT>
0264 class w32_regex_traits_char_layer : public w32_regex_traits_base<charT>
0265 {
0266 typedef std::basic_string<charT> string_type;
0267 typedef std::map<charT, regex_constants::syntax_type> map_type;
0268 typedef typename map_type::const_iterator map_iterator_type;
0269 public:
0270 w32_regex_traits_char_layer(const lcid_type l);
0271
0272 regex_constants::syntax_type syntax_type(charT c)const
0273 {
0274 map_iterator_type i = m_char_map.find(c);
0275 return ((i == m_char_map.end()) ? 0 : i->second);
0276 }
0277 regex_constants::escape_syntax_type escape_syntax_type(charT c) const
0278 {
0279 map_iterator_type i = m_char_map.find(c);
0280 if(i == m_char_map.end())
0281 {
0282 if(::boost::BOOST_REGEX_DETAIL_NS::w32_is_lower(c, this->m_locale)) return regex_constants::escape_type_class;
0283 if(::boost::BOOST_REGEX_DETAIL_NS::w32_is_upper(c, this->m_locale)) return regex_constants::escape_type_not_class;
0284 return 0;
0285 }
0286 return i->second;
0287 }
0288 charT tolower(charT c)const
0289 {
0290 return ::boost::BOOST_REGEX_DETAIL_NS::w32_tolower(c, this->m_locale);
0291 }
0292 bool isctype(std::uint32_t mask, charT c)const
0293 {
0294 return ::boost::BOOST_REGEX_DETAIL_NS::w32_is(this->m_locale, mask, c);
0295 }
0296
0297 private:
0298 string_type get_default_message(regex_constants::syntax_type);
0299
0300 map_type m_char_map;
0301 };
0302
0303 template <class charT>
0304 w32_regex_traits_char_layer<charT>::w32_regex_traits_char_layer(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l)
0305 : w32_regex_traits_base<charT>(l)
0306 {
0307
0308
0309 cat_type cat;
0310 std::string cat_name(w32_regex_traits<charT>::get_catalog_name());
0311 if(cat_name.size())
0312 {
0313 cat = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_open(cat_name);
0314 if(!cat)
0315 {
0316 std::string m("Unable to open message catalog: ");
0317 std::runtime_error err(m + cat_name);
0318 boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);
0319 }
0320 }
0321
0322
0323
0324 if(cat)
0325 {
0326 for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
0327 {
0328 string_type mss = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_get(cat, this->m_locale, i, get_default_message(i));
0329 for(typename string_type::size_type j = 0; j < mss.size(); ++j)
0330 {
0331 this->m_char_map[mss[j]] = i;
0332 }
0333 }
0334 }
0335 else
0336 {
0337 for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
0338 {
0339 const char* ptr = get_default_syntax(i);
0340 while(ptr && *ptr)
0341 {
0342 this->m_char_map[static_cast<charT>(*ptr)] = i;
0343 ++ptr;
0344 }
0345 }
0346 }
0347 }
0348
0349 template <class charT>
0350 typename w32_regex_traits_char_layer<charT>::string_type
0351 w32_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
0352 {
0353 const char* ptr = get_default_syntax(i);
0354 string_type result;
0355 while(ptr && *ptr)
0356 {
0357 result.append(1, static_cast<charT>(*ptr));
0358 ++ptr;
0359 }
0360 return result;
0361 }
0362
0363
0364
0365
0366 template <>
0367 class w32_regex_traits_char_layer<char> : public w32_regex_traits_base<char>
0368 {
0369 typedef std::string string_type;
0370 public:
0371 w32_regex_traits_char_layer(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l)
0372 : w32_regex_traits_base<char>(l)
0373 {
0374 init<char>();
0375 }
0376
0377 regex_constants::syntax_type syntax_type(char c)const
0378 {
0379 return m_char_map[static_cast<unsigned char>(c)];
0380 }
0381 regex_constants::escape_syntax_type escape_syntax_type(char c) const
0382 {
0383 return m_char_map[static_cast<unsigned char>(c)];
0384 }
0385 char tolower(char c)const
0386 {
0387 return m_lower_map[static_cast<unsigned char>(c)];
0388 }
0389 bool isctype(std::uint32_t mask, char c)const
0390 {
0391 return m_type_map[static_cast<unsigned char>(c)] & mask;
0392 }
0393
0394 private:
0395 regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
0396 char m_lower_map[1u << CHAR_BIT];
0397 std::uint16_t m_type_map[1u << CHAR_BIT];
0398 template <class U>
0399 void init();
0400 };
0401
0402
0403
0404
0405
0406 template <class charT>
0407 class w32_regex_traits_implementation : public w32_regex_traits_char_layer<charT>
0408 {
0409 public:
0410 typedef typename w32_regex_traits<charT>::char_class_type char_class_type;
0411 static const char_class_type mask_word = 0x0400;
0412 static const char_class_type mask_unicode = 0x0800;
0413 static const char_class_type mask_horizontal = 0x1000;
0414 static const char_class_type mask_vertical = 0x2000;
0415 static const char_class_type mask_base = 0x3ff;
0416
0417 typedef std::basic_string<charT> string_type;
0418 typedef charT char_type;
0419 w32_regex_traits_implementation(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l);
0420 std::string error_string(regex_constants::error_type n) const
0421 {
0422 if(!m_error_strings.empty())
0423 {
0424 std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
0425 return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
0426 }
0427 return get_default_error_string(n);
0428 }
0429 char_class_type lookup_classname(const charT* p1, const charT* p2) const
0430 {
0431 char_class_type result = lookup_classname_imp(p1, p2);
0432 if(result == 0)
0433 {
0434 typedef typename string_type::size_type size_type;
0435 string_type temp(p1, p2);
0436 for(size_type i = 0; i < temp.size(); ++i)
0437 temp[i] = this->tolower(temp[i]);
0438 result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
0439 }
0440 return result;
0441 }
0442 string_type lookup_collatename(const charT* p1, const charT* p2) const;
0443 string_type transform_primary(const charT* p1, const charT* p2) const;
0444 string_type transform(const charT* p1, const charT* p2) const
0445 {
0446 return ::boost::BOOST_REGEX_DETAIL_NS::w32_transform(this->m_locale, p1, p2);
0447 }
0448 private:
0449 std::map<int, std::string> m_error_strings;
0450 std::map<string_type, char_class_type> m_custom_class_names;
0451 std::map<string_type, string_type> m_custom_collate_names;
0452 unsigned m_collate_type;
0453 charT m_collate_delim;
0454
0455
0456
0457 char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
0458 };
0459
0460 template <class charT>
0461 typename w32_regex_traits_implementation<charT>::string_type
0462 w32_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
0463 {
0464 string_type result;
0465
0466
0467
0468
0469 switch(m_collate_type)
0470 {
0471 case sort_C:
0472 case sort_unknown:
0473
0474 {
0475 result.assign(p1, p2);
0476 typedef typename string_type::size_type size_type;
0477 for(size_type i = 0; i < result.size(); ++i)
0478 result[i] = this->tolower(result[i]);
0479 result = this->transform(&*result.begin(), &*result.begin() + result.size());
0480 break;
0481 }
0482 case sort_fixed:
0483 {
0484
0485 result.assign(this->transform(p1, p2));
0486 result.erase(this->m_collate_delim);
0487 break;
0488 }
0489 case sort_delim:
0490
0491 result.assign(this->transform(p1, p2));
0492 std::size_t i;
0493 for(i = 0; i < result.size(); ++i)
0494 {
0495 if(result[i] == m_collate_delim)
0496 break;
0497 }
0498 result.erase(i);
0499 break;
0500 }
0501 if(result.empty())
0502 result = string_type(1, charT(0));
0503 return result;
0504 }
0505
0506 template <class charT>
0507 typename w32_regex_traits_implementation<charT>::string_type
0508 w32_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
0509 {
0510 typedef typename std::map<string_type, string_type>::const_iterator iter_type;
0511 if(m_custom_collate_names.size())
0512 {
0513 iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
0514 if(pos != m_custom_collate_names.end())
0515 return pos->second;
0516 }
0517 std::string name(p1, p2);
0518 name = lookup_default_collate_name(name);
0519 if(name.size())
0520 return string_type(name.begin(), name.end());
0521 if(p2 - p1 == 1)
0522 return string_type(1, *p1);
0523 return string_type();
0524 }
0525
0526 template <class charT>
0527 w32_regex_traits_implementation<charT>::w32_regex_traits_implementation(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l)
0528 : w32_regex_traits_char_layer<charT>(l)
0529 {
0530 cat_type cat;
0531 std::string cat_name(w32_regex_traits<charT>::get_catalog_name());
0532 if(cat_name.size())
0533 {
0534 cat = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_open(cat_name);
0535 if(!cat)
0536 {
0537 std::string m("Unable to open message catalog: ");
0538 std::runtime_error err(m + cat_name);
0539 boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);
0540 }
0541 }
0542
0543
0544
0545 if(cat)
0546 {
0547
0548
0549
0550 for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0);
0551 i <= boost::regex_constants::error_unknown;
0552 i = static_cast<boost::regex_constants::error_type>(i + 1))
0553 {
0554 const char* p = get_default_error_string(i);
0555 string_type default_message;
0556 while(*p)
0557 {
0558 default_message.append(1, static_cast<charT>(*p));
0559 ++p;
0560 }
0561 string_type s = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_get(cat, this->m_locale, i+200, default_message);
0562 std::string result;
0563 for(std::string::size_type j = 0; j < s.size(); ++j)
0564 {
0565 result.append(1, static_cast<char>(s[j]));
0566 }
0567 m_error_strings[i] = result;
0568 }
0569
0570
0571
0572 static const char_class_type masks[14] =
0573 {
0574 0x0104u,
0575 0x0100u,
0576 0x0020u,
0577 0x0004u,
0578 (~(0x0020u|0x0008u) & 0x01ffu) | 0x0400u,
0579 0x0002u,
0580 (~0x0020u & 0x01ffu) | 0x0400,
0581 0x0010u,
0582 0x0008u,
0583 0x0001u,
0584 0x0080u,
0585 0x0040u,
0586 w32_regex_traits_implementation<charT>::mask_word,
0587 w32_regex_traits_implementation<charT>::mask_unicode,
0588 };
0589 static const string_type null_string;
0590 for(unsigned int j = 0; j <= 13; ++j)
0591 {
0592 string_type s(::boost::BOOST_REGEX_DETAIL_NS::w32_cat_get(cat, this->m_locale, j+300, null_string));
0593 if(s.size())
0594 this->m_custom_class_names[s] = masks[j];
0595 }
0596 }
0597
0598
0599
0600 m_collate_type = BOOST_REGEX_DETAIL_NS::find_sort_syntax(this, &m_collate_delim);
0601 }
0602
0603 template <class charT>
0604 typename w32_regex_traits_implementation<charT>::char_class_type
0605 w32_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const
0606 {
0607 static const char_class_type masks[22] =
0608 {
0609 0,
0610 0x0104u,
0611 0x0100u,
0612 0x0040u,
0613 0x0020u,
0614 0x0004u,
0615 0x0004u,
0616 (~(0x0020u|0x0008u|0x0040) & 0x01ffu) | 0x0400u,
0617 w32_regex_traits_implementation<charT>::mask_horizontal,
0618 0x0002u,
0619 0x0002u,
0620 (~0x0020u & 0x01ffu) | 0x0400,
0621 0x0010u,
0622 0x0008u,
0623 0x0008u,
0624 0x0001u,
0625 w32_regex_traits_implementation<charT>::mask_unicode,
0626 0x0001u,
0627 w32_regex_traits_implementation<charT>::mask_vertical,
0628 0x0104u | w32_regex_traits_implementation<charT>::mask_word,
0629 0x0104u | w32_regex_traits_implementation<charT>::mask_word,
0630 0x0080u,
0631 };
0632 if(m_custom_class_names.size())
0633 {
0634 typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;
0635 map_iter pos = m_custom_class_names.find(string_type(p1, p2));
0636 if(pos != m_custom_class_names.end())
0637 return pos->second;
0638 }
0639 std::size_t state_id = 1u + (std::size_t)BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);
0640 if(state_id < sizeof(masks) / sizeof(masks[0]))
0641 return masks[state_id];
0642 return masks[0];
0643 }
0644
0645
0646 template <class charT>
0647 std::shared_ptr<const w32_regex_traits_implementation<charT> > create_w32_regex_traits(::boost::BOOST_REGEX_DETAIL_NS::lcid_type l)
0648 {
0649
0650 return boost::object_cache< ::boost::BOOST_REGEX_DETAIL_NS::lcid_type, w32_regex_traits_implementation<charT> >::get(l, 5);
0651 }
0652
0653 }
0654
0655 template <class charT>
0656 class w32_regex_traits
0657 {
0658 public:
0659 typedef charT char_type;
0660 typedef std::size_t size_type;
0661 typedef std::basic_string<char_type> string_type;
0662 typedef ::boost::BOOST_REGEX_DETAIL_NS::lcid_type locale_type;
0663 typedef std::uint_least32_t char_class_type;
0664
0665 struct boost_extensions_tag{};
0666
0667 w32_regex_traits()
0668 : m_pimpl(BOOST_REGEX_DETAIL_NS::create_w32_regex_traits<charT>(::boost::BOOST_REGEX_DETAIL_NS::w32_get_default_locale()))
0669 { }
0670 static size_type length(const char_type* p)
0671 {
0672 return std::char_traits<charT>::length(p);
0673 }
0674 regex_constants::syntax_type syntax_type(charT c)const
0675 {
0676 return m_pimpl->syntax_type(c);
0677 }
0678 regex_constants::escape_syntax_type escape_syntax_type(charT c) const
0679 {
0680 return m_pimpl->escape_syntax_type(c);
0681 }
0682 charT translate(charT c) const
0683 {
0684 return c;
0685 }
0686 charT translate_nocase(charT c) const
0687 {
0688 return this->m_pimpl->tolower(c);
0689 }
0690 charT translate(charT c, bool icase) const
0691 {
0692 return icase ? this->m_pimpl->tolower(c) : c;
0693 }
0694 charT tolower(charT c) const
0695 {
0696 return this->m_pimpl->tolower(c);
0697 }
0698 charT toupper(charT c) const
0699 {
0700 return ::boost::BOOST_REGEX_DETAIL_NS::w32_toupper(c, this->m_pimpl->m_locale);
0701 }
0702 string_type transform(const charT* p1, const charT* p2) const
0703 {
0704 return ::boost::BOOST_REGEX_DETAIL_NS::w32_transform(this->m_pimpl->m_locale, p1, p2);
0705 }
0706 string_type transform_primary(const charT* p1, const charT* p2) const
0707 {
0708 return m_pimpl->transform_primary(p1, p2);
0709 }
0710 char_class_type lookup_classname(const charT* p1, const charT* p2) const
0711 {
0712 return m_pimpl->lookup_classname(p1, p2);
0713 }
0714 string_type lookup_collatename(const charT* p1, const charT* p2) const
0715 {
0716 return m_pimpl->lookup_collatename(p1, p2);
0717 }
0718 bool isctype(charT c, char_class_type f) const
0719 {
0720 if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_base)
0721 && (this->m_pimpl->isctype(f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_base, c)))
0722 return true;
0723 else if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_unicode) && BOOST_REGEX_DETAIL_NS::is_extended(c))
0724 return true;
0725 else if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_word) && (c == '_'))
0726 return true;
0727 else if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_vertical)
0728 && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == '\v')))
0729 return true;
0730 else if((f & BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_horizontal)
0731 && this->isctype(c, 0x0008u) && !this->isctype(c, BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT>::mask_vertical))
0732 return true;
0733 return false;
0734 }
0735 std::intmax_t toi(const charT*& p1, const charT* p2, int radix)const
0736 {
0737 return ::boost::BOOST_REGEX_DETAIL_NS::global_toi(p1, p2, radix, *this);
0738 }
0739 int value(charT c, int radix)const
0740 {
0741 int result = (int)::boost::BOOST_REGEX_DETAIL_NS::global_value(c);
0742 return result < radix ? result : -1;
0743 }
0744 locale_type imbue(locale_type l)
0745 {
0746 ::boost::BOOST_REGEX_DETAIL_NS::lcid_type result(getloc());
0747 m_pimpl = BOOST_REGEX_DETAIL_NS::create_w32_regex_traits<charT>(l);
0748 return result;
0749 }
0750 locale_type getloc()const
0751 {
0752 return m_pimpl->m_locale;
0753 }
0754 std::string error_string(regex_constants::error_type n) const
0755 {
0756 return m_pimpl->error_string(n);
0757 }
0758
0759
0760
0761
0762
0763 static std::string catalog_name(const std::string& name);
0764 static std::string get_catalog_name();
0765
0766 private:
0767 std::shared_ptr<const BOOST_REGEX_DETAIL_NS::w32_regex_traits_implementation<charT> > m_pimpl;
0768
0769
0770
0771 static std::string& get_catalog_name_inst();
0772
0773 #ifdef BOOST_HAS_THREADS
0774 static std::mutex& get_mutex_inst();
0775 #endif
0776 };
0777
0778 template <class charT>
0779 std::string w32_regex_traits<charT>::catalog_name(const std::string& name)
0780 {
0781 #ifdef BOOST_HAS_THREADS
0782 std::lock_guard<std::mutex> lk(get_mutex_inst());
0783 #endif
0784 std::string result(get_catalog_name_inst());
0785 get_catalog_name_inst() = name;
0786 return result;
0787 }
0788
0789 template <class charT>
0790 std::string& w32_regex_traits<charT>::get_catalog_name_inst()
0791 {
0792 static std::string s_name;
0793 return s_name;
0794 }
0795
0796 template <class charT>
0797 std::string w32_regex_traits<charT>::get_catalog_name()
0798 {
0799 #ifdef BOOST_HAS_THREADS
0800 std::lock_guard<std::mutex> lk(get_mutex_inst());
0801 #endif
0802 std::string result(get_catalog_name_inst());
0803 return result;
0804 }
0805
0806 #ifdef BOOST_HAS_THREADS
0807 template <class charT>
0808 std::mutex& w32_regex_traits<charT>::get_mutex_inst()
0809 {
0810 static std::mutex s_mutex;
0811 return s_mutex;
0812 }
0813 #endif
0814
0815 namespace BOOST_REGEX_DETAIL_NS {
0816
0817 #ifdef BOOST_NO_ANSI_APIS
0818 inline unsigned int get_code_page_for_locale_id(lcid_type idx)
0819 {
0820 wchar_t code_page_string[7];
0821 if (boost::BOOST_REGEX_DETAIL_NS::GetLocaleInfoW(idx, locale_idefaultansicodepage, code_page_string, 7) == 0)
0822 return 0;
0823
0824 return static_cast<unsigned int>(_wtol(code_page_string));
0825 }
0826 #endif
0827
0828 template <class U>
0829 inline void w32_regex_traits_char_layer<char>::init()
0830 {
0831
0832
0833 std::memset(m_char_map, 0, sizeof(m_char_map));
0834 cat_type cat;
0835 std::string cat_name(w32_regex_traits<char>::get_catalog_name());
0836 if (cat_name.size())
0837 {
0838 cat = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_open(cat_name);
0839 if (!cat)
0840 {
0841 std::string m("Unable to open message catalog: ");
0842 std::runtime_error err(m + cat_name);
0843 ::boost::BOOST_REGEX_DETAIL_NS::raise_runtime_error(err);
0844 }
0845 }
0846
0847
0848
0849 if (cat)
0850 {
0851 for (regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
0852 {
0853 string_type mss = ::boost::BOOST_REGEX_DETAIL_NS::w32_cat_get(cat, this->m_locale, i, get_default_syntax(i));
0854 for (string_type::size_type j = 0; j < mss.size(); ++j)
0855 {
0856 m_char_map[static_cast<unsigned char>(mss[j])] = i;
0857 }
0858 }
0859 }
0860 else
0861 {
0862 for (regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
0863 {
0864 const char* ptr = get_default_syntax(i);
0865 while (ptr && *ptr)
0866 {
0867 m_char_map[static_cast<unsigned char>(*ptr)] = i;
0868 ++ptr;
0869 }
0870 }
0871 }
0872
0873
0874
0875 unsigned char i = 'A';
0876 do
0877 {
0878 if (m_char_map[i] == 0)
0879 {
0880 if (::boost::BOOST_REGEX_DETAIL_NS::w32_is(this->m_locale, 0x0002u, (char)i))
0881 m_char_map[i] = regex_constants::escape_type_class;
0882 else if (::boost::BOOST_REGEX_DETAIL_NS::w32_is(this->m_locale, 0x0001u, (char)i))
0883 m_char_map[i] = regex_constants::escape_type_not_class;
0884 }
0885 } while (0xFF != i++);
0886
0887
0888
0889
0890 char char_map[1 << CHAR_BIT];
0891 for (int ii = 0; ii < (1 << CHAR_BIT); ++ii)
0892 char_map[ii] = static_cast<char>(ii);
0893 #ifndef BOOST_NO_ANSI_APIS
0894 int r = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA(this->m_locale, lcmap_lowercase, char_map, 1 << CHAR_BIT, this->m_lower_map, 1 << CHAR_BIT);
0895 BOOST_REGEX_ASSERT(r != 0);
0896 #else
0897 unsigned int code_page = get_code_page_for_locale_id(this->m_locale);
0898 BOOST_REGEX_ASSERT(code_page != 0);
0899
0900 wchar_t wide_char_map[1 << CHAR_BIT];
0901 int conv_r = boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, char_map, 1 << CHAR_BIT, wide_char_map, 1 << CHAR_BIT);
0902 BOOST_REGEX_ASSERT(conv_r != 0);
0903
0904 wchar_t wide_lower_map[1 << CHAR_BIT];
0905 int r = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(this->m_locale, lcmap_lowercase, wide_char_map, 1 << CHAR_BIT, wide_lower_map, 1 << CHAR_BIT);
0906 BOOST_REGEX_ASSERT(r != 0);
0907
0908 conv_r = boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(code_page, 0, wide_lower_map, r, this->m_lower_map, 1 << CHAR_BIT, NULL, NULL);
0909 BOOST_REGEX_ASSERT(conv_r != 0);
0910 #endif
0911 if (r < (1 << CHAR_BIT))
0912 {
0913
0914
0915 for (int jj = r; jj < (1 << CHAR_BIT); ++jj)
0916 this->m_lower_map[jj] = static_cast<char>(jj);
0917 }
0918
0919 #ifndef BOOST_NO_ANSI_APIS
0920 r = boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExA(this->m_locale, ct_ctype1, char_map, 1 << CHAR_BIT, this->m_type_map);
0921 #else
0922 r = boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(this->m_locale, ct_ctype1, wide_char_map, 1 << CHAR_BIT, this->m_type_map);
0923 #endif
0924 BOOST_REGEX_ASSERT(0 != r);
0925 }
0926
0927 inline lcid_type w32_get_default_locale()
0928 {
0929 return boost::BOOST_REGEX_DETAIL_NS::GetUserDefaultLCID();
0930 }
0931
0932 inline bool w32_is_lower(char c, lcid_type idx)
0933 {
0934 #ifndef BOOST_NO_ANSI_APIS
0935 word mask;
0936 if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExA(idx, ct_ctype1, &c, 1, &mask) && (mask & c1_lower))
0937 return true;
0938 return false;
0939 #else
0940 unsigned int code_page = get_code_page_for_locale_id(idx);
0941 if (code_page == 0)
0942 return false;
0943
0944 wchar_t wide_c;
0945 if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)
0946 return false;
0947
0948 word mask;
0949 if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &wide_c, 1, &mask) && (mask & c1_lower))
0950 return true;
0951 return false;
0952 #endif
0953 }
0954
0955 inline bool w32_is_lower(wchar_t c, lcid_type idx)
0956 {
0957 word mask;
0958 if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &c, 1, &mask) && (mask & c1_lower))
0959 return true;
0960 return false;
0961 }
0962
0963 inline bool w32_is_upper(char c, lcid_type idx)
0964 {
0965 #ifndef BOOST_NO_ANSI_APIS
0966 word mask;
0967 if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExA(idx, ct_ctype1, &c, 1, &mask) && (mask & c1_upper))
0968 return true;
0969 return false;
0970 #else
0971 unsigned int code_page = get_code_page_for_locale_id(idx);
0972 if (code_page == 0)
0973 return false;
0974
0975 wchar_t wide_c;
0976 if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)
0977 return false;
0978
0979 word mask;
0980 if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &wide_c, 1, &mask) && (mask & c1_upper))
0981 return true;
0982 return false;
0983 #endif
0984 }
0985
0986 inline bool w32_is_upper(wchar_t c, lcid_type idx)
0987 {
0988 word mask;
0989 if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &c, 1, &mask) && (mask & c1_upper))
0990 return true;
0991 return false;
0992 }
0993
0994 inline void free_module(void* mod)
0995 {
0996 boost::BOOST_REGEX_DETAIL_NS::FreeLibrary(static_cast<HMODULE>(mod));
0997 }
0998
0999 inline cat_type w32_cat_open(const std::string& name)
1000 {
1001 #ifndef BOOST_NO_ANSI_APIS
1002 cat_type result(boost::BOOST_REGEX_DETAIL_NS::LoadLibraryA(name.c_str()), &free_module);
1003 return result;
1004 #else
1005 wchar_t* wide_name = (wchar_t*)_alloca((name.size() + 1) * sizeof(wchar_t));
1006 if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(cp_acp, 0, name.c_str(), (int)name.size(), wide_name, (int)(name.size() + 1)) == 0)
1007 return cat_type();
1008
1009 cat_type result(boost::BOOST_REGEX_DETAIL_NS::LoadLibraryW(wide_name), &free_module);
1010 return result;
1011 #endif
1012 }
1013
1014 inline std::string w32_cat_get(const cat_type& cat, lcid_type, int i, const std::string& def)
1015 {
1016 #ifndef BOOST_NO_ANSI_APIS
1017 char buf[256];
1018 if (0 == boost::BOOST_REGEX_DETAIL_NS::LoadStringA(
1019 static_cast<HMODULE>(cat.get()),
1020 i,
1021 buf,
1022 256
1023 ))
1024 {
1025 return def;
1026 }
1027 #else
1028 wchar_t wbuf[256];
1029 int r = boost::BOOST_REGEX_DETAIL_NS::LoadStringW(
1030 static_cast<HMODULE>(cat.get()),
1031 i,
1032 wbuf,
1033 256
1034 );
1035 if (r == 0)
1036 return def;
1037
1038
1039 int buf_size = 1 + boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(cp_acp, 0, wbuf, r, NULL, 0, NULL, NULL);
1040 char* buf = (char*)_alloca(buf_size);
1041 if (boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(cp_acp, 0, wbuf, r, buf, buf_size, NULL, NULL) == 0)
1042 return def;
1043 #endif
1044 return std::string(buf);
1045 }
1046
1047 #ifndef BOOST_NO_WREGEX
1048 inline std::wstring w32_cat_get(const cat_type& cat, lcid_type, int i, const std::wstring& def)
1049 {
1050 wchar_t buf[256];
1051 if (0 == boost::BOOST_REGEX_DETAIL_NS::LoadStringW(static_cast<HMODULE>(cat.get()), i, buf, 256))
1052 {
1053 return def;
1054 }
1055 return std::wstring(buf);
1056 }
1057 #endif
1058 inline std::string w32_transform(lcid_type idx, const char* p1, const char* p2)
1059 {
1060 #ifndef BOOST_NO_ANSI_APIS
1061 int bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA(
1062 idx,
1063 lcmap_sortkey,
1064 p1,
1065 static_cast<int>(p2 - p1),
1066 0,
1067 0
1068 );
1069 if (!bytes)
1070 return std::string(p1, p2);
1071 std::string result(++bytes, '\0');
1072 bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA(
1073 idx,
1074 lcmap_sortkey,
1075 p1,
1076 static_cast<int>(p2 - p1),
1077 &*result.begin(),
1078 bytes
1079 );
1080 #else
1081 unsigned int code_page = get_code_page_for_locale_id(idx);
1082 if (code_page == 0)
1083 return std::string(p1, p2);
1084
1085 int src_len = static_cast<int>(p2 - p1);
1086 wchar_t* wide_p1 = (wchar_t*)_alloca((src_len + 1) * 2);
1087 if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, p1, src_len, wide_p1, src_len + 1) == 0)
1088 return std::string(p1, p2);
1089
1090 int bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(
1091 idx,
1092 lcmap_sortkey,
1093 wide_p1,
1094 src_len,
1095 0,
1096 0
1097 );
1098 if (!bytes)
1099 return std::string(p1, p2);
1100 std::string result(++bytes, '\0');
1101 bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(
1102 idx,
1103 lcmap_sortkey,
1104 wide_p1,
1105 src_len,
1106 (wchar_t*) & *result.begin(),
1107 bytes
1108 );
1109 #endif
1110 if (bytes > static_cast<int>(result.size()))
1111 return std::string(p1, p2);
1112 while (result.size() && result[result.size() - 1] == '\0')
1113 {
1114 result.erase(result.size() - 1);
1115 }
1116 return result;
1117 }
1118
1119 #ifndef BOOST_NO_WREGEX
1120 inline std::wstring w32_transform(lcid_type idx, const wchar_t* p1, const wchar_t* p2)
1121 {
1122 int bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(
1123 idx,
1124 lcmap_sortkey,
1125 p1,
1126 static_cast<int>(p2 - p1),
1127 0,
1128 0
1129 );
1130 if (!bytes)
1131 return std::wstring(p1, p2);
1132 std::string result(++bytes, '\0');
1133 bytes = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(
1134 idx,
1135 lcmap_sortkey,
1136 p1,
1137 static_cast<int>(p2 - p1),
1138 reinterpret_cast<wchar_t*>(&*result.begin()),
1139 bytes
1140 );
1141 if (bytes > static_cast<int>(result.size()))
1142 return std::wstring(p1, p2);
1143 while (result.size() && result[result.size() - 1] == L'\0')
1144 {
1145 result.erase(result.size() - 1);
1146 }
1147 std::wstring r2;
1148 for (std::string::size_type i = 0; i < result.size(); ++i)
1149 r2.append(1, static_cast<wchar_t>(static_cast<unsigned char>(result[i])));
1150 return r2;
1151 }
1152 #endif
1153 inline char w32_tolower(char c, lcid_type idx)
1154 {
1155 char result[2];
1156 #ifndef BOOST_NO_ANSI_APIS
1157 int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA(
1158 idx,
1159 lcmap_lowercase,
1160 &c,
1161 1,
1162 result,
1163 1);
1164 if (b == 0)
1165 return c;
1166 #else
1167 unsigned int code_page = get_code_page_for_locale_id(idx);
1168 if (code_page == 0)
1169 return c;
1170
1171 wchar_t wide_c;
1172 if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)
1173 return c;
1174
1175 wchar_t wide_result;
1176 int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(
1177 idx,
1178 lcmap_lowercase,
1179 &wide_c,
1180 1,
1181 &wide_result,
1182 1);
1183 if (b == 0)
1184 return c;
1185
1186 if (boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(code_page, 0, &wide_result, 1, result, 2, NULL, NULL) == 0)
1187 return c;
1188 #endif
1189 return result[0];
1190 }
1191
1192 #ifndef BOOST_NO_WREGEX
1193 inline wchar_t w32_tolower(wchar_t c, lcid_type idx)
1194 {
1195 wchar_t result[2];
1196 int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(
1197 idx,
1198 lcmap_lowercase,
1199 &c,
1200 1,
1201 result,
1202 1);
1203 if (b == 0)
1204 return c;
1205 return result[0];
1206 }
1207 #endif
1208 inline char w32_toupper(char c, lcid_type idx)
1209 {
1210 char result[2];
1211 #ifndef BOOST_NO_ANSI_APIS
1212 int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringA(
1213 idx,
1214 lcmap_uppercase,
1215 &c,
1216 1,
1217 result,
1218 1);
1219 if (b == 0)
1220 return c;
1221 #else
1222 unsigned int code_page = get_code_page_for_locale_id(idx);
1223 if (code_page == 0)
1224 return c;
1225
1226 wchar_t wide_c;
1227 if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)
1228 return c;
1229
1230 wchar_t wide_result;
1231 int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(
1232 idx,
1233 lcmap_uppercase,
1234 &wide_c,
1235 1,
1236 &wide_result,
1237 1);
1238 if (b == 0)
1239 return c;
1240
1241 if (boost::BOOST_REGEX_DETAIL_NS::WideCharToMultiByte(code_page, 0, &wide_result, 1, result, 2, NULL, NULL) == 0)
1242 return c;
1243 #endif
1244 return result[0];
1245 }
1246
1247 #ifndef BOOST_NO_WREGEX
1248 inline wchar_t w32_toupper(wchar_t c, lcid_type idx)
1249 {
1250 wchar_t result[2];
1251 int b = boost::BOOST_REGEX_DETAIL_NS::LCMapStringW(
1252 idx,
1253 lcmap_uppercase,
1254 &c,
1255 1,
1256 result,
1257 1);
1258 if (b == 0)
1259 return c;
1260 return result[0];
1261 }
1262 #endif
1263 inline bool w32_is(lcid_type idx, std::uint32_t m, char c)
1264 {
1265 word mask;
1266 #ifndef BOOST_NO_ANSI_APIS
1267 if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExA(idx, ct_ctype1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation<char>::mask_base))
1268 return true;
1269 #else
1270 unsigned int code_page = get_code_page_for_locale_id(idx);
1271 if (code_page == 0)
1272 return false;
1273
1274 wchar_t wide_c;
1275 if (boost::BOOST_REGEX_DETAIL_NS::MultiByteToWideChar(code_page, 0, &c, 1, &wide_c, 1) == 0)
1276 return false;
1277
1278 if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &wide_c, 1, &mask) && (mask & m & w32_regex_traits_implementation<char>::mask_base))
1279 return true;
1280 #endif
1281 if ((m & w32_regex_traits_implementation<char>::mask_word) && (c == '_'))
1282 return true;
1283 return false;
1284 }
1285
1286 #ifndef BOOST_NO_WREGEX
1287 inline bool w32_is(lcid_type idx, std::uint32_t m, wchar_t c)
1288 {
1289 word mask;
1290 if (boost::BOOST_REGEX_DETAIL_NS::GetStringTypeExW(idx, ct_ctype1, &c, 1, &mask) && (mask & m & w32_regex_traits_implementation<wchar_t>::mask_base))
1291 return true;
1292 if ((m & w32_regex_traits_implementation<wchar_t>::mask_word) && (c == '_'))
1293 return true;
1294 if ((m & w32_regex_traits_implementation<wchar_t>::mask_unicode) && (c > 0xff))
1295 return true;
1296 return false;
1297 }
1298 #endif
1299
1300 }
1301
1302
1303 }
1304
1305 #ifdef BOOST_REGEX_MSVC
1306 #pragma warning(pop)
1307 #endif
1308
1309 #endif
1310
1311 #endif