From 2788d9fb9b228a993b9396b91c9fcd4845635b64 Mon Sep 17 00:00:00 2001
From: Karl Berry <karl@freefriends.org>
Date: Tue, 24 Mar 2020 20:57:29 +0000
Subject: yquant (24mar20)

git-svn-id: svn://tug.org/texlive/trunk@54527 c570f23f-e606-0410-a88d-b1316a301751
---
 .../tex/latex/yquant/yquant-registers.tex          | 532 +++++++++++++++++++++
 1 file changed, 532 insertions(+)
 create mode 100644 Master/texmf-dist/tex/latex/yquant/yquant-registers.tex

(limited to 'Master/texmf-dist/tex/latex/yquant/yquant-registers.tex')

diff --git a/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex b/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex
new file mode 100644
index 00000000000..7f640fe4996
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/yquant/yquant-registers.tex
@@ -0,0 +1,532 @@
+\def\yquant@register@type@none{0}
+\def\yquant@register@type@q{1}
+\def\yquant@register@type@c{2}
+\def\yquant@register@type@qs{3}
+
+% Internally, we store the register information in a single macro. Indeed, this is almost always faster than using multiple macros (at least in the way implemented here), apart from changing a single type of information, which is almost as fast.
+% BEGIN_FOLD Constructor: create single register and cleanup environment
+
+% #1: type
+% #2: x position
+% #3: name
+% #4: index
+\protected\def\yquant@register@define#1#2#3#4{%
+   \csnumgdef{\yquant@prefix registers}%
+             {\csname\yquant@prefix registers\endcsname+1}%
+   \csxdef{\yquant@prefix register@\csname\yquant@prefix registers\endcsname}{%
+      {#1}% type
+      {#2}% x pos
+      {\yquant@config@register@minimum@height}% height; at the end, the y position
+      {}% wire start positions
+   }%
+   \global\csletcs{\yquant@prefix registername@#3[#4]}{\yquant@prefix registers}%
+   \csxdef{\yquant@prefix registerhigh@\reg}{#4}%
+   \yquant@cleanup@csadd{\yquant@prefix register@\csname\yquant@prefix registers\endcsname}%
+   \yquant@cleanup@csadd{\yquant@prefix registername@#3[#4]}%
+   \ifnum0=#4\relax%
+      \yquant@cleanup@csadd{\yquant@prefix registerhigh@\reg}%
+   \fi%
+}
+% END_FOLD
+
+% BEGIN_FOLD Converter: convert a register name to its id
+% store the number corresponding to register #2 into #1
+\protected\def\yquant@register@get@id#1#2{%
+   \ifcsname\yquant@prefix registername@#2\endcsname%
+      \letcs#1{\yquant@prefix registername@#2}%
+   \else%
+      \yquant@register@get@id@lazycreate{#2}%
+      \letcs#1{\yquant@prefix registers}%
+   \fi%
+}
+
+% same as before, but resolves to the _index_ of the last register
+\protected\def\yquant@register@get@id@high#1#2{%
+   \ifcsname\yquant@prefix registerhigh@#2\endcsname%
+      \letcs#1{\yquant@prefix registerhigh@#2}%
+   \else%
+      \yquant@register@get@id@lazycreate{#2}%
+      \letcs#1{\yquant@prefix registers}%
+   \fi%
+}
+
+% In the lazy mode, we create all unknown registers on-the-fly.
+\def\yquant@register@get@id@lazycreate#1{%
+   \ifyquant@env@lazy%
+      % In principle, we could just call \yquant@lang@@qubit. However, if access to a vector register is desired and a _part_ of this does already exist (though not the requested index), we only create the missing registers.
+      \yquant@register@get@id@lazycreate@parse#1[;
+   \else%
+      \PackageError{yquant.sty}{Register `#1' unknown}%
+         {You referred to an unknown register.
+          Declare registers first using `qubit' and friends.}%
+   \fi%
+}
+
+\def\yquant@register@get@id@lazycreate@parse#1[#2;{%
+   \if\relax\detokenize{#2}\relax%
+      \yquant@register@get@id@lazycreate@do#1[0][;%
+   \else%
+      \yquant@register@get@id@lazycreate@do#1[#2;%
+   \fi%
+}
+
+\protected\def\yquant@register@get@id@lazycreate@do#1[#2]#3[;{%
+   % parse length
+   \if\relax\detokenize{#3}\relax%
+      \yquant@langhelper@validate\len\count{#2}%
+      \numdef\len{\len+1}%
+   \else%
+      \PackageError{yquant.sty}{Invalid register name}%
+         {Register names must not contain `[' apart from register length indication.}%
+   \fi%
+   \edef\reg{\trim@spaces{#1}}%
+   % Was this register already defined?
+   \ifcsname\yquant@prefix registerhigh@\reg\endcsname%
+      \numdef\idx{\csname\yquant@prefix registerhigh@\reg\endcsname+1}%
+      \unless\ifnum\idx<\len\relax%
+         \PackageError{yquant.sty}{Internal inconsistency detected}%
+            {Tried to create a register on-the-fly that already existed.}%
+      \fi%
+   \else%
+      \def\idx{0}%
+   \fi%
+   \begingroup%
+      % pre-set y position
+      \yquant@for \idx := \idx to \numexpr \len -1\relax {%
+         \yquant@register@define%
+            \yquant@register@type@q%
+            {0pt}%
+            \reg\idx
+         % Prepare to shipout
+         \csxappto{\yquant@prefix draw}{%
+            \yquant@lang@create@draw{\csname\yquant@prefix registers\endcsname}%
+                                    {0pt}%
+                                    {qubit}%
+                                    {}%
+                                    {}%
+         }%
+      }%
+   \endgroup%
+}
+
+\newif\ifyquant@register@get@allowmulti
+% converts names to indices
+% #1: comma-separated string of names or ranges
+%     range format: startname-endname
+%     Both startname and endname may be omitted, denoting the very first and last
+%     register, respectively
+%     If \ifyquant@register@get@allowmulti is set to true, multi-qubit registers are
+%     allowed, which are surrounded by parentheses. They may not appear in ranges.
+% \yquant@register@get@ids@list, \yquant@register@get@ids@min, \yquant@register@get@ids@max and \yquant@register@get@ids@count will be set appropriately
+\begingroup%
+\catcode`[=\active%
+\catcode`(=\active%
+\protected\gdef\yquant@register@get@ids#1{%
+   \begingroup%
+      \let\yquant@register@get@ids@list=\empty%
+      \count0=2147483647 % minimal id
+      \count2=0 % maximal id
+      \count4=0 % number of total registers
+      \ifblank{#1}{}{%
+         \let\ifinmulti=\iffalse%
+         \let\do=\yquant@register@get@ids@outerlist%
+         \begingroup%
+            \catcode`[=\active%
+            \catcode`(=\active%
+            \def[##1]{\yquant@register@get@ids@@index{##1}}%
+            \def(##1){\yquant@register@get@ids@@multi{##1}}%
+            \edef\yquant@register@get@ids@retokenized{\scantokens{#1\noexpand}}%
+            \expandafter%
+         \endgroup%
+         \expandafter\docsvlist\expandafter{\yquant@register@get@ids@retokenized}%
+      }%
+      \global\let\yquant@register@get@ids@list=\yquant@register@get@ids@list%
+      \xdef\yquant@register@get@ids@min{\the\count0}%
+      \xdef\yquant@register@get@ids@max{\the\count2}%
+      \xdef\yquant@register@get@ids@count{\the\count4}%
+   \endgroup%
+}
+\endgroup
+
+\protected\def\yquant@register@get@ids@@index{}
+\protected\def\yquant@register@get@ids@@multi{}
+
+\def\yquant@register@get@ids@outerlist#1{%
+   \ifyquant@firsttoken\yquant@register@get@ids@@multi{#1}{%
+      \unless\ifyquant@register@get@allowmulti%
+         \PackageError{yquant.sty}{Multi-register gate not allowed}%
+                      {The selected gate can only be used in a single-register context.}%
+      \fi%
+      \yquant@register@get@ids@multi#1\yquant@sep%
+   }{%
+      \yquant@register@get@ids@checkrange#1-\yquant@sep%
+   }%
+}
+
+\protected\def\yquant@register@get@ids@multi\yquant@register@get@ids@@multi#1\yquant@sep{%
+   \begingroup%
+      \let\yquant@register@get@ids@list=\empty%
+      \count0=2147483647 % minimal id
+      \count2=0 % maximal id
+      \count4=0 % number of total registers
+      \let\ifinmulti=\iftrue%
+      \let\do=\yquant@register@get@ids@multilist%
+      \docsvlist{#1}%
+      \edef\process{%
+            \endgroup%
+         \noexpand\listadd\noexpand\yquant@register@get@ids@list{%
+            \noexpand\yquant@register@multi%
+               {\the\count0}{\the\count2}{\the\count4}%
+               {\yquant@register@get@ids@list}%
+         }%
+         \noexpand\ifnum\count0>\the\count0\space%
+            \count0=\the\count0\space%
+         \noexpand\fi%
+         \noexpand\ifnum\count2<\the\count2\space%
+            \count2=\the\count2\space%
+         \noexpand\fi%
+         \advance\count4 by 1 %
+      }%
+      \process%
+}
+
+\def\yquant@register@get@ids@multilist#1{%
+   \yquant@register@get@ids@checkrange#1-\yquant@sep%
+}
+
+\def\yquant@register@get@ids@checkrange#1-#2\yquant@sep{%
+   \if\relax\detokenize{#2}\relax%
+      % the string does not contain a dash
+      \yquant@register@get@ids@norange{#1}%
+   \else%
+      % this is a range argument
+      \yquant@register@get@ids@range#1-#2\yquant@sep%
+   \fi%
+}
+
+\def\yquant@register@get@ids@norange#1{%
+   % the register is not used within a range, which gives us full freedom with respect to sub-index selections
+   \yquant@register@get@ids@norange@checkindex%
+      #1%
+      \yquant@register@get@ids@@index%
+      \yquant@sep%
+}
+
+\protected\def\yquant@register@get@ids@norange@checkindex#1\yquant@register@get@ids@@index#2\yquant@sep{%
+   \edef\current{\trim@spaces{#1}}%
+   \if\relax\detokenize{#2}\relax%
+      % the string does not contain a sub-index; we add the full register
+      \yquant@register@get@id\first{\current[0]}%
+      \letcs\high{\yquant@prefix registerhigh@\current}%
+      \yquant@register@get@id\last{\current[\high]}%
+      \ifnum\first<\count0 %
+         \count0=\first\relax%
+      \fi%
+      \ifnum\last>\count2 %
+         \count2=\last\relax%
+      \fi%
+      \advance\count4 by \numexpr\high+1\relax%
+      \yquant@for \i := 0 to \high {%
+         \yquant@register@get@id\idx{\current[\i]}%
+         \listeadd\yquant@register@get@ids@list{\idx}%
+      }%
+   \else%
+      \yquant@register@get@ids@norange@index#2%
+   \fi%
+}
+
+\protected\def\yquant@register@get@ids@norange@index#1\yquant@register@get@ids@@index{%
+   \let\olddo=\do%
+   % the string contains sub-indices; since we are not in a range, multi-indices may still be allowed
+   \ifinmulti%
+      \let\do=\yquant@register@get@ids@subindex@nomulti%
+   \else%
+      \let\do=\yquant@register@get@ids@subindex@allowmulti%
+   \fi%
+   \docsvlist{#1}%
+   \let\do=\olddo%
+}
+
+\def\yquant@register@get@ids@subindex@nomulti#1{%
+   \yquant@register@get@ids@subindex@checkrange#1-\yquant@sep%
+}
+
+\def\yquant@register@get@ids@subindex@allowmulti#1{%
+   \ifyquant@firsttoken\yquant@register@get@ids@@multi{#1}{%
+      \unless\ifyquant@register@get@allowmulti%
+         \PackageError{yquant.sty}{Multi-register gate not allowed}%
+                      {The selected gate can only be used in a single-register context.}%
+      \fi%
+      \yquant@register@get@ids@subindex@multi#1\yquant@sep%
+   }{%
+      \yquant@register@get@ids@subindex@checkrange#1-\yquant@sep%
+   }%
+}
+
+\protected\def\yquant@register@get@ids@subindex@multi\yquant@register@get@ids@@multi#1\yquant@sep{%
+   \begingroup%
+      \let\yquant@register@get@ids@list=\empty%
+      \count0=2147483647 % minimal id
+      \count2=0 % maximal id
+      \count4=0 % number of total registers
+      \let\ifinmulti=\iftrue%
+      \let\do=\yquant@register@get@ids@subindex@nomulti%
+      \docsvlist{#1}%
+      \edef\process{%
+            \endgroup%
+         \noexpand\listadd\noexpand\yquant@register@get@ids@list{%
+            \noexpand\yquant@register@multi%
+               {\the\count0}{\the\count2}{\the\count4}%
+               {\yquant@register@get@ids@list}%
+         }%
+         \noexpand\ifnum\count0>\the\count0\space%
+            \count0=\the\count0\space%
+         \noexpand\fi%
+         \noexpand\ifnum\count2<\the\count2\space%
+            \count2=\the\count2\space%
+         \noexpand\fi%
+         \advance\count4 by 1 %
+      }%
+      \process%
+}
+
+\def\yquant@register@get@ids@subindex@checkrange#1-#2\yquant@sep{%
+   \if\relax\detokenize{#2}\relax%
+      % the string does not contain a dash, this is a single sub-item
+      \yquant@register@get@ids@subindex@norange{\trim@spaces{#1}}%
+   \else%
+      % this is a range argument
+      \yquant@register@get@ids@subindex@range#1-#2\yquant@sep%
+   \fi%
+}
+
+\protected\def\yquant@register@get@ids@subindex@norange#1{%
+   \yquant@register@get@id\idx{\current[#1]}%
+   \ifnum\idx<\count0 %
+      \count0=\idx\relax%
+   \fi%
+   \ifnum\idx>\count2 %
+      \count2=\idx\relax%
+   \fi%
+   \advance\count4 by 1\relax%
+   \listeadd\yquant@register@get@ids@list{\idx}%
+}
+
+\protected\def\yquant@register@get@ids@subindex@range#1-#2-\yquant@sep{%
+   \ifblank{#1}{%
+      \def\first{0}%
+   }{%
+      \yquant@langhelper@validate\first\count{#1}%
+   }%
+   \ifblank{#2}{%
+      \yquant@register@get@id@high\last\current%
+   }{%
+      \yquant@langhelper@validate\last\count{#2}%
+   }%
+   \yquant@for \i := \first to \last {%
+      \yquant@register@get@ids@subindex@norange\i%
+   }%
+}
+
+\protected\def\yquant@register@get@ids@range#1-#2-\yquant@sep{%
+   % being a range between two registers, those must be uniquely identifiable, i.e. either a single sub-indexed part of a vector register, or no vector specification at all.
+   \ifblank{#1}{%
+      \def\first{1}%
+   }{%
+      \yquant@register@get@ids@range@getfirst#1\yquant@register@get@ids@@index\yquant@sep%
+   }%
+   \ifblank{#2}{%
+      \letcs\last{\yquant@prefix registers}%
+   }{%%
+      \yquant@register@get@ids@range@getlast#2\yquant@register@get@ids@@index\yquant@sep%
+   }%
+   \ifnum\first<\last\relax%
+      \ifnum\first<\count0 %
+         \count0=\first\relax%
+      \fi%
+      \ifnum\last>\count2 %
+         \count2=\last\relax%
+      \fi%
+      \advance\count4 by \numexpr\last-\first+1\relax%
+   \else%
+      \ifnum\last<\count0 %
+         \count0=\last\relax%
+      \fi%
+      \ifnum\first>\count2 %
+         \count2=\first\relax%
+      \fi%
+      \advance\count4 by \numexpr\first-\last+1\relax%
+   \fi%
+   \yquant@for \i := \first to \last {%
+      \listeadd\yquant@register@get@ids@list{\i}%
+   }%
+}
+
+\def\yquant@register@get@ids@range@getfirst#1\yquant@register@get@ids@@index#2\yquant@sep{%
+   \if\relax\detokenize{#2}\relax%
+      \yquant@register@get@id\first{\trim@spaces{#1}[0]}%
+   \else%
+      \yquant@register@get@ids@range@get\first#1\yquant@register@get@ids@@index#2%
+   \fi%
+}
+
+\protected\def\yquant@register@get@ids@range@getlast#1\yquant@register@get@ids@@index#2\yquant@sep{%
+   \if\relax\detokenize{#2}\relax%
+      \yquant@register@get@id@high\last{\trim@spaces{#1}}%
+      \yquant@register@get@id\last{\trim@spaces{#1}[\last]}%
+   \else%
+      \yquant@register@get@ids@range@get\last#1\yquant@register@get@ids@@index#2%
+   \fi%
+}
+
+\def\yquant@register@get@ids@range@get#1#2\yquant@register@get@ids@@index#3\yquant@register@get@ids@@index{%
+   \yquant@register@get@id#1{\trim@spaces{#2}[\trim@spaces{\trim@spaces#3}]}%
+}
+
+\let\yquant@register@multi=\empty%
+% END_FOLD
+
+% BEGIN_FOLD Getters: extract the requested information from the register with given id
+\def\yquant@register@get@type#1{%
+   \expandafter\expandafter\expandafter%
+   \yquant@register@get@type@aux\csname\yquant@prefix register@#1\endcsname%
+}
+
+\def\yquant@register@get@type@aux#1#2#3#4{#1}
+
+\def\yquant@register@get@x#1{%
+   \expandafter\expandafter\expandafter%
+   \yquant@register@get@x@aux\csname\yquant@prefix register@#1\endcsname%
+}
+
+\def\yquant@register@get@x@aux#1#2#3#4{#2}
+
+\def\yquant@register@get@height#1{%
+   \expandafter\expandafter\expandafter%
+   \yquant@register@get@height@aux\csname\yquant@prefix register@#1\endcsname%
+}
+
+\def\yquant@register@get@height@aux#1#2#3#4{#3}
+
+% The y parameter get macros exist in two forms: The protected one is used during the storage to the draw macro; it should never be executed. The env environment then maps them to their proper expandable forms.
+\protected\def\yquant@register@get@@protected{%
+   \PackageError%
+      {yquant.sty}%
+      {Execution of a get-y macro in an illegal context}%
+      {get-y macros may not be called unless the yquant environment ends.}%
+}
+
+\let\yquant@register@get@y=\yquant@register@get@@protected
+\let\yquant@register@y=\yquant@register@get@@protected
+% This plays a similar role: It must never be expanded before the tikz command is invoked (because it does not exist).
+\let\nodepart=\yquant@register@get@@protected
+
+% getting the y position is the same as getting the height parameter, since we will reuse it at the end.
+\let\yquant@register@get@y@unprotected=\yquant@register@get@height
+
+% y distance between two registers.
+\def\yquant@register@get@ydist#1#2{%
+   \expandafter\yquant@abs\expandafter%
+      {\the\dimexpr\yquant@register@get@y{#2}-\yquant@register@get@y{#1}\relax}%
+}
+
+% y position of the current register
+\def\yquant@register@y@unprotected{0pt}%
+
+\protected\def\yquant@register@get@y@@expandable{%
+   \let\yquant@register@get@y=\yquant@register@get@y@unprotected%
+   \let\yquant@register@y=\yquant@register@y@unprotected%
+}
+
+\def\yquant@register@get@lastwire#1{%
+   \expandafter\expandafter\expandafter%
+   \yquant@register@get@lastwire@aux\csname\yquant@prefix register@#1\endcsname%
+}
+
+\def\yquant@register@get@lastwire@aux#1#2#3#4{#4}
+
+% Set #1 to the maximum x value found between #2 and #3
+\protected\def\yquant@register@get@maxxrange#1#2#3{%
+   \begingroup%
+      \dimen0=-16383.99999pt %
+      \yquant@for \yquant@register@get@maxx@i := #2 to #3 {%
+         \dimen2=\yquant@register@get@x{\yquant@register@get@maxx@i}\relax%
+         \ifdim\dimen0<\dimen2 %
+            \dimen0=\dimen2 %
+         \fi%
+      }%
+      \expandafter%
+   \endgroup%
+   \expandafter\def\expandafter#1\expandafter{\the\dimen0}%
+}
+
+% Set #1 to the maximum x value found in the list #2
+\protected\def\yquant@register@get@maxxlist#1#2{%
+   \begingroup%
+      \dimen0=-16383.99999pt %
+      \def\do##1{%
+         \dimen2=\yquant@register@get@x{##1}\relax%
+         \ifdim\dimen0<\dimen2 %
+            \dimen0=\dimen2 %
+         \fi%
+      }%
+      \dolistloop{#2}%
+      \expandafter%
+   \endgroup%
+   \expandafter\def\expandafter#1\expandafter{\the\dimen0}%
+}
+% END_FOLD
+
+% BEGIN_FOLD Setters: change register information
+\protected\long\def\yquant@register@set@@aux#1#2#3{%
+   \long\xdef#1{\expandafter#2#1{#3}}%
+}
+
+\protected\def\yquant@register@set@type#1{%
+   \expandafter\yquant@register@set@@aux%
+   \csname\yquant@prefix register@#1\endcsname\yquant@register@set@type@aux%
+}
+
+\long\def\yquant@register@set@type@aux#1#2#3#4#5{%
+   {#5}{#2}{#3}{#4}%
+}
+
+\protected\def\yquant@register@set@x#1{%
+   \expandafter\yquant@register@set@@aux%
+   \csname\yquant@prefix register@#1\endcsname\yquant@register@set@x@aux%
+}
+
+\long\def\yquant@register@set@x@aux#1#2#3#4#5{%
+   {#1}{#5}{#3}{#4}%
+}
+
+\protected\def\yquant@register@update@height#1#2{%
+   \ifdim#2>\yquant@register@get@height{#1} %
+      \expandafter\yquant@register@set@@aux%
+      \csname\yquant@prefix register@#1\endcsname\yquant@register@set@height@aux{#2}%
+   \fi%
+}
+
+\protected\def\yquant@register@set@y#1{%
+   \expandafter\yquant@register@set@@aux%
+   \csname\yquant@prefix register@#1\endcsname\yquant@register@set@height@aux%
+}
+
+% Set the currently used register
+\protected\def\yquant@register@use#1{%
+   \edef\yquant@register@y{\yquant@register@get@y{#1}}%
+}
+
+\long\def\yquant@register@set@height@aux#1#2#3#4#5{%
+   {#1}{#2}{#5}{#4}%
+}
+
+\protected\def\yquant@register@set@lastwire#1{%
+   \expandafter\yquant@register@set@@aux%
+   \csname\yquant@prefix register@#1\endcsname\yquant@register@set@lastwire@aux%
+}
+
+\long\def\yquant@register@set@lastwire@aux#1#2#3#4#5{%
+   {#1}{#2}{#3}{#5}%
+}
+% END_FOLD
\ No newline at end of file
-- 
cgit v1.2.3

