/*
 *
 * Copyright (c) 2004 John Maddock
 * Copyright 2011 Garmin Ltd. or its subsidiaries
 *
 * Use, modification and distribution are subject to the 
 * Boost Software License, Version 1.0. (See accompanying file 
 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 *
 */
 
 /*
  *   LOCATION:    see http://www.boost.org for most recent version.
  *   FILE         cpp_regex_traits.hpp
  *   VERSION      see <ndnboost/version.hpp>
  *   DESCRIPTION: Declares regular expression traits class cpp_regex_traits.
  */

#ifndef NDNBOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
#define NDNBOOST_CPP_REGEX_TRAITS_HPP_INCLUDED

#include <ndnboost/config.hpp>
#include <ndnboost/integer.hpp>

#ifndef NDNBOOST_NO_STD_LOCALE

#ifndef NDNBOOST_RE_PAT_EXCEPT_HPP
#include <ndnboost/regex/pattern_except.hpp>
#endif
#ifndef NDNBOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
#include <ndnboost/regex/v4/regex_traits_defaults.hpp>
#endif
#ifdef NDNBOOST_HAS_THREADS
#include <ndnboost/regex/pending/static_mutex.hpp>
#endif
#ifndef NDNBOOST_REGEX_PRIMARY_TRANSFORM
#include <ndnboost/regex/v4/primary_transform.hpp>
#endif
#ifndef NDNBOOST_REGEX_OBJECT_CACHE_HPP
#include <ndnboost/regex/pending/object_cache.hpp>
#endif

#include <istream>
#include <ios>
#include <climits>

#ifdef NDNBOOST_MSVC
#pragma warning(push)
#pragma warning(disable: 4103)
#endif
#ifdef NDNBOOST_HAS_ABI_HEADERS
#  include NDNBOOST_ABI_PREFIX
#endif
#ifdef NDNBOOST_MSVC
#pragma warning(pop)
#endif

#ifdef NDNBOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4786 4251)
#endif

namespace ndnboost{ 

//
// forward declaration is needed by some compilers:
//
template <class charT>
class cpp_regex_traits;
   
namespace re_detail{

//
// class parser_buf:
// acts as a stream buffer which wraps around a pair of pointers:
//
template <class charT,
          class traits = ::std::char_traits<charT> >
class parser_buf : public ::std::basic_streambuf<charT, traits>
{
   typedef ::std::basic_streambuf<charT, traits> base_type;
   typedef typename base_type::int_type int_type;
   typedef typename base_type::char_type char_type;
   typedef typename base_type::pos_type pos_type;
   typedef ::std::streamsize streamsize;
   typedef typename base_type::off_type off_type;
public:
   parser_buf() : base_type() { setbuf(0, 0); }
   const charT* getnext() { return this->gptr(); }
protected:
   std::basic_streambuf<charT, traits>* setbuf(char_type* s, streamsize n);
   typename parser_buf<charT, traits>::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which);
   typename parser_buf<charT, traits>::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which);
private:
   parser_buf& operator=(const parser_buf&);
   parser_buf(const parser_buf&);
};

template<class charT, class traits>
std::basic_streambuf<charT, traits>*
parser_buf<charT, traits>::setbuf(char_type* s, streamsize n)
{
   this->setg(s, s, s + n);
   return this;
}

template<class charT, class traits>
typename parser_buf<charT, traits>::pos_type
parser_buf<charT, traits>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)
{
   typedef typename ndnboost::int_t<sizeof(way) * CHAR_BIT>::least cast_type;

   if(which & ::std::ios_base::out)
      return pos_type(off_type(-1));
   std::ptrdiff_t size = this->egptr() - this->eback();
   std::ptrdiff_t pos = this->gptr() - this->eback();
   charT* g = this->eback();
   switch(static_cast<cast_type>(way))
   {
   case ::std::ios_base::beg:
      if((off < 0) || (off > size))
         return pos_type(off_type(-1));
      else
         this->setg(g, g + off, g + size);
      break;
   case ::std::ios_base::end:
      if((off < 0) || (off > size))
         return pos_type(off_type(-1));
      else
         this->setg(g, g + size - off, g + size);
      break;
   case ::std::ios_base::cur:
   {
      std::ptrdiff_t newpos = static_cast<std::ptrdiff_t>(pos + off);
      if((newpos < 0) || (newpos > size))
         return pos_type(off_type(-1));
      else
         this->setg(g, g + newpos, g + size);
      break;
   }
   default: ;
   }
#ifdef NDNBOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4244)
#endif
   return static_cast<pos_type>(this->gptr() - this->eback());
#ifdef NDNBOOST_MSVC
#pragma warning(pop)
#endif
}

