PageRenderTime 32ms CodeModel.GetById 11ms app.highlight 16ms RepoModel.GetById 1ms app.codeStats 1ms

/Src/Dependencies/Boost/boost/xpressive/basic_regex.hpp

http://hadesmem.googlecode.com/
C++ Header | 295 lines | 163 code | 32 blank | 100 comment | 2 complexity | 2822d483b717776bcc3112d8646a3c67 MD5 | raw file
  1///////////////////////////////////////////////////////////////////////////////
  2/// \file basic_regex.hpp
  3/// Contains the definition of the basic_regex\<\> class template and its
  4/// associated helper functions.
  5//
  6//  Copyright 2008 Eric Niebler. Distributed under the Boost
  7//  Software License, Version 1.0. (See accompanying file
  8//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9
 10#ifndef BOOST_XPRESSIVE_BASIC_REGEX_HPP_EAN_10_04_2005
 11#define BOOST_XPRESSIVE_BASIC_REGEX_HPP_EAN_10_04_2005
 12
 13// MS compatible compilers support #pragma once
 14#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 15# pragma once
 16#endif
 17
 18#include <boost/config.hpp>
 19#include <boost/mpl/bool.hpp>
 20#include <boost/xpressive/xpressive_fwd.hpp>
 21#include <boost/xpressive/regex_constants.hpp>
 22#include <boost/xpressive/detail/detail_fwd.hpp>
 23#include <boost/xpressive/detail/core/regex_impl.hpp>
 24#include <boost/xpressive/detail/core/regex_domain.hpp>
 25
 26// Doxygen can't handle proto :-(
 27#ifndef BOOST_XPRESSIVE_DOXYGEN_INVOKED
 28# include <boost/xpressive/detail/static/grammar.hpp>
 29# include <boost/proto/extends.hpp>
 30#endif
 31
 32#if BOOST_XPRESSIVE_HAS_MS_STACK_GUARD
 33# include <excpt.h>     // for _exception_code()
 34# include <malloc.h>    // for _resetstkoflw()
 35#endif
 36
 37namespace boost { namespace xpressive
 38{
 39
 40namespace detail
 41{
 42    inline void throw_on_stack_error(bool stack_error)
 43    {
 44        BOOST_XPR_ENSURE_(!stack_error, regex_constants::error_stack, "Regex stack space exhausted");
 45    }
 46}
 47
 48///////////////////////////////////////////////////////////////////////////////
 49// basic_regex
 50//
 51/// \brief Class template basic_regex\<\> is a class for holding a compiled regular expression.
 52template<typename BidiIter>
 53struct basic_regex
 54  : proto::extends<
 55        proto::expr<proto::tag::terminal, proto::term<detail::tracking_ptr<detail::regex_impl<BidiIter> > >, 0>
 56      , basic_regex<BidiIter>
 57      , detail::regex_domain
 58    >
 59{
 60private:
 61    typedef proto::expr<proto::tag::terminal, proto::term<detail::tracking_ptr<detail::regex_impl<BidiIter> > >, 0> pimpl_type;
 62    typedef proto::extends<pimpl_type, basic_regex<BidiIter>, detail::regex_domain> base_type;
 63
 64public:
 65    typedef BidiIter iterator_type;
 66    typedef typename iterator_value<BidiIter>::type char_type;
 67    // For compatibility with std::basic_regex
 68    typedef typename iterator_value<BidiIter>::type value_type;
 69    typedef typename detail::string_type<char_type>::type string_type;
 70    typedef regex_constants::syntax_option_type flag_type;
 71
 72    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, ECMAScript         = regex_constants::ECMAScript);
 73    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, icase              = regex_constants::icase_);
 74    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, nosubs             = regex_constants::nosubs);
 75    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, optimize           = regex_constants::optimize);
 76    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, collate            = regex_constants::collate);
 77    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, single_line        = regex_constants::single_line);
 78    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, not_dot_null       = regex_constants::not_dot_null);
 79    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, not_dot_newline    = regex_constants::not_dot_newline);
 80    BOOST_STATIC_CONSTANT(regex_constants::syntax_option_type, ignore_white_space = regex_constants::ignore_white_space);
 81
 82    /// \post regex_id()    == 0
 83    /// \post mark_count()  == 0
 84    basic_regex()
 85      : base_type()
 86    {
 87    }
 88
 89    /// \param that The basic_regex object to copy.
 90    /// \post regex_id()    == that.regex_id()
 91    /// \post mark_count()  == that.mark_count()
 92    basic_regex(basic_regex<BidiIter> const &that)
 93      : base_type(that)
 94    {
 95    }
 96
 97    /// \param that The basic_regex object to copy.
 98    /// \post regex_id()    == that.regex_id()
 99    /// \post mark_count()  == that.mark_count()
