[latex3-commits] [latex3/latex3] gh1040-prop-large: Simplify prop_concat to run the same code for flat and linked props (59a2d3130)

github at latex-project.org github at latex-project.org
Sun Feb 11 17:09:16 CET 2024


Repository : https://github.com/latex3/latex3
On branch  : gh1040-prop-large
Link       : https://github.com/latex3/latex3/commit/59a2d3130ebd1004483938329afb386e45ead634

>---------------------------------------------------------------

commit 59a2d3130ebd1004483938329afb386e45ead634
Author: Bruno Le Floch <blflatex at gmail.com>
Date:   Sun Feb 11 17:09:16 2024 +0100

    Simplify prop_concat to run the same code for flat and linked props
    
    This helps get the same order of items in both implementations.


>---------------------------------------------------------------

59a2d3130ebd1004483938329afb386e45ead634
 l3kernel/l3prop.dtx              | 73 ++++++++++++----------------------------
 l3kernel/testfiles/m3prop005.tlg |  4 +--
 2 files changed, 23 insertions(+), 54 deletions(-)

diff --git a/l3kernel/l3prop.dtx b/l3kernel/l3prop.dtx
index 4d6a04aab..4c503d1b6 100644
--- a/l3kernel/l3prop.dtx
+++ b/l3kernel/l3prop.dtx
@@ -1247,45 +1247,23 @@
 %     \prop_concat:NNN, \prop_concat:ccc,
 %     \prop_gconcat:NNN, \prop_gconcat:ccc, \@@_concat:NNNNNN
 %   }
-%   Combine two property lists.  We must beware of duplicate keys between the
-%   two property lists.  Let us read \cs{@@_concat:NNNNNN} inside out.  The
-%   basic idea is to copy one property list to a scratch space
-%   \cs{l_@@_internal_prop} (a linked prop to efficiently find duplicates), then
-%   add entries of the second property list one by one.  Our convention is to
-%   always clear \cs{l_@@_internal_prop} at the end.
-%
-%   If the target~|#4| is itself a linked prop, then copying from
-%   \cs{l_@@_internal_prop} to it would be needlessly wasteful so we directly
-%   work with~|#4| as a scratch space.  In that case we must use correctly
-%   scoped assignments.  Using |#4|~directly is also problematic if~|#6| is the
-%   same linked prop as~|#4|, so in that case we instead add the items of~|#5|
-%   one by one using \cs[index=prop_put_if_new:Nnn]{prop_(g)put_if_new:Nnn} to
-%   respect which entry should remain in case of duplicates.  There is no need
-%   to check for the case where |#4| is equal to~|#5| because in that case the
-%   line |#1| |#4| |#5|, namely \cs[index=prop_set_eq:NN]{prop_(g)set_eq:NN}
-%   |#4| |#5| is correctly set up to do no needless work.
-%
-%   A typical use of \cs{prop_concat:NNN} with two equal arguments is to
-%   repeatedly add a few entries to an ever growing prop.  In such a situation
-%   it is wasteful to convert from a flat prop to a linked prop
-%   \cs{l_@@_internal_prop}, and searching for items directly in a flat prop may
-%   be less expensive in practice.  Thus, it might be better to special-case the
-%   situation where |#4=#5| or |#4=#6| also for flat props, namely replace the
-%   flat case by
-%   \begin{verbatim}
-%     \cs_if_eq:NNTF #4 #5
-%       { \@@_concat:NNN #2 #4 #6 }
-%       {
-%         \cs_if_eq:NNTF #4 #6
-%           { \@@_concat:NNN #3 #4 #5 }
-%           {
-%             \prop_set_eq:NN \l_@@_internal_prop #5
-%             \@@_concat:NNN \prop_put:Nnn \l_@@_internal_prop #6
-%             \prop_set_eq:NN #4 \l_@@_internal_prop
-%             \prop_clear:N \l_@@_internal_prop
-%           }
-%       }
-%   \end{verbatim}
+%   Combine two property lists.  We must beware of duplicate keys
+%   between the two property lists.  The basic idea of
+%   \cs{@@_concat:NNNNNN} is to copy the first prop |#5| into the target
+%   |#4| (converting as needed between flat and linked props), and then
+%   loop through the second prop |#6| (with \cs{@@_concat:NNN}), calling
+%   \cs[index=prop_put:Nnn]{prop_(g)put:Nnn}.  We work directly with the
+%   target prop |#4| as a scratch space, because copying over from a
+%   temporary \cs{l_@@_internal_prop} to |#4| would be slow in the
+%   linked case.  If |#6| is |#4| itself we have to be careful not to
+%   lose the data.  We could expand |#6| in advance, but instead we
+%   optimize by treating this case separately, avoiding an unnecessary
+%   copy; we use \cs[index=prop_put_if_new:Nnn]{prop_(g)put_if_new:Nnn}
+%   to keep the correct version of duplicate keys.  There is no need to
+%   check for the case where |#4| is equal to~|#5| because in that case
+%   the line |#1| |#4| |#5|, namely
+%   \cs[index=prop_set_eq:NN]{prop_(g)set_eq:NN} |#4| |#5| is correctly
+%   set up to do no needless work.
 %    \begin{macrocode}
 \cs_new_protected:Npn \prop_concat:NNN
   {
@@ -1301,20 +1279,11 @@
 \cs_generate_variant:Nn \prop_gconcat:NNN { ccc }
 \cs_new_protected:Npn \@@_concat:NNNNNN #1#2#3#4#5#6
   {
-    \@@_if_flat:NTF #4
-      {
-        \prop_set_eq:NN \l_@@_internal_prop #5
-        \@@_concat:NNN \prop_put:Nnn \l_@@_internal_prop #6
-        \prop_set_eq:NN #4 \l_@@_internal_prop
-        \prop_clear:N \l_@@_internal_prop
-      }
+    \cs_if_eq:NNTF #4 #6
+      { \@@_concat:NNN #3 #4 #5 }
       {
-        \cs_if_eq:NNTF #4 #6
-          { \@@_concat:NNN #3 #4 #5 }
-          {
-            #1 #4 #5
-            \@@_concat:NNN #2 #4 #6
-          }
+        #1 #4 #5
+        \@@_concat:NNN #2 #4 #6
       }
   }
 \cs_new_protected:Npn \@@_concat:NNN #1#2#3
diff --git a/l3kernel/testfiles/m3prop005.tlg b/l3kernel/testfiles/m3prop005.tlg
index 3e6c1aa32..7c89893e7 100644
--- a/l3kernel/testfiles/m3prop005.tlg
+++ b/l3kernel/testfiles/m3prop005.tlg
@@ -127,11 +127,11 @@ TEST 3: prop_concat
 ============================================================
 TRUE
 The property list \g_tmpa_prop contains the pairs (without outer braces):
+>  {x}  =>  {y}
 >  {\a }  =>  {c}
 >  {\c }  =>  { \D =E }
 >  {}  =>  {?}
->  {=}  =>  {}
->  {x}  =>  {y}.
+>  {=}  =>  {}.
 ============================================================
 ============================================================
 TEST 4: prop_put_from_keyval





More information about the latex3-commits mailing list.