# Global Metrics

path: .metrics.cyclomatic.average
old: 3.4166666666666665
new: 2.7096774193548385
path: .metrics.cyclomatic.sum
old: 41.0
new: 84.0
path: .metrics.nargs.average
old: 1.3636363636363635
new: 0.6666666666666666
path: .metrics.nargs.sum
old: 15.0
new: 18.0
path: .metrics.nom.total
old: 11.0
new: 27.0
path: .metrics.nom.closures
old: 3.0
new: 0.0
path: .metrics.nom.functions
old: 8.0
new: 27.0
path: .metrics.cognitive.sum
old: 30.0
new: 58.0
path: .metrics.cognitive.average
old: 2.727272727272727
new: 2.1481481481481484
path: .metrics.nexits.average
old: 1.0
new: 0.8148148148148148
path: .metrics.nexits.sum
old: 11.0
new: 22.0
path: .metrics.halstead.purity_ratio
old: 1.4832459377145806
new: 0.8856739178023794
path: .metrics.halstead.n1
old: 26.0
new: 42.0
path: .metrics.halstead.level
old: 0.033268790705861646
new: 0.012274475007394262
path: .metrics.halstead.vocabulary
old: 215.0
new: 208.0
path: .metrics.halstead.time
old: 13533.888249009273
new: 57089.20454265513
path: .metrics.halstead.n2
old: 189.0
new: 166.0
path: .metrics.halstead.volume
old: 8104.609720670575
new: 12613.320258315109
path: .metrics.halstead.N2
old: 437.0
new: 644.0
path: .metrics.halstead.difficulty
old: 30.058201058201057
new: 81.46987951807229
path: .metrics.halstead.length
old: 1046.0
new: 1638.0
path: .metrics.halstead.N1
old: 609.0
new: 994.0
path: .metrics.halstead.effort
old: 243609.98848216687
new: 1027605.6817677924
path: .metrics.halstead.estimated_program_length
old: 1551.4752508494512
new: 1450.7338773602974
path: .metrics.halstead.bugs
old: 1.300195941597515
new: 3.394400451525694
path: .metrics.loc.ploc
old: 227.0
new: 322.0
path: .metrics.loc.sloc
old: 301.0
new: 494.0
path: .metrics.loc.cloc
old: 35.0
new: 101.0
path: .metrics.loc.blank
old: 39.0
new: 71.0
path: .metrics.loc.lloc
old: 91.0
new: 210.0
path: .metrics.mi.mi_original
old: 22.31383465454229
new: 2.0978793925055896
path: .metrics.mi.mi_visual_studio
old: 13.04902611376742
new: 1.226830054096836
path: .metrics.mi.mi_sei
old: -14.132159213228183
new: -31.891709388862537

# Spaces Data

## Minimal test - lines (43, 334)

path: .spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: 14.227796268649804
new: 11.771384773878722
path: .spaces[0].spaces[0].metrics.mi.mi_sei
old: -12.947079694349554
new: -12.4211089861571
path: .spaces[0].spaces[0].metrics.mi.mi_original
old: 24.32953161939116
new: 20.129067963332616
path: .spaces[0].spaces[0].metrics.halstead.difficulty
old: 31.244318181818183
new: 85.51530612244898
path: .spaces[0].spaces[0].metrics.halstead.level
old: 0.03200581923986179
new: 0.01169381301831633
path: .spaces[0].spaces[0].metrics.halstead.n2
old: 176.0
new: 98.0
path: .spaces[0].spaces[0].metrics.halstead.volume
old: 7872.641404268845
new: 7975.571177876286
path: .spaces[0].spaces[0].metrics.halstead.n1
old: 26.0
new: 37.0
path: .spaces[0].spaces[0].metrics.halstead.purity_ratio
old: 1.3959838497585924
new: 0.7462212415719268
path: .spaces[0].spaces[0].metrics.halstead.vocabulary
old: 202.0
new: 135.0
path: .spaces[0].spaces[0].metrics.halstead.length
old: 1028.0
new: 1127.0
path: .spaces[0].spaces[0].metrics.halstead.N2
old: 423.0
new: 453.0
path: .spaces[0].spaces[0].metrics.halstead.time
old: 13665.295164796204
new: 37890.74504319287
path: .spaces[0].spaces[0].metrics.halstead.effort
old: 245975.3129663317
new: 682033.4107774716
path: .spaces[0].spaces[0].metrics.halstead.bugs
old: 1.3085985251455552
new: 2.582750842732423
path: .spaces[0].spaces[0].metrics.halstead.N1
old: 605.0
new: 674.0
path: .spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: 1435.071397551833
new: 840.9913392515615
path: .spaces[0].spaces[0].metrics.loc.ploc
old: 213.0
new: 197.0
path: .spaces[0].spaces[0].metrics.loc.lloc
old: 91.0
new: 111.0
path: .spaces[0].spaces[0].metrics.loc.sloc
old: 276.0
new: 292.0
path: .spaces[0].spaces[0].metrics.loc.blank
old: 35.0
new: 49.0
path: .spaces[0].spaces[0].metrics.loc.cloc
old: 28.0
new: 46.0
path: .spaces[0].spaces[0].metrics.nexits.average
old: 1.0
new: 0.7391304347826086
path: .spaces[0].spaces[0].metrics.nexits.sum
old: 11.0
new: 17.0
path: .spaces[0].spaces[0].metrics.cyclomatic.average
old: 3.9
new: 2.2083333333333335
path: .spaces[0].spaces[0].metrics.cyclomatic.sum
old: 39.0
new: 53.0
path: .spaces[0].spaces[0].metrics.cognitive.sum
old: 30.0
new: 42.0
path: .spaces[0].spaces[0].metrics.cognitive.average
old: 2.727272727272727
new: 1.826086956521739
path: .spaces[0].spaces[0].metrics.nom.closures
old: 3.0
new: 0.0
path: .spaces[0].spaces[0].metrics.nom.total
old: 11.0
new: 23.0
path: .spaces[0].spaces[0].metrics.nom.functions
old: 8.0
new: 23.0
path: .spaces[0].spaces[0].metrics.nargs.average
old: 1.3636363636363635
new: 0.782608695652174
path: .spaces[0].spaces[0].metrics.nargs.sum
old: 15.0
new: 18.0

