% BEGIN_FOLD Drawing wires
% a bit faster than nested \@firstoftwo/\@secondoftwo
% note \@thirdofthree is defined in the latex kernel already.
\long\def\@firstofthree#1#2#3{#1}%
\long\def\@secondofthree#1#2#3{#2}%
\long\def\@firstoffour#1#2#3#4{#1}%
\long\def\@secondoffour#1#2#3#4{#2}%
\long\def\@thirdoffour#1#2#3#4{#3}%
\long\def\@fourthoffour#1#2#3#4{#4}%
\long\def\@thirdandfourthoffour#1#2#3#4{#3#4}%

% extends the wire of register #1. Assumes a node called yquantbox is set up, and the \pgfshapeclippathhorzresult was set up appropriately for this node.
\protected\def\yquant@circuit@extendwire#1{%
   \begingroup%
      \pgfpointanchor{yquantbox}{center}%
      \edef\wirexpos{\the\pgf@x}%
      \yquant@register@get@typeywire{#1}\wiretype\wireypos\wirelast%
      \edef\wirexprevpos{\expandafter\@firstoffour\wirelast}%
      \ifnum\wiretype=\yquant@register@type@none%
         % the clippings of the previous operator will for sure not be needed, but the type might be turned into an active one, so we need the last clipping.
         \yquant@register@set@lastwire{#1}{%
            {\wirexprevpos}{\wirexpos}{}%
            {\unexpanded\expandafter{\pgfshapeclippathhorzresult}}%
         }%
      \else%
         % append the previous `last' clipping to the old list and insert the new one
         \yquant@register@set@lastwire{#1}{%
            {\wirexprevpos}{\wirexpos}%
            {\unexpanded\expandafter\expandafter\expandafter{%
                \expandafter\@thirdandfourthoffour\wirelast%
             }%
            }
            {\unexpanded\expandafter{\pgfshapeclippathhorzresult}}%
         }%
      \fi%
   \endgroup%
}

% finishes the wire of registers 1 to #1 until x position \yquant@env@end@xpos
\protected\def\yquant@circuit@endwires#1{%
   \yquant@for \yquant@circuit@endwires@i := 1 to #1 {
      \yquant@draw@wire\yquant@circuit@endwires@i\yquant@env@end@xpos%
   }%
}

% outputs the wire according to its previous instructions and prepares for a change in the wire style
\protected\def\yquant@circuit@flushwire#1{%
   \yquant@draw@wire{#1}{}%
   \begingroup%
      \yquant@register@get@lastwire{#1}\wirelast%
      \yquant@register@set@lastwire{#1}{%
         {\expandafter\@secondoffour\wirelast}{\expandafter\@secondoffour\wirelast}{}%
         {\unexpanded\expandafter\expandafter\expandafter{%
             \expandafter\@fourthoffour\wirelast%
          }}%
      }%
   \endgroup%
}
% END_FOLD

% BEGIN_FOLD Drawing control lines
% populates a drawing macro with the current control line with style #1 at position #2. Assumes a node called yquantbox is set up, and the \pgfshapeclippathvertresult was set up appropriately for this node. At the first call, \yquant@circuit@extendcontrolline@cmd must be \let to \empty and \yquant@circuit@extendcontrolline@prev to \relax.
\protected\def\yquant@circuit@extendcontrolline#1#2{%
   \begingroup%
      \tikzset{/yquant/every control line}%
      \expandafter%
   \endgroup%
   \eappto\yquant@circuit@extendcontrolline@clip{%
      \unexpanded\expandafter{\pgfshapeclippathvertresult}%
   }%
   \expandafter\@tempdima\the\pgflinewidth%
   \ifcase#1%
      % no control (or to a discarded target, which we don't do)
   \or%
      % qubit
      \pgfpointanchor{yquantbox}{center}%
      \unless\ifx\yquant@circuit@extendcontrolline@prev\relax%
         \eappto\yquant@circuit@extendcontrolline@cmd{%
            \expandafter\@secondofthree\yquant@circuit@extendcontrolline@prev%
            -- (#2,\the\pgf@y)%
         }%
      \fi%
      \yquant@circuit@extendcontrolline@store{#2}%
   \or%
      % cbit
      \pgfpointanchor{yquantbox}{center}%
      \unless\ifx\yquant@circuit@extendcontrolline@prev\relax%
         \eappto\yquant@circuit@extendcontrolline@cmd{%
            \expandafter\@firstofthree\yquant@circuit@extendcontrolline@prev%
            -- (\the\dimexpr#2-2\@tempdima\relax,\the\pgf@y)%
            \expandafter\@thirdofthree\yquant@circuit@extendcontrolline@prev%
            -- (\the\dimexpr#2+2\@tempdima\relax,\the\pgf@y)%
         }%
      \fi%
      \yquant@circuit@extendcontrolline@store{#2}%
   \or%
      % quantum-bundle (very unusual, but perhaps for transversal operations?)
      \pgfpointanchor{yquantbox}{center}%
      \unless\ifx\yquant@circuit@extendcontrolline@prev\relax%
         \eappto\yquant@circuit@extendcontrolline@cmd{%
            \expandafter\@firstofthree\yquant@circuit@extendcontrolline@prev%
            -- (\the\dimexpr#2-2\@tempdima\relax,\the\pgf@y)%
            \expandafter\@secondofthree\yquant@circuit@extendcontrolline@prev%
            -- (\the\dimexpr#2\relax,\the\pgf@y)%
            \expandafter\@thirdofthree\yquant@circuit@extendcontrolline@prev%
            -- (\the\dimexpr#2+2\@tempdima\relax,\the\pgf@y)%
         }%
      \fi%
      \yquant@circuit@extendcontrolline@store{#2}%
   \else%
      \PackageError{yquant.sty}{Invalid control line type `#1'}%
                   {yquant encountered an internal error.}%
   \fi%
}

