/*
 *
 * Copyright (c) 2004
 * John Maddock
 *
 * 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         icu.hpp
  *   VERSION      see <ndnboost/version.hpp>
  *   DESCRIPTION: Unicode regular expressions on top of the ICU Library.
  */

#ifndef NDNBOOST_REGEX_ICU_HPP
#define NDNBOOST_REGEX_ICU_HPP

#include <unicode/utypes.h>
#include <unicode/uchar.h>
#include <unicode/coll.h>
#include <ndnboost/regex.hpp>
#include <ndnboost/regex/pending/unicode_iterator.hpp>
#include <ndnboost/mpl/int_fwd.hpp>
#include <bitset>

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

namespace ndnboost{

namespace re_detail{

// 
// Implementation details:
//
class NDNBOOST_REGEX_DECL icu_regex_traits_implementation
{
   typedef UChar32                      char_type;
   typedef std::size_t                  size_type;
   typedef std::vector<char_type>       string_type;
   typedef U_NAMESPACE_QUALIFIER Locale locale_type;
   typedef ndnboost::uint_least32_t        char_class_type;
public:
   icu_regex_traits_implementation(const U_NAMESPACE_QUALIFIER Locale& l)
      : m_locale(l)
   {
      UErrorCode success = U_ZERO_ERROR;
      m_collator.reset(U_NAMESPACE_QUALIFIER Collator::createInstance(l, success));
      if(U_SUCCESS(success) == 0)
         init_error();
      m_collator->setStrength(U_NAMESPACE_QUALIFIER Collator::IDENTICAL);
      success = U_ZERO_ERROR;
      m_primary_collator.reset(U_NAMESPACE_QUALIFIER Collator::createInstance(l, success));
      if(U_SUCCESS(success) == 0)
         init_error();
      m_primary_collator->setStrength(U_NAMESPACE_QUALIFIER Collator::PRIMARY);
   }
   U_NAMESPACE_QUALIFIER Locale getloc()const
   {
      return m_locale;
   }
   string_type do_transform(const char_type* p1, const char_type* p2, const U_NAMESPACE_QUALIFIER Collator* pcoll) const;
   string_type transform(const char_type* p1, const char_type* p2) const
   {
      return do_transform(p1, p2, m_collator.get());
   }
   string_type transform_primary(const char_type* p1, const char_type* p2) const
   {
      return do_transform(p1, p2, m_primary_collator.get());
   }
private:
   void init_error()
   {
      std::runtime_error e("Could not initialize ICU resources");
      ndnboost::throw_exception(e);
   }
   U_NAMESPACE_QUALIFIER Locale m_locale;                                  // The ICU locale that we're using
   ndnboost::scoped_ptr< U_NAMESPACE_QUALIFIER Collator> m_collator;          // The full collation object
   ndnboost::scoped_ptr< U_NAMESPACE_QUALIFIER Collator> m_primary_collator;  // The primary collation object
};

inline ndnboost::shared_ptr<icu_regex_traits_implementation> get_icu_regex_traits_implementation(const U_NAMESPACE_QUALIFIER Locale& loc)
{
   return ndnboost::shared_ptr<icu_regex_traits_implementation>(new icu_regex_traits_implementation(loc));
}

}

class NDNBOOST_REGEX_DECL icu_regex_traits
{
public:
   typedef UChar32                      char_type;
   typedef std::size_t                  size_type;
   typedef std::vector<char_type>       string_type;
   typedef U_NAMESPACE_QUALIFIER Locale locale_type;
#ifdef NDNBOOST_NO_INT64_T
   typedef std::bitset<64>              char_class_type;
#else
   typedef ndnboost::uint64_t              char_class_type;
#endif

   struct boost_extensions_tag{};

   icu_regex_traits()
      : m_pimpl(re_detail::get_icu_regex_traits_implementation(U_NAMESPACE_QUALIFIER Locale()))
   {
   }
   static size_type length(const char_type* p);

