% \iffalse meta-comment
%
%% File: l3prg.dtx Copyright (C) 2005-2011 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
%% 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/svnroot/experimental/trunk/
%%
%% 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 LaTeX3 Project.
%%
%% -----------------------------------------------------------------------
%
%<*driver|package>
\RequirePackage{l3names}
\GetIdInfo$Id: l3prg.dtx 2553 2011-08-11 23:55:20Z bruno $
  {L3 Experimental control structures}
%</driver|package>
%<*driver>
\documentclass[full]{l3doc}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \title{^^A
%   The \pkg{l3prg} package\\ Control structures^^A
%   \thanks{This file describes v\ExplFileVersion,
%      last revised \ExplFileDate.}^^A
% }
%
% \author{^^A
%  The \LaTeX3 Project\thanks
%    {^^A
%      E-mail:
%        \href{mailto:latex-team@latex-project.org}
%          {latex-team@latex-project.org}^^A
%    }^^A
% }
%
% \date{Released \ExplFileDate}
%
% \maketitle
%
% \begin{documentation}
%
% Conditional processing in \LaTeX3 is defined as something that
% performs a series of tests, possibly involving assignments and
% calling other functions that do not read further ahead in the input
% stream. After processing the input, a \emph{state} is returned. The
% typical states returned are \meta{true} and \meta{false} but other
% states are possible, say an \meta{error} state for erroneous
% input, \emph{e.g.}, text as input in a function comparing integers.
%
% \LaTeX3 has two primary forms of conditional flow processing based
% on these states. One type is predicate functions that turn the
% returned state into a boolean \meta{true} or \meta{false}. For
% example, the function |\cs_if_free_p:N| checks whether the control
% sequence given as its argument is free and then returns the boolean
% \meta{true} or \meta{false} values to be used in testing with
% |\if_predicate:w| or in functions to be described below.  The other type
% is the kind of functions choosing a particular argument from the
% input stream based on the result of the testing as in
% |\cs_if_free:NTF| which also takes one argument (the |N|) and then
% executes either \meta{true} or \meta{false} depending on the
% result. Important to note here is that the arguments are executed
% after exiting the underlying |\if...\fi:| structure
%
% \section{Defining a set of conditional functions}
%
% \begin{function}
%   {
%     \prg_new_conditional:Npnn, \prg_set_conditional:Npnn,
%     \prg_new_conditional:Nnn,  \prg_set_conditional:Nnn
%    }
%   \begin{syntax}
%     \cs{prg_set_conditional:Npnn} \cs{\meta{name}:\meta{arg spec}}
%     ~~\meta{parameters} \Arg{conditions} \Arg{code}
%     \cs{prg_set_conditional:Nnn} \cs{\meta{name}:\meta{arg spec}}
%     ~~\Arg{conditions} \Arg{code}
%   \end{syntax}
%   These functions creates a family of conditionals using the same
%   \Arg{code} to perform the test created. The \texttt{new} version will
%   check for existing definitions (\emph{cf.}~\cs{cs_new:Npn}) whereas
%   the \texttt{set} version will not (\emph{cf.}~\cs{cs_set:Npn}). The
%   conditionals created are depended on the comma-separated list of
%   \meta{conditions}, which should be one or more of \texttt{p},
%   \texttt{T}, \texttt{F} and \texttt{TF}. The conditionals are then
%   defined in the obvious way as:
%   \begin{itemize}
%     \item \cs{\meta{name}_p:\meta{arg spec}}, a predicate function
%       which will supply either a logical \texttt{true} or
%       logical \texttt{false}. This function is intended for use
%       in cases where one or more logical tests are combined to
%       lead to a final outcome.
%     \item \cs{\meta{name}:\meta{arg spec}T}, a function with one
%       more argument than the original \meta{arg spec} demands. The
%       \meta{true branch} code in this additional argument will be
%       left on the input stream only if the test is \texttt{true}.
%     \item \cs{\meta{name}:\meta{arg spec}F}, a function with one
%       more argument than the original \meta{arg spec} demands. The
%       \meta{false branch} code in this additional argument will be
%       left on the input stream only if the test is \texttt{false}.
%     \item \cs{\meta{name}:\meta{arg spec}TF} , a function with two
%       more argument than the original \meta{arg spec} demands. The
%       \meta{true branch} code in the first additional argument will
%       be left on the input stream if the test is \texttt{true}, while
%       the \meta{false branch} code in the second argument will be
%       left on the input stream if the test is \texttt{false}.
%   \end{itemize}
%   The \meta{code} of the test may use \meta{parameters} as specified
%   by the second argument to \cs{prg_set_conditional:Npnn}: this should
%   match the \meta{argument specification} but this is not enforced.
%   The |Nnn| versions infer the number of arguments from the argument
%   specification given (\emph{cf.}~\cs{cs_new:Nn}, \emph{etc.}).
%   Within the \meta{code}, the functions \cs{prg_return_true:} and
%   \cs{prg_return_false:} are used to indicate the logical outcomes of
%   the test. If \meta{code} is expandable then
%   \cs{prg_set_conditional:Npnn} will generate a family of conditionals
%   which are also expandable. All of the functions are created globally.
%
%   An example can easily clarify matters here:
%   \begin{verbatim}
%     \prg_set_conditional:Nnn \foo_if_bar:NN { p , T , TF }
%       {
%         \if_meaning:w \l_tmpa_tl #1
%           \prg_return_true:
%         \else:
%           \if_meaning:w \l_tmpa_tl #2
%             \prg_return_true:
%           \else:
%             \prg_return_false:
%          \fi:
%        \fi:
%      }
%   \end{verbatim}
%   This defines the function |\foo_if_bar_p:NN|, |\foo_if_bar:NNTF|,
%   |\foo_if_bar:NNT| but not |\foo_if_bar:NNF| (because |F| is missing from
%   the \meta{conds} list). The return statements
%   take care of resolving the remaining |\else:| and |\fi:| before
%   returning the state. There must be a return statement for each
%   branch, failing to do so will result in an error if that branch is
%   executed.
% \end{function}
%
% \begin{function}
%   {
%     \prg_new_protected_conditional:Npnn, \prg_set_protected_conditional:Npnn,
%     \prg_new_protected_conditional:Nnn,  \prg_set_protected_conditional:Nnn
%   }
%   \begin{syntax}
%     \cs{prg_set_protected_conditional:Npnn}
%     ~~\cs{\meta{name}:\meta{arg spec}} \meta{parameters}
%     ~~\meta{conditions} \Arg{code}
%     \cs{prg_set_protected_conditional:Nnn}
%     ~~\cs{\meta{name}:\meta{arg spec}} \meta{conditions} \Arg{code}
%   \end{syntax}
%   These functions creates a family of conditionals using the same
%   \Arg{code} to perform the test created. The \texttt{new} version will
%   check for existing definitions (\emph{cf.}~\cs{cs_new:Npn}) whereas
%   the \texttt{set} version will not (\emph{cf.}~\cs{cs_set:Npn}). The
%   conditionals created are depended on the comma-separated list of
%   \meta{conditions}, which should be one or more of \texttt{T},
%   \texttt{F} and \texttt{TF}. The conditionals are then defined in the
%   obvious way as:
%   \begin{itemize}
%     \item \cs{\meta{name}:\meta{arg spec}T}, a function with one
%       more argument than the original \meta{arg spec} demands. The
%       \meta{true branch} code in this additional argument will be
%       left on the input stream only if the test is \texttt{true}.
%     \item \cs{\meta{name}:\meta{arg spec}F}, a function with one
%       more argument than the original \meta{arg spec} demands. The
%       \meta{false branch} code in this additional argument will be
%       left on the input stream only if the test is \texttt{false}.
%     \item \cs{\meta{name}:\meta{arg spec}TF} , a function with two
%       more argument than the original \meta{arg spec} demands. The
%       \meta{true branch} code in the first additional argument will
%       be left on the input stream if the test is \texttt{true}, while
%       the \meta{false branch} code in the second argument will be
%       left on the input stream if the test is \texttt{false}.
%   \end{itemize}
%   The \meta{code} of the test may use \meta{parameters} as specified
%   by the second argument to \cs{prg_set_conditional:Npn}: this should
%   match the \meta{argument specification} but this is not enforced.
%   The |Nnn| versions infer the number of arguments from the argument
%   specification given (\emph{cf.}~\cs{cs_new:Nn}, \emph{etc.}).
%   Within the \meta{code}, the functions \cs{prg_return_true:} and
%   \cs{prg_return_false:} are used to indicate the logical outcomes of
%   the test. \cs{prg_set_protected_conditional:Npn} will generate
%   a family of protected conditional functions, and so \meta{code}
%   does not need to be expandable. All of the functions are created
%   globally.
%\end{function}
%
% \begin{function}{\prg_new_eq_conditional:NN, \prg_set_eq_conditional:NN}
%   \begin{syntax}
%     \cs{prg_new_eq_conditional:NN}
%     ~~\cs{\meta{name1}:\meta{arg spec1}} \cs{\meta{name2}:\meta{arg spec2}}
%   \end{syntax}
%   These will set the definitions of the functions
%   \begin{itemize}
%     \item \cs{\meta{name1}_p:\meta{arg spec1}}
%     \item \cs{\meta{name1}:\meta{arg spec1}T}
%     \item \cs{\meta{name1}:\meta{arg spec1}F}
%     \item \cs{\meta{name1}:\meta{arg spec1}TF}
%   \end{itemize}
%   equal to those for
%   \begin{itemize}
%     \item \cs{\meta{name2}_p:\meta{arg spec2}}
%     \item \cs{\meta{name2}:\meta{arg spec2}T}
%     \item \cs{\meta{name2}:\meta{arg spec2}F}
%     \item \cs{\meta{name2}:\meta{arg spec2}TF}
%   \end{itemize}
%   In most cases, the two \meta{arg specs} will be identical, although
%   this is not enforced. In the case of the \texttt{new} function, a
%   check is made for any existing definitions for \meta{name1}. The
%   functions are set globally.
% \end{function}
%
% \begin{function}[EXP]{\prg_return_true:, \prg_return_false:}
%   \begin{syntax}
%     \cs{prg_return_true:}
%     \cs{prg_return_false:}
%   \end{syntax}
%   These functions define the logical state at the end of a conditional.
%   As such, they should appear within the code for a conditional
%   statement generated by \cs{prg_set_conditional:Npnn}, \emph{etc}.
% \end{function}
%
% \section{The boolean data type}
%
% This section describes a boolean data type which is closely
% connected to conditional processing as sometimes you want to
% execute some code depending on the value of a switch
% (\emph{e.g.},~draft/final) and other times you perhaps want to use it as a
% predicate function in an |\if_predicate:w| test. The problem of the
% primitive |\if_false:| and |\if_true:| tokens is that it is not
% always safe to pass them around as they may interfere with scanning
% for termination of primitive conditional processing. Therefore, we
% employ two canonical booleans: |\c_true_bool| or
% |\c_false_bool|. Besides preventing problems as described above, it
% also allows us to implement a simple boolean parser supporting the
% logical operations And, Or, Not, \emph{etc.}\ which can then be used on
% both the boolean type and predicate functions.
%
% All conditional |\bool_| functions are expandable and expect the
% input to also be fully expandable (which will generally mean being
% constructed from predicate functions, possibly nested).
%
% \begin{function}{\bool_new:N, \bool_new:c}
%   \begin{syntax}
%     \cs{bool_new:N} \meta{boolean}
%   \end{syntax}
%   Creates a new \meta{boolean} or raises an error if the
%   name is already taken. The declaration is global. The
%   \meta{boolean} will initially be \texttt{false}.
% \end{function}
%
% \begin{function}{\bool_set_false:N, \bool_set_false:c}
%   \begin{syntax}
%     \cs{bool_set_false:N} \meta{boolean}
%   \end{syntax}
%   Sets \meta{boolean} logically \texttt{false} within the current
%   \TeX{} group.
% \end{function}
%
% \begin{function}{\bool_gset_false:N, \bool_gset_false:c}
%   \begin{syntax}
%     \cs{bool_sget_false:N} \meta{boolean}
%   \end{syntax}
%   Sets \meta{boolean} logically \texttt{false} globally.
% \end{function}
%
% \begin{function}{\bool_set_true:N, \bool_set_true:c}
%   \begin{syntax}
%     \cs{bool_set_true:N} \meta{boolean}
%   \end{syntax}
%   Sets \meta{boolean} logically \texttt{true} within the current
%   \TeX{} group.
% \end{function}
%
% \begin{function}{\bool_gset_true:N, \bool_gset_true:c}
%   \begin{syntax}
%     \cs{bool_gset_true:N} \meta{boolean}
%   \end{syntax}
%   Sets \meta{boolean} logically \texttt{true} globally.
% \end{function}
%
% \begin{function}
%   {\bool_set_eq:NN, \bool_set_eq:cN, \bool_set_eq:Nc, \bool_set_eq:cc}
%   \begin{syntax}
%     \cs{bool_set_eq:NN} \meta{boolean1} \meta{boolean2}
%   \end{syntax}
%   Sets the content of \meta{boolean1} equal to that of \meta{boolean2}.
%   This assignment is restricted to the current \TeX{} group level.
% \end{function}
%
% \begin{function}
%   {\bool_gset_eq:NN, \bool_gset_eq:cN, \bool_gset_eq:Nc, \bool_gset_eq:cc}
%   \begin{syntax}
%     \cs{bool_gset_eq:NN} \meta{boolean1} \meta{boolean2}
%   \end{syntax}
%   Sets the content of \meta{boolean1} equal to that of \meta{boolean2}.
%   This assignment is global and so is not limited by the current
%   \TeX{} group level.
% \end{function}
%
% \begin{function}{\bool_set:Nn, \bool_set:cn}
%   \begin{syntax}
%     \cs{bool_set:Nn} \meta{boolean} \Arg{boolexpr}
%   \end{syntax}
%   Evaluates the \meta{boolean expression} as described for
%   \cs{bool_if:n(TF)}, and sets the \meta{boolean} variable to
%   the logical truth of this evaluation. This assignment is local.
% \end{function}
%
% \begin{function}{\bool_gset:Nn, \bool_gset:cn}
%   \begin{syntax}
%     \cs{bool_gset:Nn} \meta{boolean} \Arg{boolexpr}
%   \end{syntax}
%   Evaluates the \meta{boolean expression} as described for
%   \cs{bool_if:n(TF)}, and sets the \meta{boolean} variable to
%   the logical truth of this evaluation. This assignment is global.
% \end{function}
%
% \begin{function}[EXP,pTF]{\bool_if:N, \bool_if:c}
%   \begin{syntax}
%     \cs{bool_if_p:N} \Arg{boolean}
%     \cs{bool_if:NTF} \Arg{boolean} \Arg{true code} \Arg{false code}
%   \end{syntax}
%   Tests the current truth of \meta{boolean}, and continues expansion
%   based on this result. The branching versions then leave either
%   \meta{true code} or \meta{false code} in the input stream, as
%   appropriate to the truth of the test and the variant of the function
%   chosen. The logical truth of the test is left in the input stream by
%   the predicate version.
% \end{function}
%
% \begin{variable}{\l_tmpa_bool}
%   A scratch boolean for local assignment. It is never used by
%   the kernel code, and so is safe for use with any \LaTeX3-defined
%   function. However, it may be overwritten by other non-kernel
%   code and so should only be used for short-term storage.
% \end{variable}
%
% \begin{variable}{\g_tmpa_bool}
%   A scratch boolean for global assignment. It is never used by
%   the kernel code, and so is safe for use with any \LaTeX3-defined
%   function. However, it may be overwritten by other non-kernel
%   code and so should only be used for short-term storage.
% \end{variable}
%
% \section{Boolean expressions}
%
% As we have a boolean datatype and predicate functions returning
% boolean \meta{true} or \meta{false} values, it seems only fitting
% that we also provide a parser for \meta{boolean expressions}.
%
% A boolean expression is an expression which given input in the form
% of predicate functions and boolean variables, return boolean
% \meta{true} or \meta{false}. It supports the logical operations And,
% Or and Not as the well-known infix operators |&&|, \verb"||" and |!|. In
% addition to this, parentheses can be used to isolate
% sub-expressions. For example,
% \begin{verbatim}
%     \int_compare_p:n { 1 = 1 } &&
%       (
%         \int_compare_p:n { 2 = 3 } ||
%         \int_compare_p:n { 4 = 4 } ||
%         \int_compare_p:n { 1 = \error } % is skipped
%       ) &&
%     ! ( \int_compare_p:n { 2 = 4 } )
% \end{verbatim}
% is a valid boolean expression. Note that minimal evaluation is
% carried out whenever possible so that whenever a truth value cannot
% be changed any more, the remaining tests within the current group
% are skipped.
%
% \begin{function}[EXP,pTF]{\bool_if:n}
%   \begin{syntax}
%     \cs{bool_if_p:n} \Arg{boolean expression}
%     \cs{bool_if:nTF} \Arg{boolean expression} \Arg{true code}
%     ~~\Arg{false code}
%   \end{syntax}
%   Tests the current truth of \meta{boolean expression}, and
%   continues expansion based on this result. The
%   \meta{boolean expression} should consist of a series of predicates
%   or boolean variables with the logical relationship between these
%   defined using |&&| (\enquote{And}), \verb"||" (\enquote{Or}),
%   |!| (\enquote{Not}) and parentheses. Minimal evaluation is used
%   in the processing, so that once a result is defined there is
%   not further expansion of the tests. For example
%  \begin{verbatim}
%     \bool_if_p:n
%       {
%        \int_compare_p:nNn { 1 } = { 1 }
%        &&
%        (
%          \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 } = { 4 } )
%     }
%   \end{verbatim}
%   will be \texttt{true} and will not evaluate
%   |\int_compare_p:nNn { 1 } = { \error }|. The logical Not applies to
%   the next single predicate or group. As shown above, this means that
%   any predicates requiring an argument have to be given within
%   parentheses. The branching versions then leave either
%   \meta{true code} or \meta{false code} in the input stream, as
%   appropriate to the truth of the test and the variant of the function
%   chosen. The logical truth of the test is left in the input stream by
%   the predicate version.
% \end{function}
%
% \begin{function}[EXP]{\bool_not_p:n}
%   \begin{syntax}
%      \cs{bool_not_p:n} \Arg{boolean expression}
%   \end{syntax}
%   Function version of |!(|\meta{boolean expression}|)| within a boolean
%   expression.
% \end{function}
%
% \begin{function}[EXP]{\bool_xor_p:nn}
%   \begin{syntax}
%     \cs{bool_xor_p:nn} \Arg{boolexpr1} \Arg{boolexpr1}
%   \end{syntax}
%   Implements an \enquote{exclusive or} operation between two boolean
%   expressions. There is no infix operation for this logical
%   operator.
% \end{function}
%
% \section{Logical loops}
%
%  Loops using either boolean expressions or stored boolean values.
%
% \begin{function}[EXP]{\bool_until_do:Nn, \bool_until_do:cn}
%   \begin{syntax}
%     \cs{bool_until_do:Nn} \Arg{boolean} \Arg{code}
%   \end{syntax}
%   This function firsts checks the logical value of the \meta{boolean}.
%   If it is \texttt{false} the \meta{code} is placed in the input stream
%   and expanded. After the completion of the \meta{code} the truth
%   of the \meta{boolean} is re-evaluated. The process will then loop
%   until the \meta{boolean} is \texttt{true}.
% \end{function}
%
% \begin{function}[EXP]{\bool_while_do:Nn, \bool_while_do:cn}
%   \begin{syntax}
%     \cs{bool_while_do:Nn} \Arg{boolean} \Arg{code}
%   \end{syntax}
%   This function firsts checks the logical value of the \meta{boolean}.
%   If it is \texttt{true} the \meta{code} is placed in the input stream
%   and expanded. After the completion of the \meta{code} the truth
%   of the \meta{boolean} is re-evaluated. The process will then loop
%   until the \meta{boolean} is \texttt{false}.
% \end{function}
%
% \begin{function}[EXP]{\bool_until_do:nn}
%   \begin{syntax}
%     \cs{bool_until_do:nn} \Arg{boolean expression} \Arg{code}
%   \end{syntax}
%   This function firsts checks the logical value of the
%   \meta{boolean expression} (as described for \cs{bool_if:nTF}).
%   If it is \texttt{false} the \meta{code} is placed in the input stream
%   and expanded. After the completion of the \meta{code} the truth
%   of the \meta{boolean expression} is re-evaluated. The process will
%   then loop until the \meta{boolean expression} is \texttt{true}.
% \end{function}
%
% \begin{function}[EXP]{\bool_while_do:nn}
%   \begin{syntax}
%     \cs{bool_while_do:nn} \Arg{boolean expression} \Arg{code}
%   \end{syntax}
%   This function firsts checks the logical value of the
%   \meta{boolean expression} (as described for \cs{bool_if:nTF}).
%   If it is \texttt{true} the \meta{code} is placed in the input stream
%   and expanded. After the completion of the \meta{code} the truth
%   of the \meta{boolean expression} is re-evaluated. The process will
%   then loop until the \meta{boolean expression} is \texttt{false}.
% \end{function}
%
% \section{Switching by case}
%
% For cases where a number of cases need to be considered a family of
% case-selecting functions are available.
%
% \begin{function}[EXP]{\prg_case_int:nnn}
%   \begin{syntax}
%     \cs{prg_case_int:nnn}
%     ~~\Arg{test integer expression}
%     ~~|{|
%     ~~~~\Arg{intexpr case1} \Arg{code case1}
%     ~~~~\Arg{intexpr case2} \Arg{code case2}
%     ~~~~\ldots
%     ~~~~\Arg{intexpr case$_n$} \Arg{code case$_n$}
%     ~~|}|
%     ~~\Arg{else case}
%   \end{syntax}
%   This function evaluates the \meta{test integer expression} and
%   compares this in turn to each of the
%   \meta{integer expression cases}. If the two are equal then the
%   associated \meta{code} is left in the input stream. If none of
%   the tests are \texttt{true} then the \texttt{else code} will be
%   left in the input stream. For example
%   \begin{verbatim}
%     \prg_case_int:nnn
%       { 2 * 5 }
%       {
%         { 5 }       { Small }
%         { 4 + 6 }   { Medium }
%         { -2 * 10 } { Negative }
%       }
%       { No idea! }
%    \end{verbatim}
%   will leave \enquote{\texttt{Medium}} in the input stream.
% \end{function}
%
% \begin{function}[EXP]{\prg_case_dim:nnn}
%   \begin{syntax}
%     \cs{prg_case_dim:nnn}
%     ~~\Arg{test dimension expression}
%     ~~|{|
%     ~~~~\Arg{dimexpr case1} \Arg{code case1}
%     ~~~~\Arg{dimexpr case2} \Arg{code case2}
%     ~~~~\ldots
%     ~~~~\Arg{dimexpr case$_n$} \Arg{code case$_n$}
%     ~~|}|
%     ~~\Arg{else case}
%   \end{syntax}
%   This function evaluates the \meta{test dimension expression} and
%   compares this in turn to each of the
%   \meta{dimension expression cases}. If the two are equal then the
%   associated \meta{code} is left in the input stream. If none of
%   the tests are \texttt{true} then the \texttt{else code} will be
%   left in the input stream.
% \end{function}
%
% \begin{function}[EXP]
%   {\prg_case_str:nnn, \prg_case_str:onn, \prg_case_str:xxn}
%   \begin{syntax}
%     \cs{prg_case_str:nnn}
%     ~~\Arg{test string}
%     ~~|{|
%     ~~~~\Arg{string case1} \Arg{code case1}
%     ~~~~\Arg{string case2} \Arg{code case2}
%     ~~~~\ldots
%     ~~~~\Arg{string case$_n$} \Arg{code case$_n$}
%     ~~|}|
%     ~~\Arg{else case}
%   \end{syntax}
%   This function compares the \meta{test string} in turn with each
%   of the \meta{string cases}. If the two are equal (as described for
%   \cs{str_if_eq:nnTF} then the
%   associated \meta{code} is left in the input stream. If none of
%   the tests are \texttt{true} then the \texttt{else code} will be
%   left in the input stream. The |xx| variant is fully expandable,
%   in the same way as the underlying \cs{str_if_eq:xxTF} test.
% \end{function}
%
% \begin{function}[EXP]{\prg_case_tl:Nnn, \prg_case_tl:cnn}
%   \begin{syntax}
%     \cs{prg_case_tl:Nnn}
%     ~~\meta{test token list variable}
%     ~~"{"
%     ~~~~\meta{token list variable case1} \Arg{code case1}
%     ~~~~\meta{token list variable case2} \Arg{code case2}
%     ~~~~\ldots
%     ~~~~\meta{token list variable case$_n$} \Arg{code case$_n$}
%     ~~"}"
%     ~~\Arg{else case}
%   \end{syntax}
%   This function compares the \meta{test token list variable} in turn
%   with each of the \meta{token list variable cases}. If the two
%   are equal (as described for
%   \cs{tl_if_eq:nnTF}
%   then the associated \meta{code} is left in the input
%   stream. If none of the tests are \texttt{true} then the
%   \texttt{else code} will be left in the input stream.
% \end{function}
%
% \section{Producing $n$ copies}
%
% \begin{function}[EXP]{\prg_replicate:nn}
%   \begin{syntax}
%     \cs{prg_replicate:nn} \Arg{integer expression} \Arg{tokens}
%   \end{syntax}
%   Evaluates the \meta{integer expression} (which should be
%   zero or positive) and creates the resulting number of copies
%   of the \meta{tokens}. The function is both expandable and safe for
%   nesting. It yields its result after two expansion steps.
% \end{function}
%
% \begin{function}[EXP]{\prg_stepwise_function:nnnN}
%   \begin{syntax}
%     \cs{prg_stepwise_function:nnnN} \Arg{initial value} \Arg{step}
%     ~~\Arg{final value} \meta{function}
%   \end{syntax}
%   This function first evaluates the \meta{initial value}, \meta{step}
%   and \meta{final value}, all of which should be integer expressions.
%   The \meta{function} is then placed in front of each \meta{value}
%   from the \meta{initial value} to the \meta{final value} in turn
%   (using \meta{step} between each \meta{value}). Thus \meta{function}
%   should absorb one numerical argument. For example
%   \begin{verbatim}
%     \cs_set_nopar:Npn \my_func:n #1 { I~saw~#1 \\ }
%     \prg_stepwise_function:nnnN { 1 } { 5 } { 1 } \my_func:n
%   \end{verbatim}
%   would print
%   \begin{quote}
%     I saw 1 \\
%     I saw 2 \\
%     I saw 3 \\
%     I saw 4 \\
%     I saw 5 \\
%   \end{quote}
% \end{function}
%
% \begin{function}{\prg_stepwise_inline:nnnn}
%   \begin{syntax}
%     \cs{prg_stepwise_inline:nnnn} \Arg{initial value} \Arg{step}
%     ~~\Arg{final value} \Arg{code}
%   \end{syntax}
%   This function first evaluates the \meta{initial value}, \meta{step}
%   and \meta{final value}, all of which should be integer expressions.
%   The \meta{code} is then placed in front of each \meta{value}
%   from the \meta{initial value} to the \meta{final value} in turn
%   (using \meta{step} between each \meta{value}). Thus the \meta{code}
%   should define a function of one argument (|#1|).
% \end{function}
%
% \begin{function}{\prg_stepwise_variable:nnnn}
%   \begin{syntax}
%     \cs{prg_stepwise_inline:nnnn} \Arg{initial value} \Arg{step}
%     ~~\Arg{final value} \meta{tl~var} \Arg{code}
%   \end{syntax}
%   This function first evaluates the \meta{initial value}, \meta{step}
%   and \meta{final value}, all of which should be integer expressions.
%   The \meta{code} is inserted into the input stream, with the
%   \meta{tl~var} defined as the current \meta{value}. Thus the
%   \meta{code} should make use of the \meta{tl~var}.
% \end{function}
%
% \section{Detecting \TeX{}'s mode}
%
% \begin{function}[EXP,pTF]{\mode_if_horizontal:}
%   \begin{syntax}
%     \cs{mode_if_horizontal_p:}
%     \cs{mode_if_horizontal:TF} \Arg{true code} \Arg{false code}
%   \end{syntax}
%   Detects if \TeX{} is currently in horizontal mode. The branching
%   versions then leave either \meta{true code} or \meta{false code}
%   in the input stream, as appropriate to the truth of the test and
%   the variant of the function chosen. The logical truth of the test
%   is left in the input stream by the predicate version.
% \end{function}
%
% \begin{function}[EXP,pTF]{\mode_if_inner:}
%   \begin{syntax}
%     \cs{mode_if_inner_p:}
%     \cs{mode_if_inner:TF} \Arg{true code} \Arg{false code}
%   \end{syntax}
%   Detects if \TeX{} is currently in inner mode. The branching
%   versions then leave either \meta{true code} or \meta{false code}
%   in the input stream, as appropriate to the truth of the test and
%   the variant of the function chosen. The logical truth of the test
%   is left in the input stream by the predicate version.
% \end{function}
%
% \begin{function}[EXP,TF]{\mode_if_math:}
%   \begin{syntax}
%     \cs{mode_if_math:TF} \Arg{true code} \Arg{false code}
%   \end{syntax}
%   Detects if \TeX{} is currently in maths mode. The branching
%   versions then leave either \meta{true code} or \meta{false code}
%   in the input stream, as appropriate to the truth of the test and
%   the variant of the function chosen.
% \end{function}
%
% \begin{function}[EXP,pTF]{\mode_if_vertical:}
%   \begin{syntax}
%     \cs{mode_if_vertical_p:}
%     \cs{mode_if_vertical:TF} \Arg{true code} \Arg{false code}
%   \end{syntax}
%   Detects if \TeX{} is currently in vertical mode. The branching
%   versions then leave either \meta{true code} or \meta{false code}
%   in the input stream, as appropriate to the truth of the test and
%   the variant of the function chosen. The logical truth of the test
%   is left in the input stream by the predicate version.
% \end{function}
%
% \section{Internal programming functions}
%
% \begin{function}[EXP]{\group_align_safe_begin:, \group_align_safe_end:}
%   \begin{syntax}
%     \cs{group_align_safe_begin:}
%     \ldots
%     \cs{group_align_safe_end:}
%   \end{syntax}
%   These functions are used to enclose material in a \TeX{} alignment
%   environment within a specially-constructed group. This group is
%   designed in such a way that it does not add brace groups to the
%   output but does act as a group for the |&| token inside
%   \cs{tex_halign:D}. This is necessary to allow grabbing of tokens
%   for testing purposes, as \TeX{} uses group level to determine the
%   effect of alignment tokens. Without the special grouping, the use of
%   a function such as \cs{peek_after:Nw} will result in a forbidden
%   comparison of the internal \cs{endtemplate} token, yielding a
%    fatal error. Each \cs{group_align_safe_begin:} must be matched by a
%   \cs{group_align_safe_end:}, although this does not have to occur
%   within the same function.
% \end{function}
%
% \begin{function}{\scan_align_safe_stop:}
%   \begin{syntax}
%     \cs{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}[EXP]{\prg_variable_get_scope:N}
%   \begin{syntax}
%     \cs{prg_variable_get_scope:N} \meta{variable}
%   \end{syntax}
%   Returns the scope (\texttt{g} for global, blank otherwise) for the
%   \meta{variable}.
% \end{function}
%
% \begin{function}[EXP]{\prg_variable_get_type:N}
%   \begin{syntax}
%     \cs{prg_variable_get_type:N} \meta{variable}
%   \end{syntax}
%   Returns the type of \meta{variable} (\texttt{tl}, \texttt{int},
%   \emph{etc.})
% \end{function}
% 
% \section{Experimental programmings functions}
%
% \begin{function}{\prg_quicksort:n}
%   \begin{syntax}
%    \cs{prg_quicksort:n} |{| \Arg{item~1} \Arg{item~2} \dots \Arg{item~n} |}|
%   \end{syntax}
%   Performs a quicksort on the token list. The comparisons are
%   performed by the function \cs{prg_quicksort_compare:nnTF} which is up
%   to the programmer to define. When the sorting process is over, all
%   items are given as argument to the function
%   \cs{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" \Arg{element} \\
%    "\prg_quicksort_compare:nnTF" \Arg{element 1} \Arg{element 2}\\
%  \end{syntax}
%  The two functions the programmer must define before calling
%  |\prg_quicksort:n|. As an example we could define
% \begin{quote}
% |\cs_set_nopar:Npn\prg_quicksort_function:n #1{{#1}}|\\
% |\cs_set_nopar:Npn\prg_quicksort_compare:nnTF #1#2#3#4 {\int_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}
% |\cs_set_nopar:Npn\prg_quicksort_compare:nnTF #1#2 {|\\
% |  \int_compare:nNnTF{\tl_compare:nn{#1}{#2}}>\c_zero }|
% \end{quote}
%
%  \end{function}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3prg} implementation}
%
% \TestFiles{m3prg001.lvt,m3prg002.lvt,m3prg003.lvt}
%%
%    \begin{macrocode}
%<*initex|package>
%    \end{macrocode}
%
%    \begin{macrocode}
%<*package>
\ProvidesExplPackage
  {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
\package_check_loaded_expl:
%</package>
%    \end{macrocode}
%
% \subsection{Defining a set of conditional functions}
%
% \begin{macro}
%   {
%     \prg_set_conditional:Npnn,
%     \prg_new_conditional:Npnn,
%     \prg_set_protected_conditional:Npnn,
%     \prg_new_protected_conditional:Npnn
%   }
% \begin{macro}
%   {
%     \prg_set_conditional:Nnn,
%     \prg_new_conditional:Nnn,
%     \prg_set_protected_conditional:Nnn,
%     \prg_new_protected_conditional:Nnn
%   }
% \begin{macro}{\prg_set_eq_conditional:NNn, \prg_new_eq_conditional:NNn}
% \begin{macro}{\prg_return_true:}
% \TestMissing
%   {This function is implicitly tested with all other conditionals!}
% \begin{macro}{\prg_return_false:}
% \TestMissing
%   {This function is also implicitly tested with all other conditionals!}
%   These are all defined in \pkg{l3basics}, as they are needed
%   \enquote{early}. This is just a reminder that that is the case!
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsection{The boolean data type}
%
% \begin{macro}{\bool_new:N, \bool_new:c}
% \UnitTested
%   Boolean variables have to be initiated when they are created. Other
%   than that there is not much to say here.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \bool_new:N #1 { \cs_new_eq:NN #1 \c_false_bool }
\cs_generate_variant:Nn \bool_new:N { c }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}
%   {
%     \bool_set_true:N,   \bool_set_true:c,
%     \bool_gset_true:N,  \bool_gset_true:c,
%     \bool_set_false:N,  \bool_set_false:c,
%     \bool_gset_false:N, \bool_gset_false:c
%   }
% \UnitTested
%   Setting is already pretty easy.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \bool_set_true:N #1
  { \cs_set_eq:NN #1 \c_true_bool }
\cs_new_protected_nopar:Npn \bool_set_false:N #1
  { \cs_set_eq:NN #1 \c_false_bool }
\cs_new_protected_nopar:Npn \bool_gset_true:N #1
  { \cs_gset_eq:NN #1 \c_true_bool }
\cs_new_protected_nopar:Npn \bool_gset_false:N #1
  { \cs_gset_eq:NN #1 \c_false_bool }
\cs_generate_variant:Nn \bool_set_true:N   { c }
\cs_generate_variant:Nn \bool_set_false:N  { c }
\cs_generate_variant:Nn \bool_gset_true:N  { c }
\cs_generate_variant:Nn \bool_gset_false:N { c }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}
%   {
%     \bool_set_eq:NN,  \bool_set_eq:cN,
%     \bool_set_eq:Nc,  \bool_set_eq:cc,
%     \bool_gset_eq:NN, \bool_gset_eq:cN,
%     \bool_gset_eq:Nc, \bool_gset_eq:cc
%   }
% \UnitTested
%   The usual copy code.
%    \begin{macrocode}
\cs_new_eq:NN \bool_set_eq:NN  \cs_set_eq:NN
\cs_new_eq:NN \bool_set_eq:Nc  \cs_set_eq:Nc
\cs_new_eq:NN \bool_set_eq:cN  \cs_set_eq:cN
\cs_new_eq:NN \bool_set_eq:cc  \cs_set_eq:cc
\cs_new_eq:NN \bool_gset_eq:NN \cs_gset_eq:NN
\cs_new_eq:NN \bool_gset_eq:Nc \cs_gset_eq:Nc
\cs_new_eq:NN \bool_gset_eq:cN \cs_gset_eq:cN
\cs_new_eq:NN \bool_gset_eq:cc \cs_gset_eq:cc
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\bool_set:Nn,\bool_set:cn}
% \begin{macro}{\bool_gset:Nn,\bool_gset:cn}
%   This function evaluates a boolean expression and assigns the first
%   argument the meaning |\c_true_bool| or |\c_false_bool|.
%    \begin{macrocode}
\cs_new:Npn \bool_set:Nn #1#2
  { \tex_chardef:D #1 = \bool_if_p:n {#2} }
\cs_new:Npn \bool_gset:Nn #1#2
  { \tex_global:D \tex_chardef:D #1 = \bool_if_p:n {#2} }
\cs_generate_variant:Nn \bool_set:Nn  { c }
\cs_generate_variant:Nn \bool_gset:Nn { c }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[pTF]{\bool_if:N, \bool_if:c}
% \UnitTested
%  Straight forward here. We could optimize here if we wanted to as
%  the boolean can just be input directly.
%    \begin{macrocode}
\prg_new_conditional:Npnn \bool_if:N #1 { p , T , F , TF }
  {
    \if_bool:N #1
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\cs_generate_variant:Nn \bool_if_p:N { c }
\cs_generate_variant:Nn \bool_if:NT  { c }
\cs_generate_variant:Nn \bool_if:NF  { c }
\cs_generate_variant:Nn \bool_if:NTF { c }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{variable}{\l_tmpa_bool, \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{variable}
%
% \subsection{Boolean expressions}
%
% \begin{macro}[pTF]{\bool_if:n}
% \UnitTested
% \begin{macro}[aux]{\bool_get_next:N}
% \begin{macro}[aux]{\bool_cleanup:N}
% \begin{macro}[aux]{\bool_choose:NN}
% \begin{macro}[aux]
%   {
%     bool_!:w,
%     \bool_Not:w,
%     \bool_Not:w,
%     \bool_(:w,
%     \bool_p:w,
%     \bool_8_1:w,
%     \bool_I_1:w,
%     \bool_8_0:w,
%     \bool_I_0:w,
%     \bool_)_0:w,
%     \bool_)_1:w,
%     \bool_S_0:w,
%     \bool_S_1:w
% }
% \begin{macro}[aux]
%   {
%     \bool_eval_skip_to_end:Nw, \bool_eval_skip_to_end_aux:Nw,
%     \bool_eval_skip_to_end_aux_ii:Nw
%  }
%   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 with |(| and |)| for grouping, |!| for
%   logical \enquote{Not}, |&&| for logical \enquote{And} and \verb"||"
%   for logical \enquote{Or}. We shall use the terms Not, And, Or, Open and
%   Close for  these operations.
%
%   Any expression is terminated by a Close operation. Evaluation
%   happens from left to right in the following manner using a GetNext
%   function:
%   \begin{itemize}
%     \item If an Open is seen, start evaluating a new expression using
%       the Eval function and call GetNext again.
%     \item If a Not is seen, insert a negating function (if-even in
%       this case) and call GetNext.
%     \item If none of the above, start evaluating a new expression by
%       reinserting the token found (this is supposed to be a predicate
%       function) in front of Eval.
%   \end{itemize}
%   The Eval function then contains a post-processing operation which
%   grabs the instruction following the predicate. This is either And,
%   Or or Close. In each case the truth value is used to determine
%   where to go next. The following situations can arise:
%   \begin{description}
%     \item[\meta{true}And] Current truth value is true, logical And
%       seen, continue with GetNext to examine truth value of next
%       boolean (sub-)expression.
%     \item[\meta{false}And] Current truth value is false, logical And
%       seen, stop evaluating the predicates within this sub-expression
%       and break to the nearest Close. Then return \meta{false}.
%     \item[\meta{true}Or] Current truth value is true, logical Or
%       seen, stop evaluating the predicates within this sub-expression
%       and break to the nearest Close. Then return \meta{true}.
%     \item[\meta{false}Or] Current truth value is false, logical Or
%       seen, continue with GetNext to examine truth value of next
%       boolean (sub-)expression.
%     \item[\meta{true}Close] Current truth value is true, Close
%       seen, return \meta{true}.
%     \item[\meta{false}Close] Current truth value is false, Close
%       seen, return \meta{false}.
%   \end{description}
%   We introduce an additional Stop operation with the following
%   semantics:
%   \begin{description}
%     \item[\meta{true}Stop] Current truth value is true, return
%       \meta{true}.
%     \item[\meta{false}Stop] Current truth value is false, return
%       \meta{false}.
%   \end{description}
%   The reasons for this follow below.
%
%   Now for how these works in practice. The canonical true and false
%   values have numerical values $1$ and $0$ respectively. We evaluate
%   this using the primitive |\int_value:w:D| operation. First we
%   issue a |\group_align_safe_begin:| as we are using |&&| as syntax
%   shorthand for the And operation and we need to hide it for \TeX{}.
%   We also need to finish this special group before finally
%   returning a |\c_true_bool| or |\c_false_bool| as there might
%   otherwise be something left in front in the input stream. For
%   this we call the Stop operation, denoted simply by a |S|
%   following the last Close operation.
%    \begin{macrocode}
\prg_new_conditional:Npnn \bool_if:n #1 { T , F , TF }
  {
    \if_predicate:w \bool_if_p:n {#1}
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\cs_new:Npn \bool_if_p:n #1
  {
    \group_align_safe_begin:
    \bool_get_next:N ( #1 ) S
  }
%    \end{macrocode}
%   The GetNext operation. We make it a switch: If not a |!| or |(|, we
%   assume it is a predicate.
%    \begin{macrocode}
\cs_new:Npn \bool_get_next:N #1
  {
    \use:c
      {
        bool_
        \if_meaning:w !#1 ! \else: \if_meaning:w (#1 ( \else: p \fi: \fi:
        :w
      }
      #1
  }
%    \end{macrocode}
%   This variant gets called when a Not has just been entered.
%   It (eventually) results in a reversal of the logic of the directly
%   following material.
%    \begin{macrocode}
\cs_new:Npn \bool_get_not_next:N #1
  {
    \use:c
      {
      bool_not_
      \if_meaning:w !#1 ! \else: \if_meaning:w (#1 ( \else: p \fi: \fi:
      :w
      }
        #1
  }
%    \end{macrocode}
%   We need these later on to nullify the unity operation |!!|.
%    \begin{macrocode}
\cs_new:Npn \bool_get_next:NN #1#2 { \bool_get_next:N #2 }
\cs_new:Npn \bool_get_not_next:NN #1#2 { \bool_get_not_next:N #2 }
%    \end{macrocode}
%   The Not operation. Discard the token read and reverse the truth
%   value of the next expression if there
%   are brackets; otherwise
%   if we're coming up to a |!| then we don't need to reverse anything
%   (but we then want to continue scanning ahead in case some fool has written
%   |!!(...)|);
%   otherwise we have a boolean that we can reverse here and now.
%    \begin{macrocode}
\cs_new:cpn { bool_!:w } #1#2
  {
    \if_meaning:w ( #2
      \exp_after:wN \bool_Not:w
    \else:
      \if_meaning:w ! #2
        \exp_after:wN \exp_after:wN \exp_after:wN \bool_get_next:NN
      \else:
        \exp_after:wN \exp_after:wN \exp_after:wN \bool_Not:N
      \fi:
    \fi:
    #2
  }
%    \end{macrocode}
%   Variant called when already inside a Not.
%   Essentially the opposite of the above.
%    \begin{macrocode}
\cs_new:cpn { bool_not_!:w } #1#2
  {
    \if_meaning:w ( #2
      \exp_after:wN \bool_not_Not:w
    \else:
      \if_meaning:w ! #2
        \exp_after:wN \exp_after:wN \exp_after:wN \bool_get_not_next:NN
      \else:
        \exp_after:wN \exp_after:wN \exp_after:wN \bool_not_Not:N
      \fi:
    \fi:
    #2
  }
%    \end{macrocode}
%   These occur when processing |!(...)|. The idea is to use a variant
%   of |\bool_get_next:N| that finishes its parsing with a logic reversal.
%   Of course, the double logic reversal gets us back to where we started.
%    \begin{macrocode}
\cs_new:Npn \bool_Not:w { \exp_after:wN \int_value:w \bool_get_not_next:N }
\cs_new:Npn \bool_not_Not:w { \exp_after:wN \int_value:w \bool_get_next:N }
%    \end{macrocode}
%   These occur when processing |!<bool>| and can be evaluated directly.
%    \begin{macrocode}
\cs_new:Npn \bool_Not:N #1
  {
    \exp_after:wN \bool_p:w
    \if_meaning:w #1 \c_true_bool
      \c_false_bool
    \else:
      \c_true_bool
    \fi:
  }
\cs_new:Npn \bool_not_Not:N #1
  {
    \exp_after:wN \bool_p:w
    \if_meaning:w #1 \c_true_bool
      \c_true_bool
    \else:
      \c_false_bool
    \fi:
  }
%    \end{macrocode}
%   The Open operation. Discard the token read and start a
%   sub-expression.
%   |\bool_get_next:N| continues building up the logical expressions as usual;
%   |\bool_not_cleanup:N| is what reverses the logic if we're inside |!(...)|.
%    \begin{macrocode}
\cs_new:cpn { bool_(:w } #1
  { \exp_after:wN  \bool_cleanup:N \int_value:w \bool_get_next:N }
\cs_new:cpn { bool_not_(:w } #1
  { \exp_after:wN  \bool_not_cleanup:N \int_value:w \bool_get_next:N }
%    \end{macrocode}
%   Otherwise just evaluate the predicate and look for And, Or or Close
%   afterwards.
%    \begin{macrocode}
\cs_new:cpn { bool_p:w } { \exp_after:wN \bool_cleanup:N \int_value:w  }
\cs_new:cpn { bool_not_p:w } {\exp_after:wN \bool_not_cleanup:N \int_value:w }
%    \end{macrocode}
%   This cleanup function can be omitted once predicates return their
%   true/false booleans outside the conditionals.
%    \begin{macrocode}
\cs_new:Npn \bool_cleanup:N #1
  {
    \exp_after:wN \bool_choose:NN \exp_after:wN #1
    \int_to_roman:w - `\q
  }
\cs_new:Npn \bool_not_cleanup:N #1
  {
    \exp_after:wN \bool_not_choose:NN \exp_after:wN #1
    \int_to_roman:w - `\q
  }
%    \end{macrocode}
%   Branching the six way switch.
%   Reversals should be reasonably straightforward.
%    \begin{macrocode}
\cs_new_nopar:Npn \bool_choose:NN #1#2 { \use:c { bool_ #2 _ #1 :w } }
\cs_new_nopar:Npn \bool_not_choose:NN #1#2 { \use:c { bool_not_ #2 _ #1 :w } }
%    \end{macrocode}
%   Continues scanning. Must remove the second "&" or \verb"|".
%    \begin{macrocode}
\cs_new_nopar:cpn { bool_&_1:w } & { \bool_get_next:N }
\cs_new_nopar:cpn { bool_|_0:w } | { \bool_get_next:N }
\cs_new_nopar:cpn { bool_not_&_0:w } & { \bool_get_next:N }
\cs_new_nopar:cpn { bool_not_|_1:w } | { \bool_get_next:N }
%    \end{macrocode}
%   Closing a group is just about returning the result. The Stop
%   operation is similar except it closes the special alignment group
%   before returning the boolean.
%    \begin{macrocode}
\cs_new_nopar:cpn { bool_)_0:w } { \c_false_bool }
\cs_new_nopar:cpn { bool_)_1:w } { \c_true_bool }
\cs_new_nopar:cpn { bool_not_)_0:w } { \c_true_bool }
\cs_new_nopar:cpn { bool_not_)_1:w } { \c_false_bool }
\cs_new_nopar:cpn { bool_S_0:w } { \group_align_safe_end: \c_false_bool }
\cs_new_nopar:cpn { bool_S_1:w } { \group_align_safe_end: \c_true_bool }
%    \end{macrocode}
%   When the truth value has already been decided, we have to throw away
%   the remainder of the current group as we are doing minimal
%   evaluation. This is slightly tricky as there are no braces so we
%   have to play match the |()| manually.
%    \begin{macrocode}
\cs_new_nopar:cpn { bool_&_0:w } & { \bool_eval_skip_to_end:Nw \c_false_bool }
\cs_new_nopar:cpn { bool_|_1:w } | { \bool_eval_skip_to_end:Nw \c_true_bool }
\cs_new_nopar:cpn { bool_not_&_1:w } &
  { \bool_eval_skip_to_end:Nw \c_false_bool }
\cs_new_nopar:cpn { bool_not_|_0:w } |
  { \bool_eval_skip_to_end:Nw \c_true_bool }
%    \end{macrocode}
%   There is always at least one |)| waiting, namely the outer
%   one. However, we are facing the problem that there may be more than
%   one that need to be finished off and we have to detect the correct
%   number of them. Here is a complicated example showing how this is
%   done. After evaluating the following, we realize we must skip
%   everything after the first And. Note the extra Close at the end.
%   \begin{quote}
%     |\c_false_bool  && ((abc) && xyz) && ((xyz) && (def)))|
%   \end{quote}
%   First read up to the first Close. This gives us the list we first
%   read up until the first right parenthesis so we are looking at the
%   token list
%   \begin{quote}
%     |((abc|
%   \end{quote}
%   This contains two Open markers so we must remove two groups. Since
%   no evaluation of the contents is to be carried out, it doesn't
%   matter how we remove the groups as long as we wind up with the
%   correct result. We therefore first remove a |()| pair and what
%   preceded the Open -- but leave the contents as it may contain Open
%   tokens itself -- leaving
%   \begin{quote}
%     |(abc && xyz) && ((xyz) && (def)))|
%   \end{quote}
%   Another round of this gives us
%   \begin{quote}
%     |(abc && xyz|
%   \end{quote}
%   which still contains an Open so we remove another |()| pair, giving us
%   \begin{quote}
%     |abc && xyz && ((xyz) && (def)))|
%   \end{quote}
%   Again we read up to a Close and again find Open tokens:
%   \begin{quote}
%     |abc && xyz && ((xyz|
%   \end{quote}
%   Further reduction gives us
%   \begin{quote}
%     |(xyz && (def)))|
%   \end{quote}
%   and then
%   \begin{quote}
%     |(xyz && (def|
%   \end{quote}
%   with reduction to
%   \begin{quote}
%     |xyz && (def))|
%   \end{quote}
%   and ultimately we arrive at no Open tokens being skipped and we can
%   finally close the group nicely.
%    \begin{macrocode}
%% (
\cs_new:Npn \bool_eval_skip_to_end:Nw #1#2 )
  {
    \bool_eval_skip_to_end_aux:Nw #1#2 ( % )
    \q_no_value \q_stop
    {#2}
  }
%    \end{macrocode}
%   If no right parenthesis, then |#3| is no_value and we are done, return
%   the boolean |#1|.  If there is, we need to grab a |()| pair and then
%   recurse
%    \begin{macrocode}
\cs_new:Npn \bool_eval_skip_to_end_aux:Nw #1#2 ( #3#4 \q_stop #5 % )
  {
    \quark_if_no_value:NTF #3
    {#1}
    { \bool_eval_skip_to_end_aux_ii:Nw #1 #5 }
  }
%    \end{macrocode}
%   Keep the boolean, throw away anything up to the |(| as it is
%   irrelevant, remove a |()| pair but remember to reinsert |#3| as it may
%   contain |(| tokens!
%    \begin{macrocode}
\cs_new:Npn \bool_eval_skip_to_end_aux_ii:Nw #1#2 ( #3 )
  { % (
    \bool_eval_skip_to_end:Nw #1#3 )
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\bool_not_p:n}
% \UnitTested
%   The Not variant just reverses the outcome of |\bool_if_p:n|. Can
%   be optimized but this is nice and simple and according to the
%   implementation plan. Not even particularly useful to have it when
%   the infix notation is easier to use.
%    \begin{macrocode}
\cs_new:Npn \bool_not_p:n #1 { \bool_if_p:n { ! ( #1 ) } }
%    \end{macrocode}
%  \end{macro}
%
% \begin{macro}{\bool_xor_p:nn}
% \UnitTested
%    Exclusive or. If the boolean expressions have same truth value,
%    return false, otherwise return true.
%    \begin{macrocode}
\cs_new:Npn \bool_xor_p:nn #1#2
  {
    \int_compare:nNnTF { \bool_if_p:n {#1} } = { \bool_if_p:n {#2} }
      \c_false_bool
      \c_true_bool
  }
%    \end{macrocode}
% \end{macro}
%
% \subsection{Logical loops}
%
% \begin{macro}{\bool_while_do:Nn,\bool_while_do:cn}
% \UnitTested
% \begin{macro}{\bool_until_do:Nn,\bool_until_do:cn}
% \UnitTested
%   A |while| loop where the boolean is tested before executing the
%   statement. The \enquote{while} version executes the code as long as the
%   boolean is true; the \enquote{until} version executes the code as
%   long as the boolean is false.
%    \begin{macrocode}
\cs_new:Npn \bool_while_do:Nn #1#2
  { \bool_if:NT #1 { #2 \bool_while_do:Nn #1 {#2} } }
\cs_new:Npn \bool_until_do:Nn #1#2
  { \bool_if:NF #1 { #2 \bool_until_do:Nn #1 {#2} } }
\cs_generate_variant:Nn \bool_while_do:Nn { c }
\cs_generate_variant:Nn \bool_until_do:Nn { c }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\bool_do_while:Nn,\bool_do_while:cn}
% \UnitTested
% \begin{macro}{\bool_do_until:Nn,\bool_do_until:cn}
% \UnitTested
%   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}
\cs_new:Npn \bool_do_while:Nn #1#2
  { #2 \bool_if:NT #1 { \bool_do_while:Nn #1 {#2} } }
\cs_new:Npn \bool_do_until:Nn #1#2
  { #2 \bool_if:NF #1 { \bool_do_until:Nn #1 {#2} } }
\cs_generate_variant:Nn \bool_do_while:Nn { c }
\cs_generate_variant:Nn \bool_do_until:Nn { c }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}
%   {
%     \bool_while_do:nn, \bool_do_while:nn ,
%     \bool_until_do:nn, \bool_do_until:nn
%   }
%  \UnitTested
%   Loop functions with the test either before or after the first body
%   expansion.
%    \begin{macrocode}
\cs_new:Npn \bool_while_do:nn #1#2
  {
    \bool_if:nT {#1}
      {
        #2
        \bool_while_do:nn {#1} {#2}
      }
  }
\cs_new:Npn \bool_do_while:nn #1#2
  {
    #2
    \bool_if:nT {#1} { \bool_do_while:nn {#1} {#2} }
  }
\cs_new:Npn \bool_until_do:nn #1#2
  {
    \bool_if:nF {#1}
      {
        #2
        \bool_until_do:nn {#1} {#2}
      }
  }
\cs_new:Npn \bool_do_until:nn #1#2
  {
    #2
    \bool_if:nF {#1} { \bool_do_until:nn {#1} {#2}  }
  }
%    \end{macrocode}
% \end{macro}
%
% \subsection{Switching by case}
%
% A family of functions to select one case of a number: the same ideas
% are used for a number of different situations.
%
% \begin{macro}[aux]{\prg_case_end:nw}
%   In all cases the end statement is the same. Here, |#1| will be the
%   code needed, |#2| the other cases to throw away, including the
% \enquote{else} case.
%    \begin{macrocode}
\cs_new_eq:NN \prg_case_end:nw \use_i_delimit_by_q_recursion_stop:nw
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\prg_case_int:nnn}
% \UnitTested
% \begin{macro}[aux]{\prg_case_int_aux:nnn,\prg_case_int_aux:nw}
%   For integer cases, the first task to fully expand the check
%   condition. After that, a loop is started to compare each possible
%   value and stop if the test is true. The tested value is put at the
%   end to ensure that there is necessarily a match, which will fire the
% \enquote{else} pathway.
%    \begin{macrocode}
\cs_new:Npn \prg_case_int:nnn #1
  { \exp_args:Nf \prg_case_int_aux:nnn { \int_eval:n {#1} } }
\cs_new:Npn \prg_case_int_aux:nnn #1 #2 #3
  { \prg_case_int_aux:nw {#1} #2 {#1} {#3} \q_recursion_stop }
\cs_new:Npn \prg_case_int_aux:nw #1#2#3
  {
    \int_compare:nNnTF {#1} = {#2}
      { \prg_case_end:nw {#3} }
      { \prg_case_int_aux:nw {#1} }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\prg_case_dim:nnn}
% \UnitTested
% \begin{macro}[aux]{\prg_case_dim_aux:nnn,\prg_case_dim_aux:nw}
%   The dimension function is the same, just a change of calculation
%   method.
%    \begin{macrocode}
\cs_new:Npn \prg_case_dim:nnn #1
  { \exp_args:Nf \prg_case_dim_aux:nnn { \dim_eval:n {#1} } }
\cs_new:Npn \prg_case_dim_aux:nnn #1 #2 #3
  { \prg_case_dim_aux:nw {#1} #2 {#1} {#3} \q_recursion_stop }
\cs_new:Npn \prg_case_dim_aux:nw #1#2#3
  {
    \dim_compare:nNnTF {#1} = {#2}
      { \prg_case_end:nw {#3} }
      { \prg_case_dim_aux:nw {#1} }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\prg_case_str:nnn, \prg_case_str:onn, \prg_case_str:xxn}
% \UnitTested
% \begin{macro}[aux]{\prg_case_str_aux:nw, \prg_case_str_x_aux:nw}
%   No calculations for strings, otherwise no surprises.
%    \begin{macrocode}
\cs_new:Npn \prg_case_str:nnn #1#2#3
  { \prg_case_str_aux:nw {#1} #2 {#1} {#3} \q_recursion_stop }
\cs_new:Npn \prg_case_str_aux:nw #1#2#3
  {
    \str_if_eq:nnTF {#1} {#2}
      { \prg_case_end:nw {#3} }
      { \prg_case_str_aux:nw {#1} }
  }
\cs_generate_variant:Nn \prg_case_str:nnn { o }
\cs_new:Npn \prg_case_str:xxn #1#2#3
  { \prg_case_str_x_aux:nw {#1} #2 {#1} {#3} \q_recursion_stop }
\cs_new:Npn \prg_case_str_x_aux:nw #1#2#3
  {
    \str_if_eq:xxTF {#1} {#2}
      { \prg_case_end:nw {#3} }
      { \prg_case_str_x_aux:nw {#1} }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\prg_case_tl:Nnn, \prg_case_tl:cnn}
% \UnitTested
% \begin{macro}[aux]{\prg_case_tl_aux:Nw}
%   Similar again, but this time with some variants.
%    \begin{macrocode}
\cs_new:Npn \prg_case_tl:Nnn #1#2#3
  { \prg_case_tl_aux:Nw #1 #2 #1 {#3} \q_recursion_stop }
\cs_new:Npn \prg_case_tl_aux:Nw #1#2#3
  {
    \tl_if_eq:NNTF #1 #2
      { \prg_case_end:nw {#3} }
      { \prg_case_tl_aux:Nw #1 }
  }
\cs_generate_variant:Nn \prg_case_tl:Nnn { c }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsection{Producing $n$ copies}
%
% \begin{macro}{\prg_replicate:nn}
% \UnitTested
% \begin{macro}[aux]{\prg_replicate_aux:N, \prg_replicate_first_aux:N}
% \begin{macro}[aux]{\prg_replicate_}
% \begin{macro}[aux]
%   {
%     \prg_replicate_0:n,
%     \prg_replicate_1:n,
%     \prg_replicate_2:n,
%     \prg_replicate_3:n,
%     \prg_replicate_4:n,
%     \prg_replicate_5:n,
%     \prg_replicate_6:n,
%     \prg_replicate_7:n,
%     \prg_replicate_8:n,
%     \prg_replicate_9:n
%   }
% \begin{macro}[aux]
%   {
%     \prg_replicate_first_-:n,
%     \prg_replicate_first_0:n,
%     \prg_replicate_first_1:n,
%     \prg_replicate_first_2:n,
%     \prg_replicate_first_3:n,
%     \prg_replicate_first_4:n,
%     \prg_replicate_first_5:n,
%     \prg_replicate_first_6:n,
%     \prg_replicate_first_7:n,
%     \prg_replicate_first_8:n,
%     \prg_replicate_first_9: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. These functions also close the expansion of
%   \cs{int_to_roman:w}, which ensures that \cs{prg_replicate:nn} only
%   requires two steps of expansion.
%
%   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, and if
%   necessary, it is possible to write
%   |\prg_replicate:nn{1000}{\prg_replicate:nn{1000}{|\meta{code}|}}|. An
%   alternative approach is to create a string of |m|'s with
%   \cs{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}
\cs_new_nopar:Npn \prg_replicate:nn #1
  {
    \int_to_roman:w
      \exp_after:wN \prg_replicate_first_aux:N
        \int_value:w \int_eval:w #1 \int_eval_end:
      \cs_end:
  }
\cs_new_nopar:Npn \prg_replicate_aux:N #1
  { \cs:w prg_replicate_#1 :n \prg_replicate_aux:N }
\cs_new_nopar:Npn \prg_replicate_first_aux:N #1
  { \cs:w prg_replicate_first_ #1 :n \prg_replicate_aux:N }
%    \end{macrocode}
% \end{macro}
% Then comes all the functions that do the hard work of inserting all
% the copies.
%    \begin{macrocode}
\cs_new_nopar:Npn \prg_replicate_ :n #1 { \cs_end: }
\cs_new:cpn { prg_replicate_0:n } #1 { \cs_end: {#1#1#1#1#1#1#1#1#1#1} }
\cs_new:cpn { prg_replicate_1:n } #1 { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1 }
\cs_new:cpn { prg_replicate_2:n } #1 { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1 }
\cs_new:cpn { prg_replicate_3:n } #1
  { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1 }
\cs_new:cpn { prg_replicate_4:n } #1
  { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1 }
\cs_new:cpn { prg_replicate_5:n } #1
  { \cs_end: {#1#1#1#1#1#1#1#1#1#1} #1#1#1#1#1 }
\cs_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 }
\cs_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 }
\cs_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 }
\cs_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}
\cs_new:cpn { prg_replicate_first_-:n } #1 { \c_zero \negative_replication }
\cs_new:cpn { prg_replicate_first_0:n } #1 { \c_zero }
\cs_new:cpn { prg_replicate_first_1:n } #1 { \c_zero #1 }
\cs_new:cpn { prg_replicate_first_2:n } #1 { \c_zero #1#1 }
\cs_new:cpn { prg_replicate_first_3:n } #1 { \c_zero #1#1#1 }
\cs_new:cpn { prg_replicate_first_4:n } #1 { \c_zero #1#1#1#1 }
\cs_new:cpn { prg_replicate_first_5:n } #1 { \c_zero #1#1#1#1#1 }
\cs_new:cpn { prg_replicate_first_6:n } #1 { \c_zero #1#1#1#1#1#1 }
\cs_new:cpn { prg_replicate_first_7:n } #1 { \c_zero #1#1#1#1#1#1#1 }
\cs_new:cpn { prg_replicate_first_8:n } #1 { \c_zero #1#1#1#1#1#1#1#1 }
\cs_new:cpn { prg_replicate_first_9:n } #1 { \c_zero #1#1#1#1#1#1#1#1#1 }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\prg_stepwise_function:nnnN}
% \begin{macro}[aux]
%  {\prg_stepwise_function_incr:nnnN, \prg_stepwise_function_decr:nnnN}
%   Repeating a function by steps fist needs a check on the direction
%   of the steps. After that, do the function for the start value
%   then step and loop around.
%    \begin{macrocode}
\cs_new:Npn \prg_stepwise_function:nnnN #1#2
  {
    \int_compare:nNnTF {#2} > { 0 }
      { \exp_args:Nf \prg_stepwise_function_incr:nnnN }
      { \exp_args:Nf \prg_stepwise_function_decr:nnnN }
        { \int_eval:n {#1} } {#2}
  }
\cs_new:Npn \prg_stepwise_function_incr:nnnN #1#2#3#4
  {
    \int_compare:nNnF {#1} > {#3}
      {
        #4 {#1}
        \exp_args:Nf \prg_stepwise_function_incr:nnnN
          { \int_eval:n { #1 + #2 } } {#2} {#3} #4
      }
  }
\cs_new:Npn \prg_stepwise_function_decr:nnnN #1#2#3#4
  {
    \int_compare:nNnF {#1}  < {#3}
      {
        #4 {#1}
        \exp_args:Nf \prg_stepwise_function_decr:nnnN
          { \int_eval:n { #1 + #2 } } {#2} {#3} #4
      }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%\begin{macro}[aux]{\g_prg_stepwise_level_int}
% For nesting, the usual approach of using a counter.
%    \begin{macrocode}
\int_new:N \g_prg_stepwise_level_int
%    \end{macrocode}
%\end{macro}
%
%\begin{macro}{\prg_stepwise_inline:nnnn}
%\begin{macro}[aux]
%  {\prg_stepwise_inline_incr:Nnnn, \prg_stepwise_inline_decr:Nnnn}
%   The approach here is similar but with a global integer required
%   to make the nesting safe (as seen in other in line functions).
%    \begin{macrocode}
\cs_new_protected:Npn \prg_stepwise_inline:nnnn #1#2#3#4
  {
    \int_gincr:N \g_prg_stepwise_level_int
    \cs_gset_nopar:cpn
      { g_prg_stepwise_ \int_use:N \g_prg_stepwise_level_int :n }
        ##1 {#4}
    \int_compare:nNnTF {#2} > { 0 }
      { \exp_args:Ncf \prg_stepwise_inline_incr:Nnnn }
      { \exp_args:Ncf \prg_stepwise_inline_decr:Nnnn }
        { g_prg_stepwise_ \int_use:N \g_prg_stepwise_level_int :n }
        { \int_eval:n {#1} } {#2} {#3}
    \int_gdecr:N \g_prg_stepwise_level_int
  }
\cs_new_protected:Npn \prg_stepwise_inline_incr:Nnnn #1#2#3#4
  {
    \int_compare:nNnF {#2} > {#4}
      {
        #1 {#2}
        \exp_args:NNf \prg_stepwise_inline_incr:Nnnn #1
          { \int_eval:n { #2 + #3 } } {#3} {#4}
      }
  }
\cs_new_protected:Npn \prg_stepwise_inline_decr:Nnnn #1#2#3#4
  {
    \int_compare:nNnF {#2} < {#4}
      {
        #1 {#2}
        \exp_args:NNf \prg_stepwise_inline_decr:Nnnn #1
          { \int_eval:n { #2 + #3 } } {#3} {#4}
      }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\prg_stepwise_variable:nnnNn}
% \UnitTested
%   A wrapper for the above.
%    \begin{macrocode}
\cs_new_protected:Npn \prg_stepwise_variable:nnnNn #1#2#3#4#5
  {
    \prg_stepwise_inline:nnnn {#1} {#2} {#3}
      {
        \tl_set:Nn #4 {##1}
        #5
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \subsection{Detecting \TeX{}'s mode}
%
% \begin{macro}[pTF]{\mode_if_vertical:}
% \UnitTested
%   For testing vertical mode. Strikes me here on the bus with David,
%   that as long as we are just talking about returning true and
%   false states, we can just use the primitive conditionals for this
%   and gobbling the |\c_zero| in the input stream. However this
%   requires knowledge of the implementation so we keep things nice
%   and clean and use the return statements.
%    \begin{macrocode}
\prg_new_conditional:Npnn \mode_if_vertical: { p , T , F , TF }
  { \if_mode_vertical: \prg_return_true: \else: \prg_return_false: \fi: }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[pTF]{\mode_if_horizontal:}
% \UnitTested
%   For testing horizontal mode.
%    \begin{macrocode}
\prg_new_conditional:Npnn \mode_if_horizontal: { p , T , F , TF }
  { \if_mode_horizontal: \prg_return_true: \else: \prg_return_false: \fi: }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[pTF]{\mode_if_inner:}
% \UnitTested
%   For testing inner mode.
%    \begin{macrocode}
\prg_new_conditional:Npnn \mode_if_inner: { p , T , F , TF }
  { \if_mode_inner: \prg_return_true: \else: \prg_return_false: \fi: }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[pTF]{\mode_if_math:}
% \UnitTested
%   For testing math mode: without \cs{scan_align_safe_stop:}
%   things go wrong in alignments.
%    \begin{macrocode}
\prg_new_conditional:Npnn \mode_if_math: { p , T , F , TF }
  {
    \scan_align_safe_stop:
    \if_mode_math: \prg_return_true: \else: \prg_return_false: \fi:
  }
%    \end{macrocode}
% \end{macro}
%
% \subsection{Internal programming functions}
%
% \begin{macro}[int]{\group_align_safe_begin:, \group_align_safe_end:}
%   \TeX{}'s alignment structures present many problems. As Knuth says
%   himself in \emph{\TeX : The Program}: \enquote{It's sort of a miracle
%   whenever \cs{halign} or \cs{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 |&|$_4$ 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
%   We place the \cs{if_false:} |{| \cs{fi:} part at that place so
%   that the successive expansions of \cs{group_align_safe_begin/end:}
%   are always brace balanced.
%    \begin{macrocode}
\cs_new_nopar:Npn \group_align_safe_begin:
  { \if_int_compare:w \if_false: { \fi: `} = \c_zero \fi: }
\cs_new_nopar:Npn \group_align_safe_end:
  { \if_int_compare:w `{ = \c_zero } \fi: }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\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 \cs{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, \emph{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 if an only
%   if 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}
\cs_new_nopar:Npn \scan_align_safe_stop:
  {
    \int_compare:nNnT \etex_currentgrouptype:D = \c_six
      {
        \int_compare:nNnF \etex_lastnodetype:D = \c_zero
          { \int_compare:nNnF \etex_lastnodetype:D = \c_seven { \scan_stop: } }
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\prg_variable_get_scope:N}
% \begin{macro}[aux]{\prg_variable_get_scope_aux:w}
% \begin{macro}[int]{\prg_variable_get_type:N}
% \begin{macro}[aux]{\prg_variable_get_type:w}
%   Expandable functions to find the type of a variable, and to
%   return \texttt{g} if the variable is global. The trick for
%   \cs{prg_variable_get_scope:N} is the same as that in
%   \cs{cs_split_function:NN}, but it can be simplified as the
%   requirements here are less complex.
%    \begin{macrocode}
\group_begin:
  \tex_lccode:D `\& = `\g \scan_stop:
  \tex_catcode:D `\& = \c_twelve
\tl_to_lowercase:n
  {
    \group_end:
    \cs_new_nopar:Npn \prg_variable_get_scope:N #1
      {
        \exp_last_unbraced:Nf \prg_variable_get_scope_aux:w
          { \cs_to_str:N #1 \exp_stop_f: \q_stop }
      }
    \cs_new_nopar:Npn \prg_variable_get_scope_aux:w #1#2 \q_stop
      { \token_if_eq_meaning:NNT & #1 { g } }
  }
\group_begin:
  \tex_lccode:D `\& = `\_ \scan_stop:
  \tex_catcode:D `\& = \c_twelve
\tl_to_lowercase:n
  {
    \group_end:
    \cs_new_nopar:Npn \prg_variable_get_type:N #1
      {
        \exp_after:wN \prg_variable_get_type_aux:w
          \token_to_str:N #1 & a \q_stop
      }
    \cs_new_nopar:Npn \prg_variable_get_type_aux:w #1 & #2#3 \q_stop
      {
        \token_if_eq_meaning:NNTF a #2
          {#1}
          { \prg_variable_get_type_aux:w #2#3 \q_stop }
      }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% 
% \subsection{Experimental programmings functions}
%
%
% \begin{macro}[aux]{\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 variable, so one additionally has to define
%   \begin{quote}
%     |\cs_set_nopar:Npn \seq_quicksort:N{\exp_args:No\seq_quicksort:n}|
%   \end{quote}
%
%
%   For details on the implementation see \enquote{Sorting in \TeX{}'s Mouth}
%   by Bernd Raichle. Firstly we define the function for parsing the
%   initial list and then the braced list afterwards.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \prg_define_quicksort:nnn #1#2#3 {
  \cs_set:cpx{#1_quicksort:n}##1{
    \exp_not:c{#1_quicksort_start_partition:w} ##1
    \exp_not:n{#2\q_nil#3\q_stop}
  }
  \cs_set:cpx{#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
  }
  \cs_set: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}{}{}
  }
  \cs_set:cpx {#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}
  \cs_set: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}
  }
  \cs_set:cpx {#1_quicksort_do_partition_i_braced:nnnn} ##1##2##3##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}
  }
  \cs_set: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}
  }
  \cs_set:cpx {#1_quicksort_do_partition_ii_braced:nnnn} ##1##2##3##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}
  \cs_set:cpx {#1_quicksort_partition_less_i:nnnn} ##1##2##3##4{
    \exp_not:c{#1_quicksort_do_partition_i:nnnw}{##1}{##2}{{##4}##3}}
  \cs_set:cpx {#1_quicksort_partition_less_ii:nnnn} ##1##2##3##4{
    \exp_not:c{#1_quicksort_do_partition_ii:nnnw}{##1}{##2}{##3{##4}}}
  \cs_set:cpx {#1_quicksort_partition_greater_i:nnnn} ##1##2##3##4{
    \exp_not:c{#1_quicksort_do_partition_i:nnnw}{##1}{{##4}##2}{##3}}
  \cs_set:cpx {#1_quicksort_partition_greater_ii:nnnn} ##1##2##3##4{
    \exp_not:c{#1_quicksort_do_partition_ii:nnnw}{##1}{##2{##4}}{##3}}
  \cs_set:cpx {#1_quicksort_partition_less_i_braced:nnnn} ##1##2##3##4{
    \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn}{##1}{##2}{{##4}##3}}
  \cs_set:cpx {#1_quicksort_partition_less_ii_braced:nnnn} ##1##2##3##4{
    \exp_not:c{#1_quicksort_do_partition_ii_braced:nnnn}{##1}{##2}{##3{##4}}}
  \cs_set:cpx {#1_quicksort_partition_greater_i_braced:nnnn} ##1##2##3##4{
    \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn}{##1}{{##4}##2}{##3}}
  \cs_set:cpx {#1_quicksort_partition_greater_ii_braced:nnnn} ##1##2##3##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}
  \cs_set: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}
% \UnitTested
%   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}
% \UnitTested
% \begin{macro}{\prg_quicksort_compare:nnTF}
% \UnitTested
%    \begin{macrocode}
\cs_set:Npn \prg_quicksort_function:n {\ERROR}
\cs_set:Npn \prg_quicksort_compare:nnTF {\ERROR}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsection{Deprecated functions}
%
% These were depreciated on 2011-05-27 and will be removed entirely by
% 2011-08-31.
%
% \begin{macro}{\prg_new_map_functions:Nn}
% \begin{macro}{\prg_set_map_functions:Nn}
%   As we have restructured the structured variables, these are no
%   longer needed.
%    \begin{macrocode}
\cs_new_protected:Npn \prg_new_map_functions:Nn #1#2 { \deprectiated }
\cs_new_protected:Npn \prg_set_map_functions:Nn #1#2 { \deprectiated }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%    \begin{macrocode}
%</initex|package>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex