aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/attr-set.hh
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2022-01-04 17:39:16 +0100
committerEelco Dolstra <edolstra@gmail.com>2022-01-04 18:00:33 +0100
commit6d9a6d2cc3a20c9047436d174c9f91a2223da220 (patch)
tree2bf36cb443a80f56db38e10c8afe2c749ff3bdcc /src/libexpr/attr-set.hh
parent1ffacad8a5201713659d5e18db47b2020bdc6aa1 (diff)
Ensure that attrsets are sorted
Previously you had to remember to call value->attrs->sort() after populating value->attrs. Now there is a BindingsBuilder helper that wraps Bindings and ensures that sort() is called before you can use it.
Diffstat (limited to 'src/libexpr/attr-set.hh')
-rw-r--r--src/libexpr/attr-set.hh34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/libexpr/attr-set.hh b/src/libexpr/attr-set.hh
index 7d6ffc9f3..903289b69 100644
--- a/src/libexpr/attr-set.hh
+++ b/src/libexpr/attr-set.hh
@@ -113,5 +113,39 @@ public:
friend class EvalState;
};
+/* A wrapper around Bindings that ensures that its always in sorted
+ order at the end. The only way to consume a BindingsBuilder is to
+ call finish(), which sorts the bindings. */
+class BindingsBuilder
+{
+ EvalState & state;
+ Bindings * bindings;
+
+public:
+
+ BindingsBuilder(EvalState & state, Bindings * bindings)
+ : state(state), bindings(bindings)
+ { }
+
+ void insert(Symbol name, Value * value, ptr<Pos> pos = ptr(&noPos))
+ {
+ insert(Attr(name, value, pos));
+ }
+
+ void insert(const Attr & attr)
+ {
+ bindings->push_back(attr);
+ }
+
+ Value & alloc(const Symbol & name, ptr<Pos> pos = ptr(&noPos));
+
+ Value & alloc(std::string_view name, ptr<Pos> pos = ptr(&noPos));
+
+ Bindings * finish()
+ {
+ bindings->sort();
+ return bindings;
+ }
+};
}