source: NonGTP/Boost/boost/regex/v4/w32_regex_traits.hpp @ 857

Revision 857, 23.0 KB checked in by igarcia, 19 years ago (diff)
Line 
1/*
2 *
3 * Copyright (c) 2004
4 * John Maddock
5 *
6 * Use, modification and distribution are subject to the
7 * Boost Software License, Version 1.0. (See accompanying file
8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 *
10 */
11 
12 /*
13  *   LOCATION:    see http://www.boost.org for most recent version.
14  *   FILE         w32_regex_traits.hpp
15  *   VERSION      see <boost/version.hpp>
16  *   DESCRIPTION: Declares regular expression traits class w32_regex_traits.
17  */
18
19#ifndef BOOST_W32_REGEX_TRAITS_HPP_INCLUDED
20#define BOOST_W32_REGEX_TRAITS_HPP_INCLUDED
21
22#ifndef BOOST_RE_PAT_EXCEPT_HPP
23#include <boost/regex/pattern_except.hpp>
24#endif
25#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
26#include <boost/regex/v4/regex_traits_defaults.hpp>
27#endif
28#ifdef BOOST_HAS_THREADS
29#include <boost/regex/pending/static_mutex.hpp>
30#endif
31#ifndef BOOST_REGEX_PRIMARY_TRANSFORM
32#include <boost/regex/v4/primary_transform.hpp>
33#endif
34#ifndef BOOST_REGEX_OBJECT_CACHE_HPP
35#include <boost/regex/pending/object_cache.hpp>
36#endif
37
38#ifdef BOOST_HAS_ABI_HEADERS
39#  include BOOST_ABI_PREFIX
40#endif
41
42#ifdef BOOST_MSVC
43#pragma warning(push)
44#pragma warning(disable:4786)
45#endif
46
47namespace boost{
48
49//
50// forward declaration is needed by some compilers:
51//
52template <class charT>
53class w32_regex_traits;
54   
55namespace re_detail{
56
57//
58// start by typedeffing the types we'll need:
59//
60typedef ::boost::uint32_t lcid_type;   // placeholder for LCID.
61typedef ::boost::shared_ptr<void> cat_type; // placeholder for dll HANDLE.
62
63//
64// then add wrappers around the actual Win32 API's (ie implementation hiding):
65//
66BOOST_REGEX_DECL lcid_type BOOST_REGEX_CALL w32_get_default_locale();
67BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(char, lcid_type);
68#ifndef BOOST_NO_WREGEX
69BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(wchar_t, lcid_type);
70#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
71BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(unsigned short ca, lcid_type id);
72#endif
73#endif
74BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(char, lcid_type);
75#ifndef BOOST_NO_WREGEX
76BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(wchar_t, lcid_type);
77#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
78BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(unsigned short ca, lcid_type id);
79#endif
80#endif
81BOOST_REGEX_DECL cat_type BOOST_REGEX_CALL w32_cat_open(const std::string& name);
82BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type id, int i, const std::string& def);
83#ifndef BOOST_NO_WREGEX
84BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type id, int i, const std::wstring& def);
85#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
86BOOST_REGEX_DECL std::basic_string<unsigned short> BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type, int i, const std::basic_string<unsigned short>& def);
87#endif
88#endif
89BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type id, const char* p1, const char* p2);
90#ifndef BOOST_NO_WREGEX
91BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_transform(lcid_type id, const wchar_t* p1, const wchar_t* p2);
92#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
93BOOST_REGEX_DECL std::basic_string<unsigned short> BOOST_REGEX_CALL w32_transform(lcid_type id, const unsigned short* p1, const unsigned short* p2);
94#endif
95#endif
96BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_tolower(char c, lcid_type);
97#ifndef BOOST_NO_WREGEX
98BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_tolower(wchar_t c, lcid_type);
99#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
100BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL w32_tolower(unsigned short c, lcid_type id);
101#endif
102#endif
103BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_toupper(char c, lcid_type);
104#ifndef BOOST_NO_WREGEX
105BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_toupper(wchar_t c, lcid_type);
106#endif
107BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type, boost::uint32_t mask, char c);
108#ifndef BOOST_NO_WREGEX
109BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type, boost::uint32_t mask, wchar_t c);
110#ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
111BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type id, boost::uint32_t m, unsigned short c);
112#endif
113#endif
114//
115// class w32_regex_traits_base:
116// acts as a container for locale and the facets we are using.
117//
118template <class charT>
119struct w32_regex_traits_base
120{
121   w32_regex_traits_base(lcid_type l)
122   { imbue(l); }
123   lcid_type imbue(lcid_type l);
124
125   lcid_type m_locale;
126};
127
128template <class charT>
129inline lcid_type w32_regex_traits_base<charT>::imbue(lcid_type l)
130{
131   lcid_type result(m_locale);
132   m_locale = l;
133   return result;
134}
135
136//
137// class w32_regex_traits_char_layer:
138// implements methods that require specialisation for narrow characters:
139//
140template <class charT>
141class w32_regex_traits_char_layer : public w32_regex_traits_base<charT>
142{
143   typedef std::basic_string<charT> string_type;
144   typedef std::map<charT, regex_constants::syntax_type> map_type;
145   typedef typename map_type::const_iterator map_iterator_type;
146public:
147   w32_regex_traits_char_layer(const lcid_type l);
148
149   regex_constants::syntax_type syntax_type(charT c)const
150   {
151      map_iterator_type i = m_char_map.find(c);
152      return ((i == m_char_map.end()) ? 0 : i->second);
153   }
154   regex_constants::escape_syntax_type escape_syntax_type(charT c) const
155   {
156      map_iterator_type i = m_char_map.find(c);
157      if(i == m_char_map.end())
158      {
159         if(::boost::re_detail::w32_is_lower(c, this->m_locale)) return regex_constants::escape_type_class;
160         if(::boost::re_detail::w32_is_upper(c, this->m_locale)) return regex_constants::escape_type_not_class;
161         return 0;
162      }
163      return i->second;
164   }
165   charT tolower(charT c)const
166   {
167      return ::boost::re_detail::w32_tolower(c, this->m_locale);
168   }
169   bool isctype(boost::uint32_t mask, charT c)
170   {
171      return ::boost::re_detail::w32_is(this->m_locale, mask, c);
172   }
173
174private:
175   string_type get_default_message(regex_constants::syntax_type);
176   // TODO: use a hash table when available!
177   map_type m_char_map;
178};
179
180template <class charT>
181w32_regex_traits_char_layer<charT>::w32_regex_traits_char_layer(::boost::re_detail::lcid_type l)
182   : w32_regex_traits_base<charT>(l)
183{
184   // we need to start by initialising our syntax map so we know which
185   // character is used for which purpose:
186   cat_type cat;
187   std::string cat_name(w32_regex_traits<charT>::get_catalog_name());
188   if(cat_name.size())
189   {
190      cat = ::boost::re_detail::w32_cat_open(cat_name);
191      if(!cat)
192      {
193         std::string m("Unable to open message catalog: ");
194         std::runtime_error err(m + cat_name);
195         boost::re_detail::raise_runtime_error(err);
196      }
197   }
198   //
199   // if we have a valid catalog then load our messages:
200   //
201   if(cat)
202   {
203      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
204      {
205         string_type mss = ::boost::re_detail::w32_cat_get(cat, this->m_locale, i, get_default_message(i));
206         for(typename string_type::size_type j = 0; j < mss.size(); ++j)
207         {
208            this->m_char_map[mss[j]] = i;
209         }
210      }
211   }
212   else
213   {
214      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
215      {
216         const char* ptr = get_default_syntax(i);
217         while(ptr && *ptr)
218         {
219            this->m_char_map[static_cast<charT>(*ptr)] = i;
220            ++ptr;
221         }
222      }
223   }
224}
225
226template <class charT>
227typename w32_regex_traits_char_layer<charT>::string_type
228   w32_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
229{
230   const char* ptr = get_default_syntax(i);
231   string_type result;
232   while(ptr && *ptr)
233   {
234      result.append(1, static_cast<charT>(*ptr));
235      ++ptr;
236   }
237   return result;
238}
239
240//
241// specialised version for narrow characters:
242//
243template <>
244class BOOST_REGEX_DECL w32_regex_traits_char_layer<char> : public w32_regex_traits_base<char>
245{
246   typedef std::string string_type;
247public:
248   w32_regex_traits_char_layer(::boost::re_detail::lcid_type l)
249   : w32_regex_traits_base<char>(l)
250   {
251      init();
252   }
253
254   regex_constants::syntax_type syntax_type(char c)const
255   {
256      return m_char_map[static_cast<unsigned char>(c)];
257   }
258   regex_constants::escape_syntax_type escape_syntax_type(char c) const
259   {
260      return m_char_map[static_cast<unsigned char>(c)];
261   }
262   char tolower(char c)const
263   {
264      return m_lower_map[static_cast<unsigned char>(c)];
265   }
266   bool isctype(boost::uint32_t mask, char c)
267   {
268      return m_type_map[static_cast<unsigned char>(c)] & mask;
269   }
270
271private:
272   regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
273   char m_lower_map[1u << CHAR_BIT];
274   boost::uint16_t m_type_map[1u << CHAR_BIT];
275   void init();
276};
277
278//
279// class w32_regex_traits_implementation:
280// provides pimpl implementation for w32_regex_traits.
281//
282template <class charT>
283class w32_regex_traits_implementation : public w32_regex_traits_char_layer<charT>
284{
285public:
286   typedef typename w32_regex_traits<charT>::char_class_type char_class_type;
287   BOOST_STATIC_CONSTANT(char_class_type, mask_word = 0x0400); // must be C1_DEFINED << 1
288   BOOST_STATIC_CONSTANT(char_class_type, mask_unicode = 0x0800); // must be C1_DEFINED << 2
289   BOOST_STATIC_CONSTANT(char_class_type, mask_base = 0x3ff);  // all the masks used by the CT_CTYPE1 group
290
291   typedef std::basic_string<charT> string_type;
292   typedef charT char_type;
293   w32_regex_traits_implementation(::boost::re_detail::lcid_type l);
294   std::string error_string(regex_constants::error_type n) const
295   {
296      if(!m_error_strings.empty())
297      {
298         std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
299         return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
300      }
301      return get_default_error_string(n);
302   }
303   char_class_type lookup_classname(const charT* p1, const charT* p2) const
304   {
305      char_class_type result = lookup_classname_imp(p1, p2);
306      if(result == 0)
307      {
308         typedef typename string_type::size_type size_type;
309         string_type temp(p1, p2);
310         for(size_type i = 0; i < temp.size(); ++i)
311            temp[i] = this->tolower(temp[i]);
312         result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
313      }
314      return result;
315   }
316   string_type lookup_collatename(const charT* p1, const charT* p2) const;
317   string_type transform_primary(const charT* p1, const charT* p2) const;
318   string_type transform(const charT* p1, const charT* p2) const
319   {
320      return ::boost::re_detail::w32_transform(this->m_locale, p1, p2);
321   }
322private:
323   std::map<int, std::string>     m_error_strings;   // error messages indexed by numberic ID
324   std::map<string_type, char_class_type>  m_custom_class_names; // character class names
325   std::map<string_type, string_type>      m_custom_collate_names; // collating element names
326   unsigned                       m_collate_type;    // the form of the collation string
327   charT                          m_collate_delim;   // the collation group delimiter
328   //
329   // helpers:
330   //
331   char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
332};
333
334template <class charT>
335typename w32_regex_traits_implementation<charT>::string_type
336   w32_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
337{
338   string_type result;
339   //
340   // What we do here depends upon the format of the sort key returned by
341   // sort key returned by this->transform:
342   //
343   switch(m_collate_type)
344   {
345   case sort_C:
346   case sort_unknown:
347      // the best we can do is translate to lower case, then get a regular sort key:
348      {
349         result.assign(p1, p2);
350         typedef typename string_type::size_type size_type;
351         for(size_type i = 0; i < result.size(); ++i)
352            result[i] = this->tolower(result[i]);
353         result = this->transform(&*result.begin(), &*result.begin() + result.size());
354         break;
355      }
356   case sort_fixed:
357      {
358         // get a regular sort key, and then truncate it:
359         result.assign(this->transform(p1, p2));
360         result.erase(this->m_collate_delim);
361         break;
362      }
363   case sort_delim:
364         // get a regular sort key, and then truncate everything after the delim:
365         result.assign(this->transform(p1, p2));
366         std::size_t i;
367         for(i = 0; i < result.size(); ++i)
368         {
369            if(result[i] == m_collate_delim)
370               break;
371         }
372         result.erase(i);
373         break;
374   }
375   if(result.empty())
376      result = string_type(1, charT(0));
377   return result;
378}
379
380template <class charT>
381typename w32_regex_traits_implementation<charT>::string_type
382   w32_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
383{
384   typedef typename std::map<string_type, string_type>::const_iterator iter_type;
385   if(m_custom_collate_names.size())
386   {
387      iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
388      if(pos != m_custom_collate_names.end())
389         return pos->second;
390   }
391#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
392               && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)\
393               && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
394   std::string name(p1, p2);
395#else
396   std::string name;
397   const charT* p0 = p1;
398   while(p0 != p2)
399      name.append(1, char(*p0++));
400#endif
401   name = lookup_default_collate_name(name);
402#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
403               && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)\
404               && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
405   if(name.size())
406      return string_type(name.begin(), name.end());
407#else
408   if(name.size())
409   {
410      string_type result;
411      typedef std::string::const_iterator iter;
412      iter b = name.begin();
413      iter e = name.end();
414      while(b != e)
415         result.append(1, charT(*b++));
416      return result;
417   }
418#endif
419   if(p2 - p1 == 1)
420      return string_type(1, *p1);
421   return string_type();
422}
423
424template <class charT>
425w32_regex_traits_implementation<charT>::w32_regex_traits_implementation(::boost::re_detail::lcid_type l)
426: w32_regex_traits_char_layer<charT>(l)
427{
428   cat_type cat;
429   std::string cat_name(w32_regex_traits<charT>::get_catalog_name());
430   if(cat_name.size())
431   {
432      cat = ::boost::re_detail::w32_cat_open(cat_name);
433      if(!cat)
434      {
435         std::string m("Unable to open message catalog: ");
436         std::runtime_error err(m + cat_name);
437         boost::re_detail::raise_runtime_error(err);
438      }
439   }
440   //
441   // if we have a valid catalog then load our messages:
442   //
443   if(cat)
444   {
445      //
446      // Error messages:
447      //
448      for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0);
449         i <= boost::regex_constants::error_unknown;
450         i = static_cast<boost::regex_constants::error_type>(i + 1))
451      {
452         const char* p = get_default_error_string(i);
453         string_type default_message;
454         while(*p)
455         {
456            default_message.append(1, static_cast<charT>(*p));
457            ++p;
458         }
459         string_type s = ::boost::re_detail::w32_cat_get(cat, this->m_locale, i+200, default_message);
460         std::string result;
461         for(std::string::size_type j = 0; j < s.size(); ++j)
462         {
463            result.append(1, static_cast<char>(s[j]));
464         }
465         m_error_strings[i] = result;
466      }
467      //
468      // Custom class names:
469      //
470      static const char_class_type masks[14] =
471      {
472         0x0104u, // C1_ALPHA | C1_DIGIT
473         0x0100u, // C1_ALPHA
474         0x0020u, // C1_CNTRL
475         0x0004u, // C1_DIGIT
476         (~(0x0020u|0x0008u) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE
477         0x0002u, // C1_LOWER
478         (~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL
479         0x0010u, // C1_PUNCT
480         0x0008u, // C1_SPACE
481         0x0001u, // C1_UPPER
482         0x0080u, // C1_XDIGIT
483         0x0040u, // C1_BLANK
484         w32_regex_traits_implementation<charT>::mask_word,
485         w32_regex_traits_implementation<charT>::mask_unicode,
486      };
487      static const string_type null_string;
488      for(unsigned int j = 0; j <= 13; ++j)
489      {
490         string_type s(::boost::re_detail::w32_cat_get(cat, this->m_locale, j+300, null_string));
491         if(s.size())
492            this->m_custom_class_names[s] = masks[j];
493      }
494   }
495   //
496   // get the collation format used by m_pcollate:
497   //
498   m_collate_type = re_detail::find_sort_syntax(this, &m_collate_delim);
499}
500
501template <class charT>
502typename w32_regex_traits_implementation<charT>::char_class_type
503   w32_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const
504{
505   static const char_class_type masks[20] =
506   {
507      0,
508      0x0104u, // C1_ALPHA | C1_DIGIT
509      0x0100u, // C1_ALPHA
510      0x0040u, // C1_BLANK
511      0x0020u, // C1_CNTRL
512      0x0004u, // C1_DIGIT
513      0x0004u, // C1_DIGIT
514      (~(0x0020u|0x0008u|0x0040) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE or C1_BLANK
515      0x0002u, // C1_LOWER
516      0x0002u, // C1_LOWER
517      (~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL
518      0x0010u, // C1_PUNCT
519      0x0008u, // C1_SPACE
520      0x0008u, // C1_SPACE
521      0x0001u, // C1_UPPER
522      w32_regex_traits_implementation<charT>::mask_unicode,
523      0x0001u, // C1_UPPER
524      0x0104u | w32_regex_traits_implementation<charT>::mask_word,
525      0x0104u | w32_regex_traits_implementation<charT>::mask_word,
526      0x0080u, // C1_XDIGIT
527   };
528   if(m_custom_class_names.size())
529   {
530      typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;
531      map_iter pos = m_custom_class_names.find(string_type(p1, p2));
532      if(pos != m_custom_class_names.end())
533         return pos->second;
534   }
535   std::size_t id = 1 + re_detail::get_default_class_id(p1, p2);
536   BOOST_ASSERT(id < sizeof(masks) / sizeof(masks[0]));
537   return masks[id];
538}
539
540
541template <class charT>
542boost::shared_ptr<w32_regex_traits_implementation<charT> > create_w32_regex_traits(::boost::re_detail::lcid_type l BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(charT))
543{
544   // TODO: create a cache for previously constructed objects.
545   return boost::object_cache< ::boost::re_detail::lcid_type, w32_regex_traits_implementation<charT> >::get(l, 5);
546}
547
548} // re_detail
549
550template <class charT>
551class w32_regex_traits
552{
553public:
554   typedef charT                         char_type;
555   typedef std::size_t                   size_type;
556   typedef std::basic_string<char_type>  string_type;
557   typedef ::boost::re_detail::lcid_type locale_type;
558   typedef boost::uint_least32_t         char_class_type;
559
560   struct boost_extensions_tag{};
561
562   w32_regex_traits()
563      : m_pimpl(re_detail::create_w32_regex_traits<charT>(::boost::re_detail::w32_get_default_locale()))
564   { }
565   static size_type length(const char_type* p)
566   {
567      return std::char_traits<charT>::length(p);
568   }
569   regex_constants::syntax_type syntax_type(charT c)const
570   {
571      return m_pimpl->syntax_type(c);
572   }
573   regex_constants::escape_syntax_type escape_syntax_type(charT c) const
574   {
575      return m_pimpl->escape_syntax_type(c);
576   }
577   charT translate(charT c) const
578   {
579      return c;
580   }
581   charT translate_nocase(charT c) const
582   {
583      return this->m_pimpl->tolower(c);
584   }
585   charT translate(charT c, bool icase) const
586   {
587      return icase ? this->m_pimpl->tolower(c) : c;
588   }
589   charT tolower(charT c) const
590   {
591      return this->m_pimpl->tolower(c);
592   }
593   charT toupper(charT c) const
594   {
595      return ::boost::re_detail::w32_toupper(c, this->m_pimpl->m_locale);
596   }
597   string_type transform(const charT* p1, const charT* p2) const
598   {
599      return ::boost::re_detail::w32_transform(this->m_pimpl->m_locale, p1, p2);
600   }
601   string_type transform_primary(const charT* p1, const charT* p2) const
602   {
603      return m_pimpl->transform_primary(p1, p2);
604   }
605   char_class_type lookup_classname(const charT* p1, const charT* p2) const
606   {
607      return m_pimpl->lookup_classname(p1, p2);
608   }
609   string_type lookup_collatename(const charT* p1, const charT* p2) const
610   {
611      return m_pimpl->lookup_collatename(p1, p2);
612   }
613   bool isctype(charT c, char_class_type f) const
614   {
615      if((f & re_detail::w32_regex_traits_implementation<charT>::mask_base)
616         && (this->m_pimpl->isctype(f & re_detail::w32_regex_traits_implementation<charT>::mask_base, c)))
617         return true;
618      else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_unicode) && re_detail::is_extended(c))
619         return true;
620      else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_word) && (c == '_'))
621         return true;
622      return false;
623   }
624   int toi(const charT*& p1, const charT* p2, int radix)const
625   {
626      return ::boost::re_detail::global_toi(p1, p2, radix, *this);
627   }
628   int value(charT c, int radix)const
629   {
630      int result = ::boost::re_detail::global_value(c);
631      return result < radix ? result : -1;
632   }
633   locale_type imbue(locale_type l)
634   {
635      ::boost::re_detail::lcid_type result(getloc());
636      m_pimpl = re_detail::create_w32_regex_traits<charT>(l);
637      return result;
638   }
639   locale_type getloc()const
640   {
641      return m_pimpl->m_locale;
642   }
643   std::string error_string(regex_constants::error_type n) const
644   {
645      return m_pimpl->error_string(n);
646   }
647
648   //
649   // extension:
650   // set the name of the message catalog in use (defaults to "boost_regex").
651   //
652   static std::string catalog_name(const std::string& name);
653   static std::string get_catalog_name();
654
655private:
656   boost::shared_ptr<re_detail::w32_regex_traits_implementation<charT> > m_pimpl;
657   //
658   // catalog name handler:
659   //
660   static std::string& get_catalog_name_inst();
661
662#ifdef BOOST_HAS_THREADS
663   static static_mutex& get_mutex_inst();
664#endif
665};
666
667template <class charT>
668std::string w32_regex_traits<charT>::catalog_name(const std::string& name)
669{
670#ifdef BOOST_HAS_THREADS
671   static_mutex::scoped_lock lk(get_mutex_inst());
672#endif
673   std::string result(get_catalog_name_inst());
674   get_catalog_name_inst() = name;
675   return result;
676}
677
678template <class charT>
679std::string& w32_regex_traits<charT>::get_catalog_name_inst()
680{
681   static std::string s_name;
682   return s_name;
683}
684
685template <class charT>
686std::string w32_regex_traits<charT>::get_catalog_name()
687{
688#ifdef BOOST_HAS_THREADS
689   static_mutex::scoped_lock lk(get_mutex_inst());
690#endif
691   std::string result(get_catalog_name_inst());
692   return result;
693}
694
695#ifdef BOOST_HAS_THREADS
696template <class charT>
697static_mutex& w32_regex_traits<charT>::get_mutex_inst()
698{
699   static static_mutex s_mutex = BOOST_STATIC_MUTEX_INIT;
700   return s_mutex;
701}
702#endif
703
704
705} // boost
706
707#ifdef BOOST_MSVC
708#pragma warning(pop)
709#endif
710
711#ifdef BOOST_HAS_ABI_HEADERS
712#  include BOOST_ABI_SUFFIX
713#endif
714
715#endif
Note: See TracBrowser for help on using the repository browser.