   ::ndnboost::regex_constants::syntax_type syntax_type(char_type c)const
   {
      return ((c < 0x7f) && (c > 0)) ? re_detail::get_default_syntax_type(static_cast<char>(c)) : regex_constants::syntax_char;
   }
   ::ndnboost::regex_constants::escape_syntax_type escape_syntax_type(char_type c) const
   {
      return ((c < 0x7f) && (c > 0)) ? re_detail::get_default_escape_syntax_type(static_cast<char>(c)) : regex_constants::syntax_char;
   }
   char_type translate(char_type c) const
   {
      return c;
   }
   char_type translate_nocase(char_type c) const
   {
      return ::u_tolower(c);
   }
   char_type translate(char_type c, bool icase) const
   {
      return icase ? translate_nocase(c) : translate(c);
   }
   char_type tolower(char_type c) const
   {
      return ::u_tolower(c);
   }
   char_type toupper(char_type c) const
   {
      return ::u_toupper(c);
   }
   string_type transform(const char_type* p1, const char_type* p2) const
   {
      return m_pimpl->transform(p1, p2);
   }
   string_type transform_primary(const char_type* p1, const char_type* p2) const
   {
      return m_pimpl->transform_primary(p1, p2);
   }
   char_class_type lookup_classname(const char_type* p1, const char_type* p2) const;
   string_type lookup_collatename(const char_type* p1, const char_type* p2) const;
   bool isctype(char_type c, char_class_type f) const;
   int toi(const char_type*& p1, const char_type* p2, int radix)const
   {
      return re_detail::global_toi(p1, p2, radix, *this);
   }
   int value(char_type c, int radix)const
   {
      return u_digit(c, static_cast< ::int8_t>(radix));
   }
   locale_type imbue(locale_type l)
   {
      locale_type result(m_pimpl->getloc());
      m_pimpl = re_detail::get_icu_regex_traits_implementation(l);
      return result;
   }
   locale_type getloc()const
   {
      return locale_type();
   }
   std::string error_string(::ndnboost::regex_constants::error_type n) const
   {
      return re_detail::get_default_error_string(n);
   }
private:
   icu_regex_traits(const icu_regex_traits&);
   icu_regex_traits& operator=(const icu_regex_traits&);

   //
   // define the bitmasks offsets we need for additional character properties:
   //
   enum{
      offset_blank = U_CHAR_CATEGORY_COUNT,
      offset_space = U_CHAR_CATEGORY_COUNT+1,
      offset_xdigit = U_CHAR_CATEGORY_COUNT+2,
      offset_underscore = U_CHAR_CATEGORY_COUNT+3,
      offset_unicode = U_CHAR_CATEGORY_COUNT+4,
      offset_any = U_CHAR_CATEGORY_COUNT+5,
      offset_ascii = U_CHAR_CATEGORY_COUNT+6,
      offset_horizontal = U_CHAR_CATEGORY_COUNT+7,
      offset_vertical = U_CHAR_CATEGORY_COUNT+8
   };

   //
   // and now the masks:
   //
   static const char_class_type mask_blank;
   static const char_class_type mask_space;
   static const char_class_type mask_xdigit;
   static const char_class_type mask_underscore;
   static const char_class_type mask_unicode;
   static const char_class_type mask_any;
   static const char_class_type mask_ascii;
   static const char_class_type mask_horizontal;
   static const char_class_type mask_vertical;

   static char_class_type lookup_icu_mask(const ::UChar32* p1, const ::UChar32* p2);

   ndnboost::shared_ptr< ::ndnboost::re_detail::icu_regex_traits_implementation> m_pimpl;
};

} // namespace ndnboost

//
// template instances:
//
#define NDNBOOST_REGEX_CHAR_T UChar32
#undef NDNBOOST_REGEX_TRAITS_T
#define NDNBOOST_REGEX_TRAITS_T , icu_regex_traits
#define NDNBOOST_REGEX_ICU_INSTANCES
#ifdef NDNBOOST_REGEX_ICU_INSTANTIATE
#  define NDNBOOST_REGEX_INSTANTIATE
#endif
#include <ndnboost/regex/v4/instances.hpp>
#undef NDNBOOST_REGEX_CHAR_T
#undef NDNBOOST_REGEX_TRAITS_T
#undef NDNBOOST_REGEX_ICU_INSTANCES
#ifdef NDNBOOST_REGEX_INSTANTIATE
#  undef NDNBOOST_REGEX_INSTANTIATE
#endif