template<class charT, class traits>
typename parser_buf<charT, traits>::pos_type
parser_buf<charT, traits>::seekpos(pos_type sp, ::std::ios_base::openmode which)
{
   if(which & ::std::ios_base::out)
      return pos_type(off_type(-1));
   off_type size = static_cast<off_type>(this->egptr() - this->eback());
   charT* g = this->eback();
   if(off_type(sp) <= size)
   {
      this->setg(g, g + off_type(sp), g + size);
   }
   return pos_type(off_type(-1));
}

//
// class cpp_regex_traits_base:
// acts as a container for locale and the facets we are using.
//
template <class charT>
struct cpp_regex_traits_base
{
   cpp_regex_traits_base(const std::locale& l)
   { imbue(l); }
   std::locale imbue(const std::locale& l);

   std::locale m_locale;
   std::ctype<charT> const* m_pctype;
#ifndef NDNBOOST_NO_STD_MESSAGES
   std::messages<charT> const* m_pmessages;
#endif
   std::collate<charT> const* m_pcollate;

   bool operator<(const cpp_regex_traits_base& b)const
   {
      if(m_pctype == b.m_pctype)
      {
#ifndef NDNBOOST_NO_STD_MESSAGES
         if(m_pmessages == b.m_pmessages)
         {
            return m_pcollate < b.m_pcollate;
         }
         return m_pmessages < b.m_pmessages;
#else
         return m_pcollate < b.m_pcollate;
#endif
      }
      return m_pctype < b.m_pctype;
   }
   bool operator==(const cpp_regex_traits_base& b)const
   {
      return (m_pctype == b.m_pctype) 
#ifndef NDNBOOST_NO_STD_MESSAGES
         && (m_pmessages == b.m_pmessages) 
#endif
         && (m_pcollate == b.m_pcollate);
   }
};

template <class charT>
std::locale cpp_regex_traits_base<charT>::imbue(const std::locale& l)
{
   std::locale result(m_locale);
   m_locale = l;
   m_pctype = &NDNBOOST_USE_FACET(std::ctype<charT>, l);
#ifndef NDNBOOST_NO_STD_MESSAGES
   m_pmessages = NDNBOOST_HAS_FACET(std::messages<charT>, l) ? &NDNBOOST_USE_FACET(std::messages<charT>, l) : 0;
#endif
   m_pcollate = &NDNBOOST_USE_FACET(std::collate<charT>, l);
   return result;
}

//
// class cpp_regex_traits_char_layer:
// implements methods that require specialisation for narrow characters:
//
template <class charT>
class cpp_regex_traits_char_layer : public cpp_regex_traits_base<charT>
{
   typedef std::basic_string<charT> string_type;
   typedef std::map<charT, regex_constants::syntax_type> map_type;
   typedef typename map_type::const_iterator map_iterator_type;
public:
   cpp_regex_traits_char_layer(const std::locale& l)
      : cpp_regex_traits_base<charT>(l)
   {
      init();
   }
   cpp_regex_traits_char_layer(const cpp_regex_traits_base<charT>& b)
      : cpp_regex_traits_base<charT>(b)
   {
      init();
   }
   void init();

   regex_constants::syntax_type syntax_type(charT c)const
   {
      map_iterator_type i = m_char_map.find(c);
      return ((i == m_char_map.end()) ? 0 : i->second);
   }
   regex_constants::escape_syntax_type escape_syntax_type(charT c) const
   {
      map_iterator_type i = m_char_map.find(c);
      if(i == m_char_map.end())
      {
         if(this->m_pctype->is(std::ctype_base::lower, c)) return regex_constants::escape_type_class;
         if(this->m_pctype->is(std::ctype_base::upper, c)) return regex_constants::escape_type_not_class;
         return 0;
      }
      return i->second;
   }

private:
   string_type get_default_message(regex_constants::syntax_type);
   // TODO: use a hash table when available!
   map_type m_char_map;
};

