Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add backport of std::variant #59

Merged
merged 28 commits into from May 1, 2020
Merged

Conversation

rnburn
Copy link
Contributor

@rnburn rnburn commented Apr 3, 2020

Will be used for AttributeValue and various parts of the SDK

Based off of https://github.com/mpark/variant which derives from libc++'s std::variant implementation

virtual const char *what() const noexcept override { return "bad_variant_access"; }
};

[[noreturn]] inline void throw_bad_variant_access()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code unconditionally uses [[noreturn]] here, which means it does require C++11 as a minimum. So in the other spot you also don't have to check for codecvt presence, it's just gonna be there... OR you'd need a compiler-version check here OR not use [[noreturn]] attribute at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C++11 isn't all or nothing.

Older compilers have support for parts of it.

This code should be portable. It's taken from https://github.com/mpark/variant and tested against a range of older compilers
https://github.com/mpark/variant#requirements

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant to say that the [[noreturn]] is part of C++11. Same with codecvt . If one place of code (here) unconditionally requires a feature that only officially exists in C++11, then we may as well require the other parts of code to freely use C++11 features too without performing any extra checks..

Otherwise we'd try to support older compilers that may have only partial support of that. Then, why not supporting vs2013, and that'd be a problem for heavily templated code and many expressions (like constexpr, static initializers, etc.). We probably just have to say that we only support compilers that have "good" (near-complete) support of C++11 and above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gcc 4.8 is still widely used and support most of C++11, but not codecvt. But why worry about this when it's easy to work around.

Copy link
Contributor

@pyohannes pyohannes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this approach. I'm not exactly sure how to handle homogeneous arrays with variants though.

api/test/nostd/BUILD Show resolved Hide resolved
static_assert(0 < sizeof...(Ts), "variant must consist of at least one alternative.");

static_assert(detail::all<!std::is_array<Ts>::value...>::value,
"variant can not have an array type as an alternative.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the spec, attribute values can be homogeneous arrays. I'm not sure how to best handle this with the variant approach.

Also, I expect attribute array values to be a problem for a bunch of vendors, but that's a different story.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arrays of primitives could be supported with something like

using AttributeValue = nostd::variant<
  int,
  double,
  nostd::string_view,
  nostd::span<int>,
  nostd::span<double>,
  nostd::span<nostd::string_view>
>;

Copy link
Contributor Author

@rnburn rnburn Apr 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added support for arrays of primitives. There's an example here

@g-easy
Copy link
Contributor

g-easy commented Apr 20, 2020

This seems a bit excessive. 22 files and adding a new license. In opencensus-cpp, we have an AttributeValue with 3 constructors and call it a day.

@rnburn
Copy link
Contributor Author

rnburn commented Apr 20, 2020

@g-easy But there are definite advantages to a variant approach

  • It has the same familiar interface and semantics you'd get from std::variant
  • The maintenance cost of adding additional types is very low (accessors, constructors, etc are all generated for you).
  • It can be reused in other places where you'd want a sum type.

One-off variant approaches like opencensus's AttributeValueRef have a maintenance cost you have to pay any time you want to include an additional type and get especially more complicated if you want to include a type with a non-trivial destructor.

@maxgolov
Copy link
Contributor

maxgolov commented Apr 27, 2020

I'm approving this.

My feedback:

  • first of all I absolutely agree with you that we do need a variant type with similar semantics, maybe we should not settle on this one? It's still great to have it in there. So we can benchmark and compare with other implementation.
  • whatever we can come up with may reuse the same API, maybe a different implementation?
  • others would ask the same question about boost license, which they'd end up needing to include in the list of their "3rd party licenses" while building a commercial product. Several products in my experience are avoiding boost entirely, implementation, license-wise, etc.
  • can we consider a provision where a nostd :: variant can be replaced by std :: variant in those frameworks where C++17 available? i.e. some form of type substitution. That way somebody compiling this from source with Visual Studio in 15.0 (/std:c++latest) or latest clang, for example, do not have to take a dependency on this implementation and the boost license requirement.

I logged a separate issue on this #67

Copy link
Contributor

@maxgolov maxgolov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved with comments above.

Copy link
Contributor

@pyohannes pyohannes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Approved pending the open license question.

@rnburn rnburn merged commit 176966a into open-telemetry:master May 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants