// Copyright 2022-2024 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_wrapper_type = typename matcher_wrapper::template wrap;
template
using matcher_context_type = typename matcher::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) = {}
// 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);
}
// 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