template <class charT>
void cpp_regex_traits_char_layer<charT>::init()
{
   // we need to start by initialising our syntax map so we know which
   // character is used for which purpose:
#ifndef NDNBOOST_NO_STD_MESSAGES
#ifndef __IBMCPP__
   typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
#else
   typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
#endif
   std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
   if(cat_name.size() && (this->m_pmessages != 0))
   {
      cat = this->m_pmessages->open(
         cat_name, 
         this->m_locale);
      if((int)cat < 0)
      {
         std::string m("Unable to open message catalog: ");
         std::runtime_error err(m + cat_name);
         ndnboost::re_detail::raise_runtime_error(err);
      }
   }
   //
   // if we have a valid catalog then load our messages:
   //
   if((int)cat >= 0)
   {
#ifndef NDNBOOST_NO_EXCEPTIONS
      try{
#endif
         for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
         {
            string_type mss = this->m_pmessages->get(cat, 0, i, get_default_message(i));
            for(typename string_type::size_type j = 0; j < mss.size(); ++j)
            {
               m_char_map[mss[j]] = i;
            }
         }
         this->m_pmessages->close(cat);
#ifndef NDNBOOST_NO_EXCEPTIONS
      }
      catch(...)
      {
         if(this->m_pmessages)
            this->m_pmessages->close(cat);
         throw;
      }
#endif
   }
   else
   {
#endif
      for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
      {
         const char* ptr = get_default_syntax(i);
         while(ptr && *ptr)
         {
            m_char_map[this->m_pctype->widen(*ptr)] = i;
            ++ptr;
         }
      }
#ifndef NDNBOOST_NO_STD_MESSAGES
   }
#endif
}

template <class charT>
typename cpp_regex_traits_char_layer<charT>::string_type 
   cpp_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
{
   const char* ptr = get_default_syntax(i);
   string_type result;
   while(ptr && *ptr)
   {
      result.append(1, this->m_pctype->widen(*ptr));
      ++ptr;
   }
   return result;
}

//
// specialised version for narrow characters:
//
template <>
class NDNBOOST_REGEX_DECL cpp_regex_traits_char_layer<char> : public cpp_regex_traits_base<char>
{
   typedef std::string string_type;
public:
   cpp_regex_traits_char_layer(const std::locale& l)
   : cpp_regex_traits_base<char>(l)
   {
      init();
   }
   cpp_regex_traits_char_layer(const cpp_regex_traits_base<char>& l)
   : cpp_regex_traits_base<char>(l)
   {
      init();
   }

   regex_constants::syntax_type syntax_type(char c)const
   {
      return m_char_map[static_cast<unsigned char>(c)];
   }
   regex_constants::escape_syntax_type escape_syntax_type(char c) const
   {
      return m_char_map[static_cast<unsigned char>(c)];
   }

private:
   regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
   void init();
};

#ifdef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
enum
{
   char_class_space=1<<0, 
   char_class_print=1<<1, 
   char_class_cntrl=1<<2, 
   char_class_upper=1<<3, 
   char_class_lower=1<<4,
   char_class_alpha=1<<5, 
   char_class_digit=1<<6, 
   char_class_punct=1<<7, 
   char_class_xdigit=1<<8,
   char_class_alnum=char_class_alpha|char_class_digit, 
   char_class_graph=char_class_alnum|char_class_punct,
   char_class_blank=1<<9,
   char_class_word=1<<10,
   char_class_unicode=1<<11,
   char_class_horizontal_space=1<<12,
   char_class_vertical_space=1<<13
};

#endif

//
// class cpp_regex_traits_implementation:
// provides pimpl implementation for cpp_regex_traits.
//
template <class charT>
class cpp_regex_traits_implementation : public cpp_regex_traits_char_layer<charT>
{
public:
   typedef typename cpp_regex_traits<charT>::char_class_type char_class_type;
   typedef typename std::ctype<charT>::mask                  native_mask_type;
#ifndef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_blank = 1u << 24);
   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_word = 1u << 25);
   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_unicode = 1u << 26);
   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_horizontal = 1u << 27);
   NDNBOOST_STATIC_CONSTANT(char_class_type, mask_vertical = 1u << 28);
#endif

   typedef std::basic_string<charT> string_type;
   typedef charT char_type;
   //cpp_regex_traits_implementation();
   cpp_regex_traits_implementation(const std::locale& l)
      : cpp_regex_traits_char_layer<charT>(l)
   {
      init();
   }
   cpp_regex_traits_implementation(const cpp_regex_traits_base<charT>& l)
      : cpp_regex_traits_char_layer<charT>(l)
   {
      init();
   }
   std::string error_string(regex_constants::error_type n) const
   {
      if(!m_error_strings.empty())
      {
         std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
         return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
      }
      return get_default_error_string(n);
   }
   char_class_type lookup_classname(const charT* p1, const charT* p2) const
   {
      char_class_type result = lookup_classname_imp(p1, p2);
      if(result == 0)
      {
         string_type temp(p1, p2);
         this->m_pctype->tolower(&*temp.begin(), &*temp.begin() + temp.size());
         result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
      }
      return result;
   }
   string_type lookup_collatename(const charT* p1, const charT* p2) const;
   string_type transform_primary(const charT* p1, const charT* p2) const;
   string_type transform(const charT* p1, const charT* p2) const;
