[m-rev.] for review: Add string.unsafe_append_string_pieces.

Mark Brown mark at mercurylang.org
Thu Nov 7 20:21:15 AEDT 2019


This looks fine.

On Thu, Nov 7, 2019 at 3:21 PM Peter Wang <novalazy at gmail.com> wrote:
>
> library/string.m:
>     Add unsafe_append_string_pieces/2 predicate.
>
> NEWS:
>     Announce addition.
> ---
>  NEWS             |  1 +
>  library/string.m | 64 ++++++++++++++++++++++++++++++++++--------------
>  2 files changed, 46 insertions(+), 19 deletions(-)
>
> diff --git a/NEWS b/NEWS
> index c8417526f..80e4504d3 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -432,6 +432,7 @@ Changes to the Mercury standard library:
>     - unsafe_compare_substrings/6
>     - nondet_append/3
>     - append_string_pieces/2
> +   - unsafe_append_string_pieces/2
>
>    The following procedures in the string module have been deprecated:
>
> diff --git a/library/string.m b/library/string.m
> index 8b74b3e9c..ebcbc8a97 100644
> --- a/library/string.m
> +++ b/library/string.m
> @@ -706,6 +706,14 @@
>      %
>  :- pred append_string_pieces(list(string_piece)::in, string::uo) is det.
>
> +    % Same as append_string_pieces/2 but without range checks.
> +    % WARNING: if any piece `substring(S, Start, End)' has `Start' or `End'
> +    % outside the range [0, length(S)], or if `Start' > `End',
> +    % then the behaviour is UNDEFINED. Use with care!
> +    %
> +:- pred unsafe_append_string_pieces(list(string_piece)::in, string::uo)
> +    is det.
> +
>  %---------------------------------------------------------------------------%
>  %
>  % Splitting up strings.
> @@ -4151,16 +4159,19 @@ copy_into_buffer(Dest0, Dest, DestOffset0, DestOffset, Src, SrcStart, SrcEnd)
>  %---------------------%
>
>  append_string_pieces(Pieces, String) :-
> -    check_pieces_and_sum_length($pred, Pieces, 0, BufferLen),
> -    alloc_buffer(BufferLen, Buffer0),
> -    list.foldl2(copy_piece_into_buffer, Pieces, 0, End, Buffer0, Buffer),
> -    expect(unify(End, BufferLen), $pred, "End != BufferLen"),
> -    buffer_to_string(Buffer, String).
> +    DoCheck = yes,
> +    sum_piece_lengths($pred, DoCheck, Pieces, 0, BufferLen),
> +    do_append_string_pieces(Pieces, BufferLen, String).
> +
> +unsafe_append_string_pieces(Pieces, String) :-
> +    DoCheck = no,
> +    sum_piece_lengths($pred, DoCheck, Pieces, 0, BufferLen),
> +    do_append_string_pieces(Pieces, BufferLen, String).
>
> -:- pred check_pieces_and_sum_length(string::in, list(string_piece)::in,
> +:- pred sum_piece_lengths(string::in, bool::in, list(string_piece)::in,
>      int::in, int::out) is det.
>
> -check_pieces_and_sum_length(PredName, Pieces, Len0, Len) :-
> +sum_piece_lengths(PredName, DoCheck, Pieces, Len0, Len) :-
>      (
>          Pieces = [],
>          Len = Len0
> @@ -4171,22 +4182,37 @@ check_pieces_and_sum_length(PredName, Pieces, Len0, Len) :-
>              PieceLen = length(Str)
>          ;
>              Piece = substring(BaseStr, Start, End),
> -            BaseLen = length(BaseStr),
> -            ( if
> -                Start >= 0,
> -                Start =< BaseLen,
> -                End >= Start,
> -                End =< BaseLen
> -            then
> -                PieceLen = End - Start
> -            else
> -                unexpected(PredName, "substring index out of range")
> -            )
> +            (
> +                DoCheck = yes,
> +                BaseLen = length(BaseStr),
> +                ( if
> +                    Start >= 0,
> +                    Start =< BaseLen,
> +                    End >= Start,
> +                    End =< BaseLen
> +                then
> +                    true
> +                else
> +                    unexpected(PredName, "substring index out of range")
> +                )
> +            ;
> +                DoCheck = no
> +            ),
> +            PieceLen = End - Start
>          ),
>          Len1 = Len0 + PieceLen,
> -        check_pieces_and_sum_length(PredName, TailPieces, Len1, Len)
> +        sum_piece_lengths(PredName, DoCheck, TailPieces, Len1, Len)
>      ).
>
> +:- pred do_append_string_pieces(list(string_piece)::in, int::in, string::uo)
> +    is det.
> +
> +do_append_string_pieces(Pieces, BufferLen, String) :-
> +    alloc_buffer(BufferLen, Buffer0),
> +    list.foldl2(copy_piece_into_buffer, Pieces, 0, End, Buffer0, Buffer),
> +    expect(unify(End, BufferLen), $pred, "End != BufferLen"),
> +    buffer_to_string(Buffer, String).
> +
>  :- pred copy_piece_into_buffer(string_piece::in, int::in, int::out,
>      string_buffer::di, string_buffer::uo) is det.
>
> --
> 2.23.0
>
> _______________________________________________
> reviews mailing list
> reviews at lists.mercurylang.org
> https://lists.mercurylang.org/listinfo/reviews


More information about the reviews mailing list