100    /// \return *this
101    basic_regex<BidiIter> &operator =(basic_regex<BidiIter> const &that)
102    {
103        proto::value(*this) = proto::value(that);
104        return *this;
105    }
106
107    /// Construct from a static regular expression.
108    ///
109    /// \param  expr The static regular expression
110    /// \pre    Expr is the type of a static regular expression.
111    /// \post   regex_id()   != 0
112    /// \post   mark_count() \>= 0
113    template<typename Expr>
114    basic_regex(Expr const &expr)
115      : base_type()
116    {
117        BOOST_XPRESSIVE_CHECK_REGEX(Expr, char_type);
118        this->compile_(expr, is_valid_regex<Expr, char_type>());
119    }
120
121    /// Construct from a static regular expression.
122    ///
123    /// \param  expr The static regular expression.
124    /// \pre    Expr is the type of a static regular expression.
125    /// \post   regex_id()   != 0
126    /// \post   mark_count() \>= 0
127    /// \throw  std::bad_alloc on out of memory
128    /// \return *this
129    template<typename Expr>
130    basic_regex<BidiIter> &operator =(Expr const &expr)
131    {
132        BOOST_XPRESSIVE_CHECK_REGEX(Expr, char_type);
133        this->compile_(expr, is_valid_regex<Expr, char_type>());
134        return *this;
135    }
136
137    /// Returns the count of capturing sub-expressions in this regular expression
138    ///
139    std::size_t mark_count() const
140    {
141        return proto::value(*this) ? proto::value(*this)->mark_count_ : 0;
142    }
143
144    /// Returns a token which uniquely identifies this regular expression.
145    ///
146    regex_id_type regex_id() const
147    {
148        return proto::value(*this) ? proto::value(*this)->xpr_.get() : 0;
149    }
150
151    /// Swaps the contents of this basic_regex object with another.
152    ///
153    /// \param      that The other basic_regex object.
154    /// \attention  This is a shallow swap that does not do reference tracking.
155    ///             If you embed a basic_regex object by reference in another
156    ///             regular expression and then swap its contents with another
157    ///             basic_regex object, the change will not be visible to the
158    ///             enclosing regular expression. It is done this way to ensure
159    ///             that swap() cannot throw.
160    /// \throw      nothrow
161    void swap(basic_regex<BidiIter> &that) // throw()
162    {
163        proto::value(*this).swap(proto::value(that));
164    }
165
166    /// Factory method for building a regex object from a range of characters.
167    /// Equivalent to regex_compiler\< BidiIter \>().compile(begin, end, flags);
168    ///
169    /// \param  begin The beginning of a range of characters representing the
170    ///         regular expression to compile.
171    /// \param  end The end of a range of characters representing the
172    ///         regular expression to compile.
173    /// \param  flags Optional bitmask that determines how the pat string is
174    ///         interpreted. (See syntax_option_type.)
175    /// \return A basic_regex object corresponding to the regular expression
176    ///         represented by the character range.
177    /// \pre    [begin,end) is a valid range.
178    /// \pre    The range of characters specified by [begin,end) contains a
179    ///         valid string-based representation of a regular expression.
180    /// \throw  regex_error when the range of characters has invalid regular
181    ///         expression syntax.
182    template<typename InputIter>
183    static basic_regex<BidiIter> compile(InputIter begin, InputIter end, flag_type flags = regex_constants::ECMAScript)
184    {
185        return regex_compiler<BidiIter>().compile(begin, end, flags);
186    }
187
188    /// \overload
189    ///
190    template<typename InputRange>
191    static basic_regex<BidiIter> compile(InputRange const &pat, flag_type flags = regex_constants::ECMAScript)
192    {
193        return regex_compiler<BidiIter>().compile(pat, flags);
194    }
195
196    /// \overload
197    ///
198    static basic_regex<BidiIter> compile(char_type const *begin, flag_type flags = regex_constants::ECMAScript)
199    {
200        return regex_compiler<BidiIter>().compile(begin, flags);
201    }
202
203    /// \overload
204    ///
205    static basic_regex<BidiIter> compile(char_type const *begin, std::size_t len, flag_type flags)
206    {
207        return regex_compiler<BidiIter>().compile(begin, len, flags);
208    }
209
210private:
211    friend struct detail::core_access<BidiIter>;
212
213    // Avoid a common programming mistake. Construction from a string is
214    // ambiguous. It could mean:
215    //   sregex rx = sregex::compile(str); // compile the string into a regex
216    // or
217    //   sregex rx = as_xpr(str);          // treat the string as a literal
218    // Since there is no easy way to disambiguate, it is disallowed. You must
219    // say what you mean.
220
221    /// INTERNAL ONLY
222    basic_regex(char_type const *);
223    /// INTERNAL ONLY
224    basic_regex(string_type const &);
225
226    /// INTERNAL ONLY
227    bool match_(detail::match_state<BidiIter> &state) const
228    {
229        #if BOOST_XPRESSIVE_HAS_MS_STACK_GUARD
230        bool success = false, stack_error = false;
231        __try
232        {
233            success = proto::value(*this)->xpr_->match(state);
234        }
235        __except(_exception_code() == 0xC00000FDUL)
236        {
237            stack_error = true;
238            _resetstkoflw();
239        }
240        detail::throw_on_stack_error(stack_error);
241        return success;
242        #else
243        return proto::value(*this)->xpr_->match(state);
244        #endif
245    }
246
247    // Compiles valid static regexes into a state machine.
248    /// INTERNAL ONLY
249    template<typename Expr>
250    void compile_(Expr const &expr, mpl::true_)
251    {
252        detail::static_compile(expr, proto::value(*this).get());
253    }
254
255    // No-op for invalid static regexes.
256    /// INTERNAL ONLY
257    template<typename Expr>
258    void compile_(Expr const &, mpl::false_)
259    {
260    }
261};
262
263#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
264template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::ECMAScript;
265template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::icase;
266template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::nosubs;
267template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::optimize;
268template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::collate;
269template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::single_line;
270template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::not_dot_null;
271template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::not_dot_newline;
272template<typename BidiIter> regex_constants::syntax_option_type const basic_regex<BidiIter>::ignore_white_space;
273#endif
274
275///////////////////////////////////////////////////////////////////////////////
276// swap
277/// \brief      Swaps the contents of two basic_regex objects.
278/// \param      left The first basic_regex object.
279/// \param      right The second basic_regex object.
280/// \attention  This is a shallow swap that does not do reference tracking.
281///             If you embed a basic_regex object by reference in another
282///             regular expression and then swap its contents with another
283///             basic_regex object, the change will not be visible to the
284///             enclosing regular expression. It is done this way to ensure
285///             that swap() cannot throw.
286/// \throw      nothrow
287template<typename BidiIter>
288inline void swap(basic_regex<BidiIter> &left, basic_regex<BidiIter> &right) // throw()
289{
290    left.swap(right);
291}
292
293}} // namespace boost::xpressive
294
295#endif // BOOST_XPRESSIVE_BASIC_REGEX_HPP_EAN_10_04_2005