private:
   std::map<int, std::string>     m_error_strings;   // error messages indexed by numberic ID
   std::map<string_type, char_class_type>  m_custom_class_names; // character class names
   std::map<string_type, string_type>      m_custom_collate_names; // collating element names
   unsigned                       m_collate_type;    // the form of the collation string
   charT                          m_collate_delim;   // the collation group delimiter
   //
   // helpers:
   //
   char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
   void init();
#ifdef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
public:
   bool isctype(charT c, char_class_type m)const;
#endif
};

#ifndef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
#if !defined(NDNBOOST_NO_INCLASS_MEMBER_INITIALIZATION)

template <class charT>
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_blank;
template <class charT>
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_word;
template <class charT>
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_unicode;
template <class charT>
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_vertical;
template <class charT>
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_horizontal;

#endif
#endif

template <class charT>
typename cpp_regex_traits_implementation<charT>::string_type 
   cpp_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
{
   //
   // PRECONDITIONS:
   //
   // A bug in gcc 3.2 (and maybe other versions as well) treats
   // p1 as a null terminated string, for efficiency reasons 
   // we work around this elsewhere, but just assert here that
   // we adhere to gcc's (buggy) preconditions...
   //
   NDNBOOST_ASSERT(*p2 == 0);

   string_type result;
   //
   // swallowing all exceptions here is a bad idea
   // however at least one std lib will always throw
   // std::bad_alloc for certain arguments...
   //
#ifndef NDNBOOST_NO_EXCEPTIONS
   try{
#endif
      //
      // What we do here depends upon the format of the sort key returned by
      // sort key returned by this->transform:
      //
      switch(m_collate_type)
      {
      case sort_C:
      case sort_unknown:
         // the best we can do is translate to lower case, then get a regular sort key:
         {
            result.assign(p1, p2);
            this->m_pctype->tolower(&*result.begin(), &*result.begin() + result.size());
            result = this->m_pcollate->transform(&*result.begin(), &*result.begin() + result.size());
            break;
         }
      case sort_fixed:
         {
            // get a regular sort key, and then truncate it:
            result.assign(this->m_pcollate->transform(p1, p2));
            result.erase(this->m_collate_delim);
            break;
         }
      case sort_delim:
            // get a regular sort key, and then truncate everything after the delim:
            result.assign(this->m_pcollate->transform(p1, p2));
            std::size_t i;
            for(i = 0; i < result.size(); ++i)
            {
               if(result[i] == m_collate_delim)
                  break;
            }
            result.erase(i);
            break;
      }
#ifndef NDNBOOST_NO_EXCEPTIONS
   }catch(...){}
#endif
   while(result.size() && (charT(0) == *result.rbegin()))
      result.erase(result.size() - 1);
   if(result.empty())
   {
      // character is ignorable at the primary level:
      result = string_type(1, charT(0));
   }
   return result;
}

template <class charT>
typename cpp_regex_traits_implementation<charT>::string_type 
   cpp_regex_traits_implementation<charT>::transform(const charT* p1, const charT* p2) const
{
   //
   // PRECONDITIONS:
   //
   // A bug in gcc 3.2 (and maybe other versions as well) treats
   // p1 as a null terminated string, for efficiency reasons 
   // we work around this elsewhere, but just assert here that
   // we adhere to gcc's (buggy) preconditions...
   //
   NDNBOOST_ASSERT(*p2 == 0);
   //
   // swallowing all exceptions here is a bad idea
   // however at least one std lib will always throw
   // std::bad_alloc for certain arguments...
   //
   string_type result;
#ifndef NDNBOOST_NO_EXCEPTIONS
   try{
#endif
      result = this->m_pcollate->transform(p1, p2);
      //
      // Borland's STLPort version returns a NULL-terminated
      // string that has garbage at the end - each call to
      // std::collate<wchar_t>::transform returns a different string!
      // So as a workaround, we'll truncate the string at the first NULL
      // which _seems_ to work....
#if NDNBOOST_WORKAROUND(__BORLANDC__, < 0x580)
      result.erase(result.find(charT(0)));
#else
      //
      // some implementations (Dinkumware) append unnecessary trailing \0's:
      while(result.size() && (charT(0) == *result.rbegin()))
         result.erase(result.size() - 1);
#endif
      NDNBOOST_ASSERT(std::find(result.begin(), result.end(), charT(0)) == result.end());
#ifndef NDNBOOST_NO_EXCEPTIONS
   }
   catch(...)
   {
   }
#endif
   return result;
}