### Code

    namespace test_assembler {

    using std::back_insert_iterator;

    Label::Label() : value_(new Binding()) {}
    Label::Label(uint64_t value) : value_(new Binding(value)) {}
    Label::Label(const Label& label) {
      value_ = label.value_;
      value_->Acquire();
    }
    Label::~Label() {
      if (value_->Release()) delete value_;
    }

    Label& Label::operator=(uint64_t value) {
      value_->Set(NULL, value);
      return *this;
    }

    Label& Label::operator=(const Label& label) {
      value_->Set(label.value_, 0);
      return *this;
    }

    Label Label::operator+(uint64_t addend) const {
      Label l;
      l.value_->Set(this->value_, addend);
      return l;
    }

    Label Label::operator-(uint64_t subtrahend) const {
      Label l;
      l.value_->Set(this->value_, -subtrahend);
      return l;
    }

    // When NDEBUG is #defined, assert doesn't evaluate its argument. This
    // means you can't simply use assert to check the return value of a
    // function with necessary side effects.
    //
    // ALWAYS_EVALUATE_AND_ASSERT(x) evaluates x regardless of whether
    // NDEBUG is #defined; when NDEBUG is not #defined, it further asserts
    // that x is true.
    #ifdef NDEBUG
    #  define ALWAYS_EVALUATE_AND_ASSERT(x) x
    #else
    #  define ALWAYS_EVALUATE_AND_ASSERT(x) assert(x)
    #endif

    uint64_t Label::operator-(const Label& label) const {
      uint64_t offset;
      ALWAYS_EVALUATE_AND_ASSERT(IsKnownOffsetFrom(label, &offset));
      return offset;
    }

    bool Label::IsKnownConstant(uint64_t* value_p) const {
      Binding* base;
      uint64_t addend;
      value_->Get(&base, &addend);
      if (base != NULL) return false;
      if (value_p) *value_p = addend;
      return true;
    }

    bool Label::IsKnownOffsetFrom(const Label& label, uint64_t* offset_p) const {
      Binding *label_base, *this_base;
      uint64_t label_addend, this_addend;
      label.value_->Get(&label_base, &label_addend);
      value_->Get(&this_base, &this_addend);
      // If this and label are related, Get will find their final
      // common ancestor, regardless of how indirect the relation is. This
      // comparison also handles the constant vs. constant case.
      if (this_base != label_base) return false;
      if (offset_p) *offset_p = this_addend - label_addend;
      return true;
    }

    Label::Binding::Binding() : base_(this), addend_(), reference_count_(1) {}

    Label::Binding::Binding(uint64_t addend)
        : base_(NULL), addend_(addend), reference_count_(1) {}

    Label::Binding::~Binding() {
      assert(reference_count_ == 0);
      if (base_ && base_ != this && base_->Release()) delete base_;
    }

    void Label::Binding::Set(Binding* binding, uint64_t addend) {
      if (!base_ && !binding) {
        // We're equating two constants. This could be okay.
        assert(addend_ == addend);
      } else if (!base_) {
        // We are a known constant, but BINDING may not be, so turn the
        // tables and try to set BINDING's value instead.
        binding->Set(NULL, addend_ - addend);
      } else {
        if (binding) {
          // Find binding's final value. Since the final value is always either
          // completely unconstrained or a constant, never a reference to
          // another variable (otherwise, it wouldn't be final), this
          // guarantees we won't create cycles here, even for code like this:
          //   l = m, m = n, n = l;
          uint64_t binding_addend;
          binding->Get(&binding, &binding_addend);
          addend += binding_addend;
        }

        // It seems likely that setting a binding to itself is a bug
        // (although I can imagine this might turn out to be helpful to
        // permit).
        assert(binding != this);

        if (base_ != this) {
          // Set the other bindings on our chain as well. Note that this
          // is sufficient even though binding relationships form trees:
          // All binding operations traverse their chains to the end, and
          // all bindings related to us share some tail of our chain, so
          // they will see the changes we make here.
          base_->Set(binding, addend - addend_);
          // We're not going to use base_ any more.
          if (base_->Release()) delete base_;
        }

        // Adopt BINDING as our base. Note that it should be correct to
        // acquire here, after the release above, even though the usual
        // reference-counting rules call for acquiring first, and then
        // releasing: the self-reference assertion above should have
        // complained if BINDING were 'this' or anywhere along our chain,
        // so we didn't release BINDING.
        if (binding) binding->Acquire();
        base_ = binding;
        addend_ = addend;
      }
    }

    void Label::Binding::Get(Binding** base, uint64_t* addend) {
      if (base_ && base_ != this) {
        // Recurse to find the end of our reference chain (the root of our
        // tree), and then rewrite every binding along the chain to refer
        // to it directly, adjusting addends appropriately. (This is why
        // this member function isn't this-const.)
        Binding* final_base;
        uint64_t final_addend;
        base_->Get(&final_base, &final_addend);
        if (final_base) final_base->Acquire();
        if (base_->Release()) delete base_;
        base_ = final_base;
        addend_ += final_addend;
      }
      *base = base_;
      *addend = addend_;
    }

    template
    static inline void InsertEndian(test_assembler::Endianness endianness,
                                    size_t size, uint64_t number, Inserter dest) {
      assert(size > 0);
      if (endianness == kLittleEndian) {
        for (size_t i = 0; i < size; i++) {
          *dest++ = (char)(number & 0xff);
          number >>= 8;
        }
      } else {
        assert(endianness == kBigEndian);
        // The loop condition is odd, but it's correct for size_t.
        for (size_t i = size - 1; i < size; i--)
          *dest++ = (char)((number >> (i * 8)) & 0xff);
      }
    }

    Section& Section::Append(Endianness endianness, size_t size, uint64_t number) {
      InsertEndian(endianness, size, number,
                   back_insert_iterator(contents_));
      return *this;
    }

    Section& Section::Append(Endianness endianness, size_t size,
                             const Label& label) {
      // If this label's value is known, there's no reason to waste an
      // entry in references_ on it.
      uint64_t value;
      if (label.IsKnownConstant(&value)) return Append(endianness, size, value);

      // This will get caught when the references are resolved, but it's
      // nicer to find out earlier.
      assert(endianness != kUnsetEndian);

      references_.push_back(Reference(contents_.size(), endianness, size, label));
      contents_.append(size, 0);
      return *this;
    }

    #define ENDIANNESS_L kLittleEndian
    #define ENDIANNESS_B kBigEndian
    #define ENDIANNESS(e) ENDIANNESS_##e

    #define DEFINE_SHORT_APPEND_NUMBER_ENDIAN(e, bits)         \
      Section& Section::e##bits(uint##bits##_t v) {            \
        InsertEndian(ENDIANNESS(e), bits / 8, v,               \
                     back_insert_iterator(contents_)); \
        return *this;                                          \
      }

    #define DEFINE_SHORT_APPEND_LABEL_ENDIAN(e, bits) \
      Section& Section::e##bits(const Label& v) {     \
        return Append(ENDIANNESS(e), bits / 8, v);    \
      }

    // Define L16, B32, and friends.
    #define DEFINE_SHORT_APPEND_ENDIAN(e, bits)  \
      DEFINE_SHORT_APPEND_NUMBER_ENDIAN(e, bits) \
      DEFINE_SHORT_APPEND_LABEL_ENDIAN(e, bits)

    DEFINE_SHORT_APPEND_LABEL_ENDIAN(L, 8);
    DEFINE_SHORT_APPEND_LABEL_ENDIAN(B, 8);
    DEFINE_SHORT_APPEND_ENDIAN(L, 16);
    DEFINE_SHORT_APPEND_ENDIAN(L, 32);
    DEFINE_SHORT_APPEND_ENDIAN(L, 64);
    DEFINE_SHORT_APPEND_ENDIAN(B, 16);
    DEFINE_SHORT_APPEND_ENDIAN(B, 32);
    DEFINE_SHORT_APPEND_ENDIAN(B, 64);

    #define DEFINE_SHORT_APPEND_NUMBER_DEFAULT(bits)           \
      Section& Section::D##bits(uint##bits##_t v) {            \
        InsertEndian(endianness_, bits / 8, v,                 \
                     back_insert_iterator(contents_)); \
        return *this;                                          \
      }
    #define DEFINE_SHORT_APPEND_LABEL_DEFAULT(bits) \
      Section& Section::D##bits(const Label& v) {   \
        return Append(endianness_, bits / 8, v);    \
      }
    #define DEFINE_SHORT_APPEND_DEFAULT(bits)  \
      DEFINE_SHORT_APPEND_NUMBER_DEFAULT(bits) \
      DEFINE_SHORT_APPEND_LABEL_DEFAULT(bits)

    DEFINE_SHORT_APPEND_LABEL_DEFAULT(8)
    DEFINE_SHORT_APPEND_DEFAULT(16);
    DEFINE_SHORT_APPEND_DEFAULT(32);
    DEFINE_SHORT_APPEND_DEFAULT(64);

    Section& Section::LEB128(long long value) {
      while (value < -0x40 || 0x3f < value) {
        contents_ += (value & 0x7f) | 0x80;
        if (value < 0)
          value = (value >> 7) | ~(((unsigned long long)-1) >> 7);
        else
          value = (value >> 7);
      }
      contents_ += value & 0x7f;
      return *this;
    }

    Section& Section::ULEB128(uint64_t value) {
      while (value > 0x7f) {
        contents_ += (value & 0x7f) | 0x80;
        value = (value >> 7);
      }
      contents_ += value;
      return *this;
    }

    Section& Section::Align(size_t alignment, uint8_t pad_byte) {
      // ALIGNMENT must be a power of two.
      assert(((alignment - 1) & alignment) == 0);
      size_t new_size = (contents_.size() + alignment - 1) & ~(alignment - 1);
      contents_.append(new_size - contents_.size(), pad_byte);
      assert((contents_.size() & (alignment - 1)) == 0);
      return *this;
    }

    bool Section::GetContents(string* contents) {
      // For each label reference, find the label's value, and patch it into
      // the section's contents.
      for (size_t i = 0; i < references_.size(); i++) {
        Reference& r = references_[i];
        uint64_t value;
        if (!r.label.IsKnownConstant(&value)) {
          fprintf(stderr, "Undefined label #%zu at offset 0x%zx\n", i, r.offset);
          return false;
        }
        assert(r.offset < contents_.size());
        assert(contents_.size() - r.offset >= r.size);
        InsertEndian(r.endianness, r.size, value, contents_.begin() + r.offset);
      }
      contents->clear();
      std::swap(contents_, *contents);
      references_.clear();
      return true;
    }

    }  // namespace test_assembler

