/////////////////////////////////////////////////////////////////////////////// | |
// 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 |