template <class charT>
typename cpp_regex_traits_implementation<charT>::string_type 
   cpp_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
{
   typedef typename std::map<string_type, string_type>::const_iterator iter_type;
   if(m_custom_collate_names.size())
   {
      iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
      if(pos != m_custom_collate_names.end())
         return pos->second;
   }
#if !defined(NDNBOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
               && !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)\
               && !NDNBOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
   std::string name(p1, p2);
#else
   std::string name;
   const charT* p0 = p1;
   while(p0 != p2)
      name.append(1, char(*p0++));
#endif
   name = lookup_default_collate_name(name);
#if !defined(NDNBOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
               && !NDNBOOST_WORKAROUND(NDNBOOST_MSVC, < 1300)\
               && !NDNBOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
   if(name.size())
      return string_type(name.begin(), name.end());
#else
   if(name.size())
   {
      string_type result;
      typedef std::string::const_iterator iter;
      iter b = name.begin();
      iter e = name.end();
      while(b != e)
         result.append(1, charT(*b++));
      return result;
   }
#endif
   if(p2 - p1 == 1)
      return string_type(1, *p1);
   return string_type();
}

template <class charT>
void cpp_regex_traits_implementation<charT>::init()
{
#ifndef NDNBOOST_NO_STD_MESSAGES
#ifndef __IBMCPP__
   typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
#else
   typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
#endif
   std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
   if(cat_name.size() && (this->m_pmessages != 0))
   {
      cat = this->m_pmessages->open(
         cat_name, 
         this->m_locale);
      if((int)cat < 0)
      {
         std::string m("Unable to open message catalog: ");
         std::runtime_error err(m + cat_name);
         ndnboost::re_detail::raise_runtime_error(err);
      }
   }
   //
   // if we have a valid catalog then load our messages:
   //
   if((int)cat >= 0)
   {
      //
      // Error messages:
      //
      for(ndnboost::regex_constants::error_type i = static_cast<ndnboost::regex_constants::error_type>(0); 
         i <= ndnboost::regex_constants::error_unknown; 
         i = static_cast<ndnboost::regex_constants::error_type>(i + 1))
      {
         const char* p = get_default_error_string(i);
         string_type default_message;
         while(*p)
         {
            default_message.append(1, this->m_pctype->widen(*p));
            ++p;
         }
         string_type s = this->m_pmessages->get(cat, 0, i+200, default_message);
         std::string result;
         for(std::string::size_type j = 0; j < s.size(); ++j)
         {
            result.append(1, this->m_pctype->narrow(s[j], 0));
         }
         m_error_strings[i] = result;
      }
      //
      // Custom class names:
      //
#ifndef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
      static const char_class_type masks[16] = 
      {
         std::ctype<charT>::alnum,
         std::ctype<charT>::alpha,
         std::ctype<charT>::cntrl,
         std::ctype<charT>::digit,
         std::ctype<charT>::graph,
         cpp_regex_traits_implementation<charT>::mask_horizontal,
         std::ctype<charT>::lower,
         std::ctype<charT>::print,
         std::ctype<charT>::punct,
         std::ctype<charT>::space,
         std::ctype<charT>::upper,
         cpp_regex_traits_implementation<charT>::mask_vertical,
         std::ctype<charT>::xdigit,
         cpp_regex_traits_implementation<charT>::mask_blank,
         cpp_regex_traits_implementation<charT>::mask_word,
         cpp_regex_traits_implementation<charT>::mask_unicode,
      };
#else
      static const char_class_type masks[16] = 
      {
         ::ndnboost::re_detail::char_class_alnum,
         ::ndnboost::re_detail::char_class_alpha,
         ::ndnboost::re_detail::char_class_cntrl,
         ::ndnboost::re_detail::char_class_digit,
         ::ndnboost::re_detail::char_class_graph,
         ::ndnboost::re_detail::char_class_horizontal_space,
         ::ndnboost::re_detail::char_class_lower,
         ::ndnboost::re_detail::char_class_print,
         ::ndnboost::re_detail::char_class_punct,
         ::ndnboost::re_detail::char_class_space,
         ::ndnboost::re_detail::char_class_upper,
         ::ndnboost::re_detail::char_class_vertical_space,
         ::ndnboost::re_detail::char_class_xdigit,
         ::ndnboost::re_detail::char_class_blank,
         ::ndnboost::re_detail::char_class_word,
         ::ndnboost::re_detail::char_class_unicode,
      };
#endif
      static const string_type null_string;
      for(unsigned int j = 0; j <= 13; ++j)
      {
         string_type s(this->m_pmessages->get(cat, 0, j+300, null_string));
         if(s.size())
            this->m_custom_class_names[s] = masks[j];
      }
   }
#endif
   //
   // get the collation format used by m_pcollate:
   //
   m_collate_type = re_detail::find_sort_syntax(this, &m_collate_delim);
}

