Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to name an arbitrary sequence of things in a macro?

Tags:

macros

rust

I am trying to use ? in a macro, matching an arbitrary keyword:

#![feature(macro_at_most_once_rep)]

macro_rules! foo {
    (
        pub fn $name:ident (
            & $m : $( mut )? self
        )
    ) => (
        pub fn $name (
            & $m self
        ) {}
    )
}

struct Foo;

impl Foo {
    foo!( pub fn bar(&mut self) );
    foo!( pub fn baz(&self) );
}

fn main() {}

I tried varied syntax, but they all failed. How to do this?

like image 916
Boiethios Avatar asked Mar 05 '18 17:03

Boiethios


People also ask

What is the correct format for naming a macro with multiple arguments?

To create a macro with arguments, put them in parentheses separated by commas after the macro name, e.g. then BadSquare(3+4) would give 3+4*3+4, which evaluates to 19, which is probably not what we intended.

What are keyword macro parameters?

Keyword parameters are symbolic parameters that can be specified in any order when the macro is called. The parameter will be replaced within the macro body by the value specified when the macro is called. These parameters can be given a default value.

Can macro names contain numbers?

Macro names should only consist of alphanumeric characters and underscores, i.e. 'a-z' , 'A-Z' , '0-9' , and '_' , and the first character should not be a digit.

What is __ Va_opt __?

The key to making this work is a new pre-processor feature in C++20, __VA_OPT__(x) , which expands to x when a variable-argument macro has more than zero arguments and to nothing otherwise.


1 Answers

One trick would be to insert a repetition with a dummy token.

#![feature(macro_at_most_once_rep)]

macro_rules! foo {
    (
        pub fn $name:ident (
            & $( $(@$m:tt)* mut )? self
        )
    ) => (
        pub fn $name (
            & $( $(@$m)* mut )? self
        ) {}
    )
}

struct Foo;

impl Foo {
    foo!( pub fn bar(&mut self) );
    foo!( pub fn baz(&self) );
}

fn main() {
    (&mut Foo).bar();
    (&mut Foo).baz();
    // (&Foo).bar(); //~ERROR cannot borrow
    (&Foo).baz();
}
like image 113
Masaki Hara Avatar answered Oct 08 '22 07:10

Masaki Hara