3
* Copyright (c) 1998-2002
6
* Permission to use, copy, modify, distribute and sell this software
7
* and its documentation for any purpose is hereby granted without fee,
8
* provided that the above copyright notice appear in all copies and
9
* that both that copyright notice and this permission notice appear
10
* in supporting documentation. Dr John Maddock makes no representations
11
* about the suitability of this software for any purpose.
12
* It is provided "as is" without express or implied warranty.
17
* LOCATION: see http://www.boost.org for most recent version.
18
* FILE: c_regex_traits.cpp
19
* VERSION: see <boost/version.hpp>
20
* DESCRIPTION: Implements the cpp_regex_traits<charT> traits class
24
#define BOOST_REGEX_SOURCE
26
#include <boost/regex/config.hpp>
28
#if !defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_WSTREAMBUF)
31
# pragma warning(disable:4786 4702 4127 4244)
41
#include <boost/regex/regex_traits.hpp>
42
#include <boost/cregex.hpp>
43
#include <boost/scoped_array.hpp>
44
#include "primary_transform.hpp"
47
# pragma warning(disable:4786 4702 4127 4244)
51
const unsigned int re_classes_max = 14;
52
const unsigned int char_set_size = CHAR_MAX - CHAR_MIN + 1;
54
boost::uint_fast32_t re_char_class_id[] = {
55
boost::re_detail::cpp_regex_traits_base::char_class_alnum,
56
boost::re_detail::cpp_regex_traits_base::char_class_alpha,
57
boost::re_detail::cpp_regex_traits_base::char_class_cntrl,
58
boost::re_detail::cpp_regex_traits_base::char_class_digit,
59
boost::re_detail::cpp_regex_traits_base::char_class_graph,
60
boost::re_detail::cpp_regex_traits_base::char_class_lower,
61
boost::re_detail::cpp_regex_traits_base::char_class_print,
62
boost::re_detail::cpp_regex_traits_base::char_class_punct,
63
boost::re_detail::cpp_regex_traits_base::char_class_space,
64
boost::re_detail::cpp_regex_traits_base::char_class_upper,
65
boost::re_detail::cpp_regex_traits_base::char_class_xdigit,
66
boost::re_detail::cpp_regex_traits_base::char_class_blank,
67
boost::re_detail::cpp_regex_traits_base::char_class_word,
68
boost::re_detail::cpp_regex_traits_base::char_class_unicode,
71
const char* re_char_class_names[] = {
88
template <class charT,
89
class traits = ::std::char_traits<charT> >
90
class parser_buf : public ::std::basic_streambuf<charT, traits>
92
typedef ::std::basic_streambuf<charT, traits> base_type;
93
typedef typename base_type::int_type int_type;
94
typedef typename base_type::char_type char_type;
95
typedef typename base_type::pos_type pos_type;
96
typedef ::std::streamsize streamsize;
97
typedef typename base_type::off_type off_type;
99
parser_buf() : base_type() { setbuf(0, 0); }
100
const charT* getnext() { return this->gptr(); }
102
std::basic_streambuf<charT, traits>* setbuf(char_type* s, streamsize n);
103
typename parser_buf<charT, traits>::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which);
104
typename parser_buf<charT, traits>::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which);
106
parser_buf& operator=(const parser_buf&);
107
parser_buf(const parser_buf&);
110
template<class charT, class traits>
111
std::basic_streambuf<charT, traits>*
112
parser_buf<charT, traits>::setbuf(char_type* s, streamsize n)
114
this->setg(s, s, s + n);
118
template<class charT, class traits>
119
typename parser_buf<charT, traits>::pos_type
120
parser_buf<charT, traits>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)
122
typedef typename parser_buf<charT, traits>::pos_type pos_type;
123
if(which & ::std::ios_base::out)
124
return pos_type(off_type(-1));
125
std::ptrdiff_t size = this->egptr() - this->eback();
126
std::ptrdiff_t pos = this->gptr() - this->eback();
127
charT* g = this->eback();
130
case ::std::ios_base::beg:
131
if((off < 0) || (off > size))
132
return pos_type(off_type(-1));
134
this->setg(g, g + off, g + size);
136
case ::std::ios_base::end:
137
if((off < 0) || (off > size))
138
return pos_type(off_type(-1));
140
this->setg(g, g + size - off, g + size);
142
case ::std::ios_base::cur:
144
std::ptrdiff_t newpos = pos + off;
145
if((newpos < 0) || (newpos > size))
146
return pos_type(off_type(-1));
148
this->setg(g, g + newpos, g + size);
153
return static_cast<pos_type>(this->gptr() - this->eback());
156
template<class charT, class traits>
157
typename parser_buf<charT, traits>::pos_type
158
parser_buf<charT, traits>::seekpos(pos_type sp, ::std::ios_base::openmode which)
160
if(which & ::std::ios_base::out)
161
return pos_type(off_type(-1));
162
std::ptrdiff_t size = this->egptr() - this->eback();
163
charT* g = this->eback();
166
this->setg(g, g + ::std::streamsize(sp), g + size);
168
return pos_type(off_type(-1));
178
struct message_data<char>
180
unsigned char syntax_map[CHAR_MAX-CHAR_MIN];
181
std::map<std::string, std::string, std::less<std::string> > collating_elements;
182
std::map<std::string, std::size_t, std::less<std::string> > classes;
185
parser_buf<char> sbuf;
187
std::string error_strings[boost::REG_E_UNKNOWN+1];
189
message_data(const std::locale& l, const std::string& regex_message_catalogue);
191
message_data(const message_data&);
192
message_data& operator=(const message_data&);
196
message_data<char>::message_data(const std::locale& l, const std::string& regex_message_catalogue)
200
#ifndef BOOST_NO_STD_MESSAGES
202
const std::messages<char>* pm = 0;
204
std::messages<char>::catalog cat = static_cast<std::messages<wchar_t>::catalog>(-1);
206
std::messages<char>::catalog cat = reinterpret_cast<std::messages<wchar_t>::catalog>(-1);
208
if(regex_message_catalogue.size())
210
pm = &BOOST_USE_FACET(std::messages<char>, l);
211
cat = pm->open(regex_message_catalogue, l);
212
#ifndef BOOST_NO_EXCEPTIONS
215
std::string m("Unable to open message catalog: ");
216
throw std::runtime_error(m + regex_message_catalogue);
219
BOOST_REGEX_NOEH_ASSERT(cat >= 0);
223
std::memset(syntax_map, cpp_regex_traits<char>::syntax_char, 256);
225
scoped_array<char> a;
226
std::size_t array_size = 0;
227
std::size_t new_size;
228
for(i = 1; i < cpp_regex_traits<char>::syntax_max; ++i)
230
new_size = re_get_default_message(0, 0, i+100);
231
if(new_size > array_size)
233
a.reset(new char[new_size]);
234
array_size = new_size;
236
re_get_default_message(a.get(), array_size, i+100);
237
std::string s = a.get();
238
#ifndef BOOST_NO_STD_MESSAGES
240
s = pm->get(cat, 0, i+100, s);
242
for(std::size_t j = 0; j < s.size(); ++j)
244
syntax_map[(unsigned char)s[j]] = (unsigned char)(i);
248
#ifndef BOOST_NO_STD_MESSAGES
249
// load any custom collate names:
251
// for some reason Borland C++ Builder 6 won't let us use
252
// std::isspace(char, std::locale) unless we call it
253
// unqualifed - weird. This seems to be affecting other
254
// STLport users as well (gcc3.1+STLport5), so enable the
255
// workaround for all STLport users...
257
#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
259
# define BOOST_REGEX_STD
261
# define BOOST_REGEX_STD std::
268
c2 = pm->get(cat, 0, i, c1);
271
const char* p1, *p2, *p3, *p4;;
273
while(*p1 && BOOST_REGEX_STD isspace((char)*p1, l))++p1;
275
while(*p2 && !BOOST_REGEX_STD isspace((char)*p2, l))++p2;
277
while(*p3 && BOOST_REGEX_STD isspace((char)*p3, l))++p3;
279
while(*p4 && !BOOST_REGEX_STD isspace((char)*p4, l))++p4;
280
collating_elements[std::string(p1, p2)] = std::string(p3, p4);
283
c2 = pm->get(cat, 0, i, c1);
289
#ifndef BOOST_NO_STD_MESSAGES
292
for(i = 0; i < re_classes_max; ++i)
294
s = pm->get(cat, 0, i+300, m);
298
for(i = 0; i <= boost::REG_E_UNKNOWN ; ++i)
300
s = pm->get(cat, 0, i+200, m);
301
error_strings[i] = s;
310
std::string BOOST_REGEX_CALL cpp_regex_traits_base::set_message_catalogue(const std::string& l)
312
if(sizeof(regex_message_cat) <= l.size())
314
std::string old(regex_message_cat);
315
std::strcpy(regex_message_cat, l.c_str());
319
char cpp_regex_traits_base::regex_message_cat[BOOST_REGEX_MAX_PATH] = {0};
322
} // namespace re_detail
325
cpp_regex_traits<char>::cpp_regex_traits()
327
pmd = new re_detail::message_data<char>(locale_inst, regex_message_cat);
328
psyntax = pmd->syntax_map;
329
#ifndef BOOST_NO_EXCEPTIONS
332
lower_map = new char[char_set_size];
333
BOOST_REGEX_NOEH_ASSERT(lower_map)
334
#ifndef BOOST_NO_EXCEPTIONS
342
for(unsigned int i = 0; i < char_set_size; ++i)
343
lower_map[i] = static_cast<char>(i);
344
pctype = &BOOST_USE_FACET(std::ctype<char>, locale_inst);
345
pctype->tolower(&lower_map[0], &lower_map[char_set_size]);
346
pcollate = &BOOST_USE_FACET(std::collate<char>, locale_inst);
347
sort_type = re_detail::find_sort_syntax(this, &(this->sort_delim));
350
cpp_regex_traits<char>::~cpp_regex_traits()
356
int BOOST_REGEX_CALL cpp_regex_traits<char>::toi(char c)const
358
pmd->sbuf.pubsetbuf(&c, 1);
370
int BOOST_REGEX_CALL cpp_regex_traits<char>::toi(const char*& first, const char* last, int radix)const
372
pmd->sbuf.pubsetbuf(const_cast<char*>(first), static_cast<std::streamsize>(last-first));
374
if(std::abs(radix) == 16) pmd->is >> std::hex;
375
else if(std::abs(radix) == 8) pmd->is >> std::oct;
376
else pmd->is >> std::dec;
380
first = first + ((last - first) - pmd->sbuf.in_avail());
387
boost::uint_fast32_t BOOST_REGEX_CALL cpp_regex_traits<char>::lookup_classname(const char* first, const char* last)const
391
std::string s(first, last);
393
std::map<std::string, std::size_t, std::less<std::string> >::const_iterator pos = pmd->classes.find(s);
394
if(pos != pmd->classes.end())
395
return re_char_class_id[(*pos).second];
397
for(i = 0; i < re_classes_max; ++i)
399
if(s == re_char_class_names[i])
400
return re_char_class_id[i];
405
bool BOOST_REGEX_CALL cpp_regex_traits<char>::lookup_collatename(std::string& s, const char* first, const char* last)const
408
std::string name(first, last);
409
std::map<std::string, std::string, std::less<std::string > >::const_iterator pos = pmd->collating_elements.find(name);
410
if(pos != pmd->collating_elements.end())
415
return re_detail::re_lookup_def_collate_name(s, name.c_str());
418
void BOOST_REGEX_CALL cpp_regex_traits<char>::transform_primary(std::string& out, const std::string& in)const
423
case re_detail::sort_C:
424
case re_detail::sort_unknown:
426
case re_detail::sort_fixed:
427
if((unsigned)sort_delim < out.size())
428
out.erase((int)sort_delim);
430
case re_detail::sort_delim:
431
for(unsigned int i = 0; i < out.size(); ++i)
433
if((out[i] == sort_delim) && (i+1 < out.size()))
443
std::string BOOST_REGEX_CALL cpp_regex_traits<char>::error_string(unsigned id)const
445
if((id <= boost::REG_E_UNKNOWN) && (pmd->error_strings[id].size()))
446
return pmd->error_strings[id];
447
return boost::re_detail::re_default_error_messages[id];
450
cpp_regex_traits<char>::locale_type BOOST_REGEX_CALL cpp_regex_traits<char>::imbue(locale_type l)
452
locale_type old_l(locale_inst);
454
re_detail::message_data<char>* npmd = new re_detail::message_data<char>(locale_inst, regex_message_cat);
457
psyntax = pmd->syntax_map;
458
for(unsigned int i = 0; i < char_set_size; ++i)
459
lower_map[i] = static_cast<char>(i);
460
pctype = &BOOST_USE_FACET(std::ctype<char>, locale_inst);
461
pctype->tolower(&lower_map[0], &lower_map[char_set_size]);
462
pcollate = &BOOST_USE_FACET(std::collate<char>, locale_inst);
463
sort_type = re_detail::find_sort_syntax(this, &(this->sort_delim));
467
#ifndef BOOST_NO_WREGEX
471
std::string BOOST_REGEX_CALL to_narrow(const std::basic_string<wchar_t>& is, const std::codecvt<wchar_t, char, std::mbstate_t>& cvt)
474
std::basic_string<wchar_t>::size_type bufsize = is.size() * 2;
476
// declare buffer first as VC6 workaround for internal compiler error!
477
char* pc = new char[bufsize];
478
scoped_array<char> t(pc);
479
#if defined(BOOST_MSVC) && !defined(DINKUMWARE_CE)
480
std::mbstate_t state = 0;
482
std::mbstate_t state = std::mbstate_t();
485
const wchar_t* next_in;
489
switch(cvt.out(state, is.c_str(), is.c_str() + is.size(), next_in, t.get(), t.get() + bufsize, next_out))
491
case std::codecvt_base::ok:
492
return std::string(t.get(), next_out);
493
case std::codecvt_base::partial:
495
t.reset(new char[bufsize]);
497
case std::codecvt_base::error:
498
// not much we can do here but guess:
499
case std::codecvt_base::noconv:
501
for(unsigned i = 0; i < is.size(); ++i)
503
out.append(1, (char)is[i]);
510
std::wstring BOOST_REGEX_CALL to_wide(const std::string& is, const std::codecvt<wchar_t, char, std::mbstate_t>& cvt)
513
std::string::size_type bufsize = is.size() + 2;
514
std::string::size_type maxsize = is.size() * 100;
516
// declare buffer first as VC6 workaround for internal compiler error!
517
wchar_t* pc = new wchar_t[bufsize];
518
scoped_array<wchar_t> t(pc);
519
#if defined(BOOST_MSVC) && !defined(DINKUMWARE_CE)
520
std::mbstate_t state = 0;
522
std::mbstate_t state = std::mbstate_t();
530
switch(cvt.in(state, is.c_str(), is.c_str() + is.size(), next_in, t.get(), t.get() + bufsize, next_out))
532
case std::codecvt_base::ok:
533
return std::wstring(t.get(), next_out);
534
case std::codecvt_base::partial:
536
if(bufsize < maxsize)
538
t.reset(new wchar_t[bufsize]);
542
// error fall through:
543
case std::codecvt_base::error:
544
// not much we can do here but guess:
545
case std::codecvt_base::noconv:
547
for(unsigned i = 0; i < is.size(); ++i)
549
out.append(1, is[i]);
559
struct message_data<wchar_t>
561
#ifndef BOOST_NO_STD_MESSAGES
562
typedef std::messages<wchar_t>::string_type string_type;
564
typedef std::wstring string_type;
575
std::list<syntax_map> syntax;
576
std::map<string_type, std::size_t> classes;
577
std::map<string_type, string_type> collating_elements;
578
unsigned char syntax_[CHAR_MAX-CHAR_MIN+1];
580
parser_buf<wchar_t> sbuf;
582
std::string error_strings[boost::REG_E_UNKNOWN+1];
584
message_data(const std::locale& l, const std::string& regex_message_catalogue);
586
message_data(const message_data&);
587
message_data& operator=(const message_data&);
590
message_data<wchar_t>::message_data(const std::locale& l, const std::string& regex_message_catalogue)
595
typedef std::codecvt<wchar_t, char, std::mbstate_t> cvt_type;
596
const cvt_type& cvt = BOOST_USE_FACET(cvt_type, l);
597
#ifndef BOOST_NO_STD_MESSAGES
598
const std::messages<wchar_t>& msgs = BOOST_USE_FACET(std::messages<wchar_t>, l);
600
std::messages<wchar_t>::catalog cat = static_cast<std::messages<wchar_t>::catalog>(-1);
602
std::messages<wchar_t>::catalog cat = reinterpret_cast<std::messages<wchar_t>::catalog>(-1);
604
if(regex_message_catalogue.size())
606
cat = msgs.open(regex_message_catalogue, l);
607
#ifndef BOOST_NO_EXCEPTIONS
610
std::string m("Unable to open message catalog: ");
611
throw std::runtime_error(m + regex_message_catalogue);
614
BOOST_REGEX_NOEH_ASSERT(cat >= 0);
618
scoped_array<char> a;
619
std::size_t array_size = 0;
620
std::size_t new_size;
622
std::memset(syntax_, cpp_regex_traits<wchar_t>::syntax_char, sizeof(syntax_));
623
for(i = 1; i < cpp_regex_traits<wchar_t>::syntax_max; ++i)
625
new_size = re_get_default_message(0, 0, i+100);
626
if(new_size > array_size)
628
a.reset(new char[new_size]);
629
array_size = new_size;
631
re_get_default_message(a.get(), array_size, i+100);
632
std::string ns = a.get();
633
string_type s = to_wide(ns, cvt);
634
#ifndef BOOST_NO_STD_MESSAGES
636
s = BOOST_USE_FACET(std::messages<wchar_t>, l).get(cat, 0, (int)i+100, s);
638
for(unsigned int j = 0; j < s.size(); ++j)
640
if((s[j] <= UCHAR_MAX) && (s[j] >= 0))
641
syntax_[s[j]] = static_cast<unsigned char>(i);
645
m.type = static_cast<unsigned int>(i);
651
#ifndef BOOST_NO_STD_MESSAGES
652
// load any custom collate names:
657
c2 = msgs.get(cat, 0, (int)i, c1);
660
const wchar_t* p1, *p2, *p3, *p4;;
662
while(*p1 && BOOST_REGEX_STD isspace((wchar_t)*p1, l))++p1;
664
while(*p2 && !BOOST_REGEX_STD isspace((wchar_t)*p2, l))++p2;
666
while(*p3 && BOOST_REGEX_STD isspace((wchar_t)*p3, l))++p3;
668
while(*p4 && !BOOST_REGEX_STD isspace((wchar_t)*p4, l))++p4;
669
collating_elements[std::basic_string<wchar_t>(p1, p2)] = std::basic_string<wchar_t>(p3, p4);
672
c2 = msgs.get(cat, 0, (int)i, c1);
679
for(i = 0; i < re_classes_max; ++i)
681
c1 = msgs.get(cat, 0, static_cast<int>(i+300), c2);
685
for(i = 0; i <= boost::REG_E_UNKNOWN ; ++i)
687
c1 = msgs.get(cat, 0, static_cast<int>(i+200), c2);
688
error_strings[i] = to_narrow(c1, cvt);
697
} // namespace re_detail
699
unsigned int BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::do_syntax_type(size_type c)const
701
std::list<re_detail::message_data<wchar_t>::syntax_map>::const_iterator i, j;
702
i = pmd->syntax.begin();
703
j = pmd->syntax.end();
706
if(((uchar_type)(*i).c) == c)
713
void BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::transform_primary(std::basic_string<wchar_t>& out, const std::basic_string<wchar_t>& in)const
718
case re_detail::sort_C:
719
case re_detail::sort_unknown:
721
case re_detail::sort_fixed:
722
if((unsigned)sort_delim < out.size())
723
out.erase((int)sort_delim);
725
case re_detail::sort_delim:
726
for(unsigned int i = 0; i < out.size(); ++i)
728
if((out[i] == sort_delim) && (i+1 < out.size()))
737
int BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::toi(wchar_t c)const
739
pmd->sbuf.pubsetbuf(&c, 1);
751
int BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::toi(const wchar_t*& first, const wchar_t* last, int radix)const
753
pmd->sbuf.pubsetbuf(const_cast<wchar_t*>(first), static_cast<std::streamsize>(last-first));
755
if(std::abs(radix) == 16) pmd->is >> std::hex;
756
else if(std::abs(radix) == 8) pmd->is >> std::oct;
757
else pmd->is >> std::dec;
761
first = first + ((last - first) - pmd->sbuf.in_avail());
768
boost::uint_fast32_t BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::lookup_classname(const wchar_t* first, const wchar_t* last)const
772
std::wstring s(first, last);
774
std::map<std::wstring, std::size_t>::const_iterator pos = pmd->classes.find(s);
775
if(pos != pmd->classes.end())
776
return re_char_class_id[(*pos).second];
778
std::string ns = re_detail::to_narrow(s, *pcdv);
780
for(i = 0; i < re_classes_max; ++i)
782
if(ns == re_char_class_names[i])
783
return re_char_class_id[i];
788
bool BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::lookup_collatename(std::basic_string<wchar_t>& s, const wchar_t* first, const wchar_t* last)const
791
std::wstring name(first, last);
792
std::map<std::wstring, std::wstring>::const_iterator pos = pmd->collating_elements.find(name);
793
if(pos != pmd->collating_elements.end())
798
std::string ns = re_detail::to_narrow(name, *pcdv);
800
bool result = re_detail::re_lookup_def_collate_name(ns2, ns.c_str());
801
s = re_detail::to_wide(ns2, *pcdv);
805
std::string BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::error_string(unsigned id)const
807
if((id <= boost::REG_E_UNKNOWN) && (pmd->error_strings[id].size()))
808
return pmd->error_strings[id];
809
return boost::re_detail::re_default_error_messages[id];
812
cpp_regex_traits<wchar_t>::cpp_regex_traits()
814
pmd = new re_detail::message_data<wchar_t>(locale_inst, std::string(regex_message_cat));
815
psyntax = pmd->syntax_;
816
#ifndef BOOST_NO_EXCEPTIONS
819
lower_map = new wchar_t[char_set_size];
820
BOOST_REGEX_NOEH_ASSERT(lower_map)
821
#ifndef BOOST_NO_EXCEPTIONS
829
for(unsigned int i = 0; i < char_set_size; ++i)
830
lower_map[i] = static_cast<wchar_t>(i);
831
pctype = &BOOST_USE_FACET(std::ctype<wchar_t>, locale_inst);
832
pctype->tolower(&lower_map[0], &lower_map[char_set_size]);
833
pcollate = &BOOST_USE_FACET(std::collate<wchar_t>, locale_inst);
834
typedef std::codecvt<wchar_t, char, std::mbstate_t> cvt_t;
835
pcdv = &BOOST_USE_FACET(cvt_t, locale_inst);
836
sort_type = re_detail::find_sort_syntax(this, &(this->sort_delim));
839
cpp_regex_traits<wchar_t>::~cpp_regex_traits()
845
cpp_regex_traits<wchar_t>::locale_type BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::imbue(locale_type l)
847
locale_type old_l(locale_inst);
849
re_detail::message_data<wchar_t>* npmd = new re_detail::message_data<wchar_t>(locale_inst, std::string(regex_message_cat));
852
psyntax = pmd->syntax_;
853
for(unsigned int i = 0; i < char_set_size; ++i)
854
lower_map[i] = static_cast<wchar_t>(i);
855
pctype = &BOOST_USE_FACET(std::ctype<wchar_t>, locale_inst);
856
pctype->tolower(&lower_map[0], &lower_map[char_set_size]);
857
pcollate = &BOOST_USE_FACET(std::collate<wchar_t>, locale_inst);
858
typedef std::codecvt<wchar_t, char, std::mbstate_t> cvt_t;
859
pcdv = &BOOST_USE_FACET(cvt_t, locale_inst);
860
sort_type = re_detail::find_sort_syntax(this, &(this->sort_delim));
864
std::size_t BOOST_REGEX_CALL cpp_regex_traits<wchar_t>::strwiden(wchar_t *s1, std::size_t len, const char *s2)const
867
std::wstring ws = re_detail::to_wide(s2, *pcdv);
869
std::wcscpy(s1, ws.c_str());
873
#endif // BOOST_NO_WREGEX