template <class charT>
typename cpp_regex_traits_implementation<charT>::char_class_type 
   cpp_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const
{
#ifndef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
   static const char_class_type masks[22] = 
   {
      0,
      std::ctype<char>::alnum, 
      std::ctype<char>::alpha,
      cpp_regex_traits_implementation<charT>::mask_blank,
      std::ctype<char>::cntrl,
      std::ctype<char>::digit,
      std::ctype<char>::digit,
      std::ctype<char>::graph,
      cpp_regex_traits_implementation<charT>::mask_horizontal,
      std::ctype<char>::lower,
      std::ctype<char>::lower,
      std::ctype<char>::print,
      std::ctype<char>::punct,
      std::ctype<char>::space,
      std::ctype<char>::space,
      std::ctype<char>::upper,
      cpp_regex_traits_implementation<charT>::mask_unicode,
      std::ctype<char>::upper,
      cpp_regex_traits_implementation<charT>::mask_vertical,
      std::ctype<char>::alnum | cpp_regex_traits_implementation<charT>::mask_word, 
      std::ctype<char>::alnum | cpp_regex_traits_implementation<charT>::mask_word, 
      std::ctype<char>::xdigit,
   };
#else
   static const char_class_type masks[22] = 
   {
      0,
      ::ndnboost::re_detail::char_class_alnum, 
      ::ndnboost::re_detail::char_class_alpha,
      ::ndnboost::re_detail::char_class_blank,
      ::ndnboost::re_detail::char_class_cntrl,
      ::ndnboost::re_detail::char_class_digit,
      ::ndnboost::re_detail::char_class_digit,
      ::ndnboost::re_detail::char_class_graph,
      ::ndnboost::re_detail::char_class_horizontal_space,
      ::ndnboost::re_detail::char_class_lower,
      ::ndnboost::re_detail::char_class_lower,
      ::ndnboost::re_detail::char_class_print,
      ::ndnboost::re_detail::char_class_punct,
      ::ndnboost::re_detail::char_class_space,
      ::ndnboost::re_detail::char_class_space,
      ::ndnboost::re_detail::char_class_upper,
      ::ndnboost::re_detail::char_class_unicode,
      ::ndnboost::re_detail::char_class_upper,
      ::ndnboost::re_detail::char_class_vertical_space,
      ::ndnboost::re_detail::char_class_alnum | ::ndnboost::re_detail::char_class_word, 
      ::ndnboost::re_detail::char_class_alnum | ::ndnboost::re_detail::char_class_word, 
      ::ndnboost::re_detail::char_class_xdigit,
   };
#endif
   if(m_custom_class_names.size())
   {
      typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;
      map_iter pos = m_custom_class_names.find(string_type(p1, p2));
      if(pos != m_custom_class_names.end())
         return pos->second;
   }
   std::size_t state_id = 1 + re_detail::get_default_class_id(p1, p2);
   NDNBOOST_ASSERT(state_id < sizeof(masks) / sizeof(masks[0]));
   return masks[state_id];
}

