diff options
Diffstat (limited to 'third_party/nix/src/libexpr/attr-set.cc')
-rw-r--r-- | third_party/nix/src/libexpr/attr-set.cc | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/third_party/nix/src/libexpr/attr-set.cc b/third_party/nix/src/libexpr/attr-set.cc index e9e2a2baded0..808ffce176ee 100644 --- a/third_party/nix/src/libexpr/attr-set.cc +++ b/third_party/nix/src/libexpr/attr-set.cc @@ -9,8 +9,6 @@ namespace nix { -static Bindings ZERO_BINDINGS; - // This function inherits its name from previous implementations, in // which Bindings was backed by an array of elements which was scanned // linearly. @@ -22,8 +20,6 @@ static Bindings ZERO_BINDINGS; // This behaviour is mimicked by using .insert(), which will *not* // override existing values. void Bindings::push_back(const Attr& attr) { - assert(this != &ZERO_BINDINGS); - auto [_, inserted] = attributes_.insert({attr.name, attr}); if (!inserted) { @@ -51,20 +47,48 @@ Bindings::iterator Bindings::find(const Symbol& name) { return attributes_.find(name); } -Bindings::iterator Bindings::begin() { return attributes_.begin(); } +bool Bindings::Equal(const Bindings* other, EvalState& state) const { + if (this == other) { + return true; + } + + if (this->attributes_.size() != other->attributes_.size()) { + return false; + } + + Bindings::const_iterator i; + Bindings::const_iterator j; + for (i = this->cbegin(), j = other->cbegin(); i != this->cend(); ++i, ++j) { + if (i->second.name != j->second.name || + !state.eqValues(*i->second.value, *j->second.value)) { + return false; + } + } + + return true; +} +Bindings::iterator Bindings::begin() { return attributes_.begin(); } Bindings::iterator Bindings::end() { return attributes_.end(); } -Bindings* Bindings::NewGC(size_t capacity) { +Bindings::const_iterator Bindings::cbegin() const { + return attributes_.cbegin(); +} + +Bindings::const_iterator Bindings::cend() const { return attributes_.cend(); } + +std::unique_ptr<Bindings> Bindings::New(size_t capacity) { if (capacity == 0) { - return &ZERO_BINDINGS; + // TODO(tazjin): A lot of 0-capacity Bindings are allocated. + // It would be nice to optimize that. } - return new Bindings; + return std::make_unique<Bindings>(); } -Bindings* Bindings::Merge(const Bindings& lhs, const Bindings& rhs) { - auto bindings = NewGC(lhs.size() + rhs.size()); +std::unique_ptr<Bindings> Bindings::Merge(const Bindings& lhs, + const Bindings& rhs) { + auto bindings = New(lhs.size() + rhs.size()); // Values are merged by inserting the entire iterator range of both // input sets. The right-hand set (the values of which take @@ -81,7 +105,7 @@ Bindings* Bindings::Merge(const Bindings& lhs, const Bindings& rhs) { void EvalState::mkAttrs(Value& v, size_t capacity) { clearValue(v); v.type = tAttrs; - v.attrs = Bindings::NewGC(capacity); + v.attrs = Bindings::New(capacity); nrAttrsets++; nrAttrsInAttrsets += capacity; } |