## Minimal test - lines (57, 60)

path: .spaces[0].spaces[0].spaces[4].metrics.nom.closures
old: 3.0
new: 0.0
path: .spaces[0].spaces[0].spaces[4].metrics.nom.total
old: 4.0
new: 1.0
path: .spaces[0].spaces[0].spaces[4].metrics.cognitive.average
old: 2.75
new: 0.0
path: .spaces[0].spaces[0].spaces[4].metrics.cognitive.sum
old: 11.0
new: 0.0
path: .spaces[0].spaces[0].spaces[4].metrics.loc.blank
old: 7.0
new: 0.0
path: .spaces[0].spaces[0].spaces[4].metrics.loc.ploc
old: 87.0
new: 4.0
path: .spaces[0].spaces[0].spaces[4].metrics.loc.sloc
old: 108.0
new: 4.0
path: .spaces[0].spaces[0].spaces[4].metrics.loc.lloc
old: 36.0
new: 2.0
path: .spaces[0].spaces[0].spaces[4].metrics.loc.cloc
old: 14.0
new: 0.0
path: .spaces[0].spaces[0].spaces[4].metrics.nargs.sum
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[4].metrics.nargs.average
old: 0.25
new: 0.0
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.bugs
old: 0.5604059795606705
new: 0.018752049849923146
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.effort
old: 68934.40366336062
new: 421.94418432572
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.n1
old: 21.0
new: 10.0
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.purity_ratio
old: 1.5439115273055908
new: 2.4904956346283575
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.level
old: 0.04616132167152576
new: 0.16666666666666666
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.difficulty
old: 21.66315789473684
new: 6.0
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.volume
old: 3182.103181739193
new: 70.32403072095333
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.estimated_program_length
old: 716.3749486697941
new: 44.82892142331043
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.time
old: 3829.689092408923
new: 23.44134357365111
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.N2
old: 196.0
new: 6.0
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.length
old: 464.0
new: 18.0
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.n2
old: 95.0
new: 5.0
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.vocabulary
old: 116.0
new: 15.0
path: .spaces[0].spaces[0].spaces[4].metrics.halstead.N1
old: 268.0
new: 12.0
path: .spaces[0].spaces[0].spaces[4].metrics.cyclomatic.average
old: 11.0
new: 1.0
path: .spaces[0].spaces[0].spaces[4].metrics.cyclomatic.sum
old: 11.0
new: 1.0
path: .spaces[0].spaces[0].spaces[4].metrics.mi.mi_visual_studio
old: 29.637383870319457
new: 73.79873729732505
path: .spaces[0].spaces[0].spaces[4].metrics.mi.mi_original
old: 50.67992641824627
new: 126.19584077842585
path: .spaces[0].spaces[0].spaces[4].metrics.mi.mi_sei
old: 24.99976212527903
new: 106.46308153923984
path: .spaces[0].spaces[0].spaces[4].metrics.nexits.average
old: 0.75
new: 1.0
path: .spaces[0].spaces[0].spaces[4].metrics.nexits.sum
old: 3.0
new: 1.0

