1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
///////////////////////////////////////////////////////////////////////////////
// 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)
# 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
|