/*
 *
 * Copyright (c) 1998-2009
 * 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         match_results.cpp
  *   VERSION      see <ndnboost/version.hpp>
  *   DESCRIPTION: Declares template class match_results.
  */

#ifndef NDNBOOST_REGEX_V4_MATCH_RESULTS_HPP
#define NDNBOOST_REGEX_V4_MATCH_RESULTS_HPP

#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

namespace ndnboost{
#ifdef NDNBOOST_MSVC
#pragma warning(push)
#pragma warning(disable : 4251 4231)
#  if NDNBOOST_MSVC < 1600
#     pragma warning(disable : 4660)
#  endif
#endif

namespace re_detail{

class named_subexpressions;

}

template <class BidiIterator, class Allocator>
class match_results
{ 
private:
#ifndef NDNBOOST_NO_STD_ALLOCATOR
   typedef          std::vector<sub_match<BidiIterator>, Allocator> vector_type;
#else
   typedef          std::vector<sub_match<BidiIterator> >           vector_type;
#endif
public: 
   typedef          sub_match<BidiIterator>                         value_type;
#if  !defined(NDNBOOST_NO_STD_ALLOCATOR) && !(defined(NDNBOOST_MSVC) && defined(_STLPORT_VERSION))
   typedef typename Allocator::const_reference                              const_reference;
#else
   typedef          const value_type&                                       const_reference;
#endif
   typedef          const_reference                                         reference;
   typedef typename vector_type::const_iterator                             const_iterator;
   typedef          const_iterator                                          iterator;
   typedef typename re_detail::regex_iterator_traits<
                                    BidiIterator>::difference_type          difference_type;
   typedef typename Allocator::size_type                                    size_type;
   typedef          Allocator                                               allocator_type;
   typedef typename re_detail::regex_iterator_traits<
                                    BidiIterator>::value_type               char_type;
   typedef          std::basic_string<char_type>                            string_type;
   typedef          re_detail::named_subexpressions                         named_sub_type;

   // construct/copy/destroy:
   explicit match_results(const Allocator& a = Allocator())
#ifndef NDNBOOST_NO_STD_ALLOCATOR
      : m_subs(a), m_base(), m_last_closed_paren(0), m_is_singular(true) {}
#else
      : m_subs(), m_base(), m_last_closed_paren(0), m_is_singular(true) { (void)a; }
#endif
   match_results(const match_results& m)
      : m_subs(m.m_subs), m_named_subs(m.m_named_subs), m_last_closed_paren(m.m_last_closed_paren), m_is_singular(m.m_is_singular) 
   {
      if(!m_is_singular)
      {
         m_base = m.m_base;
         m_null = m.m_null;
      }
   }
   match_results& operator=(const match_results& m)
   {
      m_subs = m.m_subs;
      m_named_subs = m.m_named_subs;
      m_last_closed_paren = m.m_last_closed_paren;
      m_is_singular = m.m_is_singular;
      if(!m_is_singular)
      {
         m_base = m.m_base;
         m_null = m.m_null;
      }
      return *this;
   }
   ~match_results(){}