### Code

    Label& Label::operator=(uint64_t value) {
      value_->Set(NULL, value);
      return *this;
    }

## Minimal test - lines (73, 77)

path: .spaces[0].spaces[0].spaces[7].metrics.nargs.sum
old: 3.0
new: 1.0
path: .spaces[0].spaces[0].spaces[7].metrics.nargs.average
old: 3.0
new: 1.0
path: .spaces[0].spaces[0].spaces[7].metrics.cyclomatic.average
old: 5.0
new: 1.0
path: .spaces[0].spaces[0].spaces[7].metrics.cyclomatic.sum
old: 5.0
new: 1.0
path: .spaces[0].spaces[0].spaces[7].metrics.halstead.length
old: 85.0
new: 24.0
path: .spaces[0].spaces[0].spaces[7].metrics.halstead.N2
old: 31.0
new: 10.0
path: .spaces[0].spaces[0].spaces[7].metrics.halstead.n2
old: 23.0
new: 5.0
path: .spaces[0].spaces[0].spaces[7].metrics.halstead.difficulty
old: 11.456521739130435
new: 10.0
path: .spaces[0].spaces[0].spaces[7].metrics.halstead.effort
old: 5182.516717619118
new: 937.6537429460444
path: .spaces[0].spaces[0].spaces[7].metrics.halstead.n1
old: 17.0
new: 10.0
path: .spaces[0].spaces[0].spaces[7].metrics.halstead.purity_ratio
old: 2.041515215183142
new: 1.867871725971268
path: .spaces[0].spaces[0].spaces[7].metrics.halstead.vocabulary
old: 40.0
new: 15.0
path: .spaces[0].spaces[0].spaces[7].metrics.halstead.volume
old: 452.36388806542584
new: 93.76537429460444
path: .spaces[0].spaces[0].spaces[7].metrics.halstead.time
old: 287.91759542328435
new: 52.09187460811358
path: .spaces[0].spaces[0].spaces[7].metrics.halstead.bugs
old: 0.09982497721736826
new: 0.03193305039268938
path: .spaces[0].spaces[0].spaces[7].metrics.halstead.estimated_program_length
old: 173.52879329056708
new: 44.82892142331043
path: .spaces[0].spaces[0].spaces[7].metrics.halstead.N1
old: 54.0
new: 14.0
path: .spaces[0].spaces[0].spaces[7].metrics.halstead.level
old: 0.0872865275142315
new: 0.1
path: .spaces[0].spaces[0].spaces[7].metrics.mi.mi_sei
old: 79.2589955870867
new: 99.0896514058146
path: .spaces[0].spaces[0].spaces[7].metrics.mi.mi_visual_studio
old: 50.62584559916968
new: 70.8099230820973
path: .spaces[0].spaces[0].spaces[7].metrics.mi.mi_original
old: 86.57019597458014
new: 121.08496847038636
path: .spaces[0].spaces[0].spaces[7].metrics.loc.sloc
old: 24.0
new: 5.0
path: .spaces[0].spaces[0].spaces[7].metrics.loc.blank
old: 2.0
new: 0.0
path: .spaces[0].spaces[0].spaces[7].metrics.loc.lloc
old: 10.0
new: 2.0
path: .spaces[0].spaces[0].spaces[7].metrics.loc.cloc
old: 4.0
new: 0.0
path: .spaces[0].spaces[0].spaces[7].metrics.loc.ploc
old: 18.0
new: 5.0
path: .spaces[0].spaces[0].spaces[7].metrics.nexits.average
old: 3.0
new: 1.0
path: .spaces[0].spaces[0].spaces[7].metrics.nexits.sum
old: 3.0
new: 1.0
path: .spaces[0].spaces[0].spaces[7].metrics.cognitive.sum
old: 4.0
new: 0.0
path: .spaces[0].spaces[0].spaces[7].metrics.cognitive.average
old: 4.0
new: 0.0

### Code

    Label Label::operator-(uint64_t subtrahend) const {
      Label l;
      l.value_->Set(this->value_, -subtrahend);
      return l;
    }

## Minimal test - lines (53, 55)

path: .spaces[0].spaces[0].spaces[3].metrics.cyclomatic.average
old: 5.0
new: 2.0
path: .spaces[0].spaces[0].spaces[3].metrics.cyclomatic.sum
old: 5.0
new: 2.0
path: .spaces[0].spaces[0].spaces[3].metrics.nexits.sum
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[3].metrics.nexits.average
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[3].metrics.nargs.average
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[3].metrics.nargs.sum
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[3].metrics.cognitive.average
old: 6.0
new: 1.0
path: .spaces[0].spaces[0].spaces[3].metrics.cognitive.sum
old: 6.0
new: 1.0
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.vocabulary
old: 53.0
new: 11.0
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.difficulty
old: 13.628571428571428
new: 5.333333333333333
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.level
old: 0.07337526205450734
new: 0.1875
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.N2
old: 53.0
new: 4.0
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.n1
old: 18.0
new: 8.0
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.bugs
old: 0.15704513393982142
new: 0.013519680280728329
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.n2
old: 35.0
new: 3.0
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.effort
old: 10226.301869836872
new: 258.3042275249182
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.N1
old: 78.0
new: 10.0
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.purity_ratio
old: 1.9433859207559956
new: 2.0539205358688193
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.estimated_program_length
old: 254.58355561903545
new: 28.75488750216347
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.volume
old: 750.357579547779
new: 48.43204266092216
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.time
old: 568.127881657604
new: 14.350234862495457
path: .spaces[0].spaces[0].spaces[3].metrics.halstead.length
old: 131.0
new: 14.0
path: .spaces[0].spaces[0].spaces[3].metrics.loc.ploc
old: 28.0
new: 3.0
path: .spaces[0].spaces[0].spaces[3].metrics.loc.blank
old: 6.0
new: 0.0
path: .spaces[0].spaces[0].spaces[3].metrics.loc.cloc
old: 3.0
new: 0.0
path: .spaces[0].spaces[0].spaces[3].metrics.loc.lloc
old: 14.0
new: 2.0
path: .spaces[0].spaces[0].spaces[3].metrics.loc.sloc
old: 37.0
new: 3.0
path: .spaces[0].spaces[0].spaces[3].metrics.mi.mi_sei
old: 57.13741893836033
new: 115.75457976937346
path: .spaces[0].spaces[0].spaces[3].metrics.mi.mi_visual_studio
old: 44.98612310750397
new: 77.52376633412248
path: .spaces[0].spaces[0].spaces[3].metrics.mi.mi_original
old: 76.92627051383178
new: 132.56564043134944