#ifdef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
template <class charT>
bool cpp_regex_traits_implementation<charT>::isctype(const charT c, char_class_type mask) const
{
   return
      ((mask & ::ndnboost::re_detail::char_class_space) && (this->m_pctype->is(std::ctype<charT>::space, c)))
      || ((mask & ::ndnboost::re_detail::char_class_print) && (this->m_pctype->is(std::ctype<charT>::print, c)))
      || ((mask & ::ndnboost::re_detail::char_class_cntrl) && (this->m_pctype->is(std::ctype<charT>::cntrl, c)))
      || ((mask & ::ndnboost::re_detail::char_class_upper) && (this->m_pctype->is(std::ctype<charT>::upper, c)))
      || ((mask & ::ndnboost::re_detail::char_class_lower) && (this->m_pctype->is(std::ctype<charT>::lower, c)))
      || ((mask & ::ndnboost::re_detail::char_class_alpha) && (this->m_pctype->is(std::ctype<charT>::alpha, c)))
      || ((mask & ::ndnboost::re_detail::char_class_digit) && (this->m_pctype->is(std::ctype<charT>::digit, c)))
      || ((mask & ::ndnboost::re_detail::char_class_punct) && (this->m_pctype->is(std::ctype<charT>::punct, c)))
      || ((mask & ::ndnboost::re_detail::char_class_xdigit) && (this->m_pctype->is(std::ctype<charT>::xdigit, c)))
      || ((mask & ::ndnboost::re_detail::char_class_blank) && (this->m_pctype->is(std::ctype<charT>::space, c)) && !::ndnboost::re_detail::is_separator(c))
      || ((mask & ::ndnboost::re_detail::char_class_word) && (c == '_'))
      || ((mask & ::ndnboost::re_detail::char_class_unicode) && ::ndnboost::re_detail::is_extended(c))
      || ((mask & ::ndnboost::re_detail::char_class_vertical_space) && (is_separator(c) || (c == '\v')))
      || ((mask & ::ndnboost::re_detail::char_class_horizontal_space) && this->m_pctype->is(std::ctype<charT>::space, c) && !(is_separator(c) || (c == '\v')));
}
#endif


template <class charT>
inline ndnboost::shared_ptr<const cpp_regex_traits_implementation<charT> > create_cpp_regex_traits(const std::locale& l NDNBOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(charT))
{
   cpp_regex_traits_base<charT> key(l);
   return ::ndnboost::object_cache<cpp_regex_traits_base<charT>, cpp_regex_traits_implementation<charT> >::get(key, 5);
}

} // re_detail

template <class charT>
class cpp_regex_traits
{
private:
   typedef std::ctype<charT>            ctype_type;
public:
   typedef charT                        char_type;
   typedef std::size_t                  size_type;
   typedef std::basic_string<char_type> string_type;
   typedef std::locale                  locale_type;
   typedef ndnboost::uint_least32_t        char_class_type;

   struct boost_extensions_tag{};

   cpp_regex_traits()
      : m_pimpl(re_detail::create_cpp_regex_traits<charT>(std::locale()))
   { }
   static size_type length(const char_type* p)
   {
      return std::char_traits<charT>::length(p);
   }
   regex_constants::syntax_type syntax_type(charT c)const
   {
      return m_pimpl->syntax_type(c);
   }
   regex_constants::escape_syntax_type escape_syntax_type(charT c) const
   {
      return m_pimpl->escape_syntax_type(c);
   }
   charT translate(charT c) const
   {
      return c;
   }
   charT translate_nocase(charT c) const
   {
      return m_pimpl->m_pctype->tolower(c);
   }
   charT translate(charT c, bool icase) const
   {
      return icase ? m_pimpl->m_pctype->tolower(c) : c;
   }
   charT tolower(charT c) const
   {
      return m_pimpl->m_pctype->tolower(c);
   }
   charT toupper(charT c) const
   {
      return m_pimpl->m_pctype->toupper(c);
   }
   string_type transform(const charT* p1, const charT* p2) const
   {
      return m_pimpl->transform(p1, p2);
   }
   string_type transform_primary(const charT* p1, const charT* p2) const
   {
      return m_pimpl->transform_primary(p1, p2);
   }
   char_class_type lookup_classname(const charT* p1, const charT* p2) const
   {
      return m_pimpl->lookup_classname(p1, p2);
   }
   string_type lookup_collatename(const charT* p1, const charT* p2) const
   {
      return m_pimpl->lookup_collatename(p1, p2);
   }
   bool isctype(charT c, char_class_type f) const
   {
#ifndef NDNBOOST_REGEX_BUGGY_CTYPE_FACET
      typedef typename std::ctype<charT>::mask ctype_mask;

      static const ctype_mask mask_base = 
         static_cast<ctype_mask>(
            std::ctype<charT>::alnum 
            | std::ctype<charT>::alpha
            | std::ctype<charT>::cntrl
            | std::ctype<charT>::digit
            | std::ctype<charT>::graph
            | std::ctype<charT>::lower
            | std::ctype<charT>::print
            | std::ctype<charT>::punct
            | std::ctype<charT>::space
            | std::ctype<charT>::upper
            | std::ctype<charT>::xdigit);

      if((f & mask_base) 
         && (m_pimpl->m_pctype->is(
            static_cast<ctype_mask>(f & mask_base), c)))
         return true;
      else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_unicode) && re_detail::is_extended(c))
         return true;
      else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_word) && (c == '_'))
         return true;
      else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_blank) 
         && m_pimpl->m_pctype->is(std::ctype<charT>::space, c)
         && !re_detail::is_separator(c))
         return true;
      else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_vertical) 
         && (::ndnboost::re_detail::is_separator(c) || (c == '\v')))
         return true;
      else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_horizontal) 
         && this->isctype(c, std::ctype<charT>::space) && !this->isctype(c, re_detail::cpp_regex_traits_implementation<charT>::mask_vertical))
         return true;
      return false;
