LCOV - code coverage report
Current view: top level - usr/include/boost/regex/v4 - cpp_regex_traits.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 31 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 8 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14