C++ Mutually Recursive Variant Type
Asked Answered
F

1

4

I am trying to represent a PDF object type in c++ using variants. A PDF object is one of the following:

  • Boolean
  • Integer
  • Real
  • String
  • Name
  • Stream
  • Array<Object>
  • Map<Object, Object>

As you can see, the Object type is mutually recursive because the Array type would require a declaration of the Map type which would require a declaration of the Array type. How could I go abouts representing this type in c++? If a variant isn't the best way, what is?

Here is what I have tried so far but it doesn't compile because of the requirements of std::unordered_map (I think) http://coliru.stacked-crooked.com/a/699082582e73376e

Fernferna answered 28/9, 2013 at 12:26 Comment(0)
U
5

Since you are using boost::variant, what is wrong about using its recursive wrappers ?

You can see a short example in the tutorial:

typedef boost::make_recursive_variant<
      int
    , std::vector< boost::recursive_variant_ >
    >::type int_tree_t;

std::vector< int_tree_t > subresult;
subresult.push_back(3);
subresult.push_back(5);

std::vector< int_tree_t > result;
result.push_back(1);
result.push_back(subresult);
result.push_back(7);

int_tree_t var(result);

And it works as expected.

Underbody answered 28/9, 2013 at 15:6 Comment(7)
The problem is that there is mutual recursion between the array and dictionary types. This example only shows how to nest an int_tree_t in a variant of itself, however I need to refer to a typedef which hasn't been defined yetFernferna
@Ell: I do not see such recursion. Both refer to Object, which is (I guess) the variant you are defining, but I would think that typedef boost::make_recursive_variant<Boolean, Integer, ..., Array<boost::recursive_variant_>, Map<boost::recursive_variant_, boost::recursive_variant_>>::type Object; would work just fine.Underbody
Ahh of course. I'm sorry, I didn't see how I could use that, but of course I just don't need the typedef. Thank you very much and my apologies for not seeing that this is the solution the first time!Fernferna
@Ell: you don't have to be sorry about it :)Underbody
How to get data from this int_tree_t object? I expected something like boost::get<int>(boost::get<std::vector<int_tree_t>>(var)[0]) to return 1, but it does not compile because boost::get is not defined for recursive variants.Broccoli
@AntonK: I am surprised that get does not work. In this case I suppose that you will have to switch to the visitor-based approach.Underbody
@MatthieuM. It actually works, I have misunderstanded error message, it's quite long :) Here is an example: paste.org.ru/?jvz4arBroccoli

© 2022 - 2024 — McMap. All rights reserved.