   // size:
   size_type size() const
   { return empty() ? 0 : m_subs.size() - 2; }
   size_type max_size() const
   { return m_subs.max_size(); }
   bool empty() const
   { return m_subs.size() < 2; }
   // element access:
   difference_type length(int sub = 0) const
   {
      if(m_is_singular)
         raise_logic_error();
      sub += 2;
      if((sub < (int)m_subs.size()) && (sub > 0))
         return m_subs[sub].length();
      return 0;
   }
   difference_type length(const char_type* sub) const
   {
      if(m_is_singular)
         raise_logic_error();
      const char_type* sub_end = sub;
      while(*sub_end) ++sub_end;
      return length(named_subexpression_index(sub, sub_end));
   }
   template <class charT>
   difference_type length(const charT* sub) const
   {
      if(m_is_singular)
         raise_logic_error();
      const charT* sub_end = sub;
      while(*sub_end) ++sub_end;
      return length(named_subexpression_index(sub, sub_end));
   }
   template <class charT, class Traits, class A>
   difference_type length(const std::basic_string<charT, Traits, A>& sub) const
   {
      return length(sub.c_str());
   }
   difference_type position(size_type sub = 0) const
   {
      if(m_is_singular)
         raise_logic_error();
      sub += 2;
      if(sub < m_subs.size())
      {
         const sub_match<BidiIterator>& s = m_subs[sub];
         if(s.matched || (sub == 2))
         {
            return ::ndnboost::re_detail::distance((BidiIterator)(m_base), (BidiIterator)(s.first));
         }
      }
      return ~static_cast<difference_type>(0);
   }
   difference_type position(const char_type* sub) const
   {
      const char_type* sub_end = sub;
      while(*sub_end) ++sub_end;
      return position(named_subexpression_index(sub, sub_end));
   }
   template <class charT>
   difference_type position(const charT* sub) const
   {
      const charT* sub_end = sub;
      while(*sub_end) ++sub_end;
      return position(named_subexpression_index(sub, sub_end));
   }
   template <class charT, class Traits, class A>
   difference_type position(const std::basic_string<charT, Traits, A>& sub) const
   {
      return position(sub.c_str());
   }
   string_type str(int sub = 0) const
   {
      if(m_is_singular)
         raise_logic_error();
      sub += 2;
      string_type result;
      if(sub < (int)m_subs.size() && (sub > 0))
      {
         const sub_match<BidiIterator>& s = m_subs[sub];
         if(s.matched)
         {
            result = s.str();
         }
      }
      return result;
   }
   string_type str(const char_type* sub) const
   {
      return (*this)[sub].str();
   }
   template <class Traits, class A>
   string_type str(const std::basic_string<char_type, Traits, A>& sub) const
   {
      return (*this)[sub].str();
   }
   template <class charT>
   string_type str(const charT* sub) const
   {
      return (*this)[sub].str();
   }
   template <class charT, class Traits, class A>
   string_type str(const std::basic_string<charT, Traits, A>& sub) const
   {
      return (*this)[sub].str();
   }
   const_reference operator[](int sub) const
   {
      if(m_is_singular && m_subs.empty())
         raise_logic_error();
      sub += 2;
      if(sub < (int)m_subs.size() && (sub >= 0))
      {
         return m_subs[sub];
      }
      return m_null;
   }
   //
   // Named sub-expressions:
   //
   const_reference named_subexpression(const char_type* i, const char_type* j) const
   {
      //
      // Scan for the leftmost *matched* subexpression with the specified named:
      //
      if(m_is_singular)
         raise_logic_error();
      re_detail::named_subexpressions::range_type r = m_named_subs->equal_range(i, j);
      while((r.first != r.second) && ((*this)[r.first->index].matched == false))
         ++r.first;
      return r.first != r.second ? (*this)[r.first->index] : m_null;
   }
   template <class charT>
   const_reference named_subexpression(const charT* i, const charT* j) const
   {
      NDNBOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
      if(i == j)
         return m_null;
      std::vector<char_type> s;
      while(i != j)
         s.insert(s.end(), *i++);
      return named_subexpression(&*s.begin(), &*s.begin() + s.size());
   }
   int named_subexpression_index(const char_type* i, const char_type* j) const
   {
      //
      // Scan for the leftmost *matched* subexpression with the specified named.
      // If none found then return the leftmost expression with that name,
      // otherwise an invalid index:
      //
      if(m_is_singular)
         raise_logic_error();
      re_detail::named_subexpressions::range_type s, r;
      s = r = m_named_subs->equal_range(i, j);
      while((r.first != r.second) && ((*this)[r.first->index].matched == false))
         ++r.first;
      if(r.first == r.second)
         r = s;
      return r.first != r.second ? r.first->index : -20;
   }
   template <class charT>
   int named_subexpression_index(const charT* i, const charT* j) const
   {
      NDNBOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
      if(i == j)
         return -20;
      std::vector<char_type> s;
      while(i != j)
         s.insert(s.end(), *i++);
      return named_subexpression_index(&*s.begin(), &*s.begin() + s.size());
   }
   template <class Traits, class A>
   const_reference operator[](const std::basic_string<char_type, Traits, A>& s) const
   {
      return named_subexpression(s.c_str(), s.c_str() + s.size());
   }
   const_reference operator[](const char_type* p) const
   {
      const char_type* e = p;
      while(*e) ++e;
      return named_subexpression(p, e);
   }

