% \iffalse
%% File: l3prg.dtx Copyright (C) 2005-2006 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
%% license or (at your option) any later version.  The latest version
%% of this license is in the file
%%
%%    http://www.latex-project.org/lppl.txt
%%
%% This file is part of the ``expl3 bundle'' (The Work in LPPL)
%% and all files in that bundle must be distributed together.
%%
%% The released version of this bundle is available from CTAN.
%%
%% -----------------------------------------------------------------------
%%
%% The development version of the bundle can be found at
%%
%%    http://www.latex-project.org/cgi-bin/cvsweb.cgi/
%%
%% for those people who are interested.
%%
%%%%%%%%%%%
%% NOTE: %%
%%%%%%%%%%%
%%
%%   Snapshots taken from the repository represent work in progress and may
%%   not work or may contain conflicting material!  We therefore ask
%%   people _not_ to put them into distributions, archives, etc. without
%%   prior consultation with the LaTeX Project Team.
%%
%% -----------------------------------------------------------------------
%
%<*driver|package>
\RequirePackage{l3names}
%</driver|package>
%\fi
\GetIdInfo$Id: l3prg.dtx 768 2008-08-05 19:45:06Z morten $
       {L3 Experimental control structures}
%\iffalse
%<*driver>
%\fi
\ProvidesFile{\filename.\filenameext}
  [\filedate\space v\fileversion\space\filedescription]
