#pragma once #include #include namespace erebos { class SetViewBase; template class SetView; class SetBase { protected: struct Priv; SetBase(); SetBase(const vector &); SetBase(shared_ptr); shared_ptr add(const Storage &, const vector &) const; vector> toList() const; public: bool operator==(const SetBase &) const; bool operator!=(const SetBase &) const; vector digests() const; vector store() const; protected: shared_ptr p; }; template class Set : public SetBase { Set(shared_ptr p): SetBase(p) {}; public: Set() = default; Set(const vector & refs): SetBase(move(refs)) {} Set(const Set &) = default; Set(Set &&) = default; Set & operator=(const Set &) = default; Set & operator=(Set &&) = default; static Set load(const vector & refs) { return Set(move(refs)); } Set add(const Storage &, const T &) const; template SetView view(F && cmp) const; }; template class SetView { public: template SetView(F && cmp, const vector> & refs); typename vector::const_iterator begin() const { return items.begin(); } typename vector::const_iterator end() const { return items.end(); } private: vector items; }; template Set Set::add(const Storage & st, const T & x) const { return Set(SetBase::add(st, storedRefs(Mergeable::components(x)))); } template template SetView Set::view(F && cmp) const { return SetView(std::move(cmp), toList()); } template template SetView::SetView(F && cmp, const vector> & refs) { items.reserve(refs.size()); for (const auto & crefs : refs) { vector::Component>> comps; comps.reserve(crefs.size()); for (const auto & r : crefs) comps.push_back(Stored::Component>::load(r)); filterAncestors(comps); items.push_back(Mergeable::merge(comps)); } std::sort(items.begin(), items.end(), cmp); } }