Question

Is there a way to get a copy of all of the values in a YAML::Node object into a new object (i.e. a clone)? Also is there a way to test for equality between two YAML::Node objects by the values in the node (i.e. a .equals() function as opposed to an .is() function)?

Consider the following example:

YAML::Node a;
a["x"][1]["y"][2]["z"][3] = 1;
std::cout << "A_____\n" << a << "\n\n\n\n";

std::cout << "Test 1\n";
YAML::Node z = a["x"][1]["y"][2]["z"];
z[3] = 2;
std::cout << "Z_____\n" <<  z << "\n";
std::cout << "A_____\n" <<  a << "\n\n\n\n";

std::cout << "Test 2\n";
YAML::Node b = a;
b["x"][1]["y"][2]["z"][3] = 3;
std::cout << "B_____\n" <<  b << "\n";
std::cout << "Z_____\n" <<  z << "\n";
std::cout << "A_____\n" <<  a << "\n\n\n\n";

std::cout << "Test 3\n";
YAML::Node c;
c["x"][1]["y"][2]["z"][3] = 3;
std::cout << "C_____\n" <<  c << "\n";
std::cout << "A_____\n" <<  a << "\n";
std::cout << "a == c: " <<  bool(a==c) << "\n";
std::cout << "z == a[\"x\"][1][\"y\"][2][\"z\"]: "
            <<  bool(z == a["x"][1]["y"][2]["z"]) << "\n\n";

which outputs the following when run:

A_____
x:
  1:
    y:
      2:
        z:
          3: 1



Test 1
Z_____
3: 2
A_____
x:
  1:
    y:
      2:
        z:
          3: 2



Test 2
B_____
x:
  1:
    y:
      2:
        z:
          3: 3
Z_____
3: 3
A_____
x:
  1:
    y:
      2:
        z:
          3: 3



Test 3
C_____
x:
  1:
    y:
      2:
        z:
          3: 3
A_____
x:
  1:
    y:
      2:
        z:
          3: 3
a == c: 0
z == a["x"][1]["y"][2]["z"]: 1

In test 1, modifying z also modifies the value of a["x"][1]["y"][2]["z"], and similarly in test 2, modifying b is equivalent to modifying a. Are these copy semantics considered part of the API (i.e. are they likely to change in the future)? I'd like to be able to write code such as z = getZ(), and have getZ() return a["x"][1]["y"][2]["z"] (the names for "x", "y", and "z" might change in the future). Modifying z would then modify a as shown in the example.

Also though, is there a way to get a clone of a into a new object b so that modifying b does not also modify a?

In test3, the values in c are the same as those in a. Is there some way to do a.equals(c) for YAML::Node objects in general to test if the values in the two nodes are all the same? In the example, a.equals(c) would be true.

Was it helpful?

Solution

To deep-copy a node:

YAML::Node node = /* ... */;
YAML::Node other = Clone(node);

(This is now implemented; you can see the old bug report.)

The current behavior is intended (in other words, the typical "copy" is just setting identity), and will not change.

As for equality, that's a very difficult problem, in general, for YAML. There's some discussion on this issue on the yaml-cpp project page.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top