Task #1318
closedNameTree enumeration
100%
Description
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&)> 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.
- 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 returnstd::pair<const_iterator, const_iterator>
, andbegin
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.