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

Ell
  • 4,238
  • 6
  • 34
  • 60

1 Answers1

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.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • 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 yet – Ell Sep 28 '13 at 15:38
  • 1
    @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, Map>::type Object;` would work just fine. – Matthieu M. Sep 28 '13 at 15:50
  • 1
    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! – Ell Sep 28 '13 at 16:04
  • @Ell: you don't have to be sorry about it :) – Matthieu M. Sep 28 '13 at 16:45
  • How to get data from this `int_tree_t` object? I expected something like `boost::get(boost::get>(var)[0])` to return 1, but it does not compile because `boost::get` is not defined for recursive variants. – Anton K Sep 28 '17 at 15:19
  • 1
    @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. – Matthieu M. Sep 28 '17 at 15:21
  • @MatthieuM. It actually works, I have misunderstanded error message, it's quite long :) Here is an example: http://paste.org.ru/?jvz4ar – Anton K Sep 28 '17 at 15:48