namespace ndnboost{

// types:
typedef basic_regex< ::UChar32, icu_regex_traits> u32regex;
typedef match_results<const ::UChar32*> u32match;
typedef match_results<const ::UChar*> u16match;

//
// Construction of 32-bit regex types from UTF-8 and UTF-16 primitives:
//
namespace re_detail{

#if !defined(NDNBOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
template <class InputIterator>
inline u32regex do_make_u32regex(InputIterator i, 
                              InputIterator j, 
                              ndnboost::regex_constants::syntax_option_type opt, 
                              const ndnboost::mpl::int_<1>*)
{
   typedef ndnboost::u8_to_u32_iterator<InputIterator, UChar32> conv_type;
   return u32regex(conv_type(i, i, j), conv_type(j, i, j), opt);
}

template <class InputIterator>
inline u32regex do_make_u32regex(InputIterator i, 
                              InputIterator j, 
                              ndnboost::regex_constants::syntax_option_type opt, 
                              const ndnboost::mpl::int_<2>*)
{
   typedef ndnboost::u16_to_u32_iterator<InputIterator, UChar32> conv_type;
   return u32regex(conv_type(i, i, j), conv_type(j, i, j), opt);
}

template <class InputIterator>
inline u32regex do_make_u32regex(InputIterator i, 
                              InputIterator j, 
                              ndnboost::regex_constants::syntax_option_type opt, 
                              const ndnboost::mpl::int_<4>*)
{
   return u32regex(i, j, opt);
}
#else
template <class InputIterator>
inline u32regex do_make_u32regex(InputIterator i, 
                              InputIterator j, 
                              ndnboost::regex_constants::syntax_option_type opt, 
                              const ndnboost::mpl::int_<1>*)
{
   typedef ndnboost::u8_to_u32_iterator<InputIterator, UChar32> conv_type;
   typedef std::vector<UChar32> vector_type;
   vector_type v;
   conv_type a(i, i, j), b(j, i, j);
   while(a != b)
   {
      v.push_back(*a);
      ++a;
   }
   if(v.size())
      return u32regex(&*v.begin(), v.size(), opt);
   return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
}

template <class InputIterator>
inline u32regex do_make_u32regex(InputIterator i, 
                              InputIterator j, 
                              ndnboost::regex_constants::syntax_option_type opt, 
                              const ndnboost::mpl::int_<2>*)
{
   typedef ndnboost::u16_to_u32_iterator<InputIterator, UChar32> conv_type;
   typedef std::vector<UChar32> vector_type;
   vector_type v;
   conv_type a(i, i, j), b(j, i, j);
   while(a != b)
   {
      v.push_back(*a);
      ++a;
   }
   if(v.size())
      return u32regex(&*v.begin(), v.size(), opt);
   return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
}

template <class InputIterator>
inline u32regex do_make_u32regex(InputIterator i, 
                              InputIterator j, 
                              ndnboost::regex_constants::syntax_option_type opt, 
                              const ndnboost::mpl::int_<4>*)
{
   typedef std::vector<UChar32> vector_type;
   vector_type v;
   while(i != j)
   {
      v.push_back((UChar32)(*i));
      ++i;
   }
   if(v.size())
      return u32regex(&*v.begin(), v.size(), opt);
   return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
}
#endif
}

//
// Construction from an iterator pair:
//
template <class InputIterator>
inline u32regex make_u32regex(InputIterator i, 
                              InputIterator j, 
                              ndnboost::regex_constants::syntax_option_type opt)
{
   return re_detail::do_make_u32regex(i, j, opt, static_cast<ndnboost::mpl::int_<sizeof(*i)> const*>(0));
}
//
// construction from UTF-8 nul-terminated strings:
//
inline u32regex make_u32regex(const char* p, ndnboost::regex_constants::syntax_option_type opt = ndnboost::regex_constants::perl)
{
   return re_detail::do_make_u32regex(p, p + std::strlen(p), opt, static_cast<ndnboost::mpl::int_<1> const*>(0));
}
inline u32regex make_u32regex(const unsigned char* p, ndnboost::regex_constants::syntax_option_type opt = ndnboost::regex_constants::perl)
{
   return re_detail::do_make_u32regex(p, p + std::strlen(reinterpret_cast<const char*>(p)), opt, static_cast<ndnboost::mpl::int_<1> const*>(0));
}
//
// construction from UTF-16 nul-terminated strings:
//
#ifndef NDNBOOST_NO_WREGEX
inline u32regex make_u32regex(const wchar_t* p, ndnboost::regex_constants::syntax_option_type opt = ndnboost::regex_constants::perl)
{
   return re_detail::do_make_u32regex(p, p + std::wcslen(p), opt, static_cast<ndnboost::mpl::int_<sizeof(wchar_t)> const*>(0));
}
#endif
#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2)
inline u32regex make_u32regex(const UChar* p, ndnboost::regex_constants::syntax_option_type opt = ndnboost::regex_constants::perl)
{
   return re_detail::do_make_u32regex(p, p + u_strlen(p), opt, static_cast<ndnboost::mpl::int_<2> const*>(0));
}
#endif
//
// construction from basic_string class-template:
//
template<class C, class T, class A>
inline u32regex make_u32regex(const std::basic_string<C, T, A>& s, ndnboost::regex_constants::syntax_option_type opt = ndnboost::regex_constants::perl)
{
   return re_detail::do_make_u32regex(s.begin(), s.end(), opt, static_cast<ndnboost::mpl::int_<sizeof(C)> const*>(0));
}
//
// Construction from ICU string type:
//
inline u32regex make_u32regex(const U_NAMESPACE_QUALIFIER UnicodeString& s, ndnboost::regex_constants::syntax_option_type opt = ndnboost::regex_constants::perl)
{
   return re_detail::do_make_u32regex(s.getBuffer(), s.getBuffer() + s.length(), opt, static_cast<ndnboost::mpl::int_<2> const*>(0));
}

//
// regex_match overloads that widen the character type as appropriate:
//
namespace re_detail{
template<class MR1, class MR2>
void copy_results(MR1& out, MR2 const& in)
{
   // copy results from an adapted MR2 match_results:
   out.set_size(in.size(), in.prefix().first.base(), in.suffix().second.base());
   out.set_base(in.base().base());
   for(int i = 0; i < (int)in.size(); ++i)
   {
      if(in[i].matched)
      {
         out.set_first(in[i].first.base(), i);
         out.set_second(in[i].second.base(), i);
      }
   }
}

template <class BidiIterator, class Allocator>
inline bool do_regex_match(BidiIterator first, BidiIterator last, 
                 match_results<BidiIterator, Allocator>& m, 
                 const u32regex& e, 
                 match_flag_type flags,
                 ndnboost::mpl::int_<4> const*)
{
   return ::ndnboost::regex_match(first, last, m, e, flags);
}
template <class BidiIterator, class Allocator>
bool do_regex_match(BidiIterator first, BidiIterator last, 
                 match_results<BidiIterator, Allocator>& m, 
                 const u32regex& e, 
                 match_flag_type flags,
                 ndnboost::mpl::int_<2> const*)
{
   typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;
   typedef match_results<conv_type>                   match_type;
   //typedef typename match_type::allocator_type        alloc_type;
   match_type what;
   bool result = ::ndnboost::regex_match(conv_type(first, first, last), conv_type(last, first, last), what, e, flags);
   // copy results across to m:
   if(result) copy_results(m, what);
   return result;
}
template <class BidiIterator, class Allocator>
bool do_regex_match(BidiIterator first, BidiIterator last, 
                 match_results<BidiIterator, Allocator>& m, 
                 const u32regex& e, 
                 match_flag_type flags,
                 ndnboost::mpl::int_<1> const*)
{
   typedef u8_to_u32_iterator<BidiIterator, UChar32>  conv_type;
   typedef match_results<conv_type>                   match_type;
   //typedef typename match_type::allocator_type        alloc_type;
   match_type what;
   bool result = ::ndnboost::regex_match(conv_type(first, first, last), conv_type(last, first, last), what, e, flags);
   // copy results across to m:
   if(result) copy_results(m, what);
   return result;
}
} // namespace re_detail

template <class BidiIterator, class Allocator>
inline bool u32regex_match(BidiIterator first, BidiIterator last, 
                 match_results<BidiIterator, Allocator>& m, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   return re_detail::do_regex_match(first, last, m, e, flags, static_cast<mpl::int_<sizeof(*first)> const*>(0));
}
inline bool u32regex_match(const UChar* p, 
                 match_results<const UChar*>& m, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   return re_detail::do_regex_match(p, p+u_strlen(p), m, e, flags, static_cast<mpl::int_<2> const*>(0));
}
#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(NDNBOOST_NO_WREGEX)
inline bool u32regex_match(const wchar_t* p, 
                 match_results<const wchar_t*>& m, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   return re_detail::do_regex_match(p, p+std::wcslen(p), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
}
#endif
inline bool u32regex_match(const char* p, 
                 match_results<const char*>& m, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   return re_detail::do_regex_match(p, p+std::strlen(p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
}
inline bool u32regex_match(const unsigned char* p, 
                 match_results<const unsigned char*>& m, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   return re_detail::do_regex_match(p, p+std::strlen((const char*)p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
}
inline bool u32regex_match(const std::string& s, 
                        match_results<std::string::const_iterator>& m, 
                        const u32regex& e, 
                        match_flag_type flags = match_default)
{
   return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<1> const*>(0));
}
#ifndef NDNBOOST_NO_STD_WSTRING
inline bool u32regex_match(const std::wstring& s, 
                        match_results<std::wstring::const_iterator>& m, 
                        const u32regex& e, 
                        match_flag_type flags = match_default)
{
   return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
}
#endif
inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s, 
                        match_results<const UChar*>& m, 
                        const u32regex& e, 
                        match_flag_type flags = match_default)
{
   return re_detail::do_regex_match(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
}
//
// regex_match overloads that do not return what matched:
//
template <class BidiIterator>
inline bool u32regex_match(BidiIterator first, BidiIterator last, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   match_results<BidiIterator> m;
   return re_detail::do_regex_match(first, last, m, e, flags, static_cast<mpl::int_<sizeof(*first)> const*>(0));
}
inline bool u32regex_match(const UChar* p, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   match_results<const UChar*> m;
   return re_detail::do_regex_match(p, p+u_strlen(p), m, e, flags, static_cast<mpl::int_<2> const*>(0));
}
#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(NDNBOOST_NO_WREGEX)
inline bool u32regex_match(const wchar_t* p, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   match_results<const wchar_t*> m;
   return re_detail::do_regex_match(p, p+std::wcslen(p), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
}
#endif
inline bool u32regex_match(const char* p, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   match_results<const char*> m;
   return re_detail::do_regex_match(p, p+std::strlen(p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
}
inline bool u32regex_match(const unsigned char* p, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   match_results<const unsigned char*> m;
   return re_detail::do_regex_match(p, p+std::strlen((const char*)p), m, e, flags, static_cast<mpl::int_<1> const*>(0));
}
inline bool u32regex_match(const std::string& s, 
                        const u32regex& e, 
                        match_flag_type flags = match_default)
{
   match_results<std::string::const_iterator> m;
   return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<1> const*>(0));
}
#ifndef NDNBOOST_NO_STD_WSTRING
inline bool u32regex_match(const std::wstring& s, 
                        const u32regex& e, 
                        match_flag_type flags = match_default)
{
   match_results<std::wstring::const_iterator> m;
   return re_detail::do_regex_match(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
}
#endif
inline bool u32regex_match(const U_NAMESPACE_QUALIFIER UnicodeString& s, 
                        const u32regex& e, 
                        match_flag_type flags = match_default)
{
   match_results<const UChar*> m;
   return re_detail::do_regex_match(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
}

//
// regex_search overloads that widen the character type as appropriate:
//
namespace re_detail{
template <class BidiIterator, class Allocator>
inline bool do_regex_search(BidiIterator first, BidiIterator last, 
                 match_results<BidiIterator, Allocator>& m, 
                 const u32regex& e, 
                 match_flag_type flags,
                 BidiIterator base,
                 ndnboost::mpl::int_<4> const*)
{
   return ::ndnboost::regex_search(first, last, m, e, flags, base);
}
template <class BidiIterator, class Allocator>
bool do_regex_search(BidiIterator first, BidiIterator last, 
                 match_results<BidiIterator, Allocator>& m, 
                 const u32regex& e, 
                 match_flag_type flags,
                 BidiIterator base,
                 ndnboost::mpl::int_<2> const*)
{
   typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;
   typedef match_results<conv_type>                   match_type;
   //typedef typename match_type::allocator_type        alloc_type;
   match_type what;
   bool result = ::ndnboost::regex_search(conv_type(first, first, last), conv_type(last, first, last), what, e, flags, conv_type(base));
   // copy results across to m:
   if(result) copy_results(m, what);
   return result;
}
template <class BidiIterator, class Allocator>
bool do_regex_search(BidiIterator first, BidiIterator last, 
                 match_results<BidiIterator, Allocator>& m, 
                 const u32regex& e, 
                 match_flag_type flags,
                 BidiIterator base,
                 ndnboost::mpl::int_<1> const*)
{
   typedef u8_to_u32_iterator<BidiIterator, UChar32>  conv_type;
   typedef match_results<conv_type>                   match_type;
   //typedef typename match_type::allocator_type        alloc_type;
   match_type what;
   bool result = ::ndnboost::regex_search(conv_type(first, first, last), conv_type(last, first, last), what, e, flags, conv_type(base));
   // copy results across to m:
   if(result) copy_results(m, what);
   return result;
}
}

template <class BidiIterator, class Allocator>
inline bool u32regex_search(BidiIterator first, BidiIterator last, 
                 match_results<BidiIterator, Allocator>& m, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   return re_detail::do_regex_search(first, last, m, e, flags, first, static_cast<mpl::int_<sizeof(*first)> const*>(0));
}
template <class BidiIterator, class Allocator>
inline bool u32regex_search(BidiIterator first, BidiIterator last, 
                 match_results<BidiIterator, Allocator>& m, 
                 const u32regex& e, 
                 match_flag_type flags,
                 BidiIterator base)
{
   return re_detail::do_regex_search(first, last, m, e, flags, base, static_cast<mpl::int_<sizeof(*first)> const*>(0));
}
inline bool u32regex_search(const UChar* p, 
                 match_results<const UChar*>& m, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   return re_detail::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast<mpl::int_<2> const*>(0));
}
#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(NDNBOOST_NO_WREGEX)
inline bool u32regex_search(const wchar_t* p, 
                 match_results<const wchar_t*>& m, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   return re_detail::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
}
#endif
inline bool u32regex_search(const char* p, 
                 match_results<const char*>& m, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   return re_detail::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
}
inline bool u32regex_search(const unsigned char* p, 
                 match_results<const unsigned char*>& m, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   return re_detail::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
}
inline bool u32regex_search(const std::string& s, 
                        match_results<std::string::const_iterator>& m, 
                        const u32regex& e, 
                        match_flag_type flags = match_default)
{
   return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<1> const*>(0));
}
#ifndef NDNBOOST_NO_STD_WSTRING
inline bool u32regex_search(const std::wstring& s, 
                        match_results<std::wstring::const_iterator>& m, 
                        const u32regex& e, 
                        match_flag_type flags = match_default)
{
   return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
}
#endif
inline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s, 
                        match_results<const UChar*>& m, 
                        const u32regex& e, 
                        match_flag_type flags = match_default)
{
   return re_detail::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
}
template <class BidiIterator>
inline bool u32regex_search(BidiIterator first, BidiIterator last, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   match_results<BidiIterator> m;
   return re_detail::do_regex_search(first, last, m, e, flags, first, static_cast<mpl::int_<sizeof(*first)> const*>(0));
}
inline bool u32regex_search(const UChar* p, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   match_results<const UChar*> m;
   return re_detail::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast<mpl::int_<2> const*>(0));
}
#if !defined(U_WCHAR_IS_UTF16) && (U_SIZEOF_WCHAR_T != 2) && !defined(NDNBOOST_NO_WREGEX)
inline bool u32regex_search(const wchar_t* p, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   match_results<const wchar_t*> m;
   return re_detail::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
}
#endif
inline bool u32regex_search(const char* p, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   match_results<const char*> m;
   return re_detail::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
}
inline bool u32regex_search(const unsigned char* p, 
                 const u32regex& e, 
                 match_flag_type flags = match_default)
{
   match_results<const unsigned char*> m;
   return re_detail::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
}
inline bool u32regex_search(const std::string& s, 
                        const u32regex& e, 
                        match_flag_type flags = match_default)
{
   match_results<std::string::const_iterator> m;
   return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<1> const*>(0));
}
#ifndef NDNBOOST_NO_STD_WSTRING
inline bool u32regex_search(const std::wstring& s, 
                        const u32regex& e, 
                        match_flag_type flags = match_default)
{
   match_results<std::wstring::const_iterator> m;
   return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
}
#endif
inline bool u32regex_search(const U_NAMESPACE_QUALIFIER UnicodeString& s, 
                        const u32regex& e, 
                        match_flag_type flags = match_default)
{
   match_results<const UChar*> m;
   return re_detail::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
}

//
// overloads for regex_replace with utf-8 and utf-16 data types:
//
namespace re_detail{
template <class I>
inline std::pair< ndnboost::u8_to_u32_iterator<I>, ndnboost::u8_to_u32_iterator<I> >
   make_utf32_seq(I i, I j, mpl::int_<1> const*)
{
   return std::pair< ndnboost::u8_to_u32_iterator<I>, ndnboost::u8_to_u32_iterator<I> >(ndnboost::u8_to_u32_iterator<I>(i, i, j), ndnboost::u8_to_u32_iterator<I>(j, i, j));
}
template <class I>
inline std::pair< ndnboost::u16_to_u32_iterator<I>, ndnboost::u16_to_u32_iterator<I> >
   make_utf32_seq(I i, I j, mpl::int_<2> const*)
{
   return std::pair< ndnboost::u16_to_u32_iterator<I>, ndnboost::u16_to_u32_iterator<I> >(ndnboost::u16_to_u32_iterator<I>(i, i, j), ndnboost::u16_to_u32_iterator<I>(j, i, j));
}
template <class I>
inline std::pair< I, I >
   make_utf32_seq(I i, I j, mpl::int_<4> const*)
{
   return std::pair< I, I >(i, j);
}
template <class charT>
inline std::pair< ndnboost::u8_to_u32_iterator<const charT*>, ndnboost::u8_to_u32_iterator<const charT*> >
   make_utf32_seq(const charT* p, mpl::int_<1> const*)
{
   std::size_t len = std::strlen((const char*)p);
   return std::pair< ndnboost::u8_to_u32_iterator<const charT*>, ndnboost::u8_to_u32_iterator<const charT*> >(ndnboost::u8_to_u32_iterator<const charT*>(p, p, p+len), ndnboost::u8_to_u32_iterator<const charT*>(p+len, p, p+len));
}
template <class charT>
inline std::pair< ndnboost::u16_to_u32_iterator<const charT*>, ndnboost::u16_to_u32_iterator<const charT*> >
   make_utf32_seq(const charT* p, mpl::int_<2> const*)
{
   std::size_t len = u_strlen((const UChar*)p);
   return std::pair< ndnboost::u16_to_u32_iterator<const charT*>, ndnboost::u16_to_u32_iterator<const charT*> >(ndnboost::u16_to_u32_iterator<const charT*>(p, p, p + len), ndnboost::u16_to_u32_iterator<const charT*>(p+len, p, p + len));
}
template <class charT>
inline std::pair< const charT*, const charT* >
   make_utf32_seq(const charT* p, mpl::int_<4> const*)
{
   return std::pair< const charT*, const charT* >(p, p+icu_regex_traits::length((UChar32 const*)p));
}
template <class OutputIterator>
inline OutputIterator make_utf32_out(OutputIterator o, mpl::int_<4> const*)
{
   return o;
}
template <class OutputIterator>
inline utf16_output_iterator<OutputIterator> make_utf32_out(OutputIterator o, mpl::int_<2> const*)
{
   return o;
}
template <class OutputIterator>
inline utf8_output_iterator<OutputIterator> make_utf32_out(OutputIterator o, mpl::int_<1> const*)
{
   return o;
}

template <class OutputIterator, class I1, class I2>
OutputIterator do_regex_replace(OutputIterator out,
                                 std::pair<I1, I1> const& in,
                                 const u32regex& e, 
                                 const std::pair<I2, I2>& fmt, 
                                 match_flag_type flags
                                 )
{
   // unfortunately we have to copy the format string in order to pass in onward:
   std::vector<UChar32> f;
#ifndef NDNBOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
   f.assign(fmt.first, fmt.second);
#else
   f.clear();
   I2 pos = fmt.first;
   while(pos != fmt.second)
      f.push_back(*pos++);
#endif
   
   regex_iterator<I1, UChar32, icu_regex_traits> i(in.first, in.second, e, flags);
   regex_iterator<I1, UChar32, icu_regex_traits> j;
   if(i == j)
   {
      if(!(flags & regex_constants::format_no_copy))
         out = re_detail::copy(in.first, in.second, out);
   }
   else
   {
      I1 last_m = in.first;
      while(i != j)
      {
         if(!(flags & regex_constants::format_no_copy))
            out = re_detail::copy(i->prefix().first, i->prefix().second, out); 
         if(f.size())
            out = ::ndnboost::re_detail::regex_format_imp(out, *i, &*f.begin(), &*f.begin() + f.size(), flags, e.get_traits());
         else
            out = ::ndnboost::re_detail::regex_format_imp(out, *i, static_cast<UChar32 const*>(0), static_cast<UChar32 const*>(0), flags, e.get_traits());
         last_m = (*i)[0].second;
         if(flags & regex_constants::format_first_only)
            break;
         ++i;
      }
      if(!(flags & regex_constants::format_no_copy))
         out = re_detail::copy(last_m, in.second, out);
   }
   return out;
}
template <class BaseIterator>
inline const BaseIterator& extract_output_base(const BaseIterator& b)
{
   return b;
}
template <class BaseIterator>
inline BaseIterator extract_output_base(const utf8_output_iterator<BaseIterator>& b)
{
   return b.base();
}
template <class BaseIterator>
inline BaseIterator extract_output_base(const utf16_output_iterator<BaseIterator>& b)
{
   return b.base();
}
}  // re_detail

template <class OutputIterator, class BidirectionalIterator, class charT>
inline OutputIterator u32regex_replace(OutputIterator out,
                         BidirectionalIterator first,
                         BidirectionalIterator last,
                         const u32regex& e, 
                         const charT* fmt, 
                         match_flag_type flags = match_default)
{
   return re_detail::extract_output_base
#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
   <OutputIterator>
#endif
    (
      re_detail::do_regex_replace(
         re_detail::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
         re_detail::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
         e,
         re_detail::make_utf32_seq(fmt, static_cast<mpl::int_<sizeof(*fmt)> const*>(0)),
         flags)
      );
}

template <class OutputIterator, class Iterator, class charT>
inline OutputIterator u32regex_replace(OutputIterator out,
                         Iterator first,
                         Iterator last,
                         const u32regex& e, 
                         const std::basic_string<charT>& fmt,
                         match_flag_type flags = match_default)
{
   return re_detail::extract_output_base
#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
   <OutputIterator>
#endif
    (
      re_detail::do_regex_replace(
         re_detail::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
         re_detail::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
         e,
         re_detail::make_utf32_seq(fmt.begin(), fmt.end(), static_cast<mpl::int_<sizeof(charT)> const*>(0)),
         flags)
      );
}

template <class OutputIterator, class Iterator>
inline OutputIterator u32regex_replace(OutputIterator out,
                         Iterator first,
                         Iterator last,
                         const u32regex& e, 
                         const U_NAMESPACE_QUALIFIER UnicodeString& fmt,
                         match_flag_type flags = match_default)
{
   return re_detail::extract_output_base
#if NDNBOOST_WORKAROUND(NDNBOOST_MSVC, <= 1300)
   <OutputIterator>
#endif
   (
      re_detail::do_regex_replace(
         re_detail::make_utf32_out(out, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
         re_detail::make_utf32_seq(first, last, static_cast<mpl::int_<sizeof(*first)> const*>(0)),
         e,
         re_detail::make_utf32_seq(fmt.getBuffer(), fmt.getBuffer() + fmt.length(), static_cast<mpl::int_<2> const*>(0)),
         flags)
      );
}

template <class charT>
std::basic_string<charT> u32regex_replace(const std::basic_string<charT>& s,
                         const u32regex& e, 
                         const charT* fmt,
                         match_flag_type flags = match_default)
{
   std::basic_string<charT> result;
   re_detail::string_out_iterator<std::basic_string<charT> > i(result);
   u32regex_replace(i, s.begin(), s.end(), e, fmt, flags);
   return result;
}

template <class charT>
std::basic_string<charT> u32regex_replace(const std::basic_string<charT>& s,
                         const u32regex& e, 
                         const std::basic_string<charT>& fmt,
                         match_flag_type flags = match_default)
{
   std::basic_string<charT> result;
   re_detail::string_out_iterator<std::basic_string<charT> > i(result);
   u32regex_replace(i, s.begin(), s.end(), e, fmt.c_str(), flags);
   return result;
}

namespace re_detail{

class unicode_string_out_iterator
{
   U_NAMESPACE_QUALIFIER UnicodeString* out;
public:
   unicode_string_out_iterator(U_NAMESPACE_QUALIFIER UnicodeString& s) : out(&s) {}
   unicode_string_out_iterator& operator++() { return *this; }
   unicode_string_out_iterator& operator++(int) { return *this; }
   unicode_string_out_iterator& operator*() { return *this; }
   unicode_string_out_iterator& operator=(UChar v) 
   { 
      *out += v; 
      return *this; 
   }
   typedef std::ptrdiff_t difference_type;
   typedef UChar value_type;
   typedef value_type* pointer;
   typedef value_type& reference;
   typedef std::output_iterator_tag iterator_category;
};

}

inline U_NAMESPACE_QUALIFIER UnicodeString u32regex_replace(const U_NAMESPACE_QUALIFIER UnicodeString& s,
                         const u32regex& e, 
                         const UChar* fmt,
                         match_flag_type flags = match_default)
{
   U_NAMESPACE_QUALIFIER UnicodeString result;
   re_detail::unicode_string_out_iterator i(result);
   u32regex_replace(i, s.getBuffer(), s.getBuffer()+s.length(), e, fmt, flags);
   return result;
}

inline U_NAMESPACE_QUALIFIER UnicodeString u32regex_replace(const U_NAMESPACE_QUALIFIER UnicodeString& s,
                         const u32regex& e, 
                         const U_NAMESPACE_QUALIFIER UnicodeString& fmt,
                         match_flag_type flags = match_default)
{
   U_NAMESPACE_QUALIFIER UnicodeString result;
   re_detail::unicode_string_out_iterator i(result);
   re_detail::do_regex_replace(
         re_detail::make_utf32_out(i, static_cast<mpl::int_<2> const*>(0)),
         re_detail::make_utf32_seq(s.getBuffer(), s.getBuffer()+s.length(), static_cast<mpl::int_<2> const*>(0)),
         e,
         re_detail::make_utf32_seq(fmt.getBuffer(), fmt.getBuffer() + fmt.length(), static_cast<mpl::int_<2> const*>(0)),
         flags);
   return result;
}

} // namespace ndnboost.

#ifdef NDNBOOST_MSVC
#pragma warning (pop)
#endif

#include <ndnboost/regex/v4/u32regex_iterator.hpp>
#include <ndnboost/regex/v4/u32regex_token_iterator.hpp>

#endif
