// class template regex -*- C++ -*-

// Copyright (C) 2010 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/**
 *  @file bits/regex_grep_matcher.tcc
 *  This is an internal header file, included by other library headers.
 *  Do not attempt to use it directly. @headername{regex}
 */

#include <regex>

namespace std _GLIBCXX_VISIBILITY(default)
{
namespace
{
  // A stack of states used in evaluating the NFA.
  typedef std::stack<std::__regex::_StateIdT,
                     std::vector<std::__regex::_StateIdT>
		     > _StateStack;

  // Obtains the next state set given the current state set __s and the current
  // input character.
  inline std::__regex::_StateSet
  __move(const std::__regex::_PatternCursor& __p,
         const std::__regex::_Nfa& __nfa,
         const std::__regex::_StateSet& __s)
  {
    std::__regex::_StateSet __m;
    for (std::__regex::_StateSet::const_iterator __i = __s.begin();
	 __i != __s.end(); ++__i)
      {
	if (*__i == std::__regex::_S_invalid_state_id)
	  continue;

	const std::__regex::_State& __state = __nfa[*__i];
	if (__state._M_opcode == std::__regex::_S_opcode_match
	    && __state._M_matches(__p))
	  __m.insert(__state._M_next);
      }
    return __m;
  }

  // returns true if (__s intersect __t) is not empty
  inline bool
  __includes_some(const std::__regex::_StateSet& __s,
                  const std::__regex::_StateSet& __t)
  {
    if (__s.size() > 0 && __t.size() > 0)
      {
	std::__regex::_StateSet::const_iterator __first = __s.begin();
	std::__regex::_StateSet::const_iterator __second = __t.begin();
	while (__first != __s.end() && __second != __t.end())
	  {
	    if (*__first < *__second)
	      ++__first;
	    else if (*__second < *__first)
	      ++__second;
	    else
	      return true;
	  }
      }
    return false;
  }

  // If an identified state __u is not already in the current state set __e,
  // insert it and push it on the current state stack __s.
  inline void
  __add_visited_state(const std::__regex::_StateIdT __u,
                      _StateStack&                  __s,
                      std::__regex::_StateSet&      __e)
  {
    if (__e.count(__u) == 0)
      {
	__e.insert(__u);
	__s.push(__u);
      }
  }

} // anonymous namespace

namespace __regex
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  inline _Grep_matcher::
  _Grep_matcher(_PatternCursor& __p, _Results& __r,
		const _AutomatonPtr& __nfa,
		regex_constants::match_flag_type __flags)
  : _M_nfa(static_pointer_cast<_Nfa>(__nfa)), _M_pattern(__p), _M_results(__r)
  {
    __regex::_StateSet __t = this->_M_e_closure(_M_nfa->_M_start());
    for (; !_M_pattern._M_at_end(); _M_pattern._M_next())
      __t = this->_M_e_closure(__move(_M_pattern, *_M_nfa, __t));

    _M_results._M_set_matched(0,
                              __includes_some(_M_nfa->_M_final_states(), __t));
  }

  // Creates the e-closure set for the initial state __i.
  inline _StateSet _Grep_matcher::
  _M_e_closure(_StateIdT __i)
  {
    _StateSet __s;
    __s.insert(__i);
    _StateStack __stack;
    __stack.push(__i);
    return this->_M_e_closure(__stack, __s);
  }

  // Creates the e-closure set for an arbitrary state set __s.
  inline _StateSet _Grep_matcher::
  _M_e_closure(const _StateSet& __s)
  {
    _StateStack __stack;
    for (_StateSet::const_iterator __i = __s.begin(); __i != __s.end(); ++__i)
      __stack.push(*__i);
    return this->_M_e_closure(__stack, __s);
  }

  inline _StateSet _Grep_matcher::
  _M_e_closure(_StateStack& __stack, const _StateSet& __s)
  {
    _StateSet __e = __s;
    while (!__stack.empty())
      {
	_StateIdT __t = __stack.top(); __stack.pop();
	if (__t == _S_invalid_state_id)
	  continue;
	// for each __u with edge from __t to __u labeled e do ...
	const _State& __state = _M_nfa->operator[](__t);
	switch (__state._M_opcode)
	  {
	  case _S_opcode_alternative:
	    __add_visited_state(__state._M_next, __stack, __e);
	    __add_visited_state(__state._M_alt, __stack, __e);
	    break;
	  case _S_opcode_subexpr_begin:
	    __add_visited_state(__state._M_next, __stack, __e);
	    __state._M_tagger(_M_pattern, _M_results);
	    break;
	  case _S_opcode_subexpr_end:
	    __add_visited_state(__state._M_next, __stack, __e);
	    __state._M_tagger(_M_pattern, _M_results);
	    _M_results._M_set_matched(__state._M_subexpr, true);
	    break;
	  case _S_opcode_accept:
	    __add_visited_state(__state._M_next, __stack, __e);
	    break;
	  default:
	    break;
	  }
      }
    return __e;
  }

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __regex
} // namespace
