⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 regexpr2.h

📁 vsstylemanager1.0.4希望对大家有用啊,
💻 H
📖 第 1 页 / 共 3 页
字号:
//+---------------------------------------------------------------------------
//
//  Copyright ( C ) Microsoft, 1994 - 2002.
//
//  File:       regexpr2.h
//
//  Contents:   classes for regular expression pattern matching a-la perl
//
//  Classes:    basic_rpattern_base
//
//  Functions:  rpattern::match
//              rpattern::substitute
//              match_results::cbackrefs
//              match_results::backref
//              match_results::all_backrefs
//              match_results::backref_str
//
//  Author:     Eric Niebler ( ericne@microsoft.com )
//
//----------------------------------------------------------------------------

#ifndef REGEXPR_H
#define REGEXPR_H

#ifdef _MSC_VER
  // warning C4189: local variable is initialized but not referenced
  // warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
  // warning C4702: unreachable code
  // warning C4710: function 'blah' not inlined
  // warning C4786: identifier was truncated to '255' characters in the debug information
# pragma warning( push )
# pragma warning( disable : 4189 4290 4702 4710 4786 )
# define REGEX_SEH_STACK_OVERFLOW 0xC00000FDL
# if 1200 < _MSC_VER
# include <malloc.h> // for _resetstkoflw
# else
  extern "C" int __cdecl _resetstkoflw(void);
# endif
  extern "C" unsigned long __cdecl _exception_code(void);
#endif

#include <list>
#include <iosfwd>
#include <string>
#include <vector>
#include <memory>
#include <cwctype>
#include "syntax2.h"
#include "restack.h"

namespace regex
{

// This is the default alignment for the unsafe heterogeneous stack.
// If you are getting a compiler error in one of the unsafe_stack
// methods, then compile with -DREGEX_STACK_ALIGNMENT=16 or 32
#ifndef REGEX_STACK_ALIGNMENT
# define REGEX_STACK_ALIGNMENT sizeof( void* )
#endif

#if !defined( REGEX_DEBUG ) & ( defined( DEBUG ) | defined( _DEBUG ) | defined( DBG ) )
# define REGEX_DEBUG 1
#else
# define REGEX_DEBUG 0
#endif

#if !defined( REGEX_DEBUG_ITERATORS ) & defined( _HAS_ITERATOR_DEBUGGING )
# define REGEX_DEBUG_ITERATORS 1
#else
# define REGEX_DEBUG_ITERATORS 0
#endif

namespace detail
{
#if REGEX_DEBUG | REGEX_DEBUG_ITERATORS
    // Turn on hetero_stack's run-time type checking
    typedef hetero_stack<REGEX_STACK_ALIGNMENT,true,false,32,0>       unsafe_stack;
#else
    // Assume that all types pushed on stack have trivial destructors.
    typedef hetero_stack<REGEX_STACK_ALIGNMENT,false,true,4096,1024>  unsafe_stack;
#endif

    // Used to initialize variables with the same value they would have
    // if they were initialized as a static global. ( Ptrs get NULL,
    // integer types get 0, etc, etc )
    template< typename T > struct static_init { static T const value; };
    template< typename T > T const static_init<T>::value = T();

    //
    // Forward declarations
    //
    template< typename IterT > class  sub_expr;
    template< typename IterT > class  match_group_base;
    template< typename IterT > class  basic_rpattern_base_impl;
    template< typename IterT > struct match_param;
    template< typename IterT > struct sub_expr_base;
    template< typename IterT > struct regex_access;

    // an iterator that keeps track of whether it is singular or not.
    template< typename IterT > struct smart_iter
    {
        IterT m_iter;
        bool m_valid;

        smart_iter()
            : m_iter( static_init<IterT>::value )
            , m_valid( false )
        {
        }
        smart_iter( smart_iter const & rhs )
            : m_iter( rhs.m_iter )
            , m_valid( rhs.m_valid )
        {
        }
        smart_iter( IterT iter ) // implicit conversion OK!
            : m_iter( iter )
            , m_valid( true )
        {
        }
        smart_iter & operator=( smart_iter const & rhs )
        {
            m_iter  = rhs.m_iter;
            m_valid = rhs.m_valid;
            return *this;
        }
        friend bool operator==( smart_iter const & lhs, smart_iter const & rhs )
        {
            if( !lhs.m_valid || !rhs.m_valid )
                return lhs.m_valid == rhs.m_valid;
            else
                return lhs.m_iter == rhs.m_iter;
        }
        friend bool operator!=( smart_iter const & lhs, smart_iter const & rhs )
        {
            return ! operator==( lhs, rhs );
        }
    };

