///////////////////////////////////////////////////////////////////////////////
// visitor.hpp
//
//  Copyright 2008 Eric Niebler. Distributed under 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)

#ifndef BOOST_XPRESSIVE_DETAIL_STATIC_VISITOR_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_STATIC_VISITOR_HPP_EAN_10_04_2005

// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif

#include <boost/ref.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/xpressive/detail/detail_fwd.hpp>
#include <boost/xpressive/detail/core/regex_impl.hpp>
#include <boost/xpressive/detail/static/transmogrify.hpp>
#include <boost/xpressive/detail/core/matcher/mark_begin_matcher.hpp>

namespace boost { namespace xpressive { namespace detail
{
    ///////////////////////////////////////////////////////////////////////////////
    //
    template<typename BidiIter>
    struct xpression_visitor_base
    {
        explicit xpression_visitor_base(shared_ptr<regex_impl<BidiIter> > const &self)
          : self_(self)
        {
        }

        void swap(xpression_visitor_base<BidiIter> &that)
        {
            this->self_.swap(that.self_);
        }

        int get_hidden_mark()
        {
            return -(int)(++this->self_->hidden_mark_count_);
        }

        void mark_number(int mark_nbr)
        {
            if(0 < mark_nbr)
            {
                this->self_->mark_count_ =
                    (std::max)(this->self_->mark_count_, (std::size_t)mark_nbr);
            }
        }

        shared_ptr<regex_impl<BidiIter> > &self()
        {
            return this->self_;
        }

    protected:

        template<typename Matcher>
        void visit_(Matcher const &)
        {
        }

        void visit_(reference_wrapper<basic_regex<BidiIter> > const &rex)
        {
            // when visiting an embedded regex, track the references
            this->self_->track_reference(*detail::core_access<BidiIter>::get_regex_impl(rex.get()));
        }

        void visit_(reference_wrapper<basic_regex<BidiIter> const> const &rex)
        {
            // when visiting an embedded regex, track the references
            this->self_->track_reference(*detail::core_access<BidiIter>::get_regex_impl(rex.get()));
        }

        void visit_(tracking_ptr<regex_impl<BidiIter> > const &rex)
        {
            // when visiting an embedded regex, track the references
            this->self_->track_reference(*rex.get());
        }

        void visit_(mark_placeholder const &backref)
        {
            // keep track of the largest mark number found
            this->mark_number(backref.mark_number_);
        }

        void visit_(mark_begin_matcher const &mark_begin)
        {
            // keep track of the largest mark number found
            this->mark_number(mark_begin.mark_number_);
        }

    private:
        shared_ptr<regex_impl<BidiIter> > self_;
    };

    ///////////////////////////////////////////////////////////////////////////////
    //
    template<typename BidiIter, typename ICase, typename Traits>
    struct xpression_visitor
      : xpression_visitor_base<BidiIter>
    {
        typedef BidiIter iterator_type;
        typedef ICase icase_type;
        typedef Traits traits_type;
        typedef typename boost::iterator_value<BidiIter>::type char_type;

        explicit xpression_visitor(Traits const &tr, shared_ptr<regex_impl<BidiIter> > const &self)
          : xpression_visitor_base<BidiIter>(self)
          , traits_(tr)
        {
        }

        template<typename Matcher>
        struct apply
        {
            typedef typename transmogrify<BidiIter, ICase, Traits, Matcher>::type type;
        };

        template<typename Matcher>
        typename apply<Matcher>::type
        call(Matcher const &matcher)
        {
            this->visit_(matcher);
            return transmogrify<BidiIter, ICase, Traits, Matcher>::call(matcher, *this);
        }

        Traits const &traits() const
        {
            return this->traits_;
        }

    private:

        Traits traits_;
    };

}}}

#endif