\protected\def\yquant@circuit@extendcontrolline@store#1{%
   \edef\yquant@circuit@extendcontrolline@prev{%
      {(\the\dimexpr#1-2\@tempdima\relax,\the\pgf@y)}%
      {(\the\dimexpr#1\relax,\the\pgf@y)}%
      {(\the\dimexpr#1+2\@tempdima\relax,\the\pgf@y)}%
   }%
}

% populates a drawing macro with the multi operation connector at position #2. Assumes a node called yquantbox is set up, and the \pgfshapeclippathvertresult was set up appropriately for this node. At the first call, \yquant@circuit@extendmultiline@cmd must be \let to \empty and \yquant@circuit@extendmultiline@prev to \relax.
\protected\def\yquant@circuit@extendmultiline#1{%
   \begingroup%
      \tikzset{/yquant/every multi line}%
      \expandafter%
   \endgroup%
   \eappto\yquant@circuit@extendmultiline@clip{%
      \unexpanded\expandafter{\pgfshapeclippathvertresult}%
   }%
   \expandafter\@tempdima\the\pgflinewidth%
   \pgfpointanchor{yquantbox}{center}%
   \unless\ifx\yquant@circuit@extendmultiline@prev\relax%
      \eappto\yquant@circuit@extendmultiline@cmd{%
         \yquant@circuit@extendmultiline@prev -- (#1,\the\pgf@y)%
      }%
   \fi%
   \edef\yquant@circuit@extendmultiline@prev{%
      (\the\dimexpr#1\relax,\the\pgf@y)%
   }%
}
% END_FOLD

\newif\ifyquant@circuit@operator@hasControls%
% sets up the relevant variables associated with an operator
% #1: positive controls
% #2: negative controls
% #3: targets
\protected\def\yquant@circuit@operator#1#2#3{%
   % convert all names to indices
   % targets
   \yquant@register@get@ids{#3}%
   \let\yquant@circuit@operator@targets=\yquant@register@get@ids@list%
   \let\yquant@circuit@operator@mintarget=\yquant@register@get@ids@min%
   \let\yquant@circuit@operator@maxtarget=\yquant@register@get@ids@max%
   \let\yquant@circuit@operator@numtarget=\yquant@register@get@ids@count%
   % For the targets, multi-qubit registers might have been allowed, but certainly not for
   % the controls!
   \yquant@register@get@allowmultifalse%
   % positive controls
   \yquant@register@get@ids{#1}%
   \let\yquant@circuit@operator@pctrls=\yquant@register@get@ids@list%
   \let\yquant@circuit@operator@minpctrl=\yquant@register@get@ids@min%
   \let\yquant@circuit@operator@maxpctrl=\yquant@register@get@ids@max%
   \let\yquant@circuit@operator@numpctrl=\yquant@register@get@ids@count%
   \ifnum\yquant@register@get@ids@count>0 %
      \yquant@circuit@operator@hasControlstrue%
   \fi%
   % negative controls
   \yquant@register@get@ids{#2}%
   \let\yquant@circuit@operator@nctrls=\yquant@register@get@ids@list%
   \let\yquant@circuit@operator@minnctrl=\yquant@register@get@ids@min%
   \let\yquant@circuit@operator@maxnctrl=\yquant@register@get@ids@max%
   \let\yquant@circuit@operator@numnctrl=\yquant@register@get@ids@count%
   \ifnum\yquant@register@get@ids@count>0 %
      \yquant@circuit@operator@hasControlstrue%
   \fi%
   % determine the qubits spanned
   \yquant@min\yquant@circuit@operator@minctrl%
      \yquant@circuit@operator@mintarget%
      \yquant@circuit@operator@minpctrl%
      \yquant@circuit@operator@minnctrl%
      \relax%
   \yquant@max\yquant@circuit@operator@maxctrl%
      \yquant@circuit@operator@maxtarget%
      \yquant@circuit@operator@maxpctrl%
      \yquant@circuit@operator@maxnctrl%
      \relax%
   % obtain the required minimal x position
   \yquant@register@get@maxxrange%
      \yquant@circuit@operator@x%
      \yquant@circuit@operator@minctrl%
      \yquant@circuit@operator@maxctrl%
   \dimdef\yquant@circuit@operator@x{%
      \yquant@circuit@operator@x+\yquant@config@operator@sep%
   }%
}

% BEGIN_FOLD Subcircuit-related
% Does all necessary calculations for inserting a sub-circuit
% #1: subcircuit code (should start with \begin{yquant})
%\newbox\yquant@circuit@subcircuit@box
%\protected\long\def\yquant@circuit@subcircuit#1{%
%   % We need to place the inner circuit at the correct position; but for this, we need
%   % its extent. For this, we first place it within a box. But this box is then
%   % integrated seamlessly, in particular, named nodes must be re-placed. We use a lot of
%   % inspiration from pgf's matrix capabilities.
%   % First, we anticipate the macro that is used by our subcircuit to store the node
%   % names.
%   \edef\yquant@circuit@subcircuit@nodelist{yquant@env\the\numexpr\yquant@env+1\relax @circuit@subcircuit@nodelist}%
%   \global\cslet\yquant@circuit@subcircuit@nodelist\empty%
%   \pgfinterruptboundingbox%
%      % we make sure there are no conflicts by prefixing any named nodes in any case.
%      \ifx\yquant@lang@attr@name\empty%
%         \pgfkeys{/tikz/name prefix/.expanded={sub\yquant@prefix-}}%
%      \else%
%         \pgfkeys{/tikz/name prefix/.expanded={\pgfkeysvalueof{/tikz/name prefix}\yquant@lang@attr@name-}}%
%      \fi%
%      \let\pgf@nodecallback=\yquant@circuit@subcircuit@nodecallback%
%      \pgftransformreset%
%      \global\setbox\yquant@circuit@subcircuit@box=\hbox{{%
%         % bypass 'overlay' option
%         \pgf@relevantforpicturesizetrue%
%         \pgfsys@beginpicture%
%         #1%
%         \pgfsys@endpicture%
%         \ifdim\pgf@picmaxx=-16000pt %
%            \global\pgf@picmaxx=0pt %
%            \global\pgf@picminx=0pt %
%            \global\pgf@picmaxy=0pt %
%            \global\pgf@picminy=0pt %
%         \fi%
%      }}%
%      \wd\yquant@circuit@subcircuit@box=0pt %
%      \global\setbox\yquant@circuit@subcircuit@box=\hbox{{%
%         \hskip-\pgf@picminx%
%         \unhbox\yquant@circuit@subcircuit@box%
%         \hskip\pgf@picmaxx%
%      }}%
%      \ht\yquant@circuit@subcircuit@box=\pgf@picmaxy%
%      \dp\yquant@circuit@subcircuit@box=-\pgf@picminy%
%      % We need to remember the offset for the coordinate shifts
%      \dimgdef\yquant@circuit@subcircuit@shiftx{-\pgf@picminx}%
%   \endpgfinterruptboundingbox%
%   \ifx\yquant@lang@attr@name\empty%
%      % However, if the outer node was not named, no access to the inner nodes is desired,
%      % so we delete all nodes again.
%      \def\do##1{%
%         \csgundef{pgf@sh@ns@##1}%
%         \csgundef{pgf@sh@np@##1}%
%         \csgundef{pgf@sh@nt@##1}%
%         \csgundef{pgf@sh@pi@##1}%
%         \csgundef{pgf@sh@ma@##1}%
%      }%
%      \dolistcsloop\yquant@circuit@subcircuit@nodelist%
%      \global\cslet\yquant@circuit@subcircuit@nodelist\empty%
%   \else%
%      % But now access is desired, and probably we are deeply nested. Append the sublist to ours, so that our parent can re-map them again.
%      \ifx\pgf@nodecallback\yquant@circuit@subcircuit@nodecallback%
%         \csxappto{\yquant@prefix circuit@subcircuit@nodelist}%
%                  {\csname\yquant@circuit@subcircuit@nodelist\endcsname}%
%      \fi%
%   \fi%
%}
%
%\def\yquant@circuit@subcircuit@nodecallback#1{%
%   \listcsxadd{\yquant@prefix circuit@subcircuit@nodelist}{#1}%
%}

%\protected\def\yquant@circuit@subcircuit@shiftnodes#1{%
%   \expandafter\unless\expandafter\ifx\csname\yquant@circuit@subcircuit@nodelist\endcsname\empty{%
%      \pgftransformreset%
%      \pgf@process{\pgfpointanchor{#1}{text}}%
%      \edef\yquant@circuit@subcircuit@offset{%
%         \noexpand\pgfqpoint{\the\dimexpr\pgf@x+\yquant@circuit@subcircuit@shiftx\relax}%
%                            {\the\dimexpr\pgf@y\relax}%
%      }%
%      \def\do##1{%
%         \pgf@shift@node{##1}\yquant@circuit@subcircuit@offset%
%      }%
%      \dolistcsloop\yquant@circuit@subcircuit@nodelist%
%   }\fi%
%}
% END_FOLD

% BEGIN_FOLD Helpers for operator callbacks
% turn a wire into a different type
\def\yquant@circuit@settype#1{%
   \yquant@circuit@flushwire{#1}%
   \yquant@register@set@type{#1}{\yquant@circuit@settype@to}%
}

\protected\long\def\yquant@circuit@setstyle#1#2{%
   \yquant@circuit@flushwire{#1}%
   \yquant@register@set@style{#1}{#2}%
}

\protected\long\def\yquant@circuit@addstyle#1#2{%
   \yquant@circuit@flushwire{#1}%
   \yquant@register@set@style{#1}{\yquant@register@get@style{#1},#2}%
}

% performs an alignment of all registers specified in the argument; that is, the next operation on any of the listed registers will be after the maximum position of all of them
% #1: arbitrary register list
\protected\def\yquant@circuit@align#1{%
   \begingroup%
      \yquant@register@get@maxxlist\x{#1}%
      \def\do##1{%
         \yquant@register@set@x{##1}\x%
      }%
      \dolistloop{#1}%
   \endgroup%
}

% introduces a horizontal skip (= invisible operator of given width) among the registers; that is, those registers are first aligned, then skipped by the given amount.
% #1: arbitrary register list
% #2: skip width
\protected\def\yquant@circuit@hspace#1#2{%
   \begingroup%
      \yquant@register@get@maxxlist\x{#1}%
      \dimdef\x{\x+#2}%
      \def\do##1{%
         \yquant@register@set@x{##1}\x%
      }%
      \dolistloop{#1}%
   \endgroup%
}

% applies an action to wires a list of registers and causes them to be redrawn
% #1: action
% #2: arbitrary register list
% #3: parameter(s)
\protected\def\yquant@circuit@actonwires#1#2#3{%
   \begingroup%
      \let\tmp=\empty%
      \def\do##1{%
         % We do not extend the wire: a register that is discarded somewhere does not make
         % sense, only right after some application (which is supposed to already have
         % extended the wire appropriately).
         \appto\tmp{#1{##1}#3}%
      }%
      \dolistloop{#2}%
      \csxappto{\yquant@prefix draw}{\tmp}%
   \endgroup%
}

% sets the output of wires
% #1: arbitrary register list
\protected\def\yquant@circuit@output#1{%
   \csxappto{\yquant@prefix outputs}%
            {\noexpand\yquant@circuit@output@do%
               {\noexpand#1}% there is nothing to expand - except the first token, which might be \yquant@register@multi, and we need to preserve this.
               {\yquant@attrs@remaining}%
               {\unexpanded\expandafter{\yquant@lang@attr@value}}%
            }%
}

\protected\long\def\yquant@circuit@output@do#1#2#3{%
   % this must only be called at the end of an environment, where \yquant@env@end@xpos is
   % set up properly!
   \def\do##1{%
      \ifyquant@firsttoken\yquant@register@multi{##1}{%
         \csxappto{\yquant@prefix draw}%
                  {\noexpand\yquant@circuit@output@do@multi%
                   \yquant@circuit@output@do@multi@@extract##1{\unexpanded{#3}}}%
      }{%
         \csgappto{\yquant@prefix draw}%
                  {\yquant@circuit@output@do@single{##1}{#3}}%
      }%
   }%
   \csgappto{\yquant@prefix draw}{%
      \yquant@circuit@output@group{#2}%
   }
   % \dolistloop will carry out one \expandafter on the argument; but this expansion step
   % is already done. If #1 starts with \yquant@register@multi, this will be expanded once
   % despite \protected, so insert some expand-to-nothing token first.
   \dolistloop{\empty#1}%
   \csgappto{\yquant@prefix draw}{%
      \yquant@circuit@output@endgroup%
   }%
}

\def\yquant@circuit@output@do@multi@@extract#1#2#3#4#5{%
   {#2}{#3}{#5}%
}

\protected\long\def\yquant@circuit@output@group#1{%
   \begingroup%
      \def\idx{0}%
      \yquant@set{#1}%
}

\let\yquant@circuit@output@endgroup=\endgroup%

\long\def\yquant@circuit@output@do@single#1#2{%
   \path
      (\yquant@env@end@xpos, \yquant@register@get@y{#1})
      node[/yquant/every output,
           /yquant/every \ifcase\yquant@register@get@type{#1} nobit\or qubit\or cbit\or qubits\fi\space output] {#2};
   \numdef\idx{\idx+1}%
}

\long\def\yquant@circuit@output@do@multi#1#2#3#4{%
   % extremely similar to \yquant@draw@multiinit
   \@tempdima=-.5\dimexpr\yquant@config@register@sep\relax%
   \dimdef\yquant@draw@multiinit@@min{\yquant@register@get@y{#1}-\@tempdima}%
   \dimdef\yquant@draw@multiinit@@max{\yquant@register@get@y{#2}+\@tempdima}%
   \dimdef\yquant@draw@multiinit@@total{%
      \yquant@draw@multiinit@@max-\yquant@draw@multiinit@@min%
   }%
   \def\pgfdecorationsegmentaspect{0}%
   \let\yquant@register@multi@contiguous=\yquant@draw@multiinit@contiguous%
   \let\pgfdecorationsegmentfromto=\empty%
   #3%
   \edef\pgfdecorationsegmentfromto{\expandafter\@gobble\pgfdecorationsegmentfromto}%
   \path[/yquant/every multi output]
      (\yquant@env@end@xpos, \yquant@draw@multiinit@@min) --
      (\yquant@env@end@xpos, \yquant@draw@multiinit@@max)
      node {#4};%
   \numdef\idx{\idx+1}%
}
% END_FOLD