diff options
Diffstat (limited to 'src/libutil/reference-set.hh')
-rw-r--r-- | src/libutil/reference-set.hh | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/libutil/reference-set.hh b/src/libutil/reference-set.hh new file mode 100644 index 000000000..ac4a9994e --- /dev/null +++ b/src/libutil/reference-set.hh @@ -0,0 +1,68 @@ +#pragma once + +#include "comparator.hh" + +#include <set> + +namespace nix { + +template<typename Ref> +struct References +{ + std::set<Ref> others; + bool self = false; + + bool empty() const; + size_t size() const; + + /* Functions to view references + self as one set, mainly for + compatibility's sake. */ + std::set<Ref> possiblyToSelf(const Ref & self) const; + void insertPossiblyToSelf(const Ref & self, Ref && ref); + void setPossiblyToSelf(const Ref & self, std::set<Ref> && refs); + + GENERATE_CMP(References<Ref>, me->others, me->self); +}; + +template<typename Ref> +bool References<Ref>::empty() const +{ + return !self && others.empty(); +} + +template<typename Ref> +size_t References<Ref>::size() const +{ + return (self ? 1 : 0) + others.size(); +} + +template<typename Ref> +std::set<Ref> References<Ref>::possiblyToSelf(const Ref & selfRef) const +{ + std::set<Ref> refs { others }; + if (self) + refs.insert(selfRef); + return refs; +} + +template<typename Ref> +void References<Ref>::insertPossiblyToSelf(const Ref & selfRef, Ref && ref) +{ + if (ref == selfRef) + self = true; + else + others.insert(std::move(ref)); +} + +template<typename Ref> +void References<Ref>::setPossiblyToSelf(const Ref & selfRef, std::set<Ref> && refs) +{ + if (refs.count(selfRef)) { + self = true; + refs.erase(selfRef); + } + + others = refs; +} + +} |