summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2018-04-30 22:39:09 +0000
committerKarl Berry <karl@freefriends.org>2018-04-30 22:39:09 +0000
commita28e1bfccd6fe522fcd296426e4d89c7fb4f19b6 (patch)
treeb72347e08575b56fcfed87c4d837b48dcfd1e02a /Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
parentb40c37a9e22b8235ff9c0bc256d00f7af94304c3 (diff)
l3 (30apr18)
git-svn-id: svn://tug.org/texlive/trunk@47516 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3seq.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3seq.dtx230
1 files changed, 125 insertions, 105 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
index 95dddce8afa..0a8c475fd57 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-%% File: l3seq.dtx Copyright (C) 1990-2017 The LaTeX3 Project
+%% File: l3seq.dtx Copyright (C) 1990-2018 The LaTeX3 Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -41,7 +41,7 @@
% }^^A
% }
%
-% \date{Released 2018/03/05}
+% \date{Released 2018-04-30}
%
% \maketitle
%
@@ -855,40 +855,6 @@
% Writes the entries in the \meta{sequence} in the log file.
% \end{function}
%
-% \section{Internal sequence functions}
-%
-% \begin{variable}{\s__seq}
-% This scan mark (equal to \cs{scan_stop:}) marks the beginning of a
-% sequence variable.
-% \end{variable}
-%
-% \begin{function}[EXP]{\__seq_item:n}
-% \begin{syntax}
-% \cs{__seq_item:n} \Arg{item}
-% \end{syntax}
-% The internal token used to begin each sequence entry. If expanded
-% outside of a mapping or manipulation function, an error is
-% raised. The definition should always be set globally.
-% \end{function}
-%
-% \begin{function}{\__seq_push_item_def:n, \__seq_push_item_def:x}
-% \begin{syntax}
-% \cs{__seq_push_item_def:n} \Arg{code}
-% \end{syntax}
-% Saves the definition of \cs{__seq_item:n} and redefines it to
-% accept one parameter and expand to \meta{code}. This function
-% should always be balanced by use of \cs{__seq_pop_item_def:}.
-% \end{function}
-%
-% \begin{function}{\__seq_pop_item_def:}
-% \begin{syntax}
-% \cs{__seq_pop_item_def:}
-% \end{syntax}
-% Restores the definition of \cs{__seq_item:n} most recently saved by
-% \cs{__seq_push_item_def:n}. This function should always be used in
-% a balanced pair with \cs{__seq_push_item_def:n}.
-% \end{function}
-%
% \end{documentation}
%
% \begin{implementation}
@@ -913,10 +879,40 @@
% \meta{item_1} \cs{seq_elt_end:} \ldots \cs{seq_elt:w} \meta{item_n}
% \cs{seq_elt_end:}}. This allowed rapid searching using a delimited
% function, but was not suitable for items containing |{|, |}| and |#|
-% tokens, and also lead to the loss of surrounding braces around items.
+% tokens, and also lead to the loss of surrounding braces around items
+%
+% \begin{function}[EXP]{\@@_item:n}
+% \begin{syntax}
+% \cs{@@_item:n} \Arg{item}
+% \end{syntax}
+% The internal token used to begin each sequence entry. If expanded
+% outside of a mapping or manipulation function, an error is
+% raised. The definition should always be set globally.
+% \end{function}
+%
+% \begin{function}{\@@_push_item_def:n, \@@_push_item_def:x}
+% \begin{syntax}
+% \cs{@@_push_item_def:n} \Arg{code}
+% \end{syntax}
+% Saves the definition of \cs{@@_item:n} and redefines it to
+% accept one parameter and expand to \meta{code}. This function
+% should always be balanced by use of \cs{@@_pop_item_def:}.
+% \end{function}
+%
+% \begin{function}{\@@_pop_item_def:}
+% \begin{syntax}
+% \cs{@@_pop_item_def:}
+% \end{syntax}
+% Restores the definition of \cs{@@_item:n} most recently saved by
+% \cs{@@_push_item_def:n}. This function should always be used in
+% a balanced pair with \cs{@@_push_item_def:n}.
+% \end{function}
%
% \begin{variable}{\s_@@}
-% The variable is defined in the \pkg{l3quark} module, loaded later.
+% This private scan mark.
+% \begin{macrocode}
+\scan_new:N \s_@@
+% \end{macrocode}
% \end{variable}
%
% \begin{macro}{\@@_item:n}
@@ -962,7 +958,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \seq_new:N #1
{
- \__chk_if_free_cs:N #1
+ \__kernel_chk_if_free_cs:N #1
\cs_gset_eq:NN #1 \c_empty_seq
}
\cs_generate_variant:Nn \seq_new:N { c }
@@ -1451,10 +1447,10 @@
#1
\group_end:
\prg_return_false:
- \__prg_break_point:
+ \prg_break_point:
}
\cs_new:Npn \@@_if_in:
- { \__prg_break:n { \group_end: \prg_return_true: } }
+ { \prg_break:n { \group_end: \prg_return_true: } }
\prg_generate_conditional_variant:Nnn \seq_if_in:Nn
{ NV , Nv , No , Nx , c , cV , cv , co , cx } { T , F , TF }
% \end{macrocode}
@@ -1542,30 +1538,29 @@
%
% \begin{macro}{\seq_get_right:NN, \seq_get_right:cN}
% \UnitTested
-% \begin{macro}{\@@_get_right_loop:nn}
-% First remove \cs{s_@@} and prepend \cs{q_no_value}, then take two
-% arguments at a time. Before the right-hand end of the sequence,
-% this is a brace group followed by \cs{@@_item:n}, both removed by
-% \cs{use_none:nn}. At the end of the sequence, the two question
-% marks are taken by \cs{use_none:nn}, and the assignment is placed
-% before the right-most item. In the next iteration,
-% \cs{@@_get_right_loop:nn} receives two empty arguments, and
-% \cs{use_none:nn} stops the loop.
+% \begin{macro}[EXP]{\@@_get_right_loop:nw, \@@_get_right_end:NnN}
+% First remove \cs{s_@@} and prepend \cs{q_no_value}. The first
+% argument of \cs{@@_get_right_loop:nw} is the last item found, and
+% the second argument is empty until the end of the loop, where it is
+% code that applies \cs{exp_not:n} to the last item and ends the loop.
% \begin{macrocode}
\cs_new_protected:Npn \seq_get_right:NN #1#2
{
- \exp_after:wN \use_i_ii:nnn
- \exp_after:wN \@@_get_right_loop:nn
- \exp_after:wN \q_no_value
- #1
- { ?? \tl_set:Nn #2 }
- { } { }
+ \tl_set:Nx #2
+ {
+ \exp_after:wN \use_i_ii:nnn
+ \exp_after:wN \@@_get_right_loop:nw
+ \exp_after:wN \q_no_value
+ #1
+ \@@_get_right_end:NnN \@@_item:n
+ }
}
-\cs_new_protected:Npn \@@_get_right_loop:nn #1#2
+\cs_new:Npn \@@_get_right_loop:nw #1#2 \@@_item:n
{
- \use_none:nn #2 {#1}
- \@@_get_right_loop:nn
+ #2 \use_none:n {#1}
+ \@@_get_right_loop:nw
}
+\cs_new:Npn \@@_get_right_end:NnN #1#2#3 { \exp_not:n {#2} }
\cs_generate_variant:Nn \seq_get_right:NN { c }
% \end{macrocode}
% \end{macro}
@@ -1646,18 +1641,26 @@
% \begin{macro}[TF]{\seq_gpop_right:NN, \seq_gpop_right:cN}
% More or less the same for popping.
% \begin{macrocode}
-\prg_new_protected_conditional:Npnn \seq_pop_left:NN #1#2 { T , F , TF }
+\prg_new_protected_conditional:Npnn \seq_pop_left:NN #1#2
+ { T , F , TF }
{ \@@_pop_TF:NNNN \@@_pop_left:NNN \tl_set:Nn #1 #2 }
-\prg_new_protected_conditional:Npnn \seq_gpop_left:NN #1#2 { T , F , TF }
+\prg_new_protected_conditional:Npnn \seq_gpop_left:NN #1#2
+ { T , F , TF }
{ \@@_pop_TF:NNNN \@@_pop_left:NNN \tl_gset:Nn #1 #2 }
-\prg_new_protected_conditional:Npnn \seq_pop_right:NN #1#2 { T , F , TF }
+\prg_new_protected_conditional:Npnn \seq_pop_right:NN #1#2
+ { T , F , TF }
{ \@@_pop_TF:NNNN \@@_pop_right:NNN \tl_set:Nx #1 #2 }
-\prg_new_protected_conditional:Npnn \seq_gpop_right:NN #1#2 { T , F , TF }
+\prg_new_protected_conditional:Npnn \seq_gpop_right:NN #1#2
+ { T , F , TF }
{ \@@_pop_TF:NNNN \@@_pop_right:NNN \tl_gset:Nx #1 #2 }
-\prg_generate_conditional_variant:Nnn \seq_pop_left:NN { c } { T , F , TF }
-\prg_generate_conditional_variant:Nnn \seq_gpop_left:NN { c } { T , F , TF }
-\prg_generate_conditional_variant:Nnn \seq_pop_right:NN { c } { T , F , TF }
-\prg_generate_conditional_variant:Nnn \seq_gpop_right:NN { c } { T , F , TF }
+\prg_generate_conditional_variant:Nnn \seq_pop_left:NN { c }
+ { T , F , TF }
+\prg_generate_conditional_variant:Nnn \seq_gpop_left:NN { c }
+ { T , F , TF }
+\prg_generate_conditional_variant:Nnn \seq_pop_right:NN { c }
+ { T , F , TF }
+\prg_generate_conditional_variant:Nnn \seq_gpop_right:NN { c }
+ { T , F , TF }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1665,21 +1668,21 @@
% \end{macro}
%
% \begin{macro}{\seq_item:Nn, \seq_item:cn}
-% \begin{macro}{\@@_item:wNn, \@@_item:nN, \@@_item:nnn}
+% \begin{macro}{\@@_item:wNn, \@@_item:nN, \@@_item:nwn}
% The idea here is to find the offset of the item from the left, then use
% a loop to grab the correct item. If the resulting offset is too large,
-% then the stop code |{ ? \__prg_break: } { }| is used by the auxiliary,
-% terminating the loop and returning nothing at all.
+% then the argument delimited by \cs{@@_item:n} is \cs{prg_break:} instead
+% of being empty, terminating the loop and returning nothing at all.
% \begin{macrocode}
\cs_new:Npn \seq_item:Nn #1
{ \exp_after:wN \@@_item:wNn #1 \q_stop #1 }
\cs_new:Npn \@@_item:wNn \s_@@ #1 \q_stop #2#3
{
- \exp_args:Nf \@@_item:nnn
+ \exp_args:Nf \@@_item:nwn
{ \exp_args:Nf \@@_item:nN { \int_eval:n {#3} } #2 }
#1
- { ? \__prg_break: } { }
- \__prg_break_point:
+ \prg_break: \@@_item:n { }
+ \prg_break_point:
}
\cs_new:Npn \@@_item:nN #1#2
{
@@ -1687,12 +1690,12 @@
{ \int_eval:n { \seq_count:N #2 + 1 + #1 } }
{#1}
}
-\cs_new:Npn \@@_item:nnn #1#2#3
+\cs_new:Npn \@@_item:nwn #1#2 \@@_item:n #3
{
- \use_none:n #2
+ #2
\int_compare:nNnTF {#1} = 1
- { \__prg_break:n { \exp_not:n {#3} } }
- { \exp_args:Nf \@@_item:nnn { \int_eval:n { #1 - 1 } } }
+ { \prg_break:n { \exp_not:n {#3} } }
+ { \exp_args:Nf \@@_item:nwn { \int_eval:n { #1 - 1 } } }
}
\cs_generate_variant:Nn \seq_item:Nn { c }
% \end{macrocode}
@@ -1705,14 +1708,14 @@
% \UnitTested
% \begin{macro}{\seq_map_break:n}
% \UnitTested
-% To break a function, the special token \cs{__prg_break_point:Nn} is
+% To break a function, the special token \cs{prg_break_point:Nn} is
% used to find the end of the code. Any ending code is then inserted
% before the return value of \cs{seq_map_break:n} is inserted.
% \begin{macrocode}
\cs_new:Npn \seq_map_break:
- { \__prg_map_break:Nn \seq_map_break: { } }
+ { \prg_map_break:Nn \seq_map_break: { } }
\cs_new:Npn \seq_map_break:n
- { \__prg_map_break:Nn \seq_map_break: }
+ { \prg_map_break:Nn \seq_map_break: }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1721,26 +1724,26 @@
% \UnitTested
% \begin{macro}[rEXP]{\@@_map_function:NNn}
% The idea here is to apply the code of |#2| to each item in the
-% sequence without altering the definition of \cs{@@_item:n}. This
-% is done as by noting that every odd token in the sequence must be
-% \cs{@@_item:n}, which can be gobbled by \cs{use_none:n}. At the end of
-% the loop, |#2| is instead |? \seq_map_break:|, which therefore breaks the
-% loop without needing to do a (relatively-expensive) quark test.
+% sequence without altering the definition of \cs{@@_item:n}. The
+% argument delimited by \cs{@@_item:n} is almost always empty, except
+% at the end of the loop where it is \cs{prg_break:}. This allows to
+% break the loop without needing to do a (relatively-expensive) quark
+% test.
% \begin{macrocode}
\cs_new:Npn \seq_map_function:NN #1#2
{
\exp_after:wN \use_i_ii:nnn
- \exp_after:wN \@@_map_function:NNn
+ \exp_after:wN \@@_map_function:Nw
\exp_after:wN #2
#1
- { ? \seq_map_break: } { }
- \__prg_break_point:Nn \seq_map_break: { }
+ \prg_break: \@@_item:n { } \prg_break_point:
+ \prg_break_point:Nn \seq_map_break: { }
}
-\cs_new:Npn \@@_map_function:NNn #1#2#3
+\cs_new:Npn \@@_map_function:Nw #1#2 \@@_item:n #3
{
- \use_none:n #2
+ #2
#1 {#3}
- \@@_map_function:NNn #1
+ \@@_map_function:Nw #1
}
\cs_generate_variant:Nn \seq_map_function:NN { c }
% \end{macrocode}
@@ -1766,15 +1769,15 @@
}
\cs_new_protected:Npn \@@_push_item_def:
{
- \int_gincr:N \g__prg_map_int
- \cs_gset_eq:cN { __prg_map_ \int_use:N \g__prg_map_int :w }
+ \int_gincr:N \g__kernel_prg_map_int
+ \cs_gset_eq:cN { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
\@@_item:n
}
\cs_new_protected:Npn \@@_pop_item_def:
{
\cs_gset_eq:Nc \@@_item:n
- { __prg_map_ \int_use:N \g__prg_map_int :w }
- \int_gdecr:N \g__prg_map_int
+ { @@_map_ \int_use:N \g__kernel_prg_map_int :w }
+ \int_gdecr:N \g__kernel_prg_map_int
}
% \end{macrocode}
% \end{macro}
@@ -1791,7 +1794,7 @@
{
\@@_push_item_def:n {#2}
#1
- \__prg_break_point:Nn \seq_map_break: { \@@_pop_item_def: }
+ \prg_break_point:Nn \seq_map_break: { \@@_pop_item_def: }
}
\cs_generate_variant:Nn \seq_map_inline:Nn { c }
% \end{macrocode}
@@ -1815,7 +1818,7 @@
\exp_not:n {#3}
}
#1
- \__prg_break_point:Nn \seq_map_break: { \@@_pop_item_def: }
+ \prg_break_point:Nn \seq_map_break: { \@@_pop_item_def: }
}
\cs_generate_variant:Nn \seq_map_variable:NNn { Nc }
\cs_generate_variant:Nn \seq_map_variable:NNn { c , cc }
@@ -1823,20 +1826,37 @@
% \end{macro}
%
% \begin{macro}{\seq_count:N, \seq_count:c}
-% \begin{macro}{\@@_count:n}
-% Counting the items in a sequence is done using the same approach as for
-% other count functions: turn each entry into a \texttt{+1} then use
-% integer evaluation to actually do the mathematics.
+% \begin{macro}{\@@_count:w, \@@_count_end:w}
+% Since counting the items in a sequence is quite common, we optimize
+% it by grabbing $8$~items at a time and correspondingly adding $8$ to
+% an integer expression. At the end of the loop, |#9| is
+% \cs{@@_count_end:w} instead of being empty. It removes |8+| and
+% instead places the number of \cs{@@_item:n} that \cs{@@_count:w}
+% grabbed before reaching the end of the sequence.
% \begin{macrocode}
\cs_new:Npn \seq_count:N #1
{
\int_eval:n
{
- 0
- \seq_map_function:NN #1 \@@_count:n
+ \exp_after:wN \use_i:nn
+ \exp_after:wN \@@_count:w
+ #1
+ \@@_count_end:w \@@_item:n 7
+ \@@_count_end:w \@@_item:n 6
+ \@@_count_end:w \@@_item:n 5
+ \@@_count_end:w \@@_item:n 4
+ \@@_count_end:w \@@_item:n 3
+ \@@_count_end:w \@@_item:n 2
+ \@@_count_end:w \@@_item:n 1
+ \@@_count_end:w \@@_item:n 0
+ \prg_break_point:
}
}
-\cs_new:Npn \@@_count:n #1 { + 1 }
+\cs_new:Npn \@@_count:w
+ #1 \@@_item:n #2 \@@_item:n #3 \@@_item:n #4 \@@_item:n
+ #5 \@@_item:n #6 \@@_item:n #7 \@@_item:n #8 #9 \@@_item:n
+ { #9 8 + \@@_count:w }
+\cs_new:Npn \@@_count_end:w 8 + \@@_count:w #1#2 \prg_break_point: {#1}
\cs_generate_variant:Nn \seq_count:N { c }
% \end{macrocode}
% \end{macro}
@@ -1983,7 +2003,7 @@
\cs_generate_variant:Nn \seq_log:N { c }
\cs_new_protected:Npn \@@_show:NN #1#2
{
- \__kernel_check_defined:NT #2
+ \__kernel_chk_defined:NT #2
{
#1 { LaTeX/kernel } { show-seq }
{ \token_to_str:N #2 }