% Most drawing operations will be realized through nodes
\let\yquant@prepare@callback@prepare=\@gobble
\let\yquant@prepare@callback@draw=\@gobble%

% #1: register name
% #2: register index
% #3: register type
\protected\def\yquant@prepare@create#1#2#3{%
   \ifdefined\yquant@lang@attr@input%
      \expandafter\yquant@list@gdequeue\csname\yquant@prefix parameters\endcsname\outermap%
      \ifx\outermap\empty%
         \PackageError{yquant.sty}{Invalid subcircuit parameter count}%
                      {No outer register available for input register `#1[#2]`.}%
      \fi%
      \begingroup%
         \let\yquant@prefix=\yquant@parent %
         \unless\if#3\yquant@register@get@type\outermap%
            \PackageError{yquant.sty}%
                         {Subcircuit expects wire of type `\yquant@register@type@tostring#3', but got `\yquant@register@type@tostring{\yquant@register@get@type\outermap}'}%
                         {Outer and inner wire types must match for input wire `#1[#2]`.}%
         \fi%
      \endgroup%
      \unless\ifdefined\yquant@lang@attr@output%
         \listcsxadd{\yquant@prefix inonly}%
                    {\the\numexpr\csname\yquant@prefix registers\endcsname+1\relax}%
      \fi%
      \yquant@register@alias{#3}{#1}{#2}\outermap%
   \else%
      \ifdefined\yquant@lang@attr@output%
         \expandafter\yquant@list@gdequeue\csname\yquant@prefix parameters\endcsname\outermap%
         \ifx\outermap\empty%
            \PackageError{yquant.sty}{Invalid subcircuit parameter count}%
                         {No outer register available for output register `#1[#2]`.}%
         \fi%
         \begingroup%
            \let\yquant@prefix=\yquant@parent%
            \unless\if\yquant@register@types@nobit\yquant@register@get@type\outermap%
               \PackageError{yquant.sty}%
                            {Subcircuit expects discarded wire, got `\yquant@register@type@tostring{\yquant@register@get@type\outermap}'}%
                            {Outer wire must be discarded before being acceptable for output-only register `#1[#2]`.}%
            \fi%
         \endgroup%
         \yquant@register@alias{#3}{#1}{#2}\outermap%
      \else%
         \yquant@register@define{#3}{#1}{#2}%
      \fi%
   \fi%
   % we must be allowed to change the wire types during preparation for various reasons, so we need to reset it here (TODO: can we eliminate all those reasons?)
   \csxappto{\yquant@prefix draw}{%
      \yquant@draw@init{\csname\yquant@prefix registers\endcsname}{#3}%
   }%
}

% generic shape of an operator
% #1: value
% #2: tikz options that select the correct shape
\protected\long\def\yquant@prepare#1#2{%
   \yquant@sort@clear%
   \def\yquant@prepare@injectcontrols@count{0}%
   \let\idx=\yquant@config@idxbase%
   \yquant@prepare@ifs@direct%
   \yquant@dimenb=\yquant@config@operator@minimum@width%
   \ifyquant@circuit@operator@hasControls%
      \edef\yquant@prepare@list{%
         \yquant@list@range%
            \yquant@circuit@operator@minctrl%
            \yquant@circuit@operator@maxctrl%
      }%
   \else%
      \let\yquant@prepare@list=\empty%
   \fi%
   \pgfkeys{/yquant/internal/before styles}%
   % BEGIN_FOLD register
   \def\@yquant@do##1{%
      \ifx\yquant@lang@attr@name\empty%
         \let\@yquant@nodename=\empty%
      \else%
         \edef\@yquant@nodename{\yquant@lang@attr@name-\the\numexpr\idx-\yquant@config@idxbase\relax}%
      \fi%
      \ifyquant@firsttoken\yquant@register@multi{##1}{%
         \yquant@prepare@multi{#1}{#2}{##1}%
      }{%
         \yquant@prepare@single{#1}{#2}{##1}%
      }%
         \expandafter%
      \endpgfinterruptboundingbox%
      \expandafter\yquant@dimena\expandafter=%
         \the\dimexpr\yquant@pgf@picmaxx-\yquant@pgf@picminx\relax\space%
      \ifdim\yquant@dimena>\yquant@dimenb%
         \yquant@dimenb=\yquant@dimena%
      \fi%
      \numdef\idx{\idx+1}%
   }%
   \forlistloop\@yquant@do\yquant@circuit@operator@targets%
   % END_FOLD
   \yquant@prepare@controls%
   \yquant@prepare@finalize{#1}{#2}%
}

\newcount\yquant@prepare@injections
% generic shape of an operator - but delayed to some later point
% #1: value
% #2: tikz options that select the correct shape
\protected\long\def\yquant@prepare@injection#1#2{%
   \global\advance\yquant@prepare@injections by 1 % we just keep increasing, doesn't really matter
   \edef\yquant@draw@group{\yquant@draw@injectiongroup{\the\yquant@prepare@injections}}%
   \def\yquant@draw@endgroup{\noexpand\yquant@draw@endinjectiongroup}%
   \yquant@prepare{#1}{#2}%
   \csxdef{yquant@prepare@@injection@\the\yquant@prepare@injections}{%
      {\the\yquant@dimenb}{\unexpanded\expandafter{\yquant@circuit@operator@targets}}%
   }%
   \forlistloop\yquant@prepare@injection@loop\yquant@circuit@operator@targets%
}

\protected\def\yquant@prepare@injection@loop#1{%
   \ifyquant@firsttoken\yquant@register@multi{#1}{%
      \edef\@yquant@first{\@secondoffive#1}%
      \edef\@yquant@last{\@thirdoffive#1}%
      \yquant@for \@yquant@i := \@yquant@first to \@yquant@last {%
         \yquant@register@set@lastgate\@yquant@i{%
            % we only need this once, but it may be called multiple times if acting on multiple registers
            \noexpand\ifcsname yquant@prepare@@injection@\the\yquant@prepare@injections\noexpand\endcsname%
               % first check whether this is valid - i.e., the list of targets for this measurement is in fact a subset of the list of positive controls for the next operation
               \ifyquant@registersubset%
                  {\unexpanded\expandafter{\yquant@circuit@operator@targets}}%
                  {\noexpand\yquant@circuit@operator@pctrls}{%
                  \yquant@prepare@inject{\the\yquant@prepare@injections}%
               }{%
                  \yquant@prepare@inject@discard{\the\yquant@prepare@injections}%
               }%
               \yquant@prepare@injection@clean{\@yquant@first}{\@yquant@last}%
            \noexpand\fi
            \noexpand\@gobbletwo%
         }%
      }%
   }{%
      \yquant@register@set@lastgate{#1}{%
         \noexpand\ifcsname yquant@prepare@@injection@\the\yquant@prepare@injections\noexpand\endcsname%
            % first check whether this is valid - i.e., the list of targets for this measurement is in fact a subset of the list of positive controls for the next operation
            \ifyquant@registersubset%
               {\unexpanded\expandafter{\yquant@circuit@operator@targets}}%
               {\noexpand\yquant@circuit@operator@pctrls}{%
               \yquant@prepare@inject{\the\yquant@prepare@injections}%
            }{%
               \yquant@prepare@inject@discard{\the\yquant@prepare@injections}
            }%
         \noexpand\fi%
         \noexpand\@gobbletwo%
      }%
   }%
}

\protected\def\yquant@prepare@injection@clean#1#2{%
   \yquant@for \@yquant@i := #1 to #2 {%
      \yquant@register@set@lastgate\@yquant@i{}%
   }%
}

\protected\def\yquant@prepare@inject#1{%
   \letcs\yquant@prepare@inject@@data{yquant@prepare@@injection@#1}%
   \csgundef{yquant@prepare@@injection@#1}%
   \yquant@dimena=\expandafter\@firstoftwo\yquant@prepare@inject@@data\space%
   \let\@tmpconti=\yquant@register@multi@contiguous%
   \protected\def\yquant@register@multi@contiguous##1##2{%
      \yquant@for \@yquant@i := ##1 to ##2 {%
         \cslet{yquant@prepare@replacecontrol@\@yquant@i}\empty%
      }%
   }%
   \expandafter\expandafter\expandafter\etb@forlistloop%
      \expandafter\expandafter\expandafter{%
      \expandafter\@secondoftwo%
      \yquant@prepare@inject@@data%
   }{\yquant@prepare@inject@loop{#1}}%
   \let\yquant@register@multi@contiguous=\@tmpconti%
}

\protected\def\yquant@prepare@inject@loop#1#2{%
   \ifyquant@firsttoken\yquant@register@multi{#2}{%
      \@fifthoffive#2% this clears all the actions for the individual contiguous slices
      % but we need to do something for the first register
      \csedef{yquant@prepare@replacecontrol@\@secondoffive#2}{%
         \noexpand\ifdim\the\yquant@dimena>\yquant@dimenb%
            \yquant@dimenb=\the\yquant@dimena\space%
         \noexpand\fi%
         \yquant@sort@eadd{%
            \yquant@draw@inject{#1}%
         }
      }%
   }{%
      \csedef{yquant@prepare@replacecontrol@#2}{%
         \noexpand\ifdim\the\yquant@dimena>\yquant@dimenb%
            \yquant@dimenb=\the\yquant@dimena\space%
         \noexpand\fi%
         \yquant@sort@eadd{%
            \yquant@draw@inject{#1}%
         }%
      }%
   }%
}

\protected\def\yquant@prepare@inject@discard#1{%
   \csgappto{\yquant@prefix draw}{%
      \yquant@draw@inject@outer{#1}%
   }%
   \csgundef{yquant@prepare@@injection@#1}%
}

\def\yquant@prepare@sort#1#2{%
   \yquant@prepare@sort@aux#1\relax#2\relax%
      \expandafter\@firstoftwo%
   \else%
      \expandafter\@secondoftwo%
   \fi%
}

\def\yquant@prepare@sort@aux#1#2#3\relax#4#5#6\relax{%
   \unless\ifnum#2>#5\relax%
}

\protected\def\yquant@prepare@controls@loop#1#2{%
   \ifx\yquant@lang@attr@name\empty%
      \let\@yquant@nodename=\empty%
   \else%
      \edef\@yquant@nodename{\yquant@lang@attr@name-#1\the\numexpr\idx-\yquant@config@idxbase\relax}%
   \fi%
   \ifcsname yquant@prepare@replacecontrol@#2\endcsname%
      \ifcsempty{yquant@prepare@replacecontrol@#2}\relax{%
         % do something unorthodox
         \csname yquant@prepare@replacecontrol@#2\endcsname%
         \numdef\idx{\idx+1}%
         \unless\ifdefined\yquant@prepare@controltype%
            \edef\yquant@prepare@controltype{#2}%
         \fi%
      }%
   \else%
      \yquant@sort@eadd{%
         \expandafter\noexpand\csname yquant@draw@#1control\endcsname%
            {#2}% register index
            {\@yquant@nodename}%
      }%
      \unless\ifdefined\yquant@prepare@controltype%
         \edef\yquant@prepare@controltype{#2}%
      \fi%
      \pgfinterruptboundingbox%
         \yquant@config@operator@multifalse%
         \yquant@env@virtualize@path%
         \ifx#1p
            \path%
               (0pt, 0pt)%
               node[/yquant/every control, /yquant/every positive control, /yquant/this control,%
                    name prefix=, name suffix=, name=] {};%
         \else%
            \path%
               (0pt, 0pt)%
               node[/yquant/every control, /yquant/every negative control, /yquant/this control,%
                    name prefix=, name suffix=, name=] {};%
         \fi
         \yquant@register@update@height{#2}{\the\yquant@pgf@picmaxy}%
         \yquant@register@update@depth{#2}{\the\dimexpr-\yquant@pgf@picminy\relax}%
         \expandafter%
      \endpgfinterruptboundingbox%
      \expandafter\yquant@dimena\expandafter=%
         \the\dimexpr\yquant@pgf@picmaxx-\yquant@pgf@picminx\relax\space%
      \ifdim\yquant@dimena>\yquant@dimenb%
         \yquant@dimenb=\yquant@dimena%
      \fi%
      \numdef\idx{\idx+1}%
   \fi%
}

\protected\def\yquant@prepare@controls{%
   \ifyquant@circuit@operator@hasControls%
      \let\idx=\yquant@config@idxbase%
      \forlistloop{\yquant@prepare@controls@loop p}\yquant@circuit@operator@pctrls%
      \let\idx=\yquant@config@idxbase%
      \forlistloop{\yquant@prepare@controls@loop n}\yquant@circuit@operator@nctrls%
      \unless\ifdefined\yquant@prepare@controltype%
         \PackageError{yquant.sty}{Internal inconsistency detected}%
                      {Controlled action without controls found.}%
      \fi%
   \fi%
}

\ifnum\yquant@compat>1 %
   \expandafter\@firstoftwo
\else
   \expandafter\@secondoftwo
\fi{
   \def\yquant@prepare@ifs@Ifnum{\noexpand\ifnum}
   \def\yquant@prepare@ifs@Ifcase{\noexpand\ifcase}
   \def\yquant@prepare@ifs@Or{\noexpand\or}
   \def\yquant@prepare@ifs@Else{\noexpand\else}
   \def\yquant@prepare@ifs@Fi{\noexpand\fi}
   \def\yquant@prepare@ifs@Unless{\noexpand\unless}
   \def\yquant@prepare@ifs@The{\noexpand\the}
   \protected\def\yquant@prepare@ifs@set{%
      \let\Ifnum=\yquant@prepare@ifs@Ifnum%
      \let\Ifcase=\yquant@prepare@ifs@Ifcase%
      \let\Or=\yquant@prepare@ifs@Or%
      \let\Else=\yquant@prepare@ifs@Else%
      \let\Fi=\yquant@prepare@ifs@Fi%
      \let\Unless=\yquant@prepare@ifs@Unless%
      \let\The=\yquant@prepare@ifs@The%
   }
   \protected\def\yquant@prepare@ifs@direct{%
      \let\Ifnum=\ifnum%
      \let\Ifcase=\ifcase%
      \let\Or=\or%
      \let\Else=\else%
      \let\Fi=\fi%
      \let\Unless=\unless%
      \let\The=\the%
   }
}{
   \let\yquant@prepare@ifs@set=\relax%
   \let\yquant@prepare@ifs@direct=\relax%
}
\protected\long\def\yquant@prepare@finalize#1#2{%
   % We now know the dimensions of all the registers (though we didn't bother with the height of the control knobs [if present], we just assume they are too small to change this).
   \let\idx=\yquant@protectedempty%
   \yquant@prepare@ifs@set%
   \let\yquant@prepare@append=\empty%
   \yquant@sort\yquant@prepare@sort%
   \def\@yquant@do##1{%
      \appto\yquant@prepare@append{##1}%
      \yquant@prepare@finalize@ctrl##1%
   }%
   \yquant@sort@dolistloop%
   \protected@csxappto{\yquant@prefix draw}{%
      \yquant@draw@group%
         {\the\yquant@dimenb}%
         \ifyquant@circuit@operator@hasControls%
           \yquant@register@get@type\yquant@prepare@controltype%
         \else%
           F%
         \fi% if-switch whether controls are present
         {\yquant@attrs@remaining}% custom style
         {#2}% operator style
         {#1}%
         {\yquant@prepare@list}%
      \unexpanded\expandafter{\yquant@prepare@append}%
      \yquant@draw@endgroup%
         \ifyquant@circuit@operator@hasControls%
            T%
         \else%
            F%
         \fi%
         \ifx\yquant@lang@attr@name\empty%
            {}0%
         \else%
            {\yquant@lang@attr@name}%
            \ifnum\yquant@circuit@operator@numtarget=1 %
               \ifnum\yquant@circuit@operator@numpctrl=1 %
                  \ifnum\yquant@circuit@operator@numnctrl=1 %
                     7%
                  \else%
                     6%
                  \fi%
               \else%
                  \ifnum\yquant@circuit@operator@numnctrl=1 %
                     5%
                  \else%
                     4%
                  \fi%
               \fi%
            \else%
               \ifnum\yquant@circuit@operator@numpctrl=1 %
                  \ifnum\yquant@circuit@operator@numnctrl=1 %
                     3%
                  \else%
                     2%
                  \fi%
               \else%
                  \ifnum\yquant@circuit@operator@numnctrl=1 %
                     1%
                  \else%
                     0%
                  \fi%
               \fi%
            \fi%
         \fi%
   }%
}

\protected\def\yquant@prepare@single#1#2#3{%
   \yquant@sort@eadd{%
      \yquant@draw@single%
         {#3}% register index
         {\@yquant@nodename}%
   }%
   \unless\ifyquant@circuit@operator@hasControls%
      \listadd\yquant@prepare@list{#3}%
   \fi%
   % determine the actual dimensions by a virtual draw command
   \pgfinterruptboundingbox%
      \yquant@config@operator@multifalse%
      \yquant@env@virtualize@path%
      \path%
         (0pt, 0pt)%
         node[/yquant/every operator, #2, /yquant/this operator,%
              name prefix=, name suffix=, name=] {#1};%
      \yquant@register@update@height{#3}{\the\yquant@pgf@picmaxy}%
      \yquant@register@update@depth{#3}{\the\dimexpr-\yquant@pgf@picminy\relax}%
}

\protected\def\yquant@prepare@multi#1#2#3{%
   \yquant@sort@eadd{%
      \yquant@draw@multi%
         #3%
         {\@yquant@nodename}%
   }%
   \unless\ifyquant@circuit@operator@hasControls%
      \eappto\yquant@prepare@list{%
         \expandafter\yquant@list@range\@secondandthirdoffive#3%
      }%
   \fi%
   \pgfinterruptboundingbox%
      \yquant@config@operator@multitrue%
      \yquant@env@virtualize@path%
      \def\yquant@prepare@content{#1}%
      \def\yquant@prepare@style{#2}%
      \let\yquant@register@multi@contiguous=\yquant@prepare@multi@contiguous%
      \@fifthoffive#3%
      \ifdim\yquant@pgf@picmaxy=-16000pt %
         % if there was no single contiguous part before, determine the width now
         \path%
            (0pt, 0pt)%
            node[/yquant/every operator, #2, /yquant/this operator,%
                 name prefix=, name suffix=, name=] {#1};%
      \fi%
}

\protected\def\yquant@prepare@multi@contiguous#1#2#3{%
   \global\yquant@pgf@picmaxy=-16000pt %
   \global\yquant@pgf@picminy=16000pt %
   \edef\@yquant@cmd{%
      \noexpand\path (0pt, 0pt)%
         node[/yquant/every operator, \yquant@prepare@style, /yquant/this operator,%
              /yquant/internal/multi main=\ifnum#3=1 true\else false\fi,%
              name prefix=, name suffix=, name=]%
            {\unexpanded\expandafter{\yquant@prepare@content}};%
   }%
   \@yquant@cmd%
   \ifnum#1=#2 %
      % this is a single register in disguise
      \yquant@register@update@height{#1}{\the\yquant@pgf@picmaxy}%
      \yquant@register@update@depth{#1}{\the\dimexpr-\yquant@pgf@picminy\relax}%
   \else%
      \yquant@register@update@multispace{#1}{#2}{\the\dimexpr\yquant@pgf@picmaxy-\yquant@pgf@picminy\relax}%
   \fi%
}

\protected\def\yquant@prepare@multiinit#1#2#3{%
   \yquant@sort@eadd{%
      \yquant@draw@multiinit%
         #3%
         {\@yquant@nodename}%
   }%
   \unless\ifyquant@circuit@operator@hasControls%
      \eappto\yquant@prepare@list{%
         \expandafter\yquant@list@range\@secondandthirdoffive#3%
      }%
   \fi%
   \pgfinterruptboundingbox%
      \yquant@config@operator@multitrue%
      \yquant@env@virtualize@path%
      \edef\@yquant@first{\@secondoffive#3}%
      \def\pgfdecorationsegmentaspect{0.5}%
      \def\pgfdecorationsegmentfromto{0-1}%
      \ifnum\yquant@compat<2 %
         \path (0pt, 0pt)%
            node[/yquant/every operator, #2, /yquant/every multi label,%
                 /yquant/this operator, name prefix=, name suffix=, name=] {#1};%
      \else%
         \path (0pt, 0pt)%
            node[/yquant/every operator, #2,%
                 /yquant/this operator, name prefix=, name suffix=, name=] {#1};%
      \fi%
      \ifnum\@secondoffive#3=\@thirdoffive#3 %
         % this is a single register in disguise
         \yquant@register@update@height{\@yquant@first}{\the\yquant@pgf@picmaxy}%
         \yquant@register@update@depth{\@yquant@first}{\the\dimexpr-\yquant@pgf@picminy\relax}%
      \else%
         % this may not be sufficient. Since the text position need not necessarily be at the center (if the register corresponding to the visual center is excluded), we may require some space here which we will later only use in parts, but then extend where we should not. However, resolving this would require a special handling when calculating the y positions at the end, meaning we could not use the multispace facility. Let's assume discontiguous init registers are so scarce that this does not matter (disable the acquiration by using the operator/overlay key).
         \edef\@yquant@upd{%
            \yquant@register@update@multispace%
               {\@yquant@first}{\@thirdoffive#3}%
               {\the\dimexpr\yquant@pgf@picmaxy-\yquant@pgf@picminy\relax}%
         }%
         \@yquant@upd%
      \fi%
}

\protected\gdef\yquant@prepare@output@discard#1#2#3#4{%
   \ifstrequal{#4}{discard}{%
      % This notification is triggered in the main circuit if there was an output gate on a wire with [out] or [inout] modifier, but the wire was discarded directly after the subcircuit. Then, it would look weird to extend the wire from the output gate until the end of the subcircuit, so we change the modifier to [ancilla] (not really, this is an artificial state) or [out].
      \listcsxadd{#2inonly}{#1}%
   }\relax%
}

\protected\long\def\yquant@prepare@output@single#1#2#3{%
   \yquant@sort@eadd{%
      \yquant@draw@output@single%
         {#3}% register index
         {\@yquant@nodename}%
   }%
   \listadd\yquant@prepare@list{#3}%
   % we must be extra careful with outputs in subcircuits: Assume the wire is discarded after the subcircuit, then we don't want to extend it after our output label
   \ifdefined\yquant@parent%
      \ifinlistcs{#3}{\yquant@prefix inonly}\relax{%
         \yquant@register@set@lastgate{#3}{%
            \yquant@prepare@output@discard{#3}{\yquant@prefix}%
         }%
      }%
   \fi%
   % determine the actual dimensions by a virtual draw command
   \pgfinterruptboundingbox%
      \yquant@config@operator@multifalse%
      \yquant@env@virtualize@path%
      % #2 is empty anyway
      \edef\@yquant@cmd{%
         \noexpand\path (0pt, 0pt)%
            node[\ifnum\yquant@compat>1 /yquant/every operator, \fi /yquant/every output,%
                 /yquant/every \yquant@register@type@tostring{\yquant@register@get@type{#3}} output,%
                 \ifnum\yquant@compat>1 /yquant/this operator, \fi%
                 name prefix=, name suffix=, name=] {\unexpanded{#1}};%
      }%
      \@yquant@cmd%
      \yquant@register@update@height{#3}{\the\yquant@pgf@picmaxy}%
      \yquant@register@update@depth{#3}{\the\dimexpr-\yquant@pgf@picminy\relax}%
}

\protected\long\def\yquant@prepare@output@multi#1#2#3{%
   \yquant@sort@eadd{%
      \yquant@draw@output@multi%
         #3%
         {\@yquant@nodename}%
   }%
   \eappto\yquant@prepare@list{%
      \expandafter\yquant@list@range\@secondandthirdoffive#3%
   }%
   % we must be extra careful with outputs in subcircuits: Assume the wire is discarded after the subcircuit, then we don't want to extend it after our output label
   \ifdefined\yquant@parent%
      \edef\@yquant@first{\@secondoffive#3}%
      \edef\@yquant@last{\@thirdoffive#3}%
      \yquant@for \@yquant@i := \@yquant@first to \@yquant@last {%
         \xifinlistcs\@yquant@i{\yquant@prefix inonly}\relax{%
            \yquant@register@set@lastgate\@yquant@i{%
               \yquant@prepare@output@discard{\@yquant@i}{\yquant@prefix}%
            }%
         }%
      }%
   \fi%
   \pgfinterruptboundingbox%
      \yquant@config@operator@multitrue%
      \yquant@env@virtualize@path%
      % We need to draw a line with some vertical extent, so just take the current height, whether it makes sense or not. We only need an estimate
      \edef\@yquant@first{\@secondoffive#3}%
      \def\pgfdecorationsgmentaspect{0.5}%
      \def\pgfdecorationsegmentfromto{0-1}%
      % #2 is empty anyway
      \edef\@yquant@cmd{%
         \noexpand\path (0pt, 0pt)
            node[\ifnum\yquant@compat>1 /yquant/every operator, /yquant/every output, \fi%
                 \ifnum\yquant@compat<2 /yquant/every multi output,\fi%
                 \ifnum\yquant@compat>1  /yquant/this operator,\fi%
                 name prefix=, name suffix=, name=] {\unexpanded{#1}};%
      }%
      \@yquant@cmd%
      \ifnum\@secondoffive#3=\@thirdoffive#3 %
         % this is a single register in disguise
         \yquant@register@update@height{\@yquant@first}{\the\yquant@pgf@picmaxy}%
         \yquant@register@update@depth{\@yquant@first}{\the\dimexpr-\yquant@pgf@picminy\relax}%
      \else%
         % this may not be sufficient. Since the text position need not necessarily be at the center (if the register corresponding to the visual center is excluded), we may require some space here which we will later only use in parts, but then extend where we should not. However, resolving this would require a special handling when calculating the y positions at the end, meaning we could not use the multispace facility. Let's assume discontiguous output registers are so scarce that this does not matter (disable the acquiration by using the operator/overlay key).
         \edef\@yquant@upd{%
            \yquant@register@update@multispace%
               {\@yquant@first}{\@thirdoffive#3}%
               {\the\dimexpr\yquant@pgf@picmaxy-\yquant@pgf@picminy\relax}%
         }%
         \@yquant@upd%
      \fi%
}

% BEGIN_FOLD replacement commands for draw actions that just keep track of the width
\protected\long\def\yquant@prepare@subcircuit@init#1#2{%
   \csdef{\yquant@prefix xpos@#1}{0pt}%
   \yquant@register@set@type{#1}{#2}%
}

\protected\def\yquant@prepare@subcircuit@getmaxx#1{%
   \begingroup%
      \yquant@dimena=\yquant@orientation@minus16383.99999pt %
      \def\@yquant@do##1{%
         \ifcsname\yquant@prefix xpos@##1\endcsname%
            \yquant@dimenb=\csname\yquant@prefix xpos@##1\endcsname\relax%
            \ifdim\yquant@orientation@plus\yquant@dimena<\yquant@orientation@plus\yquant@dimenb%
               \yquant@dimena=\yquant@dimenb%
            \fi%
         \else%
            \PackageError{yquant.sty}{Internal inconsistency detected}%
                         {Undefined internal wire x position.}%
         \fi%
      }%
      \forlistloop\@yquant@do{#1}%
      \expandafter%
   \endgroup%
   \expandafter\def\expandafter\@yquant@newx\expandafter{\the\yquant@dimena}%
}

\protected\def\yquant@prepare@subcircuit@move@loop#1{%
   \cslet{\yquant@prefix xpos@#1}\@yquant@newx%
}

\protected\long\def\yquant@prepare@subcircuit@group@execute@settype#1\yquant@register@set@type#2\yquant@sep{%
   \ifstrempty{#2}\relax{%
      \yquant@prepare@subcircuit@group@execute@settype@i#2\yquant@sep%
   }%
}

\protected\long\def\yquant@prepare@subcircuit@group@execute@settype@i#1#2#3\yquant@sep{%
   \yquant@register@set@type{#1}{#2}%
   \yquant@prepare@subcircuit@group@execute@settype#3\yquant@sep%
}

\protected\long\def\yquant@prepare@subcircuit@group#1#2#3#4#5#6#7\yquant@draw@endgroup{%
   \begingroup%
      \yquant@prepare@subcircuit@getmaxx{#6}%
      % If the quotes library is loaded, activate it. (else, this is by default \relax)
      \tikz@enable@node@quotes%
      \yquant@config@operator@position@rightalignfalse%
      \yquant@config@operator@position@advancetrue%
      \yquant@set{#3}%
      \let\@yquant@next=\endgroup%
      \ifyquant@config@operator@position@rightalign%
         \ifyquanthorz{%
            \ifdim#1>-\pgf@picminx%
               \global\pgf@picminx=-\dimexpr#1\relax%
            \fi%
         }{%
            \ifdim#1>\pgf@picmaxy%
               \global\pgf@picmaxy=#1 %
            \fi%
         }%
      \else%
         \ifyquant@env@seamless{%
            \ifdim\@yquant@newx=0pt %
               \dimdef\@yquant@newx{%
                  \@yquant@newx\yquant@orientation@plus#1%
               }%
            \else%
               \dimdef\@yquant@newx{%
                  \@yquant@newx\yquant@orientation@plus\yquant@config@operator@sep\yquant@orientation@plus#1%
               }%
            \fi%
         }{%
            \dimdef\@yquant@newx{%
               \@yquant@newx\yquant@orientation@plus\yquant@config@operator@sep\yquant@orientation@plus#1%
            }%
         }%
         \ifyquanthorz{%
            \ifdim\@yquant@newx>\pgf@picmaxx%
               \global\pgf@picmaxx=\@yquant@newx%
            \fi%
         }{%
            \ifdim\@yquant@newx<\pgf@picminy%
               \global\pgf@picminy=\@yquant@newx%
            \fi%
         }%
         \ifyquant@config@operator@position@advance%
            \edef\@yquant@next{%
               \endgroup%
               \def\noexpand\@yquant@newx{\@yquant@newx}%
               \noexpand\forlistloop\yquant@prepare@subcircuit@move@loop{#6}%
            }%
         \fi%
      \fi%
   \@yquant@next%
   \yquant@prepare@subcircuit@group@execute@settype#7\yquant@register@set@type\yquant@sep% execute all inner set types
   \@gobblethree% three arguments for the endgroup
}

\let\yquant@prepare@subcircuit@pgfpointanchor=\pgfpointanchor
\patchcmd\yquant@prepare@subcircuit@pgfpointanchor{%
   \pgferror{No shape named `#1' is known}%
}{}\relax{%
   \PackageWarning{yquant.sty}{Patching \string\pgfpointanchor\space for the purpose of subcircuits failed; using and referencing named nodes in subcircuits may lead to irrelevant errors.}%
}
\let\yquant@prepare@subcircuit@pgfpointshapeborder=\pgfpointshapeborder
\patchcmd\yquant@prepare@subcircuit@pgfpointshapeborder{%
   \pgferror{No shape named `#1' is known}%
}{}\relax{%
   \PackageWarning{yquant.sty}{Patching \string\pgfpointshapeborder\space for the purpose of subcircuits failed; using and referencing named nodes in subcircuits may lead to irrelevant errors.}%
}

\protected\def\yquant@prepare@subcircuit@hspace#1#2{%
   \yquant@prepare@subcircuit@getmaxx{#1}%
   \dimdef\@yquant@newx{\@yquant@newx\yquant@orientation@plus#2}%
   \forlistloop\yquant@prepare@subcircuit@move@loop{#1}%
   \ifyquanthorz{%
      \ifdim\@yquant@newx>\pgf@picmaxx %
         \global\pgf@picmaxx=\@yquant@newx %
      \fi%
   }{%
      \ifdim\@yquant@newx<\pgf@picminy%
         \global\pgf@picminy=\@yquant@newx %
      \fi%
   }%
}

\protected\def\yquant@prepare@subcircuit@endwires{%
   \expandafter\ifx\csname\yquant@prefix outputs\endcsname\relax%
      % to have a symmetric situation, we extend again one separation at the end, unless this is supposed to be seamless and we don't have outputs (for seamless circuits with outputs, extend - since this extension will be between last register and output)
      \ifyquant@env@seamless\relax{%
         \ifyquanthorz{%
            \global\advance\pgf@picmaxx by \yquant@config@operator@sep\relax%
         }{%
            \global\advance\pgf@picminy by -\yquant@config@operator@sep\relax%
         }%
      }%
   \else%
      % if we have outputs, those will be realized as additional drawing groups following this macro, so increasing the picture at this point is rather pointless. Instead, we adjust the wire positions appropriately. The additional separation will be inserted by the outputs.
      \begingroup%
         \yquant@dimena=\yquant@orientation@minus16383.99999pt %
         \yquant@fordown \@yquant@i := \csname\yquant@prefix registers\endcsname downto 1 {%
            \ifcsname\yquant@prefix xpos@\@yquant@i\endcsname%
               \yquant@dimenb=\csname\yquant@prefix xpos@\@yquant@i\endcsname\relax%
               \ifdim\yquant@orientation@plus\yquant@dimena<\yquant@orientation@plus\yquant@dimenb%
                  \yquant@dimena=\yquant@dimenb%
               \fi%
            \else%
               \PackageError{yquant.sty}{Internal inconsistency detected}%
                            {Undefined internal wire x position.}%
            \fi%
         }%
         \expandafter%
      \endgroup%
      \expandafter\def\expandafter\@yquant@newx\expandafter{\the\yquant@dimena}%
      \yquant@fordown \@yquant@i := \csname\yquant@prefix registers\endcsname downto 1 {%
         \cslet{\yquant@prefix xpos@\@yquant@i}\@yquant@newx%
      }%
   \fi%
   \let\yquant@circuit@endwires@finalize=\relax%
   \forlistcsloop\yquant@prepare@subcircuit@endwires@loop{\yquant@prefix inonly}%
}

\protected\def\yquant@prepare@subcircuit@endwires@loop#1{%
   \eappto\yquant@circuit@endwires@finalize{%
      \yquant@register@set@type{#1}\noexpand\yquant@register@types@nobit%
   }%
}
% END_FOLD

\newbox\yquant@prepare@subcircuit@box

\protected\long\def\yquant@prepare@subcircuit#1{%
   \yquant@sort@clear%
   \let\idx=\yquant@config@idxbase%
   \yquant@dimenb=\yquant@config@operator@minimum@width%
   \ifyquant@circuit@operator@hasControls%
      \edef\yquant@prepare@list{%
         \yquant@list@range%
            \yquant@circuit@operator@minctrl%
            \yquant@circuit@operator@maxctrl%
      }%
   \else%
      \let\yquant@prepare@list=\empty%
   \fi%
   % BEGIN_FOLD register
   \def\@yquant@do##1{%
      \ifx\yquant@lang@attr@name\empty%
         \let\@yquant@nodename=\empty%
      \else%
         \edef\@yquant@nodename{\yquant@lang@attr@name-\the\numexpr\idx-\yquant@config@idxbase\relax}%
      \fi%
      \ifyquant@firsttoken\yquant@register@multi{##1}{%
         \yquant@prepare@subcircuit@multi{#1}{##1}%
      }{%
         \yquant@prepare@subcircuit@single{#1}{##1}%
      }%
      \pgfinterruptboundingbox%
         % In order to determine the width of the subcircuit, we must execute the draw command at preparation time, where we will remap all relevant commands to virtual ones so that this has no effect and is not very costly. Although nothing should be drawn, as a precaution, we "draw" everything in a box that is dropped afterwards.
         % There will still be some extra width and height taken by separations or other things related to the box itself.
         \yquant@env@virtualize@path%
         \yquant@begingroup%
            \let\yquant@parent=\yquant@prefix%
            \edef\yquant@prefix{yquant@env\yquant@circuit@subcircuit@id @}%
            \let\yquant@draw@init=\yquant@prepare@subcircuit@init%
            \let\yquant@draw@group=\yquant@prepare@subcircuit@group%
            \let\yquant@draw@startenclose=\@gobble%
            \let\yquant@draw@stopenclose=\@gobble%
            % We may have draw actions within the subcircuit which reference nodes that have been created within the same subcircuit - but they are not known at the stage of preparation! So we here hack into the node querying macros of pgf and just let every unknown node be equal to the origin. If the node is truely unknown, we will find out about this in the draw stage.
            \let\pgfpointanchor=\yquant@prepare@subcircuit@pgfpointanchor%
            \let\pgfpointshapeborder=\yquant@prepare@subcircuit@pgfpointshapeborder%
            \let\yquant@draw@alias=\@gobble%
            \let\yquant@draw@hspace=\yquant@prepare@subcircuit@hspace%
            \let\yquant@circuit@endwires=\yquant@prepare@subcircuit@endwires%
            \let\yquant@circuit@flushwire=\@gobble%
            \let\yquant@circuit@setstyle=\@gobbletwo%
            \let\yquant@circuit@addstyle=\@gobbletwo%
            % do not overwrite \yquant@register@set@type, which may also occur - we want to change the register type!
            % restore tikz commands... as in env@end
            \let\path=\tikz@command@path%
            \let\tikz@lib@scope@check=\yquant@env@substikz@scopecheck%
            \let\tikz@scope@opt=\yquant@env@substikz@scope%
            \let\endtikz@scope@env=\yquant@env@substikz@endscope%
            \let\endscope=\endtikz@scope@env%
            \let\stopscope=\endscope%
            \global\yquant@pgf@picmaxx=0pt %
            \global\yquant@pgf@picminx=0pt %
            \global\setbox\yquant@prepare@subcircuit@box=\ifyquanthorz\vbox\hbox to 1sp{%
               \csname\yquant@prefix draw\endcsname%
            }%
            \ifdim\yquant@pgf@picmaxy=-16000pt %
               \global\yquant@pgf@picmaxy=0pt %
               \global\yquant@pgf@picminy=0pt %
            \fi%
            \ifyquant@env@seamless{%
               % for seamless circuits, we do not have an initial separation. However, if there is a label to registers (which you should not do for seamless subcircuits), the "initial" separation is in fact an inner one, so we need it.
               \ifyquanthorz{%
                  \ifdim\pgf@picminx<0pt %
                     \global\advance\pgf@picmaxx by \yquant@config@operator@sep\relax%
                  \fi%
               }{%
                  \ifdim\pgf@picmaxy>0pt %
                     \global\advance\pgf@picminy by -\yquant@config@operator@sep\relax%
                  \fi%
               }%
            }\relax%
            \ifyquanthorz{%
               \global\wd\yquant@prepare@subcircuit@box=\dimexpr\pgf@picmaxx-\pgf@picminx\relax%
            }{%
               \global\ht\yquant@prepare@subcircuit@box=\pgf@picmaxy%
               \global\dp\yquant@prepare@subcircuit@box=-\pgf@picminy%
            }%
         \yquant@endgroup%
         \edef\yquant@prepare@subcircuit@width{%
            {\ifyquanthorz{\the\wd\yquant@prepare@subcircuit@box}% inner width
                          {\the\dimexpr\ht\yquant@prepare@subcircuit@box+\dp\yquant@prepare@subcircuit@box\relax}}%
            {\noexpand\the\dimexpr\yquant@pgf@picmaxx-\yquant@pgf@picminx\relax}% outer width
            {\ifyquanthorz{\the\pgf@picminx}{-\the\pgf@picmaxy}}% left margin
         }%
         \pgfresetboundingbox%
         \path%
            (0pt, 0pt)%
            node[/yquant/every operator, #1,%
                 /yquant/operators/every subcircuit box, /yquant/this operator,%
                 /yquant/operators/this subcircuit box,%
                 name prefix=, name suffix=, name=, space radius=0pt]%
            {\box\yquant@prepare@subcircuit@box};%
         % the extra height is taken care for by manually inserting it to the height of the first and last register in the subcircuit
         \ifyquanthorz{%
            \yquant@register@inject@extents{\pgf@picmaxy}{-\pgf@picminy}%
         }{%
            \yquant@register@inject@extents{-\pgf@picminx}{\pgf@picmaxx}%
         }%
         \edef\@yquant@cmd{%
            \noexpand\endpgfinterruptboundingbox%
            \yquant@dimena=\the\dimexpr\yquant@pgf@picmaxx-\yquant@pgf@picminx\relax\space%
            \yquant@prepare@subcircuit@add%
         }%
      \@yquant@cmd%
      \ifdim\yquant@dimena>\yquant@dimenb%
         \yquant@dimenb=\yquant@dimena%
      \fi%
      \numdef\idx{\idx+1}%
   }%
   \forlistloop\@yquant@do\yquant@circuit@operator@targets%
   % END_FOLD
   \yquant@prepare@controls%
   \preto\yquant@attrs@remaining{/yquant/internal/no enclose}%
   \yquant@prepare@finalize{}{#1}%
}

\protected\def\yquant@prepare@subcircuit@single#1#2{%
   \yquant@config@operator@multifalse%
   \edef\yquant@circuit@subcircuit@param{#2\yquant@list@delim}%
   \yquant@circuit@subcircuit{#1}%
   \unless\ifyquant@circuit@operator@hasControls%
      \listadd\yquant@prepare@list{#2}%
   \fi%
   \edef\yquant@prepare@subcircuit@add{%
      \yquant@sort@eadd{%
         \yquant@draw@subcircuit@single%
            {#2}% register index
            {\yquant@circuit@subcircuit@id}%
            {\@yquant@nodename}\ifnum\yquant@circuit@operator@numtarget=1 1\else0\fi%
            {\noexpand\yquant@prepare@subcircuit@width}%
      }%
   }%
}

\protected\def\yquant@prepare@subcircuit@multi#1#2{%
   \yquant@config@operator@multitrue%
   \edef\yquant@circuit@subcircuit@param{\@fifthoffive#2}%
   \yquant@sort@list\yquant@circuit@subcircuit@param\yquant@sort@ascending%
   \yquant@circuit@subcircuit{#1}%
   \unless\ifyquant@circuit@operator@hasControls%
      \eappto\yquant@prepare@list{%
         \expandafter\yquant@list@range\@secondandthirdoffive#2%
      }%
   \fi%
   \edef\yquant@prepare@subcircuit@add{%
      \yquant@sort@eadd{%
         \yquant@draw@subcircuit@multi%
            #2%
            {\yquant@circuit@subcircuit@id}%
            {\@yquant@nodename}\ifnum\yquant@circuit@operator@numtarget=1 1\else0\fi%
            {\noexpand\yquant@prepare@subcircuit@width}%
      }%
   }%
}

\protected\def\yquant@prepare@finalize@ctrl#1{%
   \let\@yquant@next=\yquant@prepare@finalize@ctrl@single%
   \ifx\yquant@draw@multi#1%
      \let\@yquant@next=\yquant@prepare@finalize@ctrl@multi%
   \else%
      \ifx\yquant@draw@multiinit#1%
         \let\@yquant@next=\yquant@prepare@finalize@ctrl@multi%
      \else%
         \ifx\yquant@draw@output@multi#1%
            \let\@yquant@next=\yquant@prepare@finalize@ctrl@multi%
         \else%
            \ifx\yquant@draw@subcircuit@multi#1%
               \let\@yquant@next=\yquant@prepare@finalize@ctrl@subcircuit@multi%
            \else%
               \ifx\yquant@draw@subcircuit@single#1%
                  \let\@yquant@next=\yquant@prepare@finalize@ctrl@subcircuit@single%
               \else%
                  \ifx\yquant@draw@inject#1%
                     \let\@yquant@next=\@gobble%
                  \fi%
               \fi%
            \fi%
         \fi%
      \fi%
   \fi%
   \@yquant@next%
}

\protected\def\yquant@prepare@finalize@ctrl@single#1#2{%
   \ifinlist{#1}\yquant@circuit@operator@pctrls\relax{%
      \ifinlist{#1}\yquant@circuit@operator@nctrls\relax{%
         \eappto\yquant@prepare@append{%
            \yquant@prepare@callback@draw{#1}%
         }%
         \yquant@prepare@callback@prepare{#1}%
      }%
   }%
}

\protected\def\yquant@prepare@finalize@ctrl@multi#1#2#3#4#5{%
   \let\yquant@register@multi@contiguous=\yquant@prepare@finalize@ctrl@multi@contiguous%
   \ifyquant@circuit@operator@hasControls%
      \ifyquant@config@operator@multi@warn%
         \ifx\yquant@register@multi@splitparts\yquant@register@multi@splitparts@sepall%
            % In the multi as single case, we assume it can be implicitly understood that we always have a maximal multi gate. Only if there are two, we are in trouble.
            \ifdefined\yquant@prepare@finalize@ctrl@multi@contiguous@warn%
               \ifnum\yquant@prepare@finalize@ctrl@multi@contiguous@warn=1 %
                  \PackageWarning{yquant.sty}{Ambiguous operation: multiple multi-register operations in combination with controls make it impossible to visually determine on which registers the gates act on.}%
                  \yquant@config@operator@multi@warnfalse%
                  \def\yquant@prepare@finalize@ctrl@multi@contiguous@warn{2}%
               \else%
                  \def\yquant@prepare@finalize@ctrl@multi@contiguous@warn{1}%
               \fi%
            \else%
               \def\yquant@prepare@finalize@ctrl@multi@contiguous@warn{1}%
            \fi%
         \else%
            \def\yquant@prepare@finalize@ctrl@multi@contiguous@warn{0}%
         \fi%
      \else%
         \def\yquant@prepare@finalize@ctrl@multi@contiguous@warn{2}%
      \fi%
   \else%
      \def\yquant@prepare@finalize@ctrl@multi@contiguous@warn{2}%
   \fi%
   \cslet{\yquant@prefix finalize@ctrl@prepare@appto}\empty%
   #4%
   \eappto\yquant@prepare@append{\csname\yquant@prefix finalize@ctrl@prepare@appto\endcsname}%
   \csgundef{\yquant@prefix finalize@ctrl@prepare@appto}%
}

\protected\def\yquant@prepare@finalize@ctrl@multi@contiguous#1#2#3{%
   \unless\ifx\yquant@register@multi@splitparts\yquant@register@multi@splitparts@sepall%
      \ifnum\yquant@prepare@finalize@ctrl@multi@contiguous@warn=1 %
         \PackageWarning{yquant.sty}{Ambiguous operation: multiple discontiguous multi-register operations in combination with controls make it hard to visually determine on which registers the gates act on.}%
         % switch the warning off for this group (which is a single operation)
         \yquant@config@operator@multi@warnfalse%
         \def\yquant@prepare@finalize@ctrl@multi@contiguous@warn{2}%
      \else%
         \numdef\yquant@prepare@finalize@ctrl@multi@contiguous@warn{%
            \yquant@prepare@finalize@ctrl@multi@contiguous@warn+1%
         }%
      \fi%
   \fi%
   {% save \body
      \yquant@for \yquant@i := #1 to #2 {{% let inner loop mess up with macros
         \xifinlist\yquant@i\yquant@circuit@operator@pctrls\relax{%
            \xifinlist\yquant@i\yquant@circuit@operator@nctrls\relax{%
               \csxappto{\yquant@prefix finalize@ctrl@prepare@appto}{%
                  \expandafter\yquant@prepare@callback@draw\expandafter{\yquant@i}%
               }%
               \expandafter\yquant@prepare@callback@prepare\expandafter{\yquant@i}%
            }%
         }%
      }}%
   }%
}

\def\yquant@prepare@finalize@ctrl@subcircuit@single#1#2#3#4#5{%
   \yquant@prepare@finalize@ctrl@single{#1}{#3}%
}

\protected\def\yquant@prepare@finalize@ctrl@subcircuit@multi@loop#1{%
   \ifinlist{#1}\yquant@circuit@operator@pctrls\relax{%
      \ifinlist{#1}\yquant@circuit@operator@nctrls\relax{%
         \eappto\yquant@prepare@append{%
            \yquant@prepare@callback@draw{#1}%
         }%
         \yquant@prepare@callback@prepare{#1}%
      }%
   }%
}

\protected\def\yquant@prepare@finalize@ctrl@subcircuit@multi#1#2#3#4#5#6#7#8{%
   % there are no contiguous parts here, don't call the normal @multi
   \forlistloop\yquant@prepare@finalize@ctrl@subcircuit@multi@loop{#4}%
}