   template <class charT>
   const_reference operator[](const charT* p) const
   {
      NDNBOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
      if(*p == 0)
         return m_null;
      std::vector<char_type> s;
      while(*p)
         s.insert(s.end(), *p++);
      return named_subexpression(&*s.begin(), &*s.begin() + s.size());
   }
   template <class charT, class Traits, class A>
   const_reference operator[](const std::basic_string<charT, Traits, A>& ns) const
   {
      NDNBOOST_STATIC_ASSERT(sizeof(charT) <= sizeof(char_type));
      if(ns.empty())
         return m_null;
      std::vector<char_type> s;
      for(unsigned i = 0; i < ns.size(); ++i)
         s.insert(s.end(), ns[i]);
      return named_subexpression(&*s.begin(), &*s.begin() + s.size());
   }

   const_reference prefix() const
   {
      if(m_is_singular)
         raise_logic_error();
      return (*this)[-1];
   }

   const_reference suffix() const
   {
      if(m_is_singular)
         raise_logic_error();
      return (*this)[-2];
   }
   const_iterator begin() const
   {
      return (m_subs.size() > 2) ? (m_subs.begin() + 2) : m_subs.end();
   }
   const_iterator end() const
   {
      return m_subs.end();
   }
   // format:
   template <class OutputIterator, class Functor>
   OutputIterator format(OutputIterator out,
                         Functor fmt,
                         match_flag_type flags = format_default) const
   {
      if(m_is_singular)
         raise_logic_error();
      typedef typename re_detail::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator>::type F;
      F func(fmt);
      return func(*this, out, flags);
   }
   template <class Functor>
   string_type format(Functor fmt, match_flag_type flags = format_default) const
   {
      if(m_is_singular)
         raise_logic_error();
      std::basic_string<char_type> result;
      re_detail::string_out_iterator<std::basic_string<char_type> > i(result);

      typedef typename re_detail::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, re_detail::string_out_iterator<std::basic_string<char_type> > >::type F;
      F func(fmt);

      func(*this, i, flags);
      return result;
   }
   // format with locale:
   template <class OutputIterator, class Functor, class RegexT>
   OutputIterator format(OutputIterator out,
                         Functor fmt,
                         match_flag_type flags,
                         const RegexT& re) const
   {
      if(m_is_singular)
         raise_logic_error();
      typedef ::ndnboost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;
      typedef typename re_detail::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, OutputIterator, traits_type>::type F;
      F func(fmt);
      return func(*this, out, flags, re.get_traits());
   }
   template <class RegexT, class Functor>
   string_type format(Functor fmt,
                      match_flag_type flags,
                      const RegexT& re) const
   {
      if(m_is_singular)
         raise_logic_error();
      typedef ::ndnboost::regex_traits_wrapper<typename RegexT::traits_type> traits_type;
      std::basic_string<char_type> result;
      re_detail::string_out_iterator<std::basic_string<char_type> > i(result);

      typedef typename re_detail::compute_functor_type<Functor, match_results<BidiIterator, Allocator>, re_detail::string_out_iterator<std::basic_string<char_type> >, traits_type >::type F;
      F func(fmt);

      func(*this, i, flags, re.get_traits());
      return result;
   }

   const_reference get_last_closed_paren()const
   {
      if(m_is_singular)
         raise_logic_error();
      return m_last_closed_paren == 0 ? m_null : (*this)[m_last_closed_paren];
   }

   allocator_type get_allocator() const
   {
#ifndef NDNBOOST_NO_STD_ALLOCATOR
      return m_subs.get_allocator();
#else
     return allocator_type();
#endif
   }
   void swap(match_results& that)
   {
      std::swap(m_subs, that.m_subs);
      std::swap(m_named_subs, that.m_named_subs);
      std::swap(m_last_closed_paren, that.m_last_closed_paren);
      if(m_is_singular)
      {
         if(!that.m_is_singular)
         {
            m_base = that.m_base;
            m_null = that.m_null;
         }
      }
      else if(that.m_is_singular)
      {
         that.m_base = m_base;
         that.m_null = m_null;
      }
      else
      {
         std::swap(m_base, that.m_base);
         std::swap(m_null, that.m_null);
      }
      std::swap(m_is_singular, that.m_is_singular);
   }
   bool operator==(const match_results& that)const
   {
      if(m_is_singular)
      {
         return that.m_is_singular;
      }
      else if(that.m_is_singular)
      {
         return false;
      }
      return (m_subs == that.m_subs) && (m_base == that.m_base) && (m_last_closed_paren == that.m_last_closed_paren);
   }
   bool operator!=(const match_results& that)const
   { return !(*this == that); }

#ifdef NDNBOOST_REGEX_MATCH_EXTRA
   typedef typename sub_match<BidiIterator>::capture_sequence_type capture_sequence_type;