    template< typename IterT > struct iter_select
    {
        typedef typename select
        <
            REGEX_DEBUG_ITERATORS && !is_scalar<IterT>::value,
            smart_iter<IterT>,
            IterT
        >::type     type;
    };

    template< int SizeT > struct type_with_size { char buffer[ SizeT ]; };

    // make up for the fact that the VC6 std::allocator does
    // not have template constructors
    template< typename ToT, typename FromT >
    std::allocator<ToT> convert_allocator( std::allocator<FromT>, int )
    {
        return std::allocator<ToT>();
    }
    
    template< typename ToT, typename FromT >
    FromT const & REGEX_CDECL convert_allocator( FromT const & from, ... )
    {
        return from;
    }

    template< int > struct rebind_helper;

    // unknown allocator
    template< typename T >
    type_with_size<1> REGEX_CDECL allocator_picker( T const &, ... );

    template<> struct rebind_helper<1>
    {
        template< typename AllocT, typename ElemT >
        struct inner
        {
            REGEX_NVC6( typedef typename AllocT::template rebind<ElemT>::other type; )
        };
    };

    // std::allocator
    template< typename T >
    type_with_size<2> allocator_picker( std::allocator<T> const &, int );

    template<> struct rebind_helper<2>
    {
        template< typename, typename ElemT >
        struct inner
        {
            typedef std::allocator<ElemT> type;
        };
    };

    template< typename AllocT, typename ElemT >
    struct rebind
    {
        enum { alloc_type = sizeof(allocator_picker(factory<AllocT>::make(),0)) };

        typedef typename rebind_helper<alloc_type>::template inner<AllocT,ElemT>::type type;
    };
}

// --------------------------------------------------------------------------
//
// Class:       width_type
//
// Description: represents the width of a sub-expression
//
// Members:     m_min      - smallest number of characters a sub-expr can span
//              m_max      - largest number of characters a sub-expr can span
//
// History:     8/14/2000 - ericne - Created
//
// --------------------------------------------------------------------------
struct width_type
{
    size_t m_min;
    size_t m_max;
};

inline width_type const uninit_width()
{
    width_type const width = { size_t( -1 ), size_t( -1 ) };
    return width;
}

// Helper function for processing escape sequences
template< typename CharT, typename TraitsT, typename AllocT >
void process_escapes( std::basic_string<CharT, TraitsT, AllocT> & str, bool fPattern = false ); //throw()

// --------------------------------------------------------------------------
//
// Class:       backref_tag
//
// Description: Struct which contains a back-reference.  It is a template
//              on the iterator type.
//
// Methods:     backref_tag   - c'tor
//              operator bool - so that if( br ) is true if this br matched
//              operator!     - inverse of operator bool()
//
// Members:     reserved      - move along, nothing to see here
//
// History:     8/9/2001 - ericne - Created
//
// --------------------------------------------------------------------------
template< typename IterT >
class backref_tag : public std::pair<IterT, IterT>
{
    struct detail_t { detail_t * d; };

    template< typename OStreamT, typename OtherT >
    void REGEX_CDECL _do_print( OStreamT & sout, OtherT, ... ) const
    {
        typedef typename OStreamT::char_type char_type;
        typedef typename OStreamT::traits_type traits_type;
        std::ostreambuf_iterator<char_type, traits_type> iout( sout );
        for( IterT iter = first; iter != second; ++iter, ++iout )
            *iout = *iter;
    }

    // overload that is optimized for bare char*
    template< typename OStreamT >
    void _do_print( OStreamT & sout, typename OStreamT::char_type const *, int ) const
    {
        sout.write( first, static_cast<std::streamsize>( std::distance( first, second ) ) );
    }

public:
    typedef IterT iterator_type;
    typedef typename std::iterator_traits<IterT>::value_type char_type;
    typedef std::basic_string<char_type> string_type;

