[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/hsutter/cppfront/main/include/cpp2regex.h2 [Back]  [Original]

//  Copyright 2022-2026 Herb Sutter
//  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//  
//  Part of the Cppfront Project, under the Apache License v2.0 with LLVM Exceptions.
//  See https://github.com/hsutter/cppfront/blob/main/LICENSE for license information.


//===========================================================================
//  Regex support
//===========================================================================

#ifndef CPP2_CPP2REGEX_H
#define CPP2_CPP2REGEX_H


template
using matcher_context_type = typename matcher::template context;

cpp2: namespace = {

regex: namespace = {

bstring:  type == std::basic_string;
bview  :  type == std::basic_string_view;

//-----------------------------------------------------------------------
//
//  Helper structures for the expression matching.
//
//-----------------------------------------------------------------------
//

//  Structure for storing group information.
//
match_group: @struct  type = 
{
    start: Iter = ();
    end: Iter = ();

    matched: bool = false;
}

//  Return value for every matcher.
// 
match_return: @struct  type = 
{
    matched: bool = false;
    pos: Iter = ();
}

//  Modifiable state during matching.
//
match_context:  type =
{
    public  begin : Iter;
    public  end   : Iter;

    private groups: std::array = ();

    operator=: (out this, begin_: Iter, end_: Iter) = {
        begin = begin_;
        end = end_;
    }

    operator=: (out this, that) = {}

    // String end and start positions
    //
    get_string_start: (in this) = begin;
    get_string_end: (in this) = end;

    //  Getter and setter for groups
    //
    get_group: (in this, group) = groups[group];

    get_group_end:    (in this, group) -> int = {
        if group >= max_groups || !groups[group].matched {
            return 0;
        }
        return cpp2::unchecked_narrow( std::distance(begin, groups[group].end) );
    }
    get_group_start:  (in this, group) -> int = {
        if group >= max_groups || !groups[group].matched {
            return 0;
        }
        return cpp2::unchecked_narrow( std::distance(begin, groups[group].start) );
    }
    get_group_string: (in this, group) -> std::string = {
        if group >= max_groups || !groups[group].matched {
            return "";
        }
        return std::string(groups[group].start, groups[group].end);
    }
    
    set_group_end: (inout this, group, pos) = {
        groups[group].end = pos;
        groups[group].matched = true;
    }

    set_group_invalid: (inout this, group) = {
        groups[group].matched = false;
    }

    set_group_start: (inout this, group, pos) = {
        groups[group].start = pos;
    }

    size: (in this) = max_groups;

    //  Misc functions
    //
    fail: (in this)            = match_return(false, end);
    pass: (in this, cur: Iter) = match_return(true, cur);

    reset: (inout this) = {
        for groups do (inout g) {
            g.matched = false;
        }
    }
}

//  Wrapper of context for reverse matches. Implements only the minimal interface for matching.
//
reverse_match_context:  type =
{
    public ReverseIter : type == std::reverse_iterator;
    public forward_context : *match_context;

    public  begin : ReverseIter;
    public  end   : ReverseIter;

    operator=: (out this, forward_context_) = {
        forward_context = forward_context_;
        begin = std::make_reverse_iterator(forward_context*.end);
        end = std::make_reverse_iterator(forward_context*.begin);
    }

    operator=: (out this, that) = {}

    // String end and start positions
    //
    get_string_start: (in this) = end;
    get_string_end: (in this) = begin;

    //  Getter and setter for groups
    //
    set_group_end: (inout this, group, pos) = {
        forward_context*..set_group_end(group, (pos).base());
    }

    set_group_invalid: (inout this, group) = {
        forward_context*..set_group_invalid(group);
    }

    set_group_start: (inout this, group, pos) = {
        forward_context*..set_group_start(group, (pos).base());
    }

    //  Misc functions
    //
    fail: (in this)            = match_return(false, end);
    pass: (in this, cur: ReverseIter) = match_return(true, cur);
}

//  Helpers for creating wrappers of the match context.
//
make_forward_match_context:  (inout ctx: match_context) -> forward _ = {
    return ctx;
}

make_forward_match_context:  (inout ctx: reverse_match_context) -> forward _ = {
    return ctx.forward_context*;
}

make_reverse_match_context:  (inout ctx: match_context) -> _ = {
    return reverse_match_context(ctx&);
}

make_reverse_match_context:  (inout ctx: reverse_match_context) -> forward _ = {
    return ctx;
}

//  Helpers for creating wrappers of the iterators.
//
cpp2_make_forward_iterator:  (pos: Iter)                        -> _ = pos;
cpp2_make_forward_iterator:  (pos: std::reverse_iterator) -> _ = pos.base();
cpp2_make_reverse_iterator:  (pos: Iter)                        -> _ = std::make_reverse_iterator(pos);
cpp2_make_reverse_iterator:  (pos: std::reverse_iterator) -> _ = pos;


//  End function that returns a valid match.
//
true_end_func: @struct type = 
{
    operator(): (in this, cur, inout ctx) = ctx..pass(cur);
}


//  Empty group reset function.
//
no_reset: @struct type = 
{
    operator(): (this, inout _:) = {}
}


//  Evaluate func on destruction of the handle.
on_return:  type = 
{
    func: Func;

    operator=: (out this, f: Func) = {
        func = f;
    }

    operator=: (move this) = {
        func();
    }
}


//  Helper for auto deduction of the Func type.
make_on_return:  (func: Func) = on_return(func);


//-----------------------------------------------------------------------
//
//  Character classes for regular expressions.
//
//-----------------------------------------------------------------------
//

//  Class syntax:  Example: a
//
single_class_entry:  type =
{
    includes : (c: CharT) = c == C;
    to_string: ()         = bstring(1, C);
}


//  Class syntax: - Example: a-c
//
range_class_entry:  type =
{
    includes : (c: CharT) = Start 

Web Proxy Viewer  |  New URL  |  Original Page