Task #1318
Updated by Junxiao Shi over 10 years ago
Implement the new API for NameTree enumeration functions. ## API namespace name_tree { /// determines whether to visit an entry typedef function<bool(const Entry&)> EntrySelector; /// a functor that accepts any entry class AnyEntry : public EntrySelector; /// determines whether to an entry and/or its descendants /// \return .first indicates whether to visit entry, .second indicates whether to visit its descendants typedef function<std::pair<bool,bool>(const Entry&)> name_tree::Entry&)> EntrySubtreeSelector; /// a functor that accepts any entry and its descendants class AnyEntrySubtree : public EntrySubtreeSelector; } // namespace name_tree partial class NameTree { /// ForwardIterator; *it is name_tree::Entry& type typedef ... const_iterator; /// full enumerate const_iterator fullEnumerate(const EntrySelector& selector = AnyEntry()) const; /// partial enumerate; an entry is included if accepted by selector, and none of its ancestors is rejected by subTreeSelector const_iterator partialEnumerate(const Name& name, const EntrySubtreeSelector& selector = AnyEntrySubtree()) const; /// enumerate along name and name's ancestors const_iterator findAllMatches(const Name& name, const EntrySelector& selector = AnyEntry()) const; /// begin iterator (full enumerate) const_iterator begin() const; /// end iterator const_iterator end() const; }; Notes: * The snippet assumes using STL iterators. It's equally fine to use [Boost.Range](http://www.boost.org/doc/libs/1_48_0/libs/range/doc/html/index.html). * The snippet assumes all three operations use the same type of iterator. It's equally fine to have different types. If different iterator types are used, `fullEnumerate` `partialEnumerate` `findAllMatches` should return `std::pair<const_iterator, const_iterator>`, and `begin` `end` are unnecessary. * It's unacceptable to create a new container and copy results into it. ## Examples Give a NameTree containing these entries: * / * /A * /A/B * /A/B/C * /A/D * /E * /F **.fullEnumerate**(f) ~ .end(), where f accepts A,C,E,F only: visits A,C,E,F in any order. **.partialEnumerate**(/A, f) ~ .end(), where f accepts root,B,C,D entries and root,A,F subtrees only: visits B,D in any order. If an entry is rejected, its children can still be visited (eg. A is rejected, but B can be visited). If a subtree is rejected, its children are skipped, but the root entry of subtree can be visited (eg. B is rejected, so C is skipped, but B is visited). **.findAllMatches**(/A/B/C/D, f) ~ .end(), where f accepts root,B,C,F only: visits root,B,C in any order. **.begin**() ~ .end(): equivalent to .fullEnumerate(AnyEntry()); visits root,A,B,C,D,E,F in any order.