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

adds isTag function to std.meta #11895

Merged
merged 6 commits into from
Oct 15, 2022
Merged

Conversation

ityonemo
Copy link
Contributor

This PR adds a runtime function called isTag to std.meta; This function returns a bool that reflects if the enum or tagged union corresponds to the tag name, which is a comptime string. Although using the actual tag enum value is generally preferable, in some cases (such as FFI) easy access to the string representation is desirable.

As indicated in the documentation, this function runs in constant time, regardless of the size of the enum/union or the length of the string representations of the tag name.

I can also provide tests against the compile-time checks if desired.

@rohlem
Copy link
Contributor

rohlem commented Jun 20, 2022

Just a suggestion, you can get rid of the inline for loop at compile time.
In particular, you can query if an Enum tag exists using the builtin @hasField,
and access that tag by comptime string using the builtin @field.

If we forewent the explicit compile errors, the implementation could use only the latter, and look like the following (untested):

pub fn isTag(tagged_value: anytype, comptime tag_name: []const u8) bool {
  const T = @TypeOf(tagged_value);

  const Enum = switch(@typeInfo(T)){
    else => @compileError("unsupported type, neither enum nor (tagged) union"), 
    .Enum => T,
    .Union => |U| ..., //get its tag type
  };

  return tagged_value == @field(Enum, tag_name);
}

If the tag doesn't exist the compile error generated by @field should already be something like "type T has no field 'abcd'", so even the @hasField check isn't strictly necessary I think.

@ityonemo
Copy link
Contributor Author

love it! Doing a bit of reworking

@andrewrk andrewrk merged commit 99c3578 into ziglang:master Oct 15, 2022
@InKryption
Copy link
Contributor

What is the difference between this and foo == .bar exactly?

@nektro
Copy link
Contributor

nektro commented Oct 15, 2022

this is entirely defeated with std.mem.eql(u8, @tagName(tagged_value), tag_name))

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.

5 participants