[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