### Code

    Label::~Label() {
      if (value_->Release()) delete value_;
    }

## Minimal test - lines (62, 65)

path: .spaces[0].spaces[0].spaces[5].metrics.halstead.n1
old: 9.0
new: 10.0
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.N1
old: 19.0
new: 13.0
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.N2
old: 14.0
new: 8.0
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.purity_ratio
old: 1.8711698776319527
new: 2.1347105439671634
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.bugs
old: 0.03068314009949471
new: 0.02517517122460569
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.time
old: 49.06356278027341
new: 36.46431222567951
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.volume
old: 140.1816079436383
new: 82.0447025077789
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.effort
old: 883.1441300449213
new: 656.3576200622311
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.length
old: 33.0
new: 21.0
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.estimated_program_length
old: 61.74860596185444
new: 44.82892142331043
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.vocabulary
old: 19.0
new: 15.0
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.difficulty
old: 6.3
new: 8.0
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.level
old: 0.15873015873015872
new: 0.125
path: .spaces[0].spaces[0].spaces[5].metrics.halstead.n2
old: 10.0
new: 5.0
path: .spaces[0].spaces[0].spaces[5].metrics.cyclomatic.average
old: 2.0
new: 1.0
path: .spaces[0].spaces[0].spaces[5].metrics.cyclomatic.sum
old: 2.0
new: 1.0
path: .spaces[0].spaces[0].spaces[5].metrics.cognitive.average
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[5].metrics.cognitive.sum
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[5].metrics.loc.sloc
old: 13.0
new: 4.0
path: .spaces[0].spaces[0].spaces[5].metrics.loc.lloc
old: 6.0
new: 2.0
path: .spaces[0].spaces[0].spaces[5].metrics.loc.cloc
old: 2.0
new: 0.0
path: .spaces[0].spaces[0].spaces[5].metrics.loc.blank
old: 2.0
new: 0.0
path: .spaces[0].spaces[0].spaces[5].metrics.loc.ploc
old: 9.0
new: 4.0
path: .spaces[0].spaces[0].spaces[5].metrics.mi.mi_original
old: 103.2845387449579
new: 125.39425724332408
path: .spaces[0].spaces[0].spaces[5].metrics.mi.mi_sei
old: 102.0576030479892
new: 105.30664094829032
path: .spaces[0].spaces[0].spaces[5].metrics.mi.mi_visual_studio
old: 60.40031505553093
new: 73.32997499609597
path: .spaces[0].spaces[0].spaces[5].metrics.nexits.sum
old: 2.0
new: 1.0
path: .spaces[0].spaces[0].spaces[5].metrics.nexits.average
old: 2.0
new: 1.0
path: .spaces[0].spaces[0].spaces[5].metrics.nargs.sum
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[5].metrics.nargs.average
old: 1.0
new: 0.0

### Code

    Label& Label::operator=(const Label& label) {
      value_->Set(label.value_, 0);
      return *this;
    }

## Minimal test - lines (47, 47)

path: .spaces[0].spaces[0].spaces[0].metrics.halstead.time
old: 61.34227922068799
new: 4.166666666666667
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.effort
old: 1104.161025972384
new: 75.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.bugs
old: 0.03560959390880295
new: 0.005928155507483437
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.level
old: 0.17105263157894737
new: 0.4
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.volume
old: 188.86964917948671
new: 30.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.N1
old: 24.0
new: 7.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.estimated_program_length
old: 72.10571633583419
new: 16.36452797660028
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.n1
old: 8.0
new: 5.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.purity_ratio
old: 1.6768771240891671
new: 1.6364527976600278
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.n2
old: 13.0
new: 3.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.difficulty
old: 5.846153846153846
new: 2.5
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.N2
old: 19.0
new: 3.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.length
old: 43.0
new: 10.0
path: .spaces[0].spaces[0].spaces[0].metrics.halstead.vocabulary
old: 21.0
new: 8.0
path: .spaces[0].spaces[0].spaces[0].metrics.cyclomatic.sum
old: 2.0
new: 1.0
path: .spaces[0].spaces[0].spaces[0].metrics.loc.lloc
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[0].metrics.loc.ploc
old: 8.0
new: 1.0
path: .spaces[0].spaces[0].spaces[0].metrics.loc.sloc
old: 8.0
new: 1.0
path: .spaces[0].spaces[0].spaces[0].metrics.nargs.sum
old: 6.0
new: 0.0
path: .spaces[0].spaces[0].spaces[0].metrics.nargs.average
old: 6.0
new: 0.0
path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_original
old: 109.59955015556356
new: 153.0837736153568
path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_sei
old: 82.62151521988892
new: 145.25416890283572
path: .spaces[0].spaces[0].spaces[0].metrics.mi.mi_visual_studio
old: 64.09330418454009
new: 89.52267462886361

### Code

    Label::Label() : value_(new Binding()) {}

## Minimal test - lines (48, 48)

path: .spaces[0].spaces[0].spaces[1].metrics.halstead.vocabulary
old: 9.0
new: 10.0
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.time
old: 5.811529169310906
new: 8.996888590319939
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.level
old: 0.3333333333333333
new: 0.26666666666666666
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.volume
old: 34.86917501586544
new: 43.18506523353571
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.length
old: 11.0
new: 13.0
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.N2
old: 3.0
new: 5.0
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.n2
old: 3.0
new: 4.0
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.purity_ratio
old: 1.842242046044582
new: 1.808444231102072
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.bugs
old: 0.007400380157174523
new: 0.009903498582139372
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.difficulty
old: 3.0
new: 3.75
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.estimated_program_length
old: 20.264662506490403
new: 23.509775004326936
path: .spaces[0].spaces[0].spaces[1].metrics.halstead.effort
old: 104.60752504759633
new: 161.9439946257589
path: .spaces[0].spaces[0].spaces[1].metrics.nargs.average
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[1].metrics.nargs.sum
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[1].metrics.loc.lloc
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[1].metrics.loc.sloc
old: 3.0
new: 1.0
path: .spaces[0].spaces[0].spaces[1].metrics.loc.ploc
old: 3.0
new: 1.0
path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_visual_studio
old: 78.65739431314731
new: 88.41486984730174
path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_original
old: 134.50414427548188
new: 151.189427438886
path: .spaces[0].spaces[0].spaces[1].metrics.mi.mi_sei
old: 118.44942979264312
new: 142.52120506831432

