Skip to content

Commit

Permalink
Make intarray public
Browse files Browse the repository at this point in the history
  • Loading branch information
josephwright committed Mar 29, 2018
1 parent ffb5def commit 28a1889
Show file tree
Hide file tree
Showing 13 changed files with 209 additions and 196 deletions.
123 changes: 68 additions & 55 deletions l3kernel/l3intarray.dtx
Expand Up @@ -30,7 +30,7 @@
%
%
% \title{^^A
% The \textsf{l3intarray} package: Low-level arrays of small integers^^A
% The \textsf{l3intarray} package: fast global integer arrays^^A
% }
%
% \author{^^A
Expand All @@ -50,66 +50,79 @@
%
% \section{\pkg{l3intarray} documentation}
%
% This module provides no user function: at present it is meant for
% kernel use only.
%
% It is a wrapper around the \tn{fontdimen} primitive, used to store
% arrays of integers (with a restricted range: absolute value at most
% $2^{30}-1$). In contrast to \pkg{l3seq} sequences the access to
% individual entries is done in constant time rather than linear time,
% but only integers can be stored. More precisely, the primitive
% \tn{fontdimen} stores dimensions but the \pkg{l3intarray} package
% transparently converts these from/to integers. Assignments are always
% global.
%
% While \LuaTeX{}'s memory is extensible, other engines can
% \enquote{only} deal with a bit less than $4\times 10^6$ entries in all
% \tn{fontdimen} arrays combined (with default \TeX{}Live settings).
%
% \subsection{Internal functions}
%
% \begin{function}{\__intarray_new:Nn}
% For applications requiring heavy use of integers, this module provides
% arrays which can be accessed in constant time (contrast \pkg{l3seq},
% where access time is linear). These arrays have several important
% features
% \begin{itemize}
% \item The size of the array is fixed and must be given at
% point of initialisation
% \item The absolute value of each entry has maximum $2^{30}-1$
% (\emph{i.e.}~one power lower than the usual \cs{c_max_int}
% ceiling of $2^{31}-1$)
% \item The total number of entries in all \texttt{intarray} storage
% must be less than $4\times 10^6$
% \end{itemize}
% The use of \texttt{intarray} data is therefore recommended for cases where
% the need for fast access is of paramount importance.
%
% \begin{function}{\intarray_new:Nn}
% \begin{syntax}
% \cs{__intarray_new:Nn} \meta{intarray~var} \Arg{size}
% \cs{intarray_new:Nn} \meta{intarray~var} \Arg{size}
% \end{syntax}
% Evaluates the integer expression \meta{size} and allocates an
% \meta{integer array variable} with that number of (zero) entries.
% \end{function}
%
% \begin{function}[EXP]{\__intarray_count:N}
% \begin{function}[EXP]{\intarray_count:N}
% \begin{syntax}
% \cs{__intarray_count:N} \meta{intarray~var}
% \cs{intarray_count:N} \meta{intarray~var}
% \end{syntax}
% Expands to the number of entries in the \meta{integer array variable}.
% Contrarily to \cs{seq_count:N} this is performed in constant time.
% \end{function}
%
% \begin{function}{\__intarray_gset:Nnn, \__intarray_gset_fast:Nnn}
% \begin{function}{\intarray_gset:Nnn, \intarray_gset_fast:Nnn}
% \begin{syntax}
% \cs{__intarray_gset:Nnn} \meta{intarray~var} \Arg{position} \Arg{value}
% \cs{__intarray_gset_fast:Nnn} \meta{intarray~var} \Arg{position} \Arg{value}
% \cs{intarray_gset:Nnn} \meta{intarray~var} \Arg{position} \Arg{value}
% \cs{intarray_gset_fast:Nnn} \meta{intarray~var} \Arg{position} \Arg{value}
% \end{syntax}
% Stores the result of evaluating the integer expression \meta{value}
% into the \meta{integer array variable} at the (integer expression)
% \meta{position}. While \cs{__intarray_gset:Nnn} checks that the
% \meta{position} is between $1$ and the \cs{__intarray_count:N} and that
% \meta{position}. While \cs{intarray_gset:Nnn} checks that the
% \meta{position} is between $1$ and the \cs{intarray_count:N} and that
% the \meta{value}'s absolute value is at most $2^{30}-1$, the
% \enquote{fast} function performs no such bound check.
% Assignments are always global.
% \end{function}
%
% \begin{function}[EXP]{\__intarray_item:Nn, \__intarray_item_fast:Nn}
% \begin{function}[EXP]{\intarray_item:Nn, \intarray_item_fast:Nn}
% \begin{syntax}
% \cs{__intarray_item:Nn} \meta{intarray~var} \Arg{position}
% \cs{__intarray_item_fast:Nn} \meta{intarray~var} \Arg{position}
% \cs{intarray_item:Nn} \meta{intarray~var} \Arg{position}
% \cs{intarray_item_fast:Nn} \meta{intarray~var} \Arg{position}
% \end{syntax}
% Expands to the integer entry stored at the (integer expression)
% \meta{position} in the \meta{integer array variable}. While
% \cs{__intarray_item:Nn} checks that the \meta{position} is between $1$
% and the \cs{__intarray_count:N}, the \enquote{fast} function performs
% \cs{intarray_item:Nn} checks that the \meta{position} is between $1$
% and the \cs{intarray_count:N}, the \enquote{fast} function performs
% no such bound check.
% \end{function}
%
% \subsection{Implementation notes}
%
% It is a wrapper around the \tn{fontdimen} primitive, used to store
% arrays of integers (with a restricted range: absolute value at most
% $2^{30}-1$). In contrast to \pkg{l3seq} sequences the access to
% individual entries is done in constant time rather than linear time,
% but only integers can be stored. More precisely, the primitive
% \tn{fontdimen} stores dimensions but the \pkg{l3intarray} package
% transparently converts these from/to integers. Assignments are always
% global.
%
% While \LuaTeX{}'s memory is extensible, other engines can
% \enquote{only} deal with a bit less than $4\times 10^6$ entries in all
% \tn{fontdimen} arrays combined (with default \TeX{}Live settings).
%
% \end{documentation}
%
% \begin{implementation}
Expand All @@ -133,7 +146,7 @@
% \end{macrocode}
% \end{variable}
%
% \begin{macro}{\@@_new:Nn}
% \begin{macro}{\intarray_new:Nn}
% Declare |#1| to be a font (arbitrarily |cmr10| at a never-used
% size). Store the array's size as the \tn{hyphenchar} of that font
% and make sure enough \tn{fontdimen} are allocated, by setting the
Expand All @@ -142,7 +155,7 @@
% number $8$ compared to other engines (for a math font we would
% replace $8$ by $22$ or some such).
% \begin{macrocode}
\cs_new_protected:Npn \@@_new:Nn #1#2
\cs_new_protected:Npn \intarray_new:Nn #1#2
{
\__chk_if_free_cs:N #1
\int_gincr:N \g_@@_font_int
Expand All @@ -156,65 +169,65 @@
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[EXP]{\@@_count:N}
% \begin{macro}[EXP]{\intarray_count:N}
% Size of an array.
% \begin{macrocode}
\cs_new:Npn \@@_count:N #1 { \tex_the:D \tex_hyphenchar:D #1 }
\cs_new:Npn \intarray_count:N #1 { \tex_the:D \tex_hyphenchar:D #1 }
% \end{macrocode}
% \end{macro}
%
% \subsection{Array items}
%
% \begin{macro}{\@@_gset:Nnn, \@@_gset_fast:Nnn}
% \begin{macro}{\@@_gset_aux:Nnn}
% \begin{macro}{\intarray_gset:Nnn, \intarray_gset_fast:Nnn}
% \begin{macro}{\@@_gset:Nnn}
% Set the appropriate \tn{fontdimen}. The slow version checks the
% position and value are within bounds.
% \begin{macrocode}
\cs_new_protected:Npn \@@_gset_fast:Nnn #1#2#3
\cs_new_protected:Npn \intarray_gset_fast:Nnn #1#2#3
{ \tex_fontdimen:D \int_eval:n {#2} #1 = \int_eval:n {#3} sp \scan_stop: }
\cs_new_protected:Npn \@@_gset:Nnn #1#2#3
\cs_new_protected:Npn \intarray_gset:Nnn #1#2#3
{
\exp_args:Nff \@@_gset_aux:Nnn #1
\exp_args:Nff \@@_gset:Nnn #1
{ \int_eval:n {#2} } { \int_eval:n {#3} }
}
\cs_new_protected:Npn \@@_gset_aux:Nnn #1#2#3
\cs_new_protected:Npn \@@_gset:Nnn #1#2#3
{
\int_compare:nTF { 1 <= #2 <= \@@_count:N #1 }
\int_compare:nTF { 1 <= #2 <= \intarray_count:N #1 }
{
\int_compare:nTF { - \c_max_dim <= \int_abs:n {#3} <= \c_max_dim }
{ \@@_gset_fast:Nnn #1 {#2} {#3} }
{ \intarray_gset_fast:Nnn #1 {#2} {#3} }
{
\__kernel_msg_error:nnxxxx { kernel } { overflow }
{ \token_to_str:N #1 } {#2} {#3}
{ \int_compare:nNnT {#3} < 0 { - } \int_value:w \c_max_dim }
\@@_gset_fast:Nnn #1 {#2}
\intarray_gset_fast:Nnn #1 {#2}
{ \int_compare:nNnT {#3} < 0 { - } \c_max_dim }
}
}
{
\__kernel_msg_error:nnxxx { kernel } { out-of-bounds }
{ \token_to_str:N #1 } {#2} { \@@_count:N #1 }
{ \token_to_str:N #1 } {#2} { \intarray_count:N #1 }
}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}[EXP]{\@@_item:Nn, \@@_item_fast:Nn}
% \begin{macro}{\@@_item_aux:Nn}
% \begin{macro}[EXP]{\intarray_item:Nn, \intarray_item_fast:Nn}
% \begin{macro}{\@@_item:Nn}
% Get the appropriate \tn{fontdimen} and perform bound checks if requested.
% \begin{macrocode}
\cs_new:Npn \@@_item_fast:Nn #1#2
\cs_new:Npn \intarray_item_fast:Nn #1#2
{ \int_eval:n { \tex_fontdimen:D \int_eval:n {#2} #1 } }
\cs_new:Npn \intarray_item:Nn #1#2
{ \exp_args:Nf \@@_item:Nn #1 { \int_eval:n {#2} } }
\cs_new:Npn \@@_item:Nn #1#2
{ \exp_args:Nf \@@_item_aux:Nn #1 { \int_eval:n {#2} } }
\cs_new:Npn \@@_item_aux:Nn #1#2
{
\int_compare:nTF { 1 <= #2 <= \@@_count:N #1 }
{ \@@_item_fast:Nn #1 {#2} }
\int_compare:nTF { 1 <= #2 <= \intarray_count:N #1 }
{ \intarray_item_fast:Nn #1 {#2} }
{
\__kernel_msg_expandable_error:nnnnn { kernel } { out-of-bounds }
{ \token_to_str:N #1 } {#2} { \@@_count:N #1 }
{ \token_to_str:N #1 } {#2} { \intarray_count:N #1 }
0
}
}
Expand Down

0 comments on commit 28a1889

Please sign in to comment.