   const capture_sequence_type& captures(int i)const
   {
      if(m_is_singular)
         raise_logic_error();
      return (*this)[i].captures();
   }
#endif

   //
   // private access functions:
   void NDNBOOST_REGEX_CALL set_second(BidiIterator i)
   {
      NDNBOOST_ASSERT(m_subs.size() > 2);
      m_subs[2].second = i;
      m_subs[2].matched = true;
      m_subs[0].first = i;
      m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
      m_null.first = i;
      m_null.second = i;
      m_null.matched = false;
      m_is_singular = false;
   }

   void NDNBOOST_REGEX_CALL set_second(BidiIterator i, size_type pos, bool m = true, bool escape_k = false)
   {
      if(pos)
         m_last_closed_paren = static_cast<int>(pos);
      pos += 2;
      NDNBOOST_ASSERT(m_subs.size() > pos);
      m_subs[pos].second = i;
      m_subs[pos].matched = m;
      if((pos == 2) && !escape_k)
      {
         m_subs[0].first = i;
         m_subs[0].matched = (m_subs[0].first != m_subs[0].second);
         m_null.first = i;
         m_null.second = i;
         m_null.matched = false;
         m_is_singular = false;
      }
   }
   void NDNBOOST_REGEX_CALL set_size(size_type n, BidiIterator i, BidiIterator j)
   {
      value_type v(j);
      size_type len = m_subs.size();
      if(len > n + 2)
      {
         m_subs.erase(m_subs.begin()+n+2, m_subs.end());
         std::fill(m_subs.begin(), m_subs.end(), v);
      }
      else
      {
         std::fill(m_subs.begin(), m_subs.end(), v);
         if(n+2 != len)
            m_subs.insert(m_subs.end(), n+2-len, v);
      }
      m_subs[1].first = i;
      m_last_closed_paren = 0;
   }
   void NDNBOOST_REGEX_CALL set_base(BidiIterator pos)
   {
      m_base = pos;
   }
   BidiIterator base()const
   {
      return m_base;
   }
   void NDNBOOST_REGEX_CALL set_first(BidiIterator i)
   {
      NDNBOOST_ASSERT(m_subs.size() > 2);
      // set up prefix:
      m_subs[1].second = i;
      m_subs[1].matched = (m_subs[1].first != i);
      // set up $0:
      m_subs[2].first = i;
      // zero out everything else:
      for(size_type n = 3; n < m_subs.size(); ++n)
      {
         m_subs[n].first = m_subs[n].second = m_subs[0].second;
         m_subs[n].matched = false;
      }
   }
   void NDNBOOST_REGEX_CALL set_first(BidiIterator i, size_type pos, bool escape_k = false)
   {
      NDNBOOST_ASSERT(pos+2 < m_subs.size());
      if(pos || escape_k)
      {
         m_subs[pos+2].first = i;
         if(escape_k)
         {
            m_subs[1].second = i;
            m_subs[1].matched = (m_subs[1].first != m_subs[1].second);
         }
      }
      else
         set_first(i);
   }
   void NDNBOOST_REGEX_CALL maybe_assign(const match_results<BidiIterator, Allocator>& m);

   void NDNBOOST_REGEX_CALL set_named_subs(ndnboost::shared_ptr<named_sub_type> subs)
   {
      m_named_subs = subs;
   }

private:
   //
   // Error handler called when an uninitialized match_results is accessed:
   //
   static void raise_logic_error()
   {
      std::logic_error e("Attempt to access an uninitialzed ndnboost::match_results<> class.");
      ndnboost::throw_exception(e);
   }


   vector_type            m_subs;                      // subexpressions
   BidiIterator   m_base;                              // where the search started from
   sub_match<BidiIterator> m_null;                     // a null match
   ndnboost::shared_ptr<named_sub_type> m_named_subs;     // Shared copy of named subs in the regex object
   int m_last_closed_paren;                            // Last ) to be seen - used for formatting
   bool m_is_singular;                                 // True if our stored iterators are singular
};

template <class BidiIterator, class Allocator>
void NDNBOOST_REGEX_CALL match_results<BidiIterator, Allocator>::maybe_assign(const match_results<BidiIterator, Allocator>& m)
{
   if(m_is_singular)
   {
      *this = m;
      return;
   }
   const_iterator p1, p2;
   p1 = begin();
   p2 = m.begin();
   //
   // Distances are measured from the start of *this* match, unless this isn't
   // a valid match in which case we use the start of the whole sequence.  Note that
   // no subsequent match-candidate can ever be to the left of the first match found.
   // This ensures that when we are using bidirectional iterators, that distances 
   // measured are as short as possible, and therefore as efficient as possible
   // to compute.  Finally note that we don't use the "matched" data member to test
   // whether a sub-expression is a valid match, because partial matches set this
   // to false for sub-expression 0.
   //
   BidiIterator l_end = this->suffix().second;
   BidiIterator l_base = (p1->first == l_end) ? this->prefix().first : (*this)[0].first;
   difference_type len1 = 0;
   difference_type len2 = 0;
   difference_type base1 = 0;
   difference_type base2 = 0;
   std::size_t i;
   for(i = 0; i < size(); ++i, ++p1, ++p2)
   {
      //
      // Leftmost takes priority over longest; handle special cases
      // where distances need not be computed first (an optimisation
      // for bidirectional iterators: ensure that we don't accidently
      // compute the length of the whole sequence, as this can be really
      // expensive).
      //
      if(p1->first == l_end)
      {
         if(p2->first != l_end)
         {
            // p2 must be better than p1, and no need to calculate
            // actual distances:
            base1 = 1;
            base2 = 0;
            break;
         }
         else
         {
            // *p1 and *p2 are either unmatched or match end-of sequence,
            // either way no need to calculate distances:
            if((p1->matched == false) && (p2->matched == true))
               break;
            if((p1->matched == true) && (p2->matched == false))
               return;
            continue;
         }
      }
      else if(p2->first == l_end)
      {
         // p1 better than p2, and no need to calculate distances:
         return;
      }
      base1 = ::ndnboost::re_detail::distance(l_base, p1->first);
      base2 = ::ndnboost::re_detail::distance(l_base, p2->first);
      NDNBOOST_ASSERT(base1 >= 0);
      NDNBOOST_ASSERT(base2 >= 0);
      if(base1 < base2) return;
      if(base2 < base1) break;

      len1 = ::ndnboost::re_detail::distance((BidiIterator)p1->first, (BidiIterator)p1->second);
      len2 = ::ndnboost::re_detail::distance((BidiIterator)p2->first, (BidiIterator)p2->second);
      NDNBOOST_ASSERT(len1 >= 0);
      NDNBOOST_ASSERT(len2 >= 0);
      if((len1 != len2) || ((p1->matched == false) && (p2->matched == true)))
         break;
      if((p1->matched == true) && (p2->matched == false))
         return;
   }
   if(i == size())
      return;
   if(base2 < base1)
      *this = m;
   else if((len2 > len1) || ((p1->matched == false) && (p2->matched == true)) )
      *this = m;
}

template <class BidiIterator, class Allocator>
void swap(match_results<BidiIterator, Allocator>& a, match_results<BidiIterator, Allocator>& b)
{
   a.swap(b);
}

#ifndef NDNBOOST_NO_STD_LOCALE
template <class charT, class traits, class BidiIterator, class Allocator>
std::basic_ostream<charT, traits>&
   operator << (std::basic_ostream<charT, traits>& os,
                const match_results<BidiIterator, Allocator>& s)
{
   return (os << s.str());
}
#else
template <class BidiIterator, class Allocator>
std::ostream& operator << (std::ostream& os,
                           const match_results<BidiIterator, Allocator>& s)
{
   return (os << s.str());
}
#endif

#ifdef NDNBOOST_MSVC
#pragma warning(pop)
#endif
} // namespace ndnboost

#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