### Code

    Label::Label(uint64_t value) : value_(new Binding(value)) {}

## Minimal test - lines (67, 71)

path: .spaces[0].spaces[0].spaces[6].metrics.mi.mi_sei
old: 93.95328610212584
new: 99.60253955663347
path: .spaces[0].spaces[0].spaces[6].metrics.mi.mi_visual_studio
old: 68.68662876803354
new: 71.017821898286
path: .spaces[0].spaces[0].spaces[6].metrics.mi.mi_original
old: 117.45413519333736
new: 121.44047544606906
path: .spaces[0].spaces[0].spaces[6].metrics.nargs.average
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[6].metrics.nargs.sum
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[6].metrics.cyclomatic.average
old: 2.0
new: 1.0
path: .spaces[0].spaces[0].spaces[6].metrics.cyclomatic.sum
old: 2.0
new: 1.0
path: .spaces[0].spaces[0].spaces[6].metrics.nexits.average
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[6].metrics.nexits.sum
old: 0.0
new: 1.0
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.effort
old: 749.3681875625622
new: 788.122468865924
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.N2
old: 8.0
new: 10.0
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.estimated_program_length
old: 53.5635228093372
new: 40.13896548741762
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.N1
old: 17.0
new: 13.0
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.level
old: 0.13636363636363638
new: 0.1111111111111111
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.difficulty
old: 7.333333333333333
new: 9.0
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.n2
old: 6.0
new: 5.0
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.time
old: 41.631565975697896
new: 43.784581603662446
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.volume
old: 102.18657103125848
new: 87.56916320732489
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.purity_ratio
old: 2.142540912373488
new: 1.7451724124964183
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.vocabulary
old: 17.0
new: 14.0
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.n1
old: 11.0
new: 9.0
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.bugs
old: 0.027500604913224463
new: 0.028440761343675472
path: .spaces[0].spaces[0].spaces[6].metrics.halstead.length
old: 25.0
new: 23.0
path: .spaces[0].spaces[0].spaces[6].metrics.cognitive.sum
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[6].metrics.cognitive.average
old: 1.0
new: 0.0
path: .spaces[0].spaces[0].spaces[6].metrics.loc.sloc
old: 6.0
new: 5.0
path: .spaces[0].spaces[0].spaces[6].metrics.loc.ploc
old: 6.0
new: 5.0

### Code

    Label Label::operator+(uint64_t addend) const {
      Label l;
      l.value_->Set(this->value_, addend);
      return l;
    }

## Minimal test - lines (49, 52)

path: .spaces[0].spaces[0].spaces[2].metrics.nargs.average
old: 3.0
new: 1.0
path: .spaces[0].spaces[0].spaces[2].metrics.nargs.sum
old: 3.0
new: 1.0
path: .spaces[0].spaces[0].spaces[2].metrics.nexits.average
old: 2.0
new: 0.0
path: .spaces[0].spaces[0].spaces[2].metrics.nexits.sum
old: 2.0
new: 0.0
path: .spaces[0].spaces[0].spaces[2].metrics.mi.mi_original
old: 66.52758643388843
new: 126.64300853627338
path: .spaces[0].spaces[0].spaces[2].metrics.mi.mi_sei
old: 35.983618726500616
new: 107.10820824593196
path: .spaces[0].spaces[0].spaces[2].metrics.mi.mi_visual_studio
old: 38.9050213063675
new: 74.0602389101014
path: .spaces[0].spaces[0].spaces[2].metrics.cyclomatic.average
old: 10.0
new: 1.0
path: .spaces[0].spaces[0].spaces[2].metrics.cyclomatic.sum
old: 10.0
new: 1.0
path: .spaces[0].spaces[0].spaces[2].metrics.cognitive.average
old: 7.0
new: 0.0
path: .spaces[0].spaces[0].spaces[2].metrics.cognitive.sum
old: 7.0
new: 0.0
path: .spaces[0].spaces[0].spaces[2].metrics.loc.blank
old: 6.0
new: 0.0
path: .spaces[0].spaces[0].spaces[2].metrics.loc.ploc
old: 46.0
new: 4.0
path: .spaces[0].spaces[0].spaces[2].metrics.loc.cloc
old: 2.0
new: 0.0
path: .spaces[0].spaces[0].spaces[2].metrics.loc.lloc
old: 20.0
new: 2.0
path: .spaces[0].spaces[0].spaces[2].metrics.loc.sloc
old: 54.0
new: 4.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.estimated_program_length
old: 418.41343573651113
new: 32.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.level
old: 0.08241758241758242
new: 0.125
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.length
old: 219.0
new: 18.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.bugs
old: 0.21692964024575936
new: 0.02145079956307671
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.difficulty
old: 12.133333333333333
new: 8.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.N1
old: 128.0
new: 10.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.time
old: 922.3329438179052
new: 28.67970000576925
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.volume
old: 1368.2961254441452
new: 64.5293250129808
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.n1
old: 16.0
new: 8.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.effort
old: 16601.992988722293
new: 516.2346001038464
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.n2
old: 60.0
new: 4.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.purity_ratio
old: 1.9105636335000509
new: 1.7777777777777777
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.N2
old: 91.0
new: 8.0
path: .spaces[0].spaces[0].spaces[2].metrics.halstead.vocabulary
old: 76.0
new: 12.0

### Code

    Label::Label(const Label& label) {
      value_ = label.value_;
      value_->Acquire();
    }

## Minimal test - lines (42, 335)