#else
      return m_pimpl->isctype(c, f);
#endif
   }
   int toi(const charT*& p1, const charT* p2, int radix)const;
   int value(charT c, int radix)const
   {
      const charT* pc = &c;
      return toi(pc, pc + 1, radix);
   }
   locale_type imbue(locale_type l)
   {
      std::locale result(getloc());
      m_pimpl = re_detail::create_cpp_regex_traits<charT>(l);
      return result;
   }
   locale_type getloc()const
   {
      return m_pimpl->m_locale;
   }
   std::string error_string(regex_constants::error_type n) const
   {
      return m_pimpl->error_string(n);
   }

   //
   // extension:
   // set the name of the message catalog in use (defaults to "boost_regex").
   //
   static std::string catalog_name(const std::string& name);
   static std::string get_catalog_name();

private:
   ndnboost::shared_ptr<const re_detail::cpp_regex_traits_implementation<charT> > m_pimpl;
   //
   // catalog name handler:
   //
   static std::string& get_catalog_name_inst();

#ifdef NDNBOOST_HAS_THREADS
   static static_mutex& get_mutex_inst();
#endif
};


template <class charT>
int cpp_regex_traits<charT>::toi(const charT*& first, const charT* last, int radix)const
{
   re_detail::parser_buf<charT>   sbuf;            // buffer for parsing numbers.
   std::basic_istream<charT>      is(&sbuf);       // stream for parsing numbers.

   // we do NOT want to parse any thousands separators inside the stream:
   last = std::find(first, last, NDNBOOST_USE_FACET(std::numpunct<charT>, is.getloc()).thousands_sep());

   sbuf.pubsetbuf(const_cast<charT*>(static_cast<const charT*>(first)), static_cast<std::streamsize>(last-first));
   is.clear();
   if(std::abs(radix) == 16) is >> std::hex;
   else if(std::abs(radix) == 8) is >> std::oct;
   else is >> std::dec;
   int val;
   if(is >> val)
   {
      first = first + ((last - first) - sbuf.in_avail());
      return val;
   }
   else
      return -1;
}

template <class charT>
std::string cpp_regex_traits<charT>::catalog_name(const std::string& name)
{
#ifdef NDNBOOST_HAS_THREADS
   static_mutex::scoped_lock lk(get_mutex_inst());
#endif
   std::string result(get_catalog_name_inst());
   get_catalog_name_inst() = name;
   return result;
}

template <class charT>
std::string& cpp_regex_traits<charT>::get_catalog_name_inst()
{
   static std::string s_name;
   return s_name;
}

template <class charT>
std::string cpp_regex_traits<charT>::get_catalog_name()
{
#ifdef NDNBOOST_HAS_THREADS
   static_mutex::scoped_lock lk(get_mutex_inst());
#endif
   std::string result(get_catalog_name_inst());
   return result;
}

#ifdef NDNBOOST_HAS_THREADS
template <class charT>
static_mutex& cpp_regex_traits<charT>::get_mutex_inst()
{
   static static_mutex s_mutex = NDNBOOST_STATIC_MUTEX_INIT;
   return s_mutex;
}
#endif


} // boost

#ifdef NDNBOOST_MSVC
#pragma warning(pop)
#endif

#ifdef NDNBOOST_MSVC
#pragma warning(push)
#pragma warning(disable: 4103)
#endif
#ifdef NDNBOOST_HAS_ABI_HEADERS
#  include NDNBOOST_ABI_SUFFIX
#endif
#ifdef NDNBOOST_MSVC
#pragma warning(pop)
#endif

#endif

#endif


