In case someone needs it, here is how I done it (sorry, no C++11):
template <typename TTree>
boost::optional<TTree&> get_parent_optional(TTree& tree,
typename TTree::path_type path)
{
if (path.empty())
return boost::optional<TTree&>();
TTree::key_type root = path.reduce();
if (path.empty())
{
return (tree.find(root) != tree.not_found()) ?
boost::optional<TTree&>(tree) : boost::optional<TTree&>();
}
std::pair<TTree::assoc_iterator, TTree::assoc_iterator> range =
tree.equal_range(root);
for (TTree::assoc_iterator it = range.first; it != range.second; ++it)
{
boost::optional<TTree&> result = get_parent_optional(it->second, path);
if (result)
return result;
}
return boost::optional<TTree&>();
}
template <typename TTree>
boost::optional<TTree&> get_parent_optional(TTree& tree,
const typename TTree::key_type & path)
{
return get_parent_optional(tree, TTree::path_type(path));
}
template <typename TTree>
boost::optional<TTree&> get_parent_optional(TTree& tree,
const char * path)
{
return get_parent_optional(tree, std::string(path));
}
template <typename TTree>
typename TTree::key_type get_last_fragment(const typename TTree::key_type & keyPath)
{
TTree::path_type path(keyPath);
if (path.empty())
return TTree::key_type(); // or exception
while (!path.single())
path.reduce();
return path.reduce();
}
template <typename TTree>
void erase(TTree & tree, const typename TTree::key_type & path)
{
boost::optional<TTree&> parent;
typename TTree::key_type subkey = get_last_fragment<TTree>(path);
while (parent = get_parent_optional(tree, path))
{
parent->erase(subkey);
}
}
Note, that in case there are several branches to delete, a tree is reiterated after every branch deletion. It could be a problem in case of a large tree.