_updateMeasureMask_gateStep(state, row, disabledReasons) {
        if (disabledReasons[row] !== undefined) {
            return;
        }

        let gate = this.gates[row];

        if (gate === undefined) {
            return;
        }

        // The measurement gate measures.
        if (gate === Gates.Special.Measurement) {
            state.measureMask |= 1<<row;
            return;
        }

        // Post-selection gates un-measure (in that the simulator can then do coherent operations on the qubit
        // without getting the wrong answer, at least).
        let hasSingleResult = gate === Gates.PostSelectionGates.PostSelectOn
            || gate === Gates.PostSelectionGates.PostSelectOff
            || gate === Gates.Detectors.ZDetector
            || gate === Gates.Detectors.ZDetectControlClear;
        if (!this.hasControl(0, 1 << row) && hasSingleResult) {
            state.measureMask &= ~(1<<row);
            return;
        }

        GateColumn._updateMeasureMask_swapGate(gate, state, row);
        GateColumn._updateMeasureMask_customPermute(gate, state, row);
    }
@param {{measureMask: !int, earlierRowWithSwapGate: undefined|!int}} state
@param row
@param {!Array.<undefined|!string>} disabledReasons
@returns {void}
@private