1#![cfg_attr(feature = "const_fn", feature(const_fn))]
2#![no_std]
3
4#[macro_export]
42macro_rules! const_ft {
43 (pub fn $fn_name:ident($($arg:ident : $typ:ty),*) $body: block ) => {
44 #[cfg(feature = "const_fn")]
45 pub const fn $fn_name($($arg : $typ,)*) $body
46
47 #[cfg(not(feature = "const_fn"))]
48 pub fn $fn_name($($arg : $typ,)*) $body
49 };
50 (pub fn $fn_name:ident($($arg:ident : $typ:ty),*) -> $ret: ty $body: block ) => {
51 #[cfg(feature = "const_fn")]
52 pub const fn $fn_name($($arg : $typ,)*) -> $ret $body
53
54 #[cfg(not(feature = "const_fn"))]
55 pub fn $fn_name($($arg : $typ,)*) -> $ret $body
56 };
57
58 (fn $fn_name:ident($($arg:ident : $typ:ty),*) -> $ret: ty $body: block ) => {
59 #[cfg(feature = "const_fn")]
60 const fn $fn_name($($arg : $typ,)*) -> $ret $body
61
62 #[cfg(not(feature = "const_fn"))]
63 fn $fn_name($($arg : $typ,)*) -> $ret $body
64 };
65
66 (fn $fn_name:ident($($arg:ident : $typ:ty),*) $body: block ) => {
67 #[cfg(feature = "const_fn")]
68 const fn $fn_name($($arg : $typ,)*) $body
69
70 #[cfg(not(feature = "const_fn"))]
71 fn $fn_name($($arg : $typ,)*) $body
72 };
73
74 (pub($scope:ident) fn $fn_name:ident($($arg:ident : $typ:ty),*) -> $ret:ty $body:block ) => {
75 #[cfg(feature = "const_fn")]
76 pub($scope) const fn $fn_name($($arg : $typ,)*) -> $ret $body
77
78 #[cfg(not(feature = "const_fn"))]
79 pub($scope) fn $fn_name($($arg : $typ,)*) -> $ret $body
80 };
81
82 (pub($scope:ident) fn $fn_name:ident($($arg:ident : $typ:ty),*) $body:block ) => {
83 #[cfg(feature = "const_fn")]
84 pub($scope) const fn $fn_name($($arg : $typ,)*) $body
85
86 #[cfg(not(feature = "const_fn"))]
87 pub($scope) fn $fn_name($($arg : $typ,)*) $body
88 };
89
90 (fn $fn_name:ident( $self_:ident, $($arg:ident : $typ:ty),*) $body: block ) => {
91 #[cfg(feature = "const_fn")]
92 pub const fn $fn_name($self_:ident, $($arg : $typ,)*) $body
93
94 #[cfg(not(feature = "const_fn"))]
95 pub fn $fn_name($self_:ident, $($arg : $typ,)*) $body
96 };
97 (fn $fn_name:ident($self_:ident, $($arg:ident : $typ:ty),*) -> $ret: ty $body: block ) => {
98 #[cfg(feature = "const_fn")]
99 pub const fn $fn_name($self_, $($arg : $typ,)*) -> $ret $body
100
101 #[cfg(not(feature = "const_fn"))]
102 pub fn $fn_name($self_, $($arg : $typ,)*) -> $ret $body
103 };
104
105 (pub fn $fn_name:ident(&$self_: ident, $($arg:ident : $typ:ty),*) -> $ret: ty $body: block ) => {
106 #[cfg(feature = "const_fn")]
107 pub const fn $fn_name(&$self_, $($arg : $typ,)*) -> $ret $body
108
109 #[cfg(not(feature = "const_fn"))]
110 pub fn $fn_name(&$self_, $($arg : $typ,)*) -> $ret $body
111 };
112
113 (pub fn $fn_name:ident(&$self_: ident, $($arg:ident : $typ:ty),*) -> $body: block ) => {
114 #[cfg(feature = "const_fn")]
115 pub const fn $fn_name(&$self_, $($arg : $typ,)*) $body
116
117 #[cfg(not(feature = "const_fn"))]
118 pub fn $fn_name(&$self_, $($arg : $typ,)*) $body
119 };
120
121 (pub fn $fn_name:ident(&$self_: ident) -> $ret: ty $body: block ) => {
122 #[cfg(feature = "const_fn")]
123 pub const fn $fn_name(&$self_) -> $ret $body
124
125 #[cfg(not(feature = "const_fn"))]
126 pub fn $fn_name(&$self_) -> $ret $body
127 };
128
129 (pub fn $fn_name:ident(&$self_: ident) -> $body: block ) => {
130 #[cfg(feature = "const_fn")]
131 pub const fn $fn_name(&$self_) $body
132
133 #[cfg(not(feature = "const_fn"))]
134 pub fn $fn_name(&$self_) $body
135 };
136
137}
138
139#[cfg(test)]
140mod tests {
141 const_ft! {
142 pub fn public_with_no_args() -> u32 {
143 1u32
144 }
145 }
146
147 const_ft! {
148 pub fn public_with_args(x: u32) -> u32 {
149 x
150 }
151 }
152
153 const_ft! {
154 pub fn public_with_no_return() {}
155 }
156
157 const_ft! {
158 fn private_with_no_args() -> u32 {
159 1u32
160 }
161 }
162
163 const_ft! {
164 fn private_with_args(x: u32, _y: u32) -> u32 {
165 x
166 }
167 }
168
169 const_ft! {
170 fn private_with_no_return(_x: u32) {}
171 }
172
173 const_ft! {
174 pub(crate) fn pub_crate_with_args(x: u32) -> u32 {
175 x
176 }
177 }
178
179 struct Foo(u32);
180 impl Foo {
181 const_ft! {
182 pub fn pub_with_self(&self, _x: u32) -> u32 {
183 self.0
184 }
185 }
186
187 const_ft! {
188 pub fn pub_with_self_and_no_args(&self) -> u32 {
189 self.0
190 }
191 }
192 }
193
194 #[test]
195 pub fn it_works() {
196 assert_eq!(public_with_no_args(), 1u32);
197 assert_eq!(public_with_args(1u32), 1u32);
198 assert_eq!(private_with_no_args(), 1u32);
199 assert_eq!(private_with_args(1u32, 2u32), 1u32);
200 assert_eq!(pub_crate_with_args(1u32), 1u32);
201
202 public_with_no_return();
203 private_with_no_return(1u32);
204
205 let foo = Foo(1u32);
206 assert_eq!(foo.pub_with_self(1u32), 1u32);
207 assert_eq!(foo.pub_with_self_and_no_args(), 1u32);
208 }
209}