%\iffalse
\documentclass{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
%</driver>
% \fi
%
%
% \title{The \textsf{l3prg} package\thanks{This file
%         has version number \fileversion, last
%         revised \filedate.}\\
% Program control structures}
% \author{\Team}
% \date{\filedate}
% \maketitle
%
%
% \section{Control structures}
%
% \subsection{Choosing modes}
%
% \begin{function}{\mode_if_vertical_p:|
%                  \mode_if_vertical:TF |
%                  \mode_if_vertical:T |
%                  \mode_if_vertical:F
%                 }
% \begin{syntax}
%   "\mode_if_vertical:TF" "{"<true code>"}" "{"<false code>"}"
% \end{syntax}
% Determines if \TeX{} is in vertical mode or not and executes either
% <true code> or <false code> accordingly.
% \end{function}
%
% \begin{function}{\mode_if_horizontal_p:|
%                  \mode_if_horizontal:TF |
%                  \mode_if_horizontal:T |
%                  \mode_if_horizontal:F
%                 }
% \begin{syntax}
%   "\mode_if_horizontal:TF" "{"<true code>"}" "{"<false code>"}"
% \end{syntax}
% Determines if \TeX{} is in horizontal mode or not and executes either
% <true code> or <false code> accordingly.
% \end{function}
%
%
% \begin{function}{
%     \mode_if_inner_p:|
%     \mode_if_inner:TF|
%     \mode_if_inner:T|
%     \mode_if_inner:F
%                 }
% \begin{syntax}
%   "\mode_if_inner:TF" "{"<true code>"}" "{"<false code>"}"
% \end{syntax}
% Determines if \TeX{} is in inner mode or not and executes either
% <true code> or <false code> accordingly.
% \end{function}
%
% \begin{function}{
%               \mode_if_math:TF|
%               \mode_if_math:T|
%               \mode_if_math:F|
%                 }
% \begin{syntax}
%   "\mode_if_math:TF" "{"<true code>"}" "{"<false code>"}"
% \end{syntax}
% Determines if \TeX{} is in math mode or not and executes either
% <true code> or <false code> accordingly.
% \begin{texnote}
% This version will choose the right branch even at the beginning of
% an alignment cell.
% \end{texnote}
% \end{function}
%
%
% \subsubsection{Alignment safe grouping and scanning}
%
% \begin{function}{\scan_align_safe_stop:}
% \begin{syntax}
%   "\scan_align_safe_stop:"
% \end{syntax}
% This function gets \TeX{} on the right track inside an alignment
% cell but without destroying any kerning.
% \end{function}
%
%
% \begin{function}{\group_align_safe_begin:|
%                  \group_align_safe_end:}
% \begin{syntax}
%   "\group_align_safe_begin:" <...> "\group_align_safe_end:"
% \end{syntax}
% Encloses <...> inside a group but is safe inside an alignment cell.
% See the implementation of |\peek_token_generic:NNTF| for an
% application.
% \end{function}
%
%
% \subsection{Producing $n$ copies}
% 
% There are often several different requirements for producing
% multiple copies of something. Sometimes one might want to produce a
% number of identical copies of a sequence of tokens whereas at other
% times the goal is to simulate a for loop as known from most real
% programming languages.
%
% \begin{function}{\prg_replicate:nn }
% \begin{syntax}
%   "\prg_replicate:nn" "{" <number> "}" "{" <arg> "}"
% \end{syntax}
% Creates <number> copies of <arg>. Expandable.
% \end{function}
%
%
% \begin{function}{\prg_stepwise_function:nnnN}
% \begin{syntax}
%   "\prg_stepwise_function:nnnN" "{"<start>"}" "{"<step>"}"
%   "{"<end>"}" <function>
% \end{syntax}
% This function performs <action> once for each step starting at
% <start> and ending once <end> is passed. <function> is placed
% directly in front of a brace group holding the current number so it
% should usually be a function taking one argument. The
% |\prg_stepwise_function:nnnN| function is expandable.
% \end{function}
%
% \begin{function}{\prg_stepwise_inline:nnnn}
% \begin{syntax}
%   "\prg_stepwise_inline:nnnn" "{"<start>"}" "{"<step>"}" "{"<end>"}"
%   "{"<action>"}"
% \end{syntax}
% Same as |\prg_stepwise_function:nnnN| except here <action> is
% performed each time with |##1| as a placeholder for the number
% currently being tested. This function is not expandable and it is
% nestable.
% \end{function}
%
% \begin{function}{\prg_stepwise_variable:nnnNn}
% \begin{syntax}
%   "\prg_stepwise_variable:nnnn" "{"<start>"}" "{"<step>"}" "{"<end>"}"
%   <temp-var> "{"<action>"}"
% \end{syntax}
% Same as |\prg_stepwise_inline:nnnn| except here the current value is
% stored in <temp-var> and the programmer can use it in <action>. This
% function is not expandable.
% \end{function}
%
%
%
%  \subsection{Conditionals and logical operations}
%
%
%  \LaTeX3 has two primary forms of conditional flow processing. The
%  one type deals with the truth value of a test directly as in
%  "\cs_free:NTF" where you test if a control sequence was undefined
%  and then execute either the \m{true} or \m{false} part depending on
%  the result and after exiting the underlying "\if...\fi:" structure.
%  The second type has to do with predicate functions like
%  "\cs_free_p:N" which return either "\c_true" or "\c_false" to be
%  used in testing with "\if:w".
%
%
%  This section describes a boolean data type which is closely
%  connected to both parts as sometimes you want to execute some code
%  depending on the value of a switch (e.g.,~draft/final) and other
%  times you perhaps want to use it as a predicate function in an
%  "\if:w" test. Parsing "\iffalse"
%  and "\iftrue" tokens can be quite tricky at times so the easiest is to
%  simply  let a boolean either be "\c_true" or "\c_false". This
%  also means we get the logical operations And, Or, and Not which can
%  then be used on both the boolean type and predicate functions. All
%  functions by the name |\predicate| are expandable and expect the
%  input to also be fully expandable. More generic constructs do not
%  contain |predicate| in their names.
%
%
%  \subsubsection{The boolean data type}
%
%  \begin{function}{%
%                   \bool_new:N |
%                   \bool_new:c |
%  }
%  \begin{syntax}
%     "\bool_new:N" <bool> 
%  \end{syntax}
%  Define a new boolean variable. The initial value is <false>. A
%  boolean is actually just either "\c_true" or "\c_false".
%  \end{function}
%
%  \begin{function}{%
%                   \bool_set_true:N |
%                   \bool_set_true:c |
%                   \bool_set_false:N |
%                   \bool_set_false:c |
%                   \bool_gset_true:N |
%                   \bool_gset_true:c |
%                   \bool_gset_false:N |
%                   \bool_gset_false:c |
%  }
%  \begin{syntax}
%     "\bool_gset_false:N" <bool>
%  \end{syntax}
%  Set <bool> either true or false. We can also do this globally.
%  \end{function}
%
%
%  \begin{function}{%
%                   \bool_set_eq:NN |
%                   \bool_set_eq:Nc |
%                   \bool_set_eq:cN |
%                   \bool_set_eq:cc |
%                   \bool_gset_eq:NN |
%                   \bool_gset_eq:Nc |
%                   \bool_gset_eq:cN |
%                   \bool_gset_eq:cc |
%
%  }
%  \begin{syntax}
%     "\bool_set_eq:NN" <bool1> <bool2>
%  \end{syntax}
%  Set <bool1> equal to the value of <bool2>.
%  \end{function}
%
%  \begin{function}{%
%                   \bool_if:NTF |
%                   \bool_if:NT |
%                   \bool_if:NF |
%                   \bool_if_p:N |
%
%  }
%  \begin{syntax}
%     "\bool_if:NTF" <bool> "{"\m{true}"}" "{"\m{false}"}"   \\
%     "\bool_if_p:N" <bool>
%  \end{syntax}
%  Test the truth value of the boolean and execute the \m{true} or
%  \m{false} code. "\bool_if_p:N" is a predicate function for use in
%  "\if:w" tests.
%  \end{function}
%
%  \begin{function}{%
%                   \bool_whiledo:NT |
%                   \bool_whiledo:NF |
%                   \bool_dowhile:NT |
%                   \bool_dowhile:NF |
%
%  }
%  \begin{syntax}
%     "\bool_whiledo:NT" <bool> "{"\m{true}"}"  \\
%     "\bool_whiledo:NF" <bool> "{"\m{false}"}"  \\
%  \end{syntax}
%  The "T" versions execute the \m{true} code as long as the boolean is
%  true and the "F" versions execute the \m{false} code as long as the
%  boolean is false. The "whiledo" functions execute the body after
%  testing the boolean and the "dowhile" functions executes the body
%  first and then tests the boolean.
%  \end{function}
%
%
%  \begin{function}{%
%                   \l_tmpa_bool |
%                   \g_tmpa_bool |
%
%  }
%  \begin{syntax}
%  \end{syntax}
%  Reserved booleans.
%  \end{function}
%
%  \subsubsection{Logical operations}
%
%  Somewhat related to the subject of conditional flow processing is
%  logical operators as these deal with \m{true} and \m{false}
%  statements which is precisely what the predicate functions return.
%
%
%  \begin{function}{%
%                   \predicate_p:n |
%                   \predicate:nTF |
%                   \predicate:nT |
%                   \predicate:nF |
%  }
%  \begin{syntax}
%    "\predicate:nTF" "{"<list of predicates>"}" "{"<true>"}"
%    "{"<false>"}"
%  \end{syntax}
%  The functions evaluate the truth value of \m{list of predicates}
%  where each predicate is separated by \verb+&&+ or \verb+||+
%  denoting logical And and Or functions. Minimal evaluation is
%  carried out so that whenever a truth value cannot be changed
%  anymore, the remainding tests are not carried out. Hence
% \begin{verbatim}
%   \predicate_p:n{
%     \int_compare_p:nNn 1=1 &&
%     \predicate_p:n {
%       \int_compare_p:nNn 2=3 ||
%       \int_compare_p:nNn 4=4 ||
%       \int_compare_p:nNn 1=\error % is skipped
%     } &&
%     \int_compare_p:nNn 2=2 
%   }
% \end{verbatim}
%  returns \meta{true}.
%  \end{function}
%
%
%
%
%  \begin{function}{%
%                   \predicate_not_p:n |
%  }
%  \begin{syntax}
%     "\predicate_not_p:n" "{"<list of predicates>"}"
%  \end{syntax}
%  "\predicate_not_p:n"
%  reverses the truth value of its argument. Thus
%  \begin{quote}
%  "\prg_if_predicate_not_p:n {\prg_if_predicate_not_p:n {\c_true}}"
%  \end{quote}
%  ultimately returns \m{true}.
%  \end{function}
%
%  \subsubsection{Case switches}
%
%
%  \begin{function}{
%                   \prg_case_int:nnn |
%
%  }
%  \begin{syntax}
%    "\prg_case_int:nnn" "{"<integer expr>"}" "{" 
%    "  {"\m{integer expr$\sb 1$}"}""{"\m{code$\sb 1$}"}""{"\m{integer expr$\sb 2$}"}""{"\m{code$\sb 2$}"}"\\
%    "    ...""{"\m{integer expr$\sb n$}"}""{"\m{code$\sb n$}"}"\\
%    "}" "{"\m{else case}"}" 
%  \end{syntax}
%  This function evaluates the first \meta{integer expr} and then compares it
%  to the values found in the list. Thus the expression
% \begin{verbatim}
% \prg_case:nnn{2*5}{
%   {5}{Small}  {4+6}{Medium}  {-2*10}{Negative}
% }{Other}
% \end{verbatim}
%  evaluates first the term to look for and then tries to find this
%  value in the list of values. If the value is found, the code on its
%  right is executed after removing the remainder of the list. If the
%  value is not found, the \meta{else case} is executed. The example
%  above will return ``Medium''.
%
% The function is expandable and is written in such a way that
% \texttt{f} style expansion can take place cleanly, i.e., no tokens
% from within the function are left over.
%  \end{function}
%
%  \begin{function}{
%                   \prg_case_dim:nnn |
%
%  }
%  \begin{syntax}
%    "\prg_case_int:nnn" "{"<dim expr>"}" "{" 
%    "  {"\m{dim expr$\sb 1$}"}""{"\m{code$\sb 1$}"}""{"\m{dim expr$\sb 2$}"}""{"\m{code$\sb 2$}"}"\\
%    "    ...""{"\m{dim expr$\sb n$}"}""{"\m{code$\sb n$}"}"\\
%    "}" "{"\m{else case}"}" 
%  \end{syntax}
%  This function works just like |\prg_case_int:nnn| except it works
%  for \meta{dim} registers.
%  \end{function}
%
%  \begin{function}{
%                   \prg_case_str:nnn |
%
%  }
%  \begin{syntax}
%    "\prg_case_str:nnn" "{"<string>"}" "{" 
%    "  {"\m{string$\sb 1$}"}""{"\m{code$\sb 1$}"}""{"\m{string$\sb 2$}"}""{"\m{code$\sb 2$}"}"\\
%    "    ...""{"\m{string$\sb n$}"}""{"\m{code$\sb n$}"}"\\
%    "}" "{"\m{else case}"}" 
%  \end{syntax}
%  This function works just like |\prg_case_int:nnn| except it
%  compares strings. Each string is evaluated fully using \texttt{x}
%  style expansion.
%
% The function is expandable\footnote{Provided you use pdfTeX v1.30 or
% later} and is written in such a way that
% \texttt{f} style expansion can take place cleanly, i.e., no tokens
% from within the function are left over.
%  \end{function}
% 
%  \subsubsection{Generic loops}
%
%
%  \begin{function}{
%                   \prg_whiledo:nT |
%                   \prg_whiledo:nF |
%                   \prg_dowhile:nT |
%                   \prg_dowhile:nF |
%
%  }
%  \begin{syntax}
%     "\prg_whiledo:nT" "{"<test>"}" "{"\m{true}"}"  \\
%     "\prg_whiledo:nF" "{"<test>"}" "{"\m{false}"}"  
%  \end{syntax}
%  The "T" versions execute the \m{true} code as long as <test> is
%  true and the "F" versions execute the \m{false} code as long as
%  <test> is false. The "whiledo" functions execute the body after
%  testing the boolean and the "dowhile" functions executes the body
%  first and then tests the boolean. For the "T" versions, <test>
%  should end with a function executing only the \meta{true} code for
%  some test such as |\tlp_if_eq:NNT|. Similarly the "F" types should
%  end with |\tlp_if_eq:NNF|.
%  \end{function}
%
% \subsection{Sorting}
%
%
%  \begin{function}{
%                   \prg_quicksort:n |
%  }
%  \begin{syntax}
%    "\prg_quicksort:n" "{" "{"<element~1>"}" "{"<element~2>"}"
%      \dots\space "{"<element~n>"}" "}"
%  \end{syntax}
%  Performs a Quicksort on the token list. The comparisons are
%  performed by the function |\prg_quicksort_compare:nnTF| which is up
%  to the programmer to define. When the sorting process is over, all
%  elements are given as argument to the function
%  |\prg_quicksort_function:n| which the programmer also controls.
%  \end{function}
%
%  \begin{function}{
%                   \prg_quicksort_function:n |
%                   \prg_quicksort_compare:nnTF
%  }
%  \begin{syntax}
%    "\prg_quicksort_function:n" "{"<element>"}" \\
%    "\prg_quicksort_compare:nnTF" "{"<element 1>"}" "{"<element 2>"}"\\
%  \end{syntax}
%  The two functions the programmer must define before calling
%  |\prg_quicksort:n|. As an example we could define
% \begin{quote}
% |\def:NNn\prg_quicksort_function:n 1{{#1}}|\\
% |\def:NNn\prg_quicksort_compare:nnTF 2{\num_compare:nNnTF{#1}>{#2}}|
% \end{quote}
% Then the function call
% \begin{quote}
% |\prg_quicksort:n {876234520}|
% \end{quote}
% would return |{0}{2}{2}{3}{4}{5}{6}{7}{8}|. An alternative example
% where one sorts a list of words, |\prg_quicksort_compare:nnTF| could
% be defined as
% \begin{quote}
% |\def:NNn\prg_quicksort_compare:nnTF 2{|\\
% |  \num_compare:nNnTF{\tlist_compare:nn{#1}{#2}}>\c_zero }|
% \end{quote}
% 
%  \end{function}
%
%
% \StopEventually{}
%
% \subsection{The Implementation}
%
%
%    We start by ensuring that the required packages are loaded.
%    \begin{macrocode}
%<*package>
\ProvidesExplPackage
  {\filename}{\filedate}{\fileversion}{\filedescription}
\RequirePackage{l3quark}
\RequirePackage{l3toks}
\RequirePackage{l3int}
%</package>
%<*initex|package>
%    \end{macrocode}
%
%
%  \subsubsection{Choosing modes}
%
%  \begin{macro}{\mode_if_vertical_p:}
%  \begin{macro}{\mode_if_vertical:TF}
%  \begin{macro}{\mode_if_vertical:T}
%  \begin{macro}{\mode_if_vertical:F}
%  For testing vertical mode.
%    \begin{macrocode}
\def_new:Npn \mode_if_vertical_p: {
  \if_mode_vertical: \c_true \else: \c_false\fi:}
\def_test_function_new:npn{mode_if_vertical:}{\if_mode_vertical:}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\mode_if_horizontal_p:}
%  \begin{macro}{\mode_if_horizontal:TF}
%  \begin{macro}{\mode_if_horizontal:T}
%  \begin{macro}{\mode_if_horizontal:F}
%  For testing horizontal mode.
%    \begin{macrocode}
\def_new:Npn \mode_if_horizontal_p: {
  \if_mode_horizontal: \c_true \else: \c_false\fi:}
\def_test_function_new:npn{mode_if_horizontal:}{\if_mode_horizontal:}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\mode_if_inner_p:}
%  \begin{macro}{\mode_if_inner:TF}
%  \begin{macro}{\mode_if_inner:T}
%  \begin{macro}{\mode_if_inner:F}
%  For testing inner mode.
%    \begin{macrocode}
\def_new:Npn \mode_if_inner_p: {
  \if_mode_inner: \c_true \else: \c_false\fi:}
\def_test_function_new:npn{mode_if_inner:}{\if_mode_inner:}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\mode_if_math:TF}
%  \begin{macro}{\mode_if_math:T}
%  \begin{macro}{\mode_if_math:F}
%  For testing math mode. Uses the kern-save |\scan_align_safe_stop:|.
%    \begin{macrocode}
\def_test_function_new:npn{mode_if_math:} {
  \scan_align_safe_stop:  \if_mode_math: }
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
% \paragraph{Alignment safe grouping and scanning}
%
%
%  \begin{macro}{\group_align_safe_begin:}
%  \begin{macro}{\group_align_safe_end:}
%  \TeX's alignment structures present many problems. As Knuth says
%  himself in \emph{\TeX: The Program}: ``It's sort of a miracle
%  whenever |\halign| or |\valign| work, [\ldots]'' One problem relates
%  to commands that internally issues a |\cr| but also peek ahead for
%  the next character for use in, say, an optional argument. If the
%  next token happens to be a |&| with category code~4 we will get some
%  sort of weird error message because the underlying
%  |\tex_futurelet:D| will store the token at the end of the alignment
%  template. This could be a |&|$\sb4$ giving a message like
%  |! Misplaced \cr.| or even worse: it could be the |\endtemplate|
%  token causing even more trouble! To solve this we have to open a
%  special group so that \TeX{} still thinks it's on safe ground but at
%  the same time we don't want to introduce any brace group that may
%  find its way to the output. The following functions help with this
%  by using code documented only in Appendix~D of
%  \emph{The \TeX book}\dots
%    \begin{macrocode}
\def_new:Npn \group_align_safe_begin: {
  \if_false:{\fi:\if_num:w`}=\c_zero\fi:}
\def_new:Npn \group_align_safe_end:   {\if_num:w`{=\c_zero}\fi:}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%
%  \begin{macro}{\scan_align_safe_stop:}
%  When \TeX{} is in the beginning of an align cell (right after the
%  |\cr|) it is in a somewhat strange mode as it is looking ahead to
%  find an |\tex_omit:D| or |\tex_noalign:D| and hasn't looked at the
%  preamble yet. Thus an |\tex_ifmmode:D| test will always fail unless
%  we insert |\scan_stop:| to stop \TeX's scanning ahead. On the other
%  hand we don't want to insert a |\scan_stop:| every time as that will
%  destroy kerning between letters\footnote{Unless we enforce an extra
%  pass with an appropriate value of \texttt{\string\pretolerance}.}
%  Unfortunately there is no way to detect if we're in the beginning of
%  an alignment cell as they have different characteristics depending
%  on column number etc. However we \emph{can} detect if we're in an
%  alignment cell by checking the current group type and we can also
%  check if the previous node was a character or ligature. What is done
%  here is that |\scan_stop:| is only inserted iff a)~we're in the
%  outer part of an alignment cell and b)~the last node \emph{wasn't} a
%  char node or a ligature node.
%    \begin{macrocode}
\def_new:Npn \scan_align_safe_stop: {
  \num_compare:nNnT \etex_currentgrouptype:D = \c_six
  {
    \num_compare:nNnF \etex_lastnodetype:D = \c_zero
    {
      \num_compare:nNnF \etex_lastnodetype:D = \c_seven
        \scan_stop:
    }
  }
}
%    \end{macrocode}
%  \end{macro}
%
% \subsubsection{Making $n$ copies}
% 
% \begin{macro}{\prg_replicate:nn}
% \begin{macro}{\prg_replicate_aux:N}
% \begin{macro}{\prg_replicate_first_aux:N}
% This function uses a cascading csname technique by David Kastrup
% (who else :-)
% 
% The idea is to make the input "25" result in first adding five, and
% then 20 copies of the code to be replicated. The technique uses
% cascading csnames which means that we start building several csnames
% so we end up with a list of functions to be called in reverse
% order. This is important here (and other places) because it means
% that we can for instance make the function that inserts five copies
% of something to also hand down ten to the next function in
% line. This is exactly what happens here: in the example with "25"
% then the next function is the one that inserts two copies but it
% sees the ten copies handed down by the previous function. In order
% to avoid the last function to insert say, 100 copies of the original
% argument just to gobble them again we define separate functions to
% be inserted first. Finally we must ensure that the cascade comes to
% a peaceful end so we make it so that the original csname \TeX{} is
% creating is simply "\use_noop:" expanding to nothing.
%
% This function has one flaw though: Since it constantly passes down
% ten copies of its previous argument it will severely affect the main
% memory once you start demanding hundreds of thousands of copies. Now
% I don't think this is a real limitation for any ordinary use. An
% alternative approach is to create a string of "m"'s with
% "\int_to_roman:w" which can be done with just four macros but that
% method has its own problems since it can exhaust the string
% pool. Also, it is considerably slower than what we use here so the
% few extra csnames are well spent I would say.
%    \begin{macrocode}
\def_new:Npn \prg_replicate:nn #1{
  \cs:w use_noop: 
  \exp_after:NN\prg_replicate_first_aux:N
  \int_use:N \int_eval:n{#1} \cs_end: 
  \cs_end: 
}
\def_new:Npn \prg_replicate_aux:N#1{
  \cs:w prg_replicate_#1:n\prg_replicate_aux:N
}
\def_new:Npn \prg_replicate_first_aux:N#1{
  \cs:w prg_replicate_first_#1:n\prg_replicate_aux:N
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% Then comes all the functions that do the hard work of inserting all
% the copies.
%    \begin{macrocode}
\def_new:Npn      \prg_replicate_ :n #1{}% no, this is not a typo!
\def_long_new:cpn {prg_replicate_0:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}}
\def_long_new:cpn {prg_replicate_1:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}#1}
\def_long_new:cpn {prg_replicate_2:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1}
\def_long_new:cpn {prg_replicate_3:n}#1{
  \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1}
\def_long_new:cpn {prg_replicate_4:n}#1{
  \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1}
\def_long_new:cpn {prg_replicate_5:n}#1{
  \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1}
