annotate DEPENDENCIES/generic/include/boost/regex/v4/cpp_regex_traits.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 /*
Chris@16 2 *
Chris@16 3 * Copyright (c) 2004 John Maddock
Chris@16 4 * Copyright 2011 Garmin Ltd. or its subsidiaries
Chris@16 5 *
Chris@16 6 * Use, modification and distribution are subject to the
Chris@16 7 * Boost Software License, Version 1.0. (See accompanying file
Chris@16 8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 9 *
Chris@16 10 */
Chris@16 11
Chris@16 12 /*
Chris@16 13 * LOCATION: see http://www.boost.org for most recent version.
Chris@16 14 * FILE cpp_regex_traits.hpp
Chris@16 15 * VERSION see <boost/version.hpp>
Chris@16 16 * DESCRIPTION: Declares regular expression traits class cpp_regex_traits.
Chris@16 17 */
Chris@16 18
Chris@16 19 #ifndef BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
Chris@16 20 #define BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
Chris@16 21
Chris@16 22 #include <boost/config.hpp>
Chris@16 23 #include <boost/integer.hpp>
Chris@101 24 #include <boost/type_traits/make_unsigned.hpp>
Chris@16 25
Chris@16 26 #ifndef BOOST_NO_STD_LOCALE
Chris@16 27
Chris@16 28 #ifndef BOOST_RE_PAT_EXCEPT_HPP
Chris@16 29 #include <boost/regex/pattern_except.hpp>
Chris@16 30 #endif
Chris@16 31 #ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
Chris@16 32 #include <boost/regex/v4/regex_traits_defaults.hpp>
Chris@16 33 #endif
Chris@16 34 #ifdef BOOST_HAS_THREADS
Chris@16 35 #include <boost/regex/pending/static_mutex.hpp>
Chris@16 36 #endif
Chris@16 37 #ifndef BOOST_REGEX_PRIMARY_TRANSFORM
Chris@16 38 #include <boost/regex/v4/primary_transform.hpp>
Chris@16 39 #endif
Chris@16 40 #ifndef BOOST_REGEX_OBJECT_CACHE_HPP
Chris@16 41 #include <boost/regex/pending/object_cache.hpp>
Chris@16 42 #endif
Chris@16 43
Chris@16 44 #include <istream>
Chris@16 45 #include <ios>
Chris@16 46 #include <climits>
Chris@16 47
Chris@16 48 #ifdef BOOST_MSVC
Chris@16 49 #pragma warning(push)
Chris@16 50 #pragma warning(disable: 4103)
Chris@16 51 #endif
Chris@16 52 #ifdef BOOST_HAS_ABI_HEADERS
Chris@16 53 # include BOOST_ABI_PREFIX
Chris@16 54 #endif
Chris@16 55 #ifdef BOOST_MSVC
Chris@16 56 #pragma warning(pop)
Chris@16 57 #endif
Chris@16 58
Chris@16 59 #ifdef BOOST_MSVC
Chris@16 60 #pragma warning(push)
Chris@16 61 #pragma warning(disable:4786 4251)
Chris@16 62 #endif
Chris@16 63
Chris@16 64 namespace boost{
Chris@16 65
Chris@16 66 //
Chris@16 67 // forward declaration is needed by some compilers:
Chris@16 68 //
Chris@16 69 template <class charT>
Chris@16 70 class cpp_regex_traits;
Chris@16 71
Chris@16 72 namespace re_detail{
Chris@16 73
Chris@16 74 //
Chris@16 75 // class parser_buf:
Chris@16 76 // acts as a stream buffer which wraps around a pair of pointers:
Chris@16 77 //
Chris@16 78 template <class charT,
Chris@16 79 class traits = ::std::char_traits<charT> >
Chris@16 80 class parser_buf : public ::std::basic_streambuf<charT, traits>
Chris@16 81 {
Chris@16 82 typedef ::std::basic_streambuf<charT, traits> base_type;
Chris@16 83 typedef typename base_type::int_type int_type;
Chris@16 84 typedef typename base_type::char_type char_type;
Chris@16 85 typedef typename base_type::pos_type pos_type;
Chris@16 86 typedef ::std::streamsize streamsize;
Chris@16 87 typedef typename base_type::off_type off_type;
Chris@16 88 public:
Chris@16 89 parser_buf() : base_type() { setbuf(0, 0); }
Chris@16 90 const charT* getnext() { return this->gptr(); }
Chris@16 91 protected:
Chris@16 92 std::basic_streambuf<charT, traits>* setbuf(char_type* s, streamsize n);
Chris@16 93 typename parser_buf<charT, traits>::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which);
Chris@16 94 typename parser_buf<charT, traits>::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which);
Chris@16 95 private:
Chris@16 96 parser_buf& operator=(const parser_buf&);
Chris@16 97 parser_buf(const parser_buf&);
Chris@16 98 };
Chris@16 99
Chris@16 100 template<class charT, class traits>
Chris@16 101 std::basic_streambuf<charT, traits>*
Chris@16 102 parser_buf<charT, traits>::setbuf(char_type* s, streamsize n)
Chris@16 103 {
Chris@16 104 this->setg(s, s, s + n);
Chris@16 105 return this;
Chris@16 106 }
Chris@16 107
Chris@16 108 template<class charT, class traits>
Chris@16 109 typename parser_buf<charT, traits>::pos_type
Chris@16 110 parser_buf<charT, traits>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)
Chris@16 111 {
Chris@16 112 typedef typename boost::int_t<sizeof(way) * CHAR_BIT>::least cast_type;
Chris@16 113
Chris@16 114 if(which & ::std::ios_base::out)
Chris@16 115 return pos_type(off_type(-1));
Chris@16 116 std::ptrdiff_t size = this->egptr() - this->eback();
Chris@16 117 std::ptrdiff_t pos = this->gptr() - this->eback();
Chris@16 118 charT* g = this->eback();
Chris@16 119 switch(static_cast<cast_type>(way))
Chris@16 120 {
Chris@16 121 case ::std::ios_base::beg:
Chris@16 122 if((off < 0) || (off > size))
Chris@16 123 return pos_type(off_type(-1));
Chris@16 124 else
Chris@16 125 this->setg(g, g + off, g + size);
Chris@16 126 break;
Chris@16 127 case ::std::ios_base::end:
Chris@16 128 if((off < 0) || (off > size))
Chris@16 129 return pos_type(off_type(-1));
Chris@16 130 else
Chris@16 131 this->setg(g, g + size - off, g + size);
Chris@16 132 break;
Chris@16 133 case ::std::ios_base::cur:
Chris@16 134 {
Chris@16 135 std::ptrdiff_t newpos = static_cast<std::ptrdiff_t>(pos + off);
Chris@16 136 if((newpos < 0) || (newpos > size))
Chris@16 137 return pos_type(off_type(-1));
Chris@16 138 else
Chris@16 139 this->setg(g, g + newpos, g + size);
Chris@16 140 break;
Chris@16 141 }
Chris@16 142 default: ;
Chris@16 143 }
Chris@16 144 #ifdef BOOST_MSVC
Chris@16 145 #pragma warning(push)
Chris@16 146 #pragma warning(disable:4244)
Chris@16 147 #endif
Chris@16 148 return static_cast<pos_type>(this->gptr() - this->eback());
Chris@16 149 #ifdef BOOST_MSVC
Chris@16 150 #pragma warning(pop)
Chris@16 151 #endif
Chris@16 152 }
Chris@16 153
Chris@16 154 template<class charT, class traits>
Chris@16 155 typename parser_buf<charT, traits>::pos_type
Chris@16 156 parser_buf<charT, traits>::seekpos(pos_type sp, ::std::ios_base::openmode which)
Chris@16 157 {
Chris@16 158 if(which & ::std::ios_base::out)
Chris@16 159 return pos_type(off_type(-1));
Chris@16 160 off_type size = static_cast<off_type>(this->egptr() - this->eback());
Chris@16 161 charT* g = this->eback();
Chris@16 162 if(off_type(sp) <= size)
Chris@16 163 {
Chris@16 164 this->setg(g, g + off_type(sp), g + size);
Chris@16 165 }
Chris@16 166 return pos_type(off_type(-1));
Chris@16 167 }
Chris@16 168
Chris@16 169 //
Chris@16 170 // class cpp_regex_traits_base:
Chris@16 171 // acts as a container for locale and the facets we are using.
Chris@16 172 //
Chris@16 173 template <class charT>
Chris@16 174 struct cpp_regex_traits_base
Chris@16 175 {
Chris@16 176 cpp_regex_traits_base(const std::locale& l)
Chris@16 177 { imbue(l); }
Chris@16 178 std::locale imbue(const std::locale& l);
Chris@16 179
Chris@16 180 std::locale m_locale;
Chris@16 181 std::ctype<charT> const* m_pctype;
Chris@16 182 #ifndef BOOST_NO_STD_MESSAGES
Chris@16 183 std::messages<charT> const* m_pmessages;
Chris@16 184 #endif
Chris@16 185 std::collate<charT> const* m_pcollate;
Chris@16 186
Chris@16 187 bool operator<(const cpp_regex_traits_base& b)const
Chris@16 188 {
Chris@16 189 if(m_pctype == b.m_pctype)
Chris@16 190 {
Chris@16 191 #ifndef BOOST_NO_STD_MESSAGES
Chris@16 192 if(m_pmessages == b.m_pmessages)
Chris@16 193 {
Chris@16 194 return m_pcollate < b.m_pcollate;
Chris@16 195 }
Chris@16 196 return m_pmessages < b.m_pmessages;
Chris@16 197 #else
Chris@16 198 return m_pcollate < b.m_pcollate;
Chris@16 199 #endif
Chris@16 200 }
Chris@16 201 return m_pctype < b.m_pctype;
Chris@16 202 }
Chris@16 203 bool operator==(const cpp_regex_traits_base& b)const
Chris@16 204 {
Chris@16 205 return (m_pctype == b.m_pctype)
Chris@16 206 #ifndef BOOST_NO_STD_MESSAGES
Chris@16 207 && (m_pmessages == b.m_pmessages)
Chris@16 208 #endif
Chris@16 209 && (m_pcollate == b.m_pcollate);
Chris@16 210 }
Chris@16 211 };
Chris@16 212
Chris@16 213 template <class charT>
Chris@16 214 std::locale cpp_regex_traits_base<charT>::imbue(const std::locale& l)
Chris@16 215 {
Chris@16 216 std::locale result(m_locale);
Chris@16 217 m_locale = l;
Chris@16 218 m_pctype = &BOOST_USE_FACET(std::ctype<charT>, l);
Chris@16 219 #ifndef BOOST_NO_STD_MESSAGES
Chris@16 220 m_pmessages = BOOST_HAS_FACET(std::messages<charT>, l) ? &BOOST_USE_FACET(std::messages<charT>, l) : 0;
Chris@16 221 #endif
Chris@16 222 m_pcollate = &BOOST_USE_FACET(std::collate<charT>, l);
Chris@16 223 return result;
Chris@16 224 }
Chris@16 225
Chris@16 226 //
Chris@16 227 // class cpp_regex_traits_char_layer:
Chris@16 228 // implements methods that require specialisation for narrow characters:
Chris@16 229 //
Chris@16 230 template <class charT>
Chris@16 231 class cpp_regex_traits_char_layer : public cpp_regex_traits_base<charT>
Chris@16 232 {
Chris@16 233 typedef std::basic_string<charT> string_type;
Chris@16 234 typedef std::map<charT, regex_constants::syntax_type> map_type;
Chris@16 235 typedef typename map_type::const_iterator map_iterator_type;
Chris@16 236 public:
Chris@16 237 cpp_regex_traits_char_layer(const std::locale& l)
Chris@16 238 : cpp_regex_traits_base<charT>(l)
Chris@16 239 {
Chris@16 240 init();
Chris@16 241 }
Chris@16 242 cpp_regex_traits_char_layer(const cpp_regex_traits_base<charT>& b)
Chris@16 243 : cpp_regex_traits_base<charT>(b)
Chris@16 244 {
Chris@16 245 init();
Chris@16 246 }
Chris@16 247 void init();
Chris@16 248
Chris@16 249 regex_constants::syntax_type syntax_type(charT c)const
Chris@16 250 {
Chris@16 251 map_iterator_type i = m_char_map.find(c);
Chris@16 252 return ((i == m_char_map.end()) ? 0 : i->second);
Chris@16 253 }
Chris@16 254 regex_constants::escape_syntax_type escape_syntax_type(charT c) const
Chris@16 255 {
Chris@16 256 map_iterator_type i = m_char_map.find(c);
Chris@16 257 if(i == m_char_map.end())
Chris@16 258 {
Chris@16 259 if(this->m_pctype->is(std::ctype_base::lower, c)) return regex_constants::escape_type_class;
Chris@16 260 if(this->m_pctype->is(std::ctype_base::upper, c)) return regex_constants::escape_type_not_class;
Chris@16 261 return 0;
Chris@16 262 }
Chris@16 263 return i->second;
Chris@16 264 }
Chris@16 265
Chris@16 266 private:
Chris@16 267 string_type get_default_message(regex_constants::syntax_type);
Chris@16 268 // TODO: use a hash table when available!
Chris@16 269 map_type m_char_map;
Chris@16 270 };
Chris@16 271
Chris@16 272 template <class charT>
Chris@16 273 void cpp_regex_traits_char_layer<charT>::init()
Chris@16 274 {
Chris@16 275 // we need to start by initialising our syntax map so we know which
Chris@16 276 // character is used for which purpose:
Chris@16 277 #ifndef BOOST_NO_STD_MESSAGES
Chris@16 278 #ifndef __IBMCPP__
Chris@16 279 typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
Chris@16 280 #else
Chris@16 281 typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
Chris@16 282 #endif
Chris@16 283 std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
Chris@16 284 if(cat_name.size() && (this->m_pmessages != 0))
Chris@16 285 {
Chris@16 286 cat = this->m_pmessages->open(
Chris@16 287 cat_name,
Chris@16 288 this->m_locale);
Chris@16 289 if((int)cat < 0)
Chris@16 290 {
Chris@16 291 std::string m("Unable to open message catalog: ");
Chris@16 292 std::runtime_error err(m + cat_name);
Chris@16 293 boost::re_detail::raise_runtime_error(err);
Chris@16 294 }
Chris@16 295 }
Chris@16 296 //
Chris@16 297 // if we have a valid catalog then load our messages:
Chris@16 298 //
Chris@16 299 if((int)cat >= 0)
Chris@16 300 {
Chris@16 301 #ifndef BOOST_NO_EXCEPTIONS
Chris@16 302 try{
Chris@16 303 #endif
Chris@16 304 for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
Chris@16 305 {
Chris@16 306 string_type mss = this->m_pmessages->get(cat, 0, i, get_default_message(i));
Chris@16 307 for(typename string_type::size_type j = 0; j < mss.size(); ++j)
Chris@16 308 {
Chris@16 309 m_char_map[mss[j]] = i;
Chris@16 310 }
Chris@16 311 }
Chris@16 312 this->m_pmessages->close(cat);
Chris@16 313 #ifndef BOOST_NO_EXCEPTIONS
Chris@16 314 }
Chris@16 315 catch(...)
Chris@16 316 {
Chris@16 317 if(this->m_pmessages)
Chris@16 318 this->m_pmessages->close(cat);
Chris@16 319 throw;
Chris@16 320 }
Chris@16 321 #endif
Chris@16 322 }
Chris@16 323 else
Chris@16 324 {
Chris@16 325 #endif
Chris@16 326 for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
Chris@16 327 {
Chris@16 328 const char* ptr = get_default_syntax(i);
Chris@16 329 while(ptr && *ptr)
Chris@16 330 {
Chris@16 331 m_char_map[this->m_pctype->widen(*ptr)] = i;
Chris@16 332 ++ptr;
Chris@16 333 }
Chris@16 334 }
Chris@16 335 #ifndef BOOST_NO_STD_MESSAGES
Chris@16 336 }
Chris@16 337 #endif
Chris@16 338 }
Chris@16 339
Chris@16 340 template <class charT>
Chris@16 341 typename cpp_regex_traits_char_layer<charT>::string_type
Chris@16 342 cpp_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
Chris@16 343 {
Chris@16 344 const char* ptr = get_default_syntax(i);
Chris@16 345 string_type result;
Chris@16 346 while(ptr && *ptr)
Chris@16 347 {
Chris@16 348 result.append(1, this->m_pctype->widen(*ptr));
Chris@16 349 ++ptr;
Chris@16 350 }
Chris@16 351 return result;
Chris@16 352 }
Chris@16 353
Chris@16 354 //
Chris@16 355 // specialised version for narrow characters:
Chris@16 356 //
Chris@16 357 template <>
Chris@16 358 class BOOST_REGEX_DECL cpp_regex_traits_char_layer<char> : public cpp_regex_traits_base<char>
Chris@16 359 {
Chris@16 360 typedef std::string string_type;
Chris@16 361 public:
Chris@16 362 cpp_regex_traits_char_layer(const std::locale& l)
Chris@16 363 : cpp_regex_traits_base<char>(l)
Chris@16 364 {
Chris@16 365 init();
Chris@16 366 }
Chris@16 367 cpp_regex_traits_char_layer(const cpp_regex_traits_base<char>& l)
Chris@16 368 : cpp_regex_traits_base<char>(l)
Chris@16 369 {
Chris@16 370 init();
Chris@16 371 }
Chris@16 372
Chris@16 373 regex_constants::syntax_type syntax_type(char c)const
Chris@16 374 {
Chris@16 375 return m_char_map[static_cast<unsigned char>(c)];
Chris@16 376 }
Chris@16 377 regex_constants::escape_syntax_type escape_syntax_type(char c) const
Chris@16 378 {
Chris@16 379 return m_char_map[static_cast<unsigned char>(c)];
Chris@16 380 }
Chris@16 381
Chris@16 382 private:
Chris@16 383 regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
Chris@16 384 void init();
Chris@16 385 };
Chris@16 386
Chris@16 387 #ifdef BOOST_REGEX_BUGGY_CTYPE_FACET
Chris@16 388 enum
Chris@16 389 {
Chris@16 390 char_class_space=1<<0,
Chris@16 391 char_class_print=1<<1,
Chris@16 392 char_class_cntrl=1<<2,
Chris@16 393 char_class_upper=1<<3,
Chris@16 394 char_class_lower=1<<4,
Chris@16 395 char_class_alpha=1<<5,
Chris@16 396 char_class_digit=1<<6,
Chris@16 397 char_class_punct=1<<7,
Chris@16 398 char_class_xdigit=1<<8,
Chris@16 399 char_class_alnum=char_class_alpha|char_class_digit,
Chris@16 400 char_class_graph=char_class_alnum|char_class_punct,
Chris@16 401 char_class_blank=1<<9,
Chris@16 402 char_class_word=1<<10,
Chris@16 403 char_class_unicode=1<<11,
Chris@16 404 char_class_horizontal_space=1<<12,
Chris@16 405 char_class_vertical_space=1<<13
Chris@16 406 };
Chris@16 407
Chris@16 408 #endif
Chris@16 409
Chris@16 410 //
Chris@16 411 // class cpp_regex_traits_implementation:
Chris@16 412 // provides pimpl implementation for cpp_regex_traits.
Chris@16 413 //
Chris@16 414 template <class charT>
Chris@16 415 class cpp_regex_traits_implementation : public cpp_regex_traits_char_layer<charT>
Chris@16 416 {
Chris@16 417 public:
Chris@16 418 typedef typename cpp_regex_traits<charT>::char_class_type char_class_type;
Chris@16 419 typedef typename std::ctype<charT>::mask native_mask_type;
Chris@16 420 #ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
Chris@16 421 BOOST_STATIC_CONSTANT(char_class_type, mask_blank = 1u << 24);
Chris@16 422 BOOST_STATIC_CONSTANT(char_class_type, mask_word = 1u << 25);
Chris@16 423 BOOST_STATIC_CONSTANT(char_class_type, mask_unicode = 1u << 26);
Chris@16 424 BOOST_STATIC_CONSTANT(char_class_type, mask_horizontal = 1u << 27);
Chris@16 425 BOOST_STATIC_CONSTANT(char_class_type, mask_vertical = 1u << 28);
Chris@16 426 #endif
Chris@16 427
Chris@16 428 typedef std::basic_string<charT> string_type;
Chris@16 429 typedef charT char_type;
Chris@16 430 //cpp_regex_traits_implementation();
Chris@16 431 cpp_regex_traits_implementation(const std::locale& l)
Chris@16 432 : cpp_regex_traits_char_layer<charT>(l)
Chris@16 433 {
Chris@16 434 init();
Chris@16 435 }
Chris@16 436 cpp_regex_traits_implementation(const cpp_regex_traits_base<charT>& l)
Chris@16 437 : cpp_regex_traits_char_layer<charT>(l)
Chris@16 438 {
Chris@16 439 init();
Chris@16 440 }
Chris@16 441 std::string error_string(regex_constants::error_type n) const
Chris@16 442 {
Chris@16 443 if(!m_error_strings.empty())
Chris@16 444 {
Chris@16 445 std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
Chris@16 446 return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
Chris@16 447 }
Chris@16 448 return get_default_error_string(n);
Chris@16 449 }
Chris@16 450 char_class_type lookup_classname(const charT* p1, const charT* p2) const
Chris@16 451 {
Chris@16 452 char_class_type result = lookup_classname_imp(p1, p2);
Chris@16 453 if(result == 0)
Chris@16 454 {
Chris@16 455 string_type temp(p1, p2);
Chris@16 456 this->m_pctype->tolower(&*temp.begin(), &*temp.begin() + temp.size());
Chris@16 457 result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
Chris@16 458 }
Chris@16 459 return result;
Chris@16 460 }
Chris@16 461 string_type lookup_collatename(const charT* p1, const charT* p2) const;
Chris@16 462 string_type transform_primary(const charT* p1, const charT* p2) const;
Chris@16 463 string_type transform(const charT* p1, const charT* p2) const;
Chris@16 464 private:
Chris@16 465 std::map<int, std::string> m_error_strings; // error messages indexed by numberic ID
Chris@16 466 std::map<string_type, char_class_type> m_custom_class_names; // character class names
Chris@16 467 std::map<string_type, string_type> m_custom_collate_names; // collating element names
Chris@16 468 unsigned m_collate_type; // the form of the collation string
Chris@16 469 charT m_collate_delim; // the collation group delimiter
Chris@16 470 //
Chris@16 471 // helpers:
Chris@16 472 //
Chris@16 473 char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
Chris@16 474 void init();
Chris@16 475 #ifdef BOOST_REGEX_BUGGY_CTYPE_FACET
Chris@16 476 public:
Chris@16 477 bool isctype(charT c, char_class_type m)const;
Chris@16 478 #endif
Chris@16 479 };
Chris@16 480
Chris@16 481 #ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
Chris@16 482 #if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
Chris@16 483
Chris@16 484 template <class charT>
Chris@16 485 typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_blank;
Chris@16 486 template <class charT>
Chris@16 487 typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_word;
Chris@16 488 template <class charT>
Chris@16 489 typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_unicode;
Chris@16 490 template <class charT>
Chris@16 491 typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_vertical;
Chris@16 492 template <class charT>
Chris@16 493 typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_horizontal;
Chris@16 494
Chris@16 495 #endif
Chris@16 496 #endif
Chris@16 497
Chris@16 498 template <class charT>
Chris@16 499 typename cpp_regex_traits_implementation<charT>::string_type
Chris@16 500 cpp_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
Chris@16 501 {
Chris@16 502 //
Chris@16 503 // PRECONDITIONS:
Chris@16 504 //
Chris@16 505 // A bug in gcc 3.2 (and maybe other versions as well) treats
Chris@16 506 // p1 as a null terminated string, for efficiency reasons
Chris@16 507 // we work around this elsewhere, but just assert here that
Chris@16 508 // we adhere to gcc's (buggy) preconditions...
Chris@16 509 //
Chris@16 510 BOOST_ASSERT(*p2 == 0);
Chris@16 511 string_type result;
Chris@101 512 #if defined(_CPPLIB_VER)
Chris@101 513 //
Chris@101 514 // A bug in VC11 and 12 causes the program to hang if we pass a null-string
Chris@101 515 // to std::collate::transform, but only for certain locales :-(
Chris@101 516 // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).
Chris@101 517 //
Chris@101 518 if(*p1 == 0)
Chris@101 519 {
Chris@101 520 return string_type(1, charT(0));
Chris@101 521 }
Chris@101 522 #endif
Chris@16 523 //
Chris@16 524 // swallowing all exceptions here is a bad idea
Chris@16 525 // however at least one std lib will always throw
Chris@16 526 // std::bad_alloc for certain arguments...
Chris@16 527 //
Chris@16 528 #ifndef BOOST_NO_EXCEPTIONS
Chris@16 529 try{
Chris@16 530 #endif
Chris@16 531 //
Chris@16 532 // What we do here depends upon the format of the sort key returned by
Chris@16 533 // sort key returned by this->transform:
Chris@16 534 //
Chris@16 535 switch(m_collate_type)
Chris@16 536 {
Chris@16 537 case sort_C:
Chris@16 538 case sort_unknown:
Chris@16 539 // the best we can do is translate to lower case, then get a regular sort key:
Chris@16 540 {
Chris@16 541 result.assign(p1, p2);
Chris@16 542 this->m_pctype->tolower(&*result.begin(), &*result.begin() + result.size());
Chris@16 543 result = this->m_pcollate->transform(&*result.begin(), &*result.begin() + result.size());
Chris@16 544 break;
Chris@16 545 }
Chris@16 546 case sort_fixed:
Chris@16 547 {
Chris@16 548 // get a regular sort key, and then truncate it:
Chris@16 549 result.assign(this->m_pcollate->transform(p1, p2));
Chris@16 550 result.erase(this->m_collate_delim);
Chris@16 551 break;
Chris@16 552 }
Chris@16 553 case sort_delim:
Chris@16 554 // get a regular sort key, and then truncate everything after the delim:
Chris@16 555 result.assign(this->m_pcollate->transform(p1, p2));
Chris@16 556 std::size_t i;
Chris@16 557 for(i = 0; i < result.size(); ++i)
Chris@16 558 {
Chris@16 559 if(result[i] == m_collate_delim)
Chris@16 560 break;
Chris@16 561 }
Chris@16 562 result.erase(i);
Chris@16 563 break;
Chris@16 564 }
Chris@16 565 #ifndef BOOST_NO_EXCEPTIONS
Chris@16 566 }catch(...){}
Chris@16 567 #endif
Chris@16 568 while(result.size() && (charT(0) == *result.rbegin()))
Chris@16 569 result.erase(result.size() - 1);
Chris@16 570 if(result.empty())
Chris@16 571 {
Chris@16 572 // character is ignorable at the primary level:
Chris@16 573 result = string_type(1, charT(0));
Chris@16 574 }
Chris@16 575 return result;
Chris@16 576 }
Chris@16 577
Chris@16 578 template <class charT>
Chris@16 579 typename cpp_regex_traits_implementation<charT>::string_type
Chris@16 580 cpp_regex_traits_implementation<charT>::transform(const charT* p1, const charT* p2) const
Chris@16 581 {
Chris@16 582 //
Chris@16 583 // PRECONDITIONS:
Chris@16 584 //
Chris@16 585 // A bug in gcc 3.2 (and maybe other versions as well) treats
Chris@16 586 // p1 as a null terminated string, for efficiency reasons
Chris@16 587 // we work around this elsewhere, but just assert here that
Chris@16 588 // we adhere to gcc's (buggy) preconditions...
Chris@16 589 //
Chris@16 590 BOOST_ASSERT(*p2 == 0);
Chris@16 591 //
Chris@16 592 // swallowing all exceptions here is a bad idea
Chris@16 593 // however at least one std lib will always throw
Chris@16 594 // std::bad_alloc for certain arguments...
Chris@16 595 //
Chris@101 596 string_type result, result2;
Chris@101 597 #if defined(_CPPLIB_VER)
Chris@101 598 //
Chris@101 599 // A bug in VC11 and 12 causes the program to hang if we pass a null-string
Chris@101 600 // to std::collate::transform, but only for certain locales :-(
Chris@101 601 // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).
Chris@101 602 //
Chris@101 603 if(*p1 == 0)
Chris@101 604 {
Chris@101 605 return result;
Chris@101 606 }
Chris@101 607 #endif
Chris@16 608 #ifndef BOOST_NO_EXCEPTIONS
Chris@16 609 try{
Chris@16 610 #endif
Chris@16 611 result = this->m_pcollate->transform(p1, p2);
Chris@16 612 //
Chris@16 613 // Borland's STLPort version returns a NULL-terminated
Chris@16 614 // string that has garbage at the end - each call to
Chris@16 615 // std::collate<wchar_t>::transform returns a different string!
Chris@16 616 // So as a workaround, we'll truncate the string at the first NULL
Chris@16 617 // which _seems_ to work....
Chris@16 618 #if BOOST_WORKAROUND(__BORLANDC__, < 0x580)
Chris@16 619 result.erase(result.find(charT(0)));
Chris@16 620 #else
Chris@16 621 //
Chris@16 622 // some implementations (Dinkumware) append unnecessary trailing \0's:
Chris@16 623 while(result.size() && (charT(0) == *result.rbegin()))
Chris@16 624 result.erase(result.size() - 1);
Chris@16 625 #endif
Chris@101 626 //
Chris@101 627 // We may have NULL's used as separators between sections of the collate string,
Chris@101 628 // an example would be Boost.Locale. We have no way to detect this case via
Chris@101 629 // #defines since this can be used with any compiler/platform combination.
Chris@101 630 // Unfortunately our state machine (which was devised when all implementations
Chris@101 631 // used underlying C language API's) can't cope with that case. One workaround
Chris@101 632 // is to replace each character with 2, fortunately this code isn't used that
Chris@101 633 // much as this is now slower than before :-(
Chris@101 634 //
Chris@101 635 typedef typename make_unsigned<charT>::type uchar_type;
Chris@101 636 result2.reserve(result.size() * 2 + 2);
Chris@101 637 for(unsigned i = 0; i < result.size(); ++i)
Chris@101 638 {
Chris@101 639 if(static_cast<uchar_type>(result[i]) == (std::numeric_limits<uchar_type>::max)())
Chris@101 640 {
Chris@101 641 result2.append(1, charT((std::numeric_limits<uchar_type>::max)())).append(1, charT('b'));
Chris@101 642 }
Chris@101 643 else
Chris@101 644 {
Chris@101 645 result2.append(1, static_cast<charT>(1 + static_cast<uchar_type>(result[i]))).append(1, charT('b') - 1);
Chris@101 646 }
Chris@101 647 }
Chris@101 648 BOOST_ASSERT(std::find(result2.begin(), result2.end(), charT(0)) == result2.end());
Chris@16 649 #ifndef BOOST_NO_EXCEPTIONS
Chris@16 650 }
Chris@16 651 catch(...)
Chris@16 652 {
Chris@16 653 }
Chris@16 654 #endif
Chris@101 655 return result2;
Chris@16 656 }
Chris@16 657
Chris@16 658
Chris@16 659 template <class charT>
Chris@16 660 typename cpp_regex_traits_implementation<charT>::string_type
Chris@16 661 cpp_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
Chris@16 662 {
Chris@16 663 typedef typename std::map<string_type, string_type>::const_iterator iter_type;
Chris@16 664 if(m_custom_collate_names.size())
Chris@16 665 {
Chris@16 666 iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
Chris@16 667 if(pos != m_custom_collate_names.end())
Chris@16 668 return pos->second;
Chris@16 669 }
Chris@16 670 #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
Chris@16 671 && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
Chris@16 672 std::string name(p1, p2);
Chris@16 673 #else
Chris@16 674 std::string name;
Chris@16 675 const charT* p0 = p1;
Chris@16 676 while(p0 != p2)
Chris@16 677 name.append(1, char(*p0++));
Chris@16 678 #endif
Chris@16 679 name = lookup_default_collate_name(name);
Chris@16 680 #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
Chris@16 681 && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
Chris@16 682 if(name.size())
Chris@16 683 return string_type(name.begin(), name.end());
Chris@16 684 #else
Chris@16 685 if(name.size())
Chris@16 686 {
Chris@16 687 string_type result;
Chris@16 688 typedef std::string::const_iterator iter;
Chris@16 689 iter b = name.begin();
Chris@16 690 iter e = name.end();
Chris@16 691 while(b != e)
Chris@16 692 result.append(1, charT(*b++));
Chris@16 693 return result;
Chris@16 694 }
Chris@16 695 #endif
Chris@16 696 if(p2 - p1 == 1)
Chris@16 697 return string_type(1, *p1);
Chris@16 698 return string_type();
Chris@16 699 }
Chris@16 700
Chris@16 701 template <class charT>
Chris@16 702 void cpp_regex_traits_implementation<charT>::init()
Chris@16 703 {
Chris@16 704 #ifndef BOOST_NO_STD_MESSAGES
Chris@16 705 #ifndef __IBMCPP__
Chris@16 706 typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
Chris@16 707 #else
Chris@16 708 typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
Chris@16 709 #endif
Chris@16 710 std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
Chris@16 711 if(cat_name.size() && (this->m_pmessages != 0))
Chris@16 712 {
Chris@16 713 cat = this->m_pmessages->open(
Chris@16 714 cat_name,
Chris@16 715 this->m_locale);
Chris@16 716 if((int)cat < 0)
Chris@16 717 {
Chris@16 718 std::string m("Unable to open message catalog: ");
Chris@16 719 std::runtime_error err(m + cat_name);
Chris@16 720 boost::re_detail::raise_runtime_error(err);
Chris@16 721 }
Chris@16 722 }
Chris@16 723 //
Chris@16 724 // if we have a valid catalog then load our messages:
Chris@16 725 //
Chris@16 726 if((int)cat >= 0)
Chris@16 727 {
Chris@16 728 //
Chris@16 729 // Error messages:
Chris@16 730 //
Chris@16 731 for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0);
Chris@16 732 i <= boost::regex_constants::error_unknown;
Chris@16 733 i = static_cast<boost::regex_constants::error_type>(i + 1))
Chris@16 734 {
Chris@16 735 const char* p = get_default_error_string(i);
Chris@16 736 string_type default_message;
Chris@16 737 while(*p)
Chris@16 738 {
Chris@16 739 default_message.append(1, this->m_pctype->widen(*p));
Chris@16 740 ++p;
Chris@16 741 }
Chris@16 742 string_type s = this->m_pmessages->get(cat, 0, i+200, default_message);
Chris@16 743 std::string result;
Chris@16 744 for(std::string::size_type j = 0; j < s.size(); ++j)
Chris@16 745 {
Chris@16 746 result.append(1, this->m_pctype->narrow(s[j], 0));
Chris@16 747 }
Chris@16 748 m_error_strings[i] = result;
Chris@16 749 }
Chris@16 750 //
Chris@16 751 // Custom class names:
Chris@16 752 //
Chris@16 753 #ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
Chris@16 754 static const char_class_type masks[16] =
Chris@16 755 {
Chris@16 756 std::ctype<charT>::alnum,
Chris@16 757 std::ctype<charT>::alpha,
Chris@16 758 std::ctype<charT>::cntrl,
Chris@16 759 std::ctype<charT>::digit,
Chris@16 760 std::ctype<charT>::graph,
Chris@16 761 cpp_regex_traits_implementation<charT>::mask_horizontal,
Chris@16 762 std::ctype<charT>::lower,
Chris@16 763 std::ctype<charT>::print,
Chris@16 764 std::ctype<charT>::punct,
Chris@16 765 std::ctype<charT>::space,
Chris@16 766 std::ctype<charT>::upper,
Chris@16 767 cpp_regex_traits_implementation<charT>::mask_vertical,
Chris@16 768 std::ctype<charT>::xdigit,
Chris@16 769 cpp_regex_traits_implementation<charT>::mask_blank,
Chris@16 770 cpp_regex_traits_implementation<charT>::mask_word,
Chris@16 771 cpp_regex_traits_implementation<charT>::mask_unicode,
Chris@16 772 };
Chris@16 773 #else
Chris@16 774 static const char_class_type masks[16] =
Chris@16 775 {
Chris@16 776 ::boost::re_detail::char_class_alnum,
Chris@16 777 ::boost::re_detail::char_class_alpha,
Chris@16 778 ::boost::re_detail::char_class_cntrl,
Chris@16 779 ::boost::re_detail::char_class_digit,
Chris@16 780 ::boost::re_detail::char_class_graph,
Chris@16 781 ::boost::re_detail::char_class_horizontal_space,
Chris@16 782 ::boost::re_detail::char_class_lower,
Chris@16 783 ::boost::re_detail::char_class_print,
Chris@16 784 ::boost::re_detail::char_class_punct,
Chris@16 785 ::boost::re_detail::char_class_space,
Chris@16 786 ::boost::re_detail::char_class_upper,
Chris@16 787 ::boost::re_detail::char_class_vertical_space,
Chris@16 788 ::boost::re_detail::char_class_xdigit,
Chris@16 789 ::boost::re_detail::char_class_blank,
Chris@16 790 ::boost::re_detail::char_class_word,
Chris@16 791 ::boost::re_detail::char_class_unicode,
Chris@16 792 };
Chris@16 793 #endif
Chris@16 794 static const string_type null_string;
Chris@16 795 for(unsigned int j = 0; j <= 13; ++j)
Chris@16 796 {
Chris@16 797 string_type s(this->m_pmessages->get(cat, 0, j+300, null_string));
Chris@16 798 if(s.size())
Chris@16 799 this->m_custom_class_names[s] = masks[j];
Chris@16 800 }
Chris@16 801 }
Chris@16 802 #endif
Chris@16 803 //
Chris@16 804 // get the collation format used by m_pcollate:
Chris@16 805 //
Chris@16 806 m_collate_type = re_detail::find_sort_syntax(this, &m_collate_delim);
Chris@16 807 }
Chris@16 808
Chris@16 809 template <class charT>
Chris@16 810 typename cpp_regex_traits_implementation<charT>::char_class_type
Chris@16 811 cpp_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const
Chris@16 812 {
Chris@16 813 #ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
Chris@16 814 static const char_class_type masks[22] =
Chris@16 815 {
Chris@16 816 0,
Chris@16 817 std::ctype<char>::alnum,
Chris@16 818 std::ctype<char>::alpha,
Chris@16 819 cpp_regex_traits_implementation<charT>::mask_blank,
Chris@16 820 std::ctype<char>::cntrl,
Chris@16 821 std::ctype<char>::digit,
Chris@16 822 std::ctype<char>::digit,
Chris@16 823 std::ctype<char>::graph,
Chris@16 824 cpp_regex_traits_implementation<charT>::mask_horizontal,
Chris@16 825 std::ctype<char>::lower,
Chris@16 826 std::ctype<char>::lower,
Chris@16 827 std::ctype<char>::print,
Chris@16 828 std::ctype<char>::punct,
Chris@16 829 std::ctype<char>::space,
Chris@16 830 std::ctype<char>::space,
Chris@16 831 std::ctype<char>::upper,
Chris@16 832 cpp_regex_traits_implementation<charT>::mask_unicode,
Chris@16 833 std::ctype<char>::upper,
Chris@16 834 cpp_regex_traits_implementation<charT>::mask_vertical,
Chris@16 835 std::ctype<char>::alnum | cpp_regex_traits_implementation<charT>::mask_word,
Chris@16 836 std::ctype<char>::alnum | cpp_regex_traits_implementation<charT>::mask_word,
Chris@16 837 std::ctype<char>::xdigit,
Chris@16 838 };
Chris@16 839 #else
Chris@16 840 static const char_class_type masks[22] =
Chris@16 841 {
Chris@16 842 0,
Chris@16 843 ::boost::re_detail::char_class_alnum,
Chris@16 844 ::boost::re_detail::char_class_alpha,
Chris@16 845 ::boost::re_detail::char_class_blank,
Chris@16 846 ::boost::re_detail::char_class_cntrl,
Chris@16 847 ::boost::re_detail::char_class_digit,
Chris@16 848 ::boost::re_detail::char_class_digit,
Chris@16 849 ::boost::re_detail::char_class_graph,
Chris@16 850 ::boost::re_detail::char_class_horizontal_space,
Chris@16 851 ::boost::re_detail::char_class_lower,
Chris@16 852 ::boost::re_detail::char_class_lower,
Chris@16 853 ::boost::re_detail::char_class_print,
Chris@16 854 ::boost::re_detail::char_class_punct,
Chris@16 855 ::boost::re_detail::char_class_space,
Chris@16 856 ::boost::re_detail::char_class_space,
Chris@16 857 ::boost::re_detail::char_class_upper,
Chris@16 858 ::boost::re_detail::char_class_unicode,
Chris@16 859 ::boost::re_detail::char_class_upper,
Chris@16 860 ::boost::re_detail::char_class_vertical_space,
Chris@16 861 ::boost::re_detail::char_class_alnum | ::boost::re_detail::char_class_word,
Chris@16 862 ::boost::re_detail::char_class_alnum | ::boost::re_detail::char_class_word,
Chris@16 863 ::boost::re_detail::char_class_xdigit,
Chris@16 864 };
Chris@16 865 #endif
Chris@16 866 if(m_custom_class_names.size())
Chris@16 867 {
Chris@16 868 typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;
Chris@16 869 map_iter pos = m_custom_class_names.find(string_type(p1, p2));
Chris@16 870 if(pos != m_custom_class_names.end())
Chris@16 871 return pos->second;
Chris@16 872 }
Chris@16 873 std::size_t state_id = 1 + re_detail::get_default_class_id(p1, p2);
Chris@16 874 BOOST_ASSERT(state_id < sizeof(masks) / sizeof(masks[0]));
Chris@16 875 return masks[state_id];
Chris@16 876 }
Chris@16 877
Chris@16 878 #ifdef BOOST_REGEX_BUGGY_CTYPE_FACET
Chris@16 879 template <class charT>
Chris@16 880 bool cpp_regex_traits_implementation<charT>::isctype(const charT c, char_class_type mask) const
Chris@16 881 {
Chris@16 882 return
Chris@16 883 ((mask & ::boost::re_detail::char_class_space) && (this->m_pctype->is(std::ctype<charT>::space, c)))
Chris@16 884 || ((mask & ::boost::re_detail::char_class_print) && (this->m_pctype->is(std::ctype<charT>::print, c)))
Chris@16 885 || ((mask & ::boost::re_detail::char_class_cntrl) && (this->m_pctype->is(std::ctype<charT>::cntrl, c)))
Chris@16 886 || ((mask & ::boost::re_detail::char_class_upper) && (this->m_pctype->is(std::ctype<charT>::upper, c)))
Chris@16 887 || ((mask & ::boost::re_detail::char_class_lower) && (this->m_pctype->is(std::ctype<charT>::lower, c)))
Chris@16 888 || ((mask & ::boost::re_detail::char_class_alpha) && (this->m_pctype->is(std::ctype<charT>::alpha, c)))
Chris@16 889 || ((mask & ::boost::re_detail::char_class_digit) && (this->m_pctype->is(std::ctype<charT>::digit, c)))
Chris@16 890 || ((mask & ::boost::re_detail::char_class_punct) && (this->m_pctype->is(std::ctype<charT>::punct, c)))
Chris@16 891 || ((mask & ::boost::re_detail::char_class_xdigit) && (this->m_pctype->is(std::ctype<charT>::xdigit, c)))
Chris@16 892 || ((mask & ::boost::re_detail::char_class_blank) && (this->m_pctype->is(std::ctype<charT>::space, c)) && !::boost::re_detail::is_separator(c))
Chris@16 893 || ((mask & ::boost::re_detail::char_class_word) && (c == '_'))
Chris@16 894 || ((mask & ::boost::re_detail::char_class_unicode) && ::boost::re_detail::is_extended(c))
Chris@16 895 || ((mask & ::boost::re_detail::char_class_vertical_space) && (is_separator(c) || (c == '\v')))
Chris@16 896 || ((mask & ::boost::re_detail::char_class_horizontal_space) && this->m_pctype->is(std::ctype<charT>::space, c) && !(is_separator(c) || (c == '\v')));
Chris@16 897 }
Chris@16 898 #endif
Chris@16 899
Chris@16 900
Chris@16 901 template <class charT>
Chris@101 902 inline boost::shared_ptr<const cpp_regex_traits_implementation<charT> > create_cpp_regex_traits(const std::locale& l)
Chris@16 903 {
Chris@16 904 cpp_regex_traits_base<charT> key(l);
Chris@16 905 return ::boost::object_cache<cpp_regex_traits_base<charT>, cpp_regex_traits_implementation<charT> >::get(key, 5);
Chris@16 906 }
Chris@16 907
Chris@16 908 } // re_detail
Chris@16 909
Chris@16 910 template <class charT>
Chris@16 911 class cpp_regex_traits
Chris@16 912 {
Chris@16 913 private:
Chris@16 914 typedef std::ctype<charT> ctype_type;
Chris@16 915 public:
Chris@16 916 typedef charT char_type;
Chris@16 917 typedef std::size_t size_type;
Chris@16 918 typedef std::basic_string<char_type> string_type;
Chris@16 919 typedef std::locale locale_type;
Chris@16 920 typedef boost::uint_least32_t char_class_type;
Chris@16 921
Chris@16 922 struct boost_extensions_tag{};
Chris@16 923
Chris@16 924 cpp_regex_traits()
Chris@16 925 : m_pimpl(re_detail::create_cpp_regex_traits<charT>(std::locale()))
Chris@16 926 { }
Chris@16 927 static size_type length(const char_type* p)
Chris@16 928 {
Chris@16 929 return std::char_traits<charT>::length(p);
Chris@16 930 }
Chris@16 931 regex_constants::syntax_type syntax_type(charT c)const
Chris@16 932 {
Chris@16 933 return m_pimpl->syntax_type(c);
Chris@16 934 }
Chris@16 935 regex_constants::escape_syntax_type escape_syntax_type(charT c) const
Chris@16 936 {
Chris@16 937 return m_pimpl->escape_syntax_type(c);
Chris@16 938 }
Chris@16 939 charT translate(charT c) const
Chris@16 940 {
Chris@16 941 return c;
Chris@16 942 }
Chris@16 943 charT translate_nocase(charT c) const
Chris@16 944 {
Chris@16 945 return m_pimpl->m_pctype->tolower(c);
Chris@16 946 }
Chris@16 947 charT translate(charT c, bool icase) const
Chris@16 948 {
Chris@16 949 return icase ? m_pimpl->m_pctype->tolower(c) : c;
Chris@16 950 }
Chris@16 951 charT tolower(charT c) const
Chris@16 952 {
Chris@16 953 return m_pimpl->m_pctype->tolower(c);
Chris@16 954 }
Chris@16 955 charT toupper(charT c) const
Chris@16 956 {
Chris@16 957 return m_pimpl->m_pctype->toupper(c);
Chris@16 958 }
Chris@16 959 string_type transform(const charT* p1, const charT* p2) const
Chris@16 960 {
Chris@16 961 return m_pimpl->transform(p1, p2);
Chris@16 962 }
Chris@16 963 string_type transform_primary(const charT* p1, const charT* p2) const
Chris@16 964 {
Chris@16 965 return m_pimpl->transform_primary(p1, p2);
Chris@16 966 }
Chris@16 967 char_class_type lookup_classname(const charT* p1, const charT* p2) const
Chris@16 968 {
Chris@16 969 return m_pimpl->lookup_classname(p1, p2);
Chris@16 970 }
Chris@16 971 string_type lookup_collatename(const charT* p1, const charT* p2) const
Chris@16 972 {
Chris@16 973 return m_pimpl->lookup_collatename(p1, p2);
Chris@16 974 }
Chris@16 975 bool isctype(charT c, char_class_type f) const
Chris@16 976 {
Chris@16 977 #ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
Chris@16 978 typedef typename std::ctype<charT>::mask ctype_mask;
Chris@16 979
Chris@16 980 static const ctype_mask mask_base =
Chris@16 981 static_cast<ctype_mask>(
Chris@16 982 std::ctype<charT>::alnum
Chris@16 983 | std::ctype<charT>::alpha
Chris@16 984 | std::ctype<charT>::cntrl
Chris@16 985 | std::ctype<charT>::digit
Chris@16 986 | std::ctype<charT>::graph
Chris@16 987 | std::ctype<charT>::lower
Chris@16 988 | std::ctype<charT>::print
Chris@16 989 | std::ctype<charT>::punct
Chris@16 990 | std::ctype<charT>::space
Chris@16 991 | std::ctype<charT>::upper
Chris@16 992 | std::ctype<charT>::xdigit);
Chris@16 993
Chris@16 994 if((f & mask_base)
Chris@16 995 && (m_pimpl->m_pctype->is(
Chris@16 996 static_cast<ctype_mask>(f & mask_base), c)))
Chris@16 997 return true;
Chris@16 998 else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_unicode) && re_detail::is_extended(c))
Chris@16 999 return true;
Chris@16 1000 else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_word) && (c == '_'))
Chris@16 1001 return true;
Chris@16 1002 else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_blank)
Chris@16 1003 && m_pimpl->m_pctype->is(std::ctype<charT>::space, c)
Chris@16 1004 && !re_detail::is_separator(c))
Chris@16 1005 return true;
Chris@16 1006 else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_vertical)
Chris@16 1007 && (::boost::re_detail::is_separator(c) || (c == '\v')))
Chris@16 1008 return true;
Chris@16 1009 else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_horizontal)
Chris@16 1010 && this->isctype(c, std::ctype<charT>::space) && !this->isctype(c, re_detail::cpp_regex_traits_implementation<charT>::mask_vertical))
Chris@16 1011 return true;
Chris@16 1012 return false;
Chris@16 1013 #else
Chris@16 1014 return m_pimpl->isctype(c, f);
Chris@16 1015 #endif
Chris@16 1016 }
Chris@16 1017 int toi(const charT*& p1, const charT* p2, int radix)const;
Chris@16 1018 int value(charT c, int radix)const
Chris@16 1019 {
Chris@16 1020 const charT* pc = &c;
Chris@16 1021 return toi(pc, pc + 1, radix);
Chris@16 1022 }
Chris@16 1023 locale_type imbue(locale_type l)
Chris@16 1024 {
Chris@16 1025 std::locale result(getloc());
Chris@16 1026 m_pimpl = re_detail::create_cpp_regex_traits<charT>(l);
Chris@16 1027 return result;
Chris@16 1028 }
Chris@16 1029 locale_type getloc()const
Chris@16 1030 {
Chris@16 1031 return m_pimpl->m_locale;
Chris@16 1032 }
Chris@16 1033 std::string error_string(regex_constants::error_type n) const
Chris@16 1034 {
Chris@16 1035 return m_pimpl->error_string(n);
Chris@16 1036 }
Chris@16 1037
Chris@16 1038 //
Chris@16 1039 // extension:
Chris@16 1040 // set the name of the message catalog in use (defaults to "boost_regex").
Chris@16 1041 //
Chris@16 1042 static std::string catalog_name(const std::string& name);
Chris@16 1043 static std::string get_catalog_name();
Chris@16 1044
Chris@16 1045 private:
Chris@16 1046 boost::shared_ptr<const re_detail::cpp_regex_traits_implementation<charT> > m_pimpl;
Chris@16 1047 //
Chris@16 1048 // catalog name handler:
Chris@16 1049 //
Chris@16 1050 static std::string& get_catalog_name_inst();
Chris@16 1051
Chris@16 1052 #ifdef BOOST_HAS_THREADS
Chris@16 1053 static static_mutex& get_mutex_inst();
Chris@16 1054 #endif
Chris@16 1055 };
Chris@16 1056
Chris@16 1057
Chris@16 1058 template <class charT>
Chris@16 1059 int cpp_regex_traits<charT>::toi(const charT*& first, const charT* last, int radix)const
Chris@16 1060 {
Chris@16 1061 re_detail::parser_buf<charT> sbuf; // buffer for parsing numbers.
Chris@16 1062 std::basic_istream<charT> is(&sbuf); // stream for parsing numbers.
Chris@16 1063
Chris@16 1064 // we do NOT want to parse any thousands separators inside the stream:
Chris@16 1065 last = std::find(first, last, BOOST_USE_FACET(std::numpunct<charT>, is.getloc()).thousands_sep());
Chris@16 1066
Chris@16 1067 sbuf.pubsetbuf(const_cast<charT*>(static_cast<const charT*>(first)), static_cast<std::streamsize>(last-first));
Chris@16 1068 is.clear();
Chris@16 1069 if(std::abs(radix) == 16) is >> std::hex;
Chris@16 1070 else if(std::abs(radix) == 8) is >> std::oct;
Chris@16 1071 else is >> std::dec;
Chris@16 1072 int val;
Chris@16 1073 if(is >> val)
Chris@16 1074 {
Chris@16 1075 first = first + ((last - first) - sbuf.in_avail());
Chris@16 1076 return val;
Chris@16 1077 }
Chris@16 1078 else
Chris@16 1079 return -1;
Chris@16 1080 }
Chris@16 1081
Chris@16 1082 template <class charT>
Chris@16 1083 std::string cpp_regex_traits<charT>::catalog_name(const std::string& name)
Chris@16 1084 {
Chris@16 1085 #ifdef BOOST_HAS_THREADS
Chris@16 1086 static_mutex::scoped_lock lk(get_mutex_inst());
Chris@16 1087 #endif
Chris@16 1088 std::string result(get_catalog_name_inst());
Chris@16 1089 get_catalog_name_inst() = name;
Chris@16 1090 return result;
Chris@16 1091 }
Chris@16 1092
Chris@16 1093 template <class charT>
Chris@16 1094 std::string& cpp_regex_traits<charT>::get_catalog_name_inst()
Chris@16 1095 {
Chris@16 1096 static std::string s_name;
Chris@16 1097 return s_name;
Chris@16 1098 }
Chris@16 1099
Chris@16 1100 template <class charT>
Chris@16 1101 std::string cpp_regex_traits<charT>::get_catalog_name()
Chris@16 1102 {
Chris@16 1103 #ifdef BOOST_HAS_THREADS
Chris@16 1104 static_mutex::scoped_lock lk(get_mutex_inst());
Chris@16 1105 #endif
Chris@16 1106 std::string result(get_catalog_name_inst());
Chris@16 1107 return result;
Chris@16 1108 }
Chris@16 1109
Chris@16 1110 #ifdef BOOST_HAS_THREADS
Chris@16 1111 template <class charT>
Chris@16 1112 static_mutex& cpp_regex_traits<charT>::get_mutex_inst()
Chris@16 1113 {
Chris@16 1114 static static_mutex s_mutex = BOOST_STATIC_MUTEX_INIT;
Chris@16 1115 return s_mutex;
Chris@16 1116 }
Chris@16 1117 #endif
Chris@16 1118
Chris@16 1119
Chris@16 1120 } // boost
Chris@16 1121
Chris@16 1122 #ifdef BOOST_MSVC
Chris@16 1123 #pragma warning(pop)
Chris@16 1124 #endif
Chris@16 1125
Chris@16 1126 #ifdef BOOST_MSVC
Chris@16 1127 #pragma warning(push)
Chris@16 1128 #pragma warning(disable: 4103)
Chris@16 1129 #endif
Chris@16 1130 #ifdef BOOST_HAS_ABI_HEADERS
Chris@16 1131 # include BOOST_ABI_SUFFIX
Chris@16 1132 #endif
Chris@16 1133 #ifdef BOOST_MSVC
Chris@16 1134 #pragma warning(pop)
Chris@16 1135 #endif
Chris@16 1136
Chris@16 1137 #endif
Chris@16 1138
Chris@16 1139 #endif
Chris@16 1140
Chris@16 1141