apiaryio / drafter

API Blueprint Parser (C++)
https://apiblueprint.org/
MIT License
302 stars 54 forks source link

Use variant for mson::Element #726

Closed tjanc closed 5 years ago

tjanc commented 5 years ago

Refactors mson::Element to use variant instead of a structure containing members for every type that could be stored in it. There are at least three more opportunities for improvement like this in MSON.h to be refactored in the future, matching this PR.

Principle

Let's say there is structure Content that can hold either Foo or Bar (but never both, i.e. a Σ-type). Currently, we use something like:

enum ContentKlass { UndefinedKlass, FooKlass, BarKlass };
struct Content {
  ContentKlass klass;
  Foo foo;
  Bar bar;
};

Much better, we can write:

class Content {
  std::variant<std::monostate, Foo, Bar> content;
public:
  const auto& foo() const noexcept { return std::get<Foo>(content); }
  const auto& bar() const noexcept { return std::get<Foo>(content); }
  template<typename F> void visit(F&& f) {
    std::visit(std::forward<F>(f), content);
  }
};

Benefits

pksunkara commented 5 years ago

Looks good to me.