7

For a platform-independent model layer, I have hierarchical data (strings, actually) that look like this:

  • Item A
    • SubItem A
    • SubItem B
    • SubItem C
      • SubSubItem A
      • SubSubItem B
    • SubItem D
  • Item B
  • Item C

Now, within each "level" (Item, SubItem, SubSubItem, etc.) the items need to be sorted alphabetically.

Seems a simple solution would be to create a simple class with a sorted std::Vector or std::MultiMap to track its Children, and a pointer to its Parent. (and one root item). I would need to generally iterate through each item's children in a forward direction.

After construction/sorting, I do not need to add or delete items. Generally small numbers of items (hundreds).

This is for model organization of the backing data of an outline-style control.

Rolling a simple class would be easy, but this is such a common pattern — isn't there already a ready-made STL container with this behavior?

SMGreenfield
  • 1,680
  • 19
  • 35

4 Answers4

5

Nothing in STL itself, but you might find this useful:

tree.hh: an STL-like C++ tree class

Its API follows STL containers exactly, and it should do what you're looking for.

I believe their example is exactly what you are asking about (a tree with strings), in fact.

Corey
  • 1,845
  • 1
  • 12
  • 23
  • thanks -- this is an elegant class. It's licensed under GPLv2 / GPLv3. I'm developing commercial software. If I DO NOT modify the code in ANY WAY, am I required to distribute any source code? – SMGreenfield May 09 '13 at 04:30
  • Hmmm I'm not an expert at all, but it sounds like you would be [required to do just that](https://www.gnu.org/licenses/gpl-faq.html#GPLInProprietarySystem). You might be able to use the [property tree class from Boost](http://www.boost.org/doc/libs/1_53_0/doc/html/property_tree.html) instead. – Corey May 09 '13 at 05:13
  • @SMGreenfield - I came to the same conclusion that this class is not suitable for commercial applications. – MarkB May 11 '13 at 12:22
2

A simple solution:

Your keys are std::vector<GUID>, where the GUID is some type (maybe a GUID, or a pointer, or a string) that uniquely identifies each element. Children of an element simply have that elements std::vector<GUID> as a "prefix".

So long as your GUID are sortable via operator<, lexographic sorting on the std::vector will get things in the order you requested.

A map<std::vector<GUID>, Value> could be your container, or a std::vector< std::pair< GUID, Value > > that you sort by .first manually.

If your GUID type can have a "last element", you can find every child of {x,y,z} by finding lower_bound of {x,y,z} and upper_bound of {x,y,z,last_guid}. Giving it a "last element" is an advantage to not using a naked pointer.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
1

No. Don't mean to be curt, but that is the answer; see e.g. Josuttis, or the standard. You'll have to create a class which parent/child pointers along the lines you suggested and use a vector or other standard container of those.

Matt Phillips
  • 9,465
  • 8
  • 44
  • 75
1

The answer to your question is no, there is no tree in the STL. The patterns you suggested are fine. Also see this question.

Community
  • 1
  • 1
Leo
  • 2,775
  • 27
  • 29