3

I use boost::property_tree::ptree quite a bit, but I've found that I create, pass around, and then save copies too many times. With big ptree objects this is expensive.

Boost provides a swap function, but no move constructor. Why would they do that?

My current solution is to extend ptree and make one myself:

class MyPtree : public boost::property_tree::ptree
{
  MyPtree(MyPtree&& other)
  {
    swap(other);
  }

  ... plus adding the other constructors and operators
};

Is this the best solution or am I missing something?

Stewart
  • 3,028
  • 1
  • 18
  • 40

3 Answers3

2

I think your solution is pretty decent. Note that it will never affect internal tree operations, as the tree will see its children as ptree, not MyPtree.

Slightly better is to propose the new feature and suggest it to de library devs.


Related is Is there a convenient way to erase a node from a property tree, preserving its child nodes?.

If you want to dig deeper, you'll find that Property Tree builds on Boost MultiIndex which, for various reasons, doesn't seemless allow moving from values: Move element from boost multi_index array

You could add a splice() operation building on the list-ness of the various indexes used:

For now, ptree could add a splice operation, which would naturally wrap multi_index's list operations: I just made a draft implementation sehe - Sep 23 '17 at 9:48

sehe
  • 328,274
  • 43
  • 416
  • 565
1

Stewart, I've seen the ptree destructor and it seems that it's not virtual. It means the base destructor (ptree) will not be invoked if MyPtree is used polymorphically. Maybe you should consider to use composition instead of inheritance. See this answer enter image description here

This might be a sketch:

class MyPtree
{
   boost::property_tree::ptree m_tree;

   MyPtree(MyPtree&& other)
   {
      m_tree.swap(other.m_tree);
   }

  ... plus adding the other constructors and operators
};
elarmando
  • 559
  • 9
  • 16
  • 1
    @JHBonarius i added a code sample, what do you think? – elarmando Jun 01 '18 at 16:22
  • It is often fine to derive from a class with a non-virtual destructor. You only get into trouble if the destructor of the derived class needs to do more than the one of the base, and you delete an object of the derived type using a pointer to the base class... – Marc Glisse Jun 01 '18 at 16:26
  • "It means the base destructor (ptree) will not be invoked when MyPtree is destroyed" this is complete nonsense. – T.C. Jun 01 '18 at 19:38
0

use composition instead inheritance

class MyPtree
{
public:
  MyPtree():{m_tree_ptr = new boost::property_tree::ptree();
  MyPtree(MyPtree&& other){m_tree_ptr = other.m_tree_ptr; other.m_tree_ptr = nullptr;}
  ~MyPtree(){if (m_tree_ptr != nullptr) delete m_tree_ptr;}
  // copy conctructor and assign operator

private:
 boost::property_tree::ptree* m_tree_ptr;
};