path: .spaces[0].metrics.nom.closures
old: 3.0
new: 0.0
path: .spaces[0].metrics.nom.functions
old: 8.0
new: 23.0
path: .spaces[0].metrics.nom.total
old: 11.0
new: 23.0
path: .spaces[0].metrics.mi.mi_visual_studio
old: 14.01615285832464
new: 11.56225135636454
path: .spaces[0].metrics.mi.mi_original
old: 23.967621387735136
new: 19.771449819383363
path: .spaces[0].metrics.mi.mi_sei
old: -13.06303553225542
new: -12.650508267330338
path: .spaces[0].metrics.halstead.effort
old: 245869.3306372341
new: 678855.1601589287
path: .spaces[0].metrics.halstead.N1
old: 606.0
new: 675.0
path: .spaces[0].metrics.halstead.N2
old: 424.0
new: 454.0
path: .spaces[0].metrics.halstead.length
old: 1030.0
new: 1129.0
path: .spaces[0].metrics.halstead.vocabulary
old: 203.0
new: 136.0
path: .spaces[0].metrics.halstead.bugs
old: 1.3082226113214566
new: 2.574720915466769
path: .spaces[0].metrics.halstead.n2
old: 177.0
new: 99.0
path: .spaces[0].metrics.halstead.n1
old: 26.0
new: 37.0
path: .spaces[0].metrics.halstead.volume
old: 7895.295994700732
new: 8001.745547771633
path: .spaces[0].metrics.halstead.purity_ratio
old: 1.401920014598407
new: 0.7520425862853433
path: .spaces[0].metrics.halstead.time
old: 13659.407257624116
new: 37714.17556438493
path: .spaces[0].metrics.halstead.difficulty
old: 31.141242937853107
new: 84.83838383838383
path: .spaces[0].metrics.halstead.level
old: 0.03211175616835994
new: 0.011787117513989762
path: .spaces[0].metrics.halstead.estimated_program_length
old: 1443.977615036359
new: 849.0560799161525
path: .spaces[0].metrics.nargs.average
old: 1.3636363636363635
new: 0.782608695652174
path: .spaces[0].metrics.nargs.sum
old: 15.0
new: 18.0
path: .spaces[0].metrics.loc.lloc
old: 91.0
new: 111.0
path: .spaces[0].metrics.loc.blank
old: 34.0
new: 48.0
path: .spaces[0].metrics.loc.ploc
old: 215.0
new: 199.0
path: .spaces[0].metrics.loc.sloc
old: 278.0
new: 294.0
path: .spaces[0].metrics.loc.cloc
old: 29.0
new: 47.0
path: .spaces[0].metrics.nexits.average
old: 1.0
new: 0.7391304347826086
path: .spaces[0].metrics.nexits.sum
old: 11.0
new: 17.0
path: .spaces[0].metrics.cyclomatic.sum
old: 40.0
new: 54.0
path: .spaces[0].metrics.cyclomatic.average
old: 3.636363636363636
new: 2.16
path: .spaces[0].metrics.cognitive.sum
old: 30.0
new: 42.0
path: .spaces[0].metrics.cognitive.average
old: 2.727272727272727
new: 1.826086956521739

