Skip to content

P3385 #102

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

Closed
wants to merge 38 commits into from
Closed

P3385 #102

wants to merge 38 commits into from

Conversation

zebullax
Copy link

@zebullax zebullax commented Oct 13, 2024

Proposal

Disclaimer

⚠️ This is a hacky experimentation to survey implementation feasibility...
It goes down happy paths so YMMV, 🟢 stands for This work in a controlled environment, probably break in a lot of cases

Status

Feature Status Comment
^^[[nodiscard]]; 🟢
std::meta::has_identifier(r) 🟢
std::meta::is_attribute(r) 🟢
std::meta::identifier_of(r) 🟢
std::meta::attributes_of(r) 🟢
[[ [: r :] ]] 🟠 Supports r reflecting a std attribute, a type
argument 🟠 Supports string litteral for [[nodiscard]], [[deprecated]]
data_member_options_t.attributes 🗑️ Descoped away from 3385

Note
Attribute argument support is experimental, only string literal is supported for standard attribute

constexpr auto r = ^^[[nodiscard("keep me")]];
struct [[ [: r :] ]] s {}; // Arg is preserved here

Test

Throwaway smoke test ( really it will mostly not compile if tests don't pass...)

#include <experimental/meta>
#include <string>
#include <iostream>
#include <utility>

// Helpers
struct Witness {
  int nodiscard;
  int maybe_unused;
  int deprecated;
};

struct [[nodiscard("yep"), deprecated("dont use me")]] Foo {};

consteval auto member_named(std::string_view name) {
  for (std::meta::info field : nonstatic_data_members_of(^^Witness)) {
    if (has_identifier(field) && identifier_of(field) == name)
      return field;
  }
  std::unreachable();
}

// Test fragments
consteval bool testHasIdentifier() {
  constexpr auto attr = ^^[[nodiscard]];
  return std::meta::has_identifier(attr);
}

consteval bool testIsAttribute() {
  constexpr auto attr = ^^[[nodiscard]];
  return std::meta::is_attribute(attr);
}

consteval bool testIdentifierOf() {
  constexpr auto attr = ^^[[deprecated]];
  Witness s{0, 0, 0};
  s.[: member_named(std::meta::identifier_of(attr)) :]++;
  return s.deprecated == 1;
}

consteval bool testAttributesOfAttr() {
  return std::meta::identifier_of(std::meta::attributes_of(^^[[nodiscard]])[0]) == "nodiscard"
    && std::meta::attributes_of(^^[[nodiscard]]).size() == 1;
}

consteval bool testAttributesOfType() {
  static_assert(std::meta::attributes_of(^^Foo).size() == 2);
  Witness s{0, 0, 0};
    s.[: member_named(std::meta::identifier_of(std::meta::attributes_of(^^Foo)[0])) :]++;
    s.[: member_named(std::meta::identifier_of(std::meta::attributes_of(^^Foo)[1])) :]++;

    return s.nodiscard == 1 && s.maybe_unused == 0 && s.deprecated == 1;
}

consteval bool testSplicingAttr() {
  constexpr auto r = ^^[[deprecated]];
  struct [[ [: r :] ]] Type;
  return std::meta::identifier_of(std::meta::attributes_of(^^Type)[0]) == "deprecated";
}

consteval bool testSplicingType() {
  constexpr auto r = ^^Foo;
  enum class [[ [: r :] ]] Error {
    e_Fatal
  };
  Error error; // This is to test diagnostic to console
  // `main.cpp:66:3: warning: 'Error' is deprecated: dont use me [-Wdeprecated-declarations]`
  return std::meta::identifier_of(std::meta::attributes_of(^^Error)[0]) == "nodiscard"
      && std::meta::identifier_of(std::meta::attributes_of(^^Error)[1]) == "deprecated";
}

// Smoke test
int main(int, char**) {

  static_assert(testIsAttribute(), "Fail ^^[[ ]]");
  static_assert(testHasIdentifier(), "Fail std::meta::has_identifier");
  static_assert(testIdentifierOf(), "Fail std::meta::identifiers_of");
  static_assert(testAttributesOfAttr() , "Fail std::meta::attributes_of(^^[[ ]])");
  static_assert(testAttributesOfType() , "Fail std::meta::attributes_of(^^MyType)");
  static_assert(testSplicingAttr() , "Fail [[ [: ^attr :] ]]");
  static_assert(testSplicingType() , "Fail [[ [: ^type :] ]]");

  return 0;
}

@zebullax zebullax changed the title [WIP] P3385 P3385 Oct 13, 2024
@katzdm katzdm force-pushed the p2996 branch 2 times, most recently from 3cc9fcd to 4ffd254 Compare April 11, 2025 21:17
* Stash custom attribute attached to spliced attr

Signed-off-by: zebullon <[email protected]>

* Recover custom attribute during function inst and run substitution

Signed-off-by: zebullon <[email protected]>

* Fix regression on arg

Signed-off-by: zebullon <[email protected]>

* Resolve delayed splice attribute on attribute instantiation

Signed-off-by: zebullon <[email protected]>

---------

Signed-off-by: zebullon <[email protected]>
Co-authored-by: zebullon <[email protected]>
@zebullax zebullax force-pushed the p3385 branch 3 times, most recently from 3e3b707 to 156110a Compare April 20, 2025 12:13
@zebullax zebullax force-pushed the p3385 branch 2 times, most recently from 2735b44 to 156110a Compare May 25, 2025 03:33
@zebullax zebullax closed this May 25, 2025
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.

2 participants