\def_long_new:cpn {prg_replicate_6:n}#1{
  \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1}
\def_long_new:cpn {prg_replicate_7:n}#1{
  \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1}
\def_long_new:cpn {prg_replicate_8:n}#1{
  \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1}
\def_long_new:cpn {prg_replicate_9:n}#1{
  \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1#1}
%    \end{macrocode}
%    Users shouldn't ask for something to be replicated once or even
%    not at all but\dots
%    \begin{macrocode}
\def_long_new:cpn {prg_replicate_first_0:n}#1{\cs_end: }
\def_long_new:cpn {prg_replicate_first_1:n}#1{\cs_end: #1}
\def_long_new:cpn {prg_replicate_first_2:n}#1{\cs_end: #1#1}
\def_long_new:cpn {prg_replicate_first_3:n}#1{\cs_end: #1#1#1}
\def_long_new:cpn {prg_replicate_first_4:n}#1{\cs_end: #1#1#1#1}
\def_long_new:cpn {prg_replicate_first_5:n}#1{\cs_end: #1#1#1#1#1}
\def_long_new:cpn {prg_replicate_first_6:n}#1{\cs_end: #1#1#1#1#1#1}
\def_long_new:cpn {prg_replicate_first_7:n}#1{\cs_end: #1#1#1#1#1#1#1}
\def_long_new:cpn {prg_replicate_first_8:n}#1{\cs_end: #1#1#1#1#1#1#1#1}
\def_long_new:cpn {prg_replicate_first_9:n}#1{\cs_end: #1#1#1#1#1#1#1#1#1}
%    \end{macrocode} 
%
%
%
%
% \begin{macro}{\prg_stepwise_function:nnnN}
% \begin{macro}{\prg_stepwise_function_incr:nnnN}
% \begin{macro}{\prg_stepwise_function_decr:nnnN}
%   A stepwise function. Firstly we check the direction of the steps
%   |#2| since that will depend on which test we should use. If the
%   step is positive we use a greater than test, otherwise a less than
%   test.  If the test comes out true exit, otherwise perform |#4|,
%   add the step to |#1| and try again with this new value of |#1|.
%    \begin{macrocode}
\def_long_new:NNn \prg_stepwise_function:nnnN 2{
  \num_compare:nNnTF{#2}<\c_zero
  {\exp_args:No\prg_stepwise_function_decr:nnnN }
  {\exp_args:No\prg_stepwise_function_incr:nnnN }
  {\int_use:N\int_eval:n{#1}}{#2}
}
\def_long_new:NNn \prg_stepwise_function_incr:nnnN 4{
  \num_compare:nNnF {#1}>{#3}
  {
    #4{#1}
    \exp_args:No \prg_stepwise_function_incr:nnnN 
    {\int_use:N\int_eval:n{#1 + #2}} 
    {#2}{#3}{#4}
  }
}
\def_long_new:NNn \prg_stepwise_function_decr:nnnN 4{
  \num_compare:nNnF {#1}<{#3}
  {
    #4{#1}
    \exp_args:No \prg_stepwise_function_decr:nnnN 
    {\int_use:N\int_eval:n{#1 + #2}} 
    {#2}{#3}{#4}
  }
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\g_prg_inline_level_int}
% \begin{macro}{\prg_stepwise_inline:nnnn}
% \begin{macro}{\prg_stepwise_inline_decr:nnnn}
% \begin{macro}{\prg_stepwise_inline_incr:nnnn}
%   This function uses the same approach as for instance
%   |\clist_map_inline:Nn| to allow arbitrary nesting. First construct
%   the special function and then call an auxiliary one which just
%   carries the newly constructed csname. Must make assignments global
%   when we maintain our own stack.
%    \begin{macrocode}
\int_new:N\g_prg_inline_level_int
\def_long_new:NNn\prg_stepwise_inline:nnnn 4{
  \int_gincr:N \g_prg_inline_level_int
  \gdef:cpn{prg_stepwise_inline_\int_use:N\g_prg_inline_level_int :n}##1{#4}
  \num_compare:nNnTF {#2}<\c_zero
  {\exp_args:Nco \prg_stepwise_inline_decr:Nnnn }
  {\exp_args:Nco \prg_stepwise_inline_incr:Nnnn }
  {prg_stepwise_inline_\int_use:N\g_prg_inline_level_int :n} 
  {\int_use:N\int_eval:n{#1}} {#2} {#3}
  \int_gdecr:N \g_prg_inline_level_int
}
\def_long_new:NNn \prg_stepwise_inline_incr:Nnnn 4{
  \num_compare:nNnF {#2}>{#4}
  {
    #1{#2}
    \exp_args:NNo \prg_stepwise_inline_incr:Nnnn #1
    {\int_use:N\int_eval:n{#2 + #3}} {#3}{#4}
  }
}
\def_long_new:NNn \prg_stepwise_inline_decr:Nnnn 4{
  \num_compare:nNnF {#2}<{#4}
  {
    #1{#2}
    \exp_args:NNo \prg_stepwise_inline_decr:Nnnn #1
    {\int_use:N\int_eval:n{#2 + #3}} {#3}{#4}
  }
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\prg_stepwise_variable:nnnNn}
% \begin{macro}{\prg_stepwise_variable_decr:nnnNn}
% \begin{macro}{\prg_stepwise_variable_incr:nnnNn}
%   Almost the same as above. Just store the value in |#4| and execute
%   |#5|.
%    \begin{macrocode}
\def_long_new:NNn \prg_stepwise_variable:nnnNn 2 {
  \num_compare:nNnTF {#2}<\c_zero
  {\exp_args:No\prg_stepwise_variable_decr:nnnNn}
  {\exp_args:No\prg_stepwise_variable_incr:nnnNn}
  {\int_use:N\int_eval:n{#1}}{#2}
}
\def_long_new:NNn \prg_stepwise_variable_incr:nnnNn 5 {
  \num_compare:nNnF {#1}>{#3}
  {
    \def:Npn #4{#1} #5
    \exp_args:No \prg_stepwise_variable_incr:nnnNn
    {\int_use:N\int_eval:n{#1 + #2}}{#2}{#3}#4{#5}
  }
}
\def_long_new:NNn \prg_stepwise_variable_decr:nnnNn 5 {
  \num_compare:nNnF {#1}<{#3}
  {
    \def:Npn #4{#1} #5
    \exp_args:No \prg_stepwise_variable_decr:nnnNn
    {\int_use:N\int_eval:n{#1 + #2}}{#2}{#3}#4{#5}
  }
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \subsubsection{Booleans}
%  For normal booleans we set them to either "\c_true" or "\c_false"
%  and then use "\if:w" to choose the right branch. The functions
%  return either the TF, T, or F case \emph{after} ending the |\if:w|.
%  We only define the |N| versions here as the |c| versions can easily
%  be constructed with the expansion module.
%
%  \begin{macro}{\bool_new:N}
%  \begin{macro}{\bool_new:c}
%  \begin{macro}{\bool_set_true:N}
%  \begin{macro}{\bool_set_true:c}
%  \begin{macro}{\bool_set_false:N}
%  \begin{macro}{\bool_set_false:c}
%  \begin{macro}{\bool_gset_true:N}
%  \begin{macro}{\bool_gset_true:c}
%  \begin{macro}{\bool_gset_false:N}
%  \begin{macro}{\bool_gset_false:c}
%  Defining and setting a boolean is easy.
%    \begin{macrocode}
\def_new:Npn \bool_new:N #1   { \let_new:NN #1 \c_false }
\def_new:Npn \bool_new:c #1   { \let_new:cN {#1} \c_false }
\def_new:Npn \bool_set_true:N   #1 { \let:NN  #1 \c_true }
\def_new:Npn \bool_set_true:c   #1 { \let:cN  {#1} \c_true }
\def_new:Npn \bool_set_false:N  #1 { \let:NN  #1 \c_false }
\def_new:Npn \bool_set_false:c  #1 { \let:cN  {#1} \c_false }
\def_new:Npn \bool_gset_true:N   #1 { \glet:NN  #1 \c_true }
\def_new:Npn \bool_gset_true:c   #1 { \glet:cN  {#1} \c_true }
\def_new:Npn \bool_gset_false:N  #1 { \glet:NN  #1 \c_false }
\def_new:Npn \bool_gset_false:c  #1 { \glet:cN  {#1} \c_false }
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\bool_set_eq:NN}
%  \begin{macro}{\bool_set_eq:Nc}
%  \begin{macro}{\bool_set_eq:cN}
%  \begin{macro}{\bool_set_eq:cc}
%  \begin{macro}{\bool_gset_eq:NN}
%  \begin{macro}{\bool_gset_eq:Nc}
%  \begin{macro}{\bool_gset_eq:cN}
%  \begin{macro}{\bool_gset_eq:cc}
%  Setting a boolean to another is also pretty easy.
%    \begin{macrocode}
\let_new:NN \bool_set_eq:NN \let:NN
\let_new:NN \bool_set_eq:Nc \let:Nc
\let_new:NN \bool_set_eq:cN \let:cN
\let_new:NN \bool_set_eq:cc \let:cc
\let_new:NN \bool_gset_eq:NN \glet:NN
\let_new:NN \bool_gset_eq:Nc \glet:Nc
\let_new:NN \bool_gset_eq:cN \glet:cN
\let_new:NN \bool_gset_eq:cc \glet:cc
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\l_tmpa_bool}
%  \begin{macro}{\g_tmpa_bool}
%  A few booleans just if you need them.
%    \begin{macrocode}
\bool_new:N \l_tmpa_bool
\bool_new:N \g_tmpa_bool
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\bool_if:NTF}
%  \begin{macro}{\bool_if:NT}
%  \begin{macro}{\bool_if:NF}
%  \begin{macro}{\bool_if:cTF}
%  \begin{macro}{\bool_if:cT}
%  \begin{macro}{\bool_if:cF}
%  Straight forward here.
%    \begin{macrocode}
\def_test_function_new:npn{bool_if:N}#1{\if:w #1}
\def_new:Npn \bool_if:cTF{\exp_args:Nc\bool_if:NTF}
\def_new:Npn \bool_if:cT{\exp_args:Nc\bool_if:NT}
\def_new:Npn \bool_if:cF{\exp_args:Nc\bool_if:NF}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\bool_if_p:N}
%  \begin{macro}{\bool_if_p:c}
%  We also make a predicate function for the "bool" data type but since
%  we use "\c_true" and "\c_false" it's rather simple\dots{}
%  Not that there's anything wrong in simplicity -- on the contrary!
%    \begin{macrocode}
\def_new:Npn \bool_if_p:N #1 { #1 }
\let_new:NN \bool_if_p:c \cs_use:c
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%
%  \begin{macro}{\bool_whiledo:NT}
%  \begin{macro}{\bool_whiledo:cT}
%  \begin{macro}{\bool_whiledo:NF}
%  \begin{macro}{\bool_whiledo:cF}
%  A "while" loop where the boolean is tested before executing the
%  statement. The "NT" version executes the "T" part as long as the
%  boolean is true while the "NF" version executes the "F" part as
%  long as the boolean is false.
%    \begin{macrocode}
\def_long_new:Npn \bool_whiledo:NT #1 #2 {
  \bool_if:NT #1 {#2 \bool_whiledo:NT #1 {#2}}
}
\def_new:Npn \bool_whiledo:cT{\exp_args:Nc\bool_whiledo:NT}
\def_long_new:Npn \bool_whiledo:NF #1 #2 {
  \bool_if:NF #1 {#2 \bool_whiledo:NF #1 {#2}}
}
\def_new:Npn \bool_whiledo:cF{\exp_args:Nc\bool_whiledo:NF}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\bool_dowhile:NT}
%  \begin{macro}{\bool_dowhile:cT}
%  \begin{macro}{\bool_dowhile:NF}
%  \begin{macro}{\bool_dowhile:cF}
%  A "do-while" loop where the body is performed at least once and the
%  boolean is tested after executing the body. Otherwise identical to
%  the above functions.
%    \begin{macrocode}
\def_long_new:Npn \bool_dowhile:NT #1 #2 {
  #2 \bool_if:NT #1 {\bool_dowhile:NT #1 {#2}}
}
\def_new:Npn \bool_dowhile:cT{\exp_args:Nc\bool_dowhile:NT}
\def_long_new:Npn \bool_dowhile:NF #1 #2 {
  #2 \bool_if:NF #1 {\bool_dowhile:NF #1 {#2}}
}
\def_new:Npn \bool_dowhiledo:cF{\exp_args:Nc\bool_dowhile:cF}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\bool_double_if:NNnnnn}
%  \begin{macro}{\bool_double_if:cNnnnn}
%  \begin{macro}{\bool_double_if:Ncnnnn}
%  \begin{macro}{\bool_double_if:ccnnnn}
%    Execute |#3| iff TT, |#4| iff TF, |#5| iff FT and |#6| iff
%    FF. The name isn't that great but I'll have to think about
%    that. Ideally it should be something with |TF| since only one of
%    the cases is executed but we haven't got any naming scheme for
%    this kind of thing so for now I'll just stick to simple |nnnn|.
%    \begin{macrocode}
\def_new:Npn \bool_double_if:NNnnnn#1#2{
  \if_case:w \num_eval:w #1\scan_stop:
    \if_case:w \num_eval:w #2\scan_stop:
      \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_i:nnnn
    \else:
      \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_ii:nnnn
    \fi:
  \else:
    \if_case:w \num_eval:w #2\scan_stop:
      \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_iii:nnnn
    \else:
      \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_iv:nnnn
    \fi:
  \fi:
}
\def_new:Npn \bool_double_if:cNnnnn{\exp_args:Nc\bool_double_if:NNnnnn}
\def_new:Npn \bool_double_if:Ncnnnn{\exp_args:NNc\bool_double_if:NNnnnn}
\def_new:Npn \bool_double_if:ccnnnn{\exp_args:Ncc\bool_double_if:NNnnnn}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
% \subsubsection{Generic testing}
%
% \begin{macro}{\prg_whiledo:nT}
% \begin{macro}{\prg_whiledo:nF}
% \begin{macro}{\prg_dowhile:nT}
% \begin{macro}{\prg_dowhile:nF}
%   We provide these four generic while loops. |#1| is a test function
%   and for the |T| functions it should be a test function ending with
%   just the true case. Similar for the |F| types.
%    \begin{macrocode}
\def_long_new:Npn \prg_whiledo:nT #1#2{
  #1 {#2 \prg_whiledo:nT {#1}{#2}}
}
\def_long_new:Npn \prg_whiledo:nF #1#2{
  #1 {#2 \prg_whiledo:nF {#1}{#2}}
}
\def_long_new:Npn \prg_dowhile:nT #1#2{
  #2 #1 {\prg_dowhile:nT {#1}{#2}}
}
\def_long_new:Npn \prg_dowhile:nF #1#2{
  #2 #1 {\prg_dowhile:nF {#1}{#2}}
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%  \begin{macro}{\predicate_p:n}
%  \begin{macro}{\predicate:nTF}
%  \begin{macro}{\predicate:nT}
%  \begin{macro}{\predicate:nF}
%  \begin{macro}{\predicate_auxi:NN}
%  \begin{macro}{\predicate_auxii:NNN}
%  \begin{macro}{\predicate_88_0:w}^^A% fix!
%  \begin{macro}{\predicate_88_1:w}^^A% fix!
%  \begin{macro}{\predicate_II_0:w}^^A% fix!
%  \begin{macro}{\predicate_II_1:w}^^A fix!
%  \begin{macro}{\predicate_02_0:w}
%  \begin{macro}{\predicate_02_1:w}
%    
%    Evaluating the truth value of a list of predicates is done using
%    an input syntax somewhat similar to the one found in other
%    programming languages. The function evaluates predicates from
%    left to right, expanding them to 00 and 01 resp., which leads to
%    six different situations of tokens in the input stream:
%    \begin{itemize}
%    \item[\texttt{00\&\&}] Current truth value is true, logical And
%      seen, continue to see if next is also true.
%    \item[\texttt{01\&\&}] Current truth value is false, logical And
%      seen, break the scanning and return \meta{false}.
%    \item[\texttt{00\char`\|\char`\|}] Current truth value is true,
%      logical Or seen, break the scanning and return \meta{true}.
%    \item[\texttt{01\char`\|\char`\|}] Current truth value is false,
%      logical Or seen, continue to see if a later predicate is true.
%    \item[\texttt{0002}] Current truth value is true, end marker
%      seen, return \meta{true}.
%    \item[\texttt{0102}] Current truth value is false, end marker
%      seen, return \meta{false}.
%    \end{itemize}
%    To accomplish this we pre-expand the predicate list using |f|
%    type expansion which leads to |00| or |01|, possibly with a
%    sequence of unfinished |\else: \c_false \fi:| or similar after
%    it, which we remove using the same trick. We also carry over the
%    truth value of the evaluated predicate. The expansion stops when
%    it sees the end marker or \verb+&&+ or \verb+||+ (assuming these
%    are not active characters at the programming level).
%    \begin{macrocode}
\def_long_new:Npn \predicate_p:n #1{
  \group_align_safe_begin:
  \exp_after:NN \predicate_auxi:NN
  \int_to_roman:w-`\q #1  02\scan_stop: 
}
\def_long_test_function_new:npn {predicate:n}#1{
  \group_align_safe_begin:
  \if:w \exp_after:NN \predicate_auxi:NN
  \int_to_roman:w-`\q #1  02\scan_stop: 
}
\def_new:Npn \predicate_auxi:NN 0 #1{
  \exp_after:NN \predicate_auxii:NNN \exp_after:NN #1
  \int_to_roman:w-`\q
}
%    \end{macrocode}
% After removing trailing conditionals we call a macro for the case we
% are in (see list above).
%    \begin{macrocode}
\def_new:Npn \predicate_auxii:NNN #1#2#3{
  \cs_use:c{predicate_#2#3_#1:w} }
\def_new:cpn{predicate_&&_0:w}{  
  \exp_after:NN \predicate_auxi:NN\int_to_roman:w-`\q
}
\def_long_new:cpn{predicate_&&_1:w} #1 02\scan_stop:{
  \group_align_safe_end: 01}
\def_long_new:cpn{predicate_||_0:w} #1 02\scan_stop:{
  \group_align_safe_end: 00}
\def_new:cpn{predicate_||_1:w}{
  \exp_after:NN \predicate_auxi:NN\int_to_roman:w-`\q
}
\def_new:cpn{predicate_02_0:w}\scan_stop:{ \group_align_safe_end: 00 }
\def_new:cpn{predicate_02_1:w}\scan_stop:{ \group_align_safe_end: 01 }
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%
%  \begin{macro}{\predicate_not_p:n}
% The "not" variant just reverses the outcome of |\predicate_p:n|.
%    \begin{macrocode}
\def_long_new:Npn \predicate_not_p:n #1{
  \if:w \predicate_p:n{#1} \c_false \else: \c_true \fi:
}
%    \end{macrocode}
%  \end{macro}
%
% \subsubsection{Case switch}
%
% \begin{macro}{\prg_case_int:nnn}
% \begin{macro}{\prg_case_int_aux:nnn}
%   This case switch is in reality quite simple. It takes three arguments:
%   \begin{enumerate}
%   \item An integer expression you wish to find.
%   \item A list of pairs of "{"\meta{integer
%   expr}"}""{"\meta{code}"}". The list can be as long as is desired
%   and \meta{integer expr} can be negative.
%   \item The code to be executed if the value wasn't found.
%   \end{enumerate}
%   We don't need the else case here yet, so leave it dangling in the
%   input stream. 
%    \begin{macrocode}
\def_long:Npn \prg_case_int:nnn #1 #2 {
%    \end{macrocode}
% We will be parsing on |#1| for each step so we might as well
% evaluate it first in case it is complicated. 
%    \begin{macrocode}
  \exp_args:No \prg_case_int_aux:nnn {\num_value:w \int_eval:n{#1}} #2
%    \end{macrocode}
% The \texttt{?} below is just so there are enough arguments when we
% reach the end. And it made you look.~\texttt{;-)}
%    \begin{macrocode}
  \q_recursion_tail ? \q_recursion_stop 
}
\def_long_new:Npn \prg_case_int_aux:nnn #1#2#3{
%    \end{macrocode}
% If we reach the end, return the else case. We just remove braces.
%    \begin{macrocode}
  \quark_if_recursion_tail_stop_do:nn{#2}{\use_arg_i:n}
%    \end{macrocode}
% Otherwise we compare (which evaluates |#2| for us)
%    \begin{macrocode}
  \num_compare:nNnTF{#1}={#2}
%    \end{macrocode}
% If true, we want to remove the remainder of the list, the else case
% and then execute the code specified.  Why not use |#3\use_none:n|?
% Because if we are doing |f| style expansion, we will get
% leftovers. If the test was false, we try the next pair, carrying the
% |#1|.
%    \begin{macrocode}
  { \use_arg_i_delimit_by_q_recursion_stop:nw {\use_arg_i:nn{#3}} }
  { \prg_case_int_aux:nnn {#1}}
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\prg_case_dim:nnn}
% \begin{macro}{\prg_case_dim_aux:nnn}
%   Same as |\prg_case_dim:nnn| except it is for \meta{dim} registers.
%    \begin{macrocode}
\def_long:Npn \prg_case_dim:nnn #1 #2 {
  \exp_args:No \prg_case_dim_aux:nnn {\dim_use:N \dim_eval:n{#1}} #2
  \q_recursion_tail ? \q_recursion_stop 
}
\def_long_new:Npn \prg_case_dim_aux:nnn #1#2#3{
  \quark_if_recursion_tail_stop_do:nn{#2}{\use_arg_i:n}
  \dim_compare:nNnTF{#1}={#2}
  { \use_arg_i_delimit_by_q_recursion_stop:nw {\use_arg_i:nn{#3}} }
  { \prg_case_dim_aux:nnn {#1}}
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\prg_case_str:nnn}
% \begin{macro}{\prg_case_str_aux:nnn}
%   Same as |\prg_case_dim:nnn| except it is for strings.
%    \begin{macrocode}
\def_long:Npn \prg_case_str:nnn #1 #2 {
  \prg_case_str_aux:nnn {#1} #2
  \q_recursion_tail ? \q_recursion_stop 
}
\def_long_new:Npn \prg_case_str_aux:nnn #1#2#3{
  \quark_if_recursion_tail_stop_do:nn{#2}{\use_arg_i:n}
  \tlist_if_eq:xxTF{#1}{#2}
  { \use_arg_i_delimit_by_q_recursion_stop:nw {\use_arg_i:nn{#3}} }
  { \prg_case_str_aux:nnn {#1}}
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsubsection{Sorting}
%
%
% \begin{macro}{\prg_define_quicksort:nnn}
%   |#1| is the name, |#2| and |#3| are the tokens enclosing the
%   argument. For the somewhat strange \meta{clist} type which doesn't
%   enclose the items but uses a separator we define it by hand
%   afterwards. When doing the first pass, the algorithm wraps all
%   elements in braces and then uses a generic quicksort which works
%   on token lists.
%
%   As an example
%   \begin{quote}
%   |\prg_define_quicksort:nnn{seq}{\seq_elt:w}{\seq_elt_end:w}|  
%   \end{quote}
%   defines the user function |\seq_quicksort:n| and furthermore
%   expects to use the two functions |\seq_quicksort_compare:nnTF|
%   which compares the items and |\seq_quicksort_function:n| which is
%   placed before each sorted item. It is up to the programmer to
%   define these functions when needed. For the |seq| type a sequence
%   is a token list pointer, so one additionally has to define
%   \begin{quote}
%     |\def:Npn \seq_quicksort:N{\exp_args:No\seq_quicksort:n}|
%   \end{quote}
%
%
%   For details on the implementation see ``Sorting in \TeX's Mouth''
%   by Bernd Raichle. Firstly we define the function for parsing the
%   ininital list and then the braced list afterwards.
%    \begin{macrocode}
\def_new:NNn \prg_define_quicksort:nnn 3 {
  \def_long:cNx{#1_quicksort:n}1{
    \exp_not:c{#1_quicksort_start_partition:w} ##1
    \exp_not:n{#2\q_nil#3\q_stop}
  }
  \def_long:cNx{#1_quicksort_braced:n}1{
    \exp_not:c{#1_quicksort_start_partition_braced:n} ##1
    \exp_not:N\q_nil\exp_not:N\q_stop
  }
  \def_long:cpx {#1_quicksort_start_partition:w} #2 ##1 #3{
    \exp_not:N \quark_if_nil:nT {##1}\exp_not:N \use_none_delimit_by_q_stop:w
    \exp_not:c{#1_quicksort_do_partition_i:nnnw} {##1}{}{} 
  }
  \def_long:cNx {#1_quicksort_start_partition_braced:n} 1 {
    \exp_not:N \quark_if_nil:nT {##1}\exp_not:N \use_none_delimit_by_q_stop:w
    \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn} {##1}{}{} 
  }
%    \end{macrocode}
% Now for doing the partitions.
%    \begin{macrocode}
  \def_long:cpx {#1_quicksort_do_partition_i:nnnw} ##1##2##3 #2 ##4 #3 {
    \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
    {
      \exp_not:c{#1_quicksort_compare:nnTF}{##1}{##4}
      \exp_not:c{#1_quicksort_partition_greater_ii:nnnn}
      \exp_not:c{#1_quicksort_partition_less_ii:nnnn}
    }
    {##1}{##2}{##3}{##4}
  }
  \def_long:cNx {#1_quicksort_do_partition_i_braced:nnnn} 4 {
    \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
    {
      \exp_not:c{#1_quicksort_compare:nnTF}{##1}{##4}
      \exp_not:c{#1_quicksort_partition_greater_ii_braced:nnnn}
      \exp_not:c{#1_quicksort_partition_less_ii_braced:nnnn}
    }
    {##1}{##2}{##3}{##4}
  }
  \def_long:cpx {#1_quicksort_do_partition_ii:nnnw} ##1##2##3 #2 ##4 #3 {
    \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
    {
      \exp_not:c{#1_quicksort_compare:nnTF}{##4}{##1}
      \exp_not:c{#1_quicksort_partition_less_i:nnnn}
      \exp_not:c{#1_quicksort_partition_greater_i:nnnn}
    }
    {##1}{##2}{##3}{##4}
  }
  \def_long:cNx {#1_quicksort_do_partition_ii_braced:nnnn} 4 {
    \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
    {
      \exp_not:c{#1_quicksort_compare:nnTF}{##4}{##1}
      \exp_not:c{#1_quicksort_partition_less_i_braced:nnnn}
      \exp_not:c{#1_quicksort_partition_greater_i_braced:nnnn}
    }
    {##1}{##2}{##3}{##4}
  }
%    \end{macrocode}
% This part of the code handles the two branches in each
% sorting. Again we will also have to do it braced.
%    \begin{macrocode}
  \def_long:cNx {#1_quicksort_partition_less_i:nnnn} 4{
    \exp_not:c{#1_quicksort_do_partition_i:nnnw}{##1}{##2}{{##4}##3}}
  \def_long:cNx {#1_quicksort_partition_less_ii:nnnn} 4{
    \exp_not:c{#1_quicksort_do_partition_ii:nnnw}{##1}{##2}{##3{##4}}}
  \def_long:cNx {#1_quicksort_partition_greater_i:nnnn} 4{
    \exp_not:c{#1_quicksort_do_partition_i:nnnw}{##1}{{##4}##2}{##3}}
  \def_long:cNx {#1_quicksort_partition_greater_ii:nnnn} 4{
    \exp_not:c{#1_quicksort_do_partition_ii:nnnw}{##1}{##2{##4}}{##3}}
  \def_long:cNx {#1_quicksort_partition_less_i_braced:nnnn} 4{
    \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn}{##1}{##2}{{##4}##3}}
  \def_long:cNx {#1_quicksort_partition_less_ii_braced:nnnn} 4{
    \exp_not:c{#1_quicksort_do_partition_ii_braced:nnnn}{##1}{##2}{##3{##4}}}
  \def_long:cNx {#1_quicksort_partition_greater_i_braced:nnnn} 4{
    \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn}{##1}{{##4}##2}{##3}}
  \def_long:cNx {#1_quicksort_partition_greater_ii_braced:nnnn} 4{
    \exp_not:c{#1_quicksort_do_partition_ii_braced:nnnn}{##1}{##2{##4}}{##3}}
%    \end{macrocode}
% Finally, the big kahuna! This is where the sub-lists are sorted.
%    \begin{macrocode}
  \def_long:cpx {#1_do_quicksort_braced:nnnnw} ##1##2##3##4\q_stop {
    \exp_not:c{#1_quicksort_braced:n}{##2}
    \exp_not:c{#1_quicksort_function:n}{##1}
    \exp_not:c{#1_quicksort_braced:n}{##3}
  }
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\prg_quicksort:n}
%   A simple version. Sorts a list of tokens, uses the function
%   |\prg_quicksort_compare:nnTF| to compare items, and places the
%   function |\prg_quicksort_function:n| in front of each of them.
%    \begin{macrocode}
\prg_define_quicksort:nnn {prg}{}{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\prg_quicksort_function:n}
% \begin{macro}{\prg_quicksort_compare:nnTF}
%    \begin{macrocode}
\let:NN \prg_quicksort_function:n \ERROR
\let:NN \prg_quicksort_compare:nnTF \ERROR
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%  That's it (for now).
%    \begin{macrocode}
%</initex|package>
%<*showmemory>
\showMemUsage
%</showmemory>
%    \end{macrocode}
%
% \endinput
%
% $Log$
% Revision 1.19  2006/08/08 10:26:09  morten
% Fixed bugs in stepwise functions
%
% Revision 1.18  2006/07/30 14:41:28  morten
% Added stepwise functions (loops going from i to k with step of j) plus quicksort.
%
% Revision 1.17  2006/07/06 14:57:13  morten
% Moved code in the `miscellaneus' section to l3basics.
%
% Revision 1.16  2006/06/03 18:55:12  morten
% Added special double boolean switches.
%
% Revision 1.15  2006/03/20 18:26:38  braams
% Updated the copyright notice (2006) and demoted all implementation
% sections to subsections and so on to clean up the toc for source3.tex
%
% Revision 1.14  2006/01/19 22:31:56  morten
% Added \bool_set_eq:NN functions plus made function collection
% complete.
%
% Revision 1.13  2006/01/04 00:58:17  morten
% Added generic loops. Changed some names plus syntax for some of the
% logical operations. Added code for defining functions with specified
% number of arguments.
%
% Revision 1.12  2005/12/27 10:01:55  morten
% Changed RCS information retrieval. Moved tlist code to l3tlp. Added
% code for inserting n copies of something. Changed \bool_while to
% \bool_whiledo.
%
% Revision 1.11  2005/04/25 15:01:59  morten
% Fixed some names. Improved \peek_char_generic:NNTF to not use token registers.
%
% Revision 1.10  2005/04/23 14:36:12  morten
% Changed \c_left|right_brace_token to \c_group_begin_token and
% \c_group_end_token. Fixed definitions of \tlist_if_head_XXX functions.
% Added example for PR/3080.
%
% Revision 1.9  2005/04/09 21:08:43  morten
% Documentation blunders fixed
%
% Revision 1.8  2005/04/06 21:27:15  morten
% More tlist functions, Moved \engine_aleph:TF to l3basics, new peek-ahead functions, definitions of implicit characters.
%
% Revision 1.7  2005/03/26 21:11:14  morten
% Fix typo in \scan_align_safe_stop:
%
% Revision 1.6  2005/03/22 23:23:30  morten
% Moved \tlist_ functions from l3basics. Added align-safe versions of important functions. Reorganized documentation slightly.
%
% Revision 1.5  2005/03/16 22:36:10  braams
% Added the tweaks necessary to be able to load with initex
%
% Revision 1.4  2005/03/11 21:28:20  braams
% Fixed the use of RCS information; added \StopEventually
%