### Code

    namespace lul_test {
    namespace test_assembler {

    using std::back_insert_iterator;

    Label::Label() : value_(new Binding()) {}
    Label::Label(uint64_t value) : value_(new Binding(value)) {}
    Label::Label(const Label& label) {
      value_ = label.value_;
      value_->Acquire();
    }
    Label::~Label() {
      if (value_->Release()) delete value_;
    }

    Label& Label::operator=(uint64_t value) {
      value_->Set(NULL, value);
      return *this;
    }

    Label& Label::operator=(const Label& label) {
      value_->Set(label.value_, 0);
      return *this;
    }

    Label Label::operator+(uint64_t addend) const {
      Label l;
      l.value_->Set(this->value_, addend);
      return l;
    }

    Label Label::operator-(uint64_t subtrahend) const {
      Label l;
      l.value_->Set(this->value_, -subtrahend);
      return l;
    }

    // When NDEBUG is #defined, assert doesn't evaluate its argument. This
    // means you can't simply use assert to check the return value of a
    // function with necessary side effects.
    //
    // ALWAYS_EVALUATE_AND_ASSERT(x) evaluates x regardless of whether
    // NDEBUG is #defined; when NDEBUG is not #defined, it further asserts
    // that x is true.
    #ifdef NDEBUG
    #  define ALWAYS_EVALUATE_AND_ASSERT(x) x
    #else
    #  define ALWAYS_EVALUATE_AND_ASSERT(x) assert(x)
    #endif

    uint64_t Label::operator-(const Label& label) const {
      uint64_t offset;
      ALWAYS_EVALUATE_AND_ASSERT(IsKnownOffsetFrom(label, &offset));
      return offset;
    }

    bool Label::IsKnownConstant(uint64_t* value_p) const {
      Binding* base;
      uint64_t addend;
      value_->Get(&base, &addend);
      if (base != NULL) return false;
      if (value_p) *value_p = addend;
      return true;
    }

    bool Label::IsKnownOffsetFrom(const Label& label, uint64_t* offset_p) const {
      Binding *label_base, *this_base;
      uint64_t label_addend, this_addend;
      label.value_->Get(&label_base, &label_addend);
      value_->Get(&this_base, &this_addend);
      // If this and label are related, Get will find their final
      // common ancestor, regardless of how indirect the relation is. This
      // comparison also handles the constant vs. constant case.
      if (this_base != label_base) return false;
      if (offset_p) *offset_p = this_addend - label_addend;
      return true;
    }

    Label::Binding::Binding() : base_(this), addend_(), reference_count_(1) {}

    Label::Binding::Binding(uint64_t addend)
        : base_(NULL), addend_(addend), reference_count_(1) {}

    Label::Binding::~Binding() {
      assert(reference_count_ == 0);
      if (base_ && base_ != this && base_->Release()) delete base_;
    }

    void Label::Binding::Set(Binding* binding, uint64_t addend) {
      if (!base_ && !binding) {
        // We're equating two constants. This could be okay.
        assert(addend_ == addend);
      } else if (!base_) {
        // We are a known constant, but BINDING may not be, so turn the
        // tables and try to set BINDING's value instead.
        binding->Set(NULL, addend_ - addend);
      } else {
        if (binding) {
          // Find binding's final value. Since the final value is always either
          // completely unconstrained or a constant, never a reference to
          // another variable (otherwise, it wouldn't be final), this
          // guarantees we won't create cycles here, even for code like this:
          //   l = m, m = n, n = l;
          uint64_t binding_addend;
          binding->Get(&binding, &binding_addend);
          addend += binding_addend;
        }

        // It seems likely that setting a binding to itself is a bug
        // (although I can imagine this might turn out to be helpful to
        // permit).
        assert(binding != this);

        if (base_ != this) {
          // Set the other bindings on our chain as well. Note that this
          // is sufficient even though binding relationships form trees:
          // All binding operations traverse their chains to the end, and
          // all bindings related to us share some tail of our chain, so
          // they will see the changes we make here.
          base_->Set(binding, addend - addend_);
          // We're not going to use base_ any more.
          if (base_->Release()) delete base_;
        }

        // Adopt BINDING as our base. Note that it should be correct to
        // acquire here, after the release above, even though the usual
        // reference-counting rules call for acquiring first, and then
        // releasing: the self-reference assertion above should have
        // complained if BINDING were 'this' or anywhere along our chain,
        // so we didn't release BINDING.
        if (binding) binding->Acquire();
        base_ = binding;
        addend_ = addend;
      }
    }

    void Label::Binding::Get(Binding** base, uint64_t* addend) {
      if (base_ && base_ != this) {
        // Recurse to find the end of our reference chain (the root of our
        // tree), and then rewrite every binding along the chain to refer
        // to it directly, adjusting addends appropriately. (This is why
        // this member function isn't this-const.)
        Binding* final_base;
        uint64_t final_addend;
        base_->Get(&final_base, &final_addend);
        if (final_base) final_base->Acquire();
        if (base_->Release()) delete base_;
        base_ = final_base;
        addend_ += final_addend;
      }
      *base = base_;
      *addend = addend_;
    }

    template
    static inline void InsertEndian(test_assembler::Endianness endianness,
                                    size_t size, uint64_t number, Inserter dest) {
      assert(size > 0);
      if (endianness == kLittleEndian) {
        for (size_t i = 0; i < size; i++) {
          *dest++ = (char)(number & 0xff);
          number >>= 8;
        }
      } else {
        assert(endianness == kBigEndian);
        // The loop condition is odd, but it's correct for size_t.
        for (size_t i = size - 1; i < size; i--)
          *dest++ = (char)((number >> (i * 8)) & 0xff);
      }
    }

    Section& Section::Append(Endianness endianness, size_t size, uint64_t number) {
      InsertEndian(endianness, size, number,
                   back_insert_iterator(contents_));
      return *this;
    }

    Section& Section::Append(Endianness endianness, size_t size,
                             const Label& label) {
      // If this label's value is known, there's no reason to waste an
      // entry in references_ on it.
      uint64_t value;
      if (label.IsKnownConstant(&value)) return Append(endianness, size, value);

      // This will get caught when the references are resolved, but it's
      // nicer to find out earlier.
      assert(endianness != kUnsetEndian);

      references_.push_back(Reference(contents_.size(), endianness, size, label));
      contents_.append(size, 0);
      return *this;
    }

    #define ENDIANNESS_L kLittleEndian
    #define ENDIANNESS_B kBigEndian
    #define ENDIANNESS(e) ENDIANNESS_##e

    #define DEFINE_SHORT_APPEND_NUMBER_ENDIAN(e, bits)         \
      Section& Section::e##bits(uint##bits##_t v) {            \
        InsertEndian(ENDIANNESS(e), bits / 8, v,               \
                     back_insert_iterator(contents_)); \
        return *this;                                          \
      }

    #define DEFINE_SHORT_APPEND_LABEL_ENDIAN(e, bits) \
      Section& Section::e##bits(const Label& v) {     \
        return Append(ENDIANNESS(e), bits / 8, v);    \
      }

    // Define L16, B32, and friends.
    #define DEFINE_SHORT_APPEND_ENDIAN(e, bits)  \
      DEFINE_SHORT_APPEND_NUMBER_ENDIAN(e, bits) \
      DEFINE_SHORT_APPEND_LABEL_ENDIAN(e, bits)

    DEFINE_SHORT_APPEND_LABEL_ENDIAN(L, 8);
    DEFINE_SHORT_APPEND_LABEL_ENDIAN(B, 8);
    DEFINE_SHORT_APPEND_ENDIAN(L, 16);
    DEFINE_SHORT_APPEND_ENDIAN(L, 32);
    DEFINE_SHORT_APPEND_ENDIAN(L, 64);
    DEFINE_SHORT_APPEND_ENDIAN(B, 16);
    DEFINE_SHORT_APPEND_ENDIAN(B, 32);
    DEFINE_SHORT_APPEND_ENDIAN(B, 64);

    #define DEFINE_SHORT_APPEND_NUMBER_DEFAULT(bits)           \
      Section& Section::D##bits(uint##bits##_t v) {            \
        InsertEndian(endianness_, bits / 8, v,                 \
                     back_insert_iterator(contents_)); \
        return *this;                                          \
      }
    #define DEFINE_SHORT_APPEND_LABEL_DEFAULT(bits) \
      Section& Section::D##bits(const Label& v) {   \
        return Append(endianness_, bits / 8, v);    \
      }
    #define DEFINE_SHORT_APPEND_DEFAULT(bits)  \
      DEFINE_SHORT_APPEND_NUMBER_DEFAULT(bits) \
      DEFINE_SHORT_APPEND_LABEL_DEFAULT(bits)

    DEFINE_SHORT_APPEND_LABEL_DEFAULT(8)
    DEFINE_SHORT_APPEND_DEFAULT(16);
    DEFINE_SHORT_APPEND_DEFAULT(32);
    DEFINE_SHORT_APPEND_DEFAULT(64);

    Section& Section::LEB128(long long value) {
      while (value < -0x40 || 0x3f < value) {
        contents_ += (value & 0x7f) | 0x80;
        if (value < 0)
          value = (value >> 7) | ~(((unsigned long long)-1) >> 7);
        else
          value = (value >> 7);
      }
      contents_ += value & 0x7f;
      return *this;
    }

    Section& Section::ULEB128(uint64_t value) {
      while (value > 0x7f) {
        contents_ += (value & 0x7f) | 0x80;
        value = (value >> 7);
      }
      contents_ += value;
      return *this;
    }

    Section& Section::Align(size_t alignment, uint8_t pad_byte) {
      // ALIGNMENT must be a power of two.
      assert(((alignment - 1) & alignment) == 0);
      size_t new_size = (contents_.size() + alignment - 1) & ~(alignment - 1);
      contents_.append(new_size - contents_.size(), pad_byte);
      assert((contents_.size() & (alignment - 1)) == 0);
      return *this;
    }

    bool Section::GetContents(string* contents) {
      // For each label reference, find the label's value, and patch it into
      // the section's contents.
      for (size_t i = 0; i < references_.size(); i++) {
        Reference& r = references_[i];
        uint64_t value;
        if (!r.label.IsKnownConstant(&value)) {
          fprintf(stderr, "Undefined label #%zu at offset 0x%zx\n", i, r.offset);
          return false;
        }
        assert(r.offset < contents_.size());
        assert(contents_.size() - r.offset >= r.size);
        InsertEndian(r.endianness, r.size, value, contents_.begin() + r.offset);
      }
      contents->clear();
      std::swap(contents_, *contents);
      references_.clear();
      return true;
    }

    }  // namespace test_assembler
    }  // namespace lul_test