    typedef typename detail::iter_select<IterT>::type smart_iter_type;

    explicit backref_tag
    (
        IterT i1 = detail::static_init<IterT>::value,
        IterT i2 = detail::static_init<IterT>::value
    )
        : std::pair<IterT, IterT>( i1, i2 )
        , matched( false )
        , reserved1( i1 )
        , reserved2( 0 )
        , reserved3( false )
        , reserved4( detail::static_init<smart_iter_type>::value )
        , reserved5( detail::static_init<smart_iter_type>::value )
    {
    }

    IterT begin() const
    {
        return first;
    }

    IterT end() const
    {
        return second;
    }

    string_type const str() const
    {
        return matched ? string_type( first, second ) : string_type();
    }

    // Use the "safe bool" idiom. This allows implicit conversion to bool,
    // but not to int. It also disallows conversion to void*.
    typedef detail_t * detail_t::* bool_type;

    operator bool_type() const //throw()
    {
        return matched ? &detail_t::d : 0;
    }

    bool operator!() const //throw()
    {
        return ! matched;
    }

    template< typename CharT, typename TraitsT >
    std::basic_ostream<CharT, TraitsT> & print( std::basic_ostream<CharT, TraitsT> & sout ) const
    {
        _do_print( sout, IterT(), 0 );
        return sout;
    }

    bool   matched;

//private:
    IterT           reserved1; // used for internal book-keeping
    size_t          reserved2; // used for internal book-keeping
    bool            reserved3; // used for internal book-keeping
    smart_iter_type reserved4; // used for internal book-keeping
    smart_iter_type reserved5; // used for internal book-keeping
};

//namespace detail
//{
    // indexing into the backref vector is faster if the backref_tag struct
    // has a size that is a power of 2.
    //static static_assert<32==sizeof(backref_tag<char*>)> const check_backref_size;
//}

// --------------------------------------------------------------------------
//
// Class:       basic_match_results
//
// Description: Use this structure for returning match/substitute results
//              out from the match()/substitute() methods.
//
// Methods:     cbackrefs      -
//              backref        -
//              all_backrefs   -
//              rlength        -
//
// Members:     m_rgbackrefs   -
//
// Typedefs:    const_iterator -
//              backref_type   -
//              backref_vector -
//
// History:     8/8/2001 - ericne - Created
//
// --------------------------------------------------------------------------
template
<
    typename IterT,
    typename AllocT = std::allocator< REGEX_DEPENDENT_TYPENAME std::iterator_traits<IterT>::value_type >
>
struct basic_match_results
{
    // const_iterator is deprecated. Use iterator_type instead.
    REGEX_DEPRECATED typedef IterT                                const_iterator;
    typedef IterT                                                 iterator_type;
    typedef backref_tag<IterT>                                    backref_type;
    typedef typename detail::rebind<AllocT, backref_type>::type   allocator_type;
    typedef std::vector<backref_type, allocator_type>             backref_vector;
    friend struct detail::regex_access<IterT>;

    explicit basic_match_results( allocator_type const & alloc = allocator_type() )
        : m_rgbackrefs( alloc )
    {
    }

    virtual ~basic_match_results()
    {
    }

    size_t cbackrefs() const //throw()
    {
        return m_rgbackrefs.size();
    }

    backref_type const & backref( size_t cbackref ) const //throw( std::out_of_range )
    {
        return m_rgbackrefs.at( cbackref );
    }

    backref_vector const & all_backrefs() const //throw()
    {
        return m_rgbackrefs;
    }

    size_t rstart( size_t cbackref = 0 ) const //throw( std::out_of_range )
    {
        return std::distance( m_ibegin, m_rgbackrefs.at( cbackref ).first );
    }

    size_t rlength( size_t cbackref = 0 ) const //throw( std::out_of_range )
    {
        return std::distance( m_rgbackrefs.at( cbackref ).first, m_rgbackrefs.at( cbackref ).second );
    }

private:
    backref_vector m_rgbackrefs;
    IterT           m_ibegin;
};

// Unnecessary and deprecated
template< typename CharT, typename AllocT = std::allocator<CharT> >

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -