1 | macro_rules! doc { |
2 | ($select:item) => { |
3 | /// Waits on multiple concurrent branches, returning when the **first** branch |
4 | /// completes, cancelling the remaining branches. |
5 | /// |
6 | /// The `select!` macro must be used inside of async functions, closures, and |
7 | /// blocks. |
8 | /// |
9 | /// The `select!` macro accepts one or more branches with the following pattern: |
10 | /// |
11 | /// ```text |
12 | /// <pattern> = <async expression> (, if <precondition>)? => <handler>, |
13 | /// ``` |
14 | /// |
15 | /// Additionally, the `select!` macro may include a single, optional `else` |
16 | /// branch, which evaluates if none of the other branches match their patterns: |
17 | /// |
18 | /// ```text |
19 | /// else => <expression> |
20 | /// ``` |
21 | /// |
22 | /// The macro aggregates all `<async expression>` expressions and runs them |
23 | /// concurrently on the **current** task. Once the **first** expression |
24 | /// completes with a value that matches its `<pattern>`, the `select!` macro |
25 | /// returns the result of evaluating the completed branch's `<handler>` |
26 | /// expression. |
27 | /// |
28 | /// Additionally, each branch may include an optional `if` precondition. If the |
29 | /// precondition returns `false`, then the branch is disabled. The provided |
30 | /// `<async expression>` is still evaluated but the resulting future is never |
31 | /// polled. This capability is useful when using `select!` within a loop. |
32 | /// |
33 | /// The complete lifecycle of a `select!` expression is as follows: |
34 | /// |
35 | /// 1. Evaluate all provided `<precondition>` expressions. If the precondition |
36 | /// returns `false`, disable the branch for the remainder of the current call |
37 | /// to `select!`. Re-entering `select!` due to a loop clears the "disabled" |
38 | /// state. |
39 | /// 2. Aggregate the `<async expression>`s from each branch, including the |
40 | /// disabled ones. If the branch is disabled, `<async expression>` is still |
41 | /// evaluated, but the resulting future is not polled. |
42 | /// 3. If **all** branches are disabled: go to step 6. |
43 | /// 4. Concurrently await on the results for all remaining `<async expression>`s. |
44 | /// 5. Once an `<async expression>` returns a value, attempt to apply the value to the |
45 | /// provided `<pattern>`. If the pattern matches, evaluate the `<handler>` and return. |
46 | /// If the pattern **does not** match, disable the current branch for the remainder of |
47 | /// the current call to `select!`. Continue from step 3. |
48 | /// 6. Evaluate the `else` expression. If no else expression is provided, panic. |
49 | /// |
50 | /// # Runtime characteristics |
51 | /// |
52 | /// By running all async expressions on the current task, the expressions are |
53 | /// able to run **concurrently** but not in **parallel**. This means all |
54 | /// expressions are run on the same thread and if one branch blocks the thread, |
55 | /// all other expressions will be unable to continue. If parallelism is |
56 | /// required, spawn each async expression using [`tokio::spawn`] and pass the |
57 | /// join handle to `select!`. |
58 | /// |
59 | /// [`tokio::spawn`]: crate::spawn |
60 | /// |
61 | /// # Fairness |
62 | /// |
63 | /// By default, `select!` randomly picks a branch to check first. This provides |
64 | /// some level of fairness when calling `select!` in a loop with branches that |
65 | /// are always ready. |
66 | /// |
67 | /// This behavior can be overridden by adding `biased;` to the beginning of the |
68 | /// macro usage. See the examples for details. This will cause `select` to poll |
69 | /// the futures in the order they appear from top to bottom. There are a few |
70 | /// reasons you may want this: |
71 | /// |
72 | /// - The random number generation of `tokio::select!` has a non-zero CPU cost |
73 | /// - Your futures may interact in a way where known polling order is significant |
74 | /// |
75 | /// But there is an important caveat to this mode. It becomes your responsibility |
76 | /// to ensure that the polling order of your futures is fair. If for example you |
77 | /// are selecting between a stream and a shutdown future, and the stream has a |
78 | /// huge volume of messages and zero or nearly zero time between them, you should |
79 | /// place the shutdown future earlier in the `select!` list to ensure that it is |
80 | /// always polled, and will not be ignored due to the stream being constantly |
81 | /// ready. |
82 | /// |
83 | /// # Panics |
84 | /// |
85 | /// The `select!` macro panics if all branches are disabled **and** there is no |
86 | /// provided `else` branch. A branch is disabled when the provided `if` |
87 | /// precondition returns `false` **or** when the pattern does not match the |
88 | /// result of `<async expression>`. |
89 | /// |
90 | /// # Cancellation safety |
91 | /// |
92 | /// When using `select!` in a loop to receive messages from multiple sources, |
93 | /// you should make sure that the receive call is cancellation safe to avoid |
94 | /// losing messages. This section goes through various common methods and |
95 | /// describes whether they are cancel safe. The lists in this section are not |
96 | /// exhaustive. |
97 | /// |
98 | /// The following methods are cancellation safe: |
99 | /// |
100 | /// * [`tokio::sync::mpsc::Receiver::recv`](crate::sync::mpsc::Receiver::recv) |
101 | /// * [`tokio::sync::mpsc::UnboundedReceiver::recv`](crate::sync::mpsc::UnboundedReceiver::recv) |
102 | /// * [`tokio::sync::broadcast::Receiver::recv`](crate::sync::broadcast::Receiver::recv) |
103 | /// * [`tokio::sync::watch::Receiver::changed`](crate::sync::watch::Receiver::changed) |
104 | /// * [`tokio::net::TcpListener::accept`](crate::net::TcpListener::accept) |
105 | /// * [`tokio::net::UnixListener::accept`](crate::net::UnixListener::accept) |
106 | /// * [`tokio::signal::unix::Signal::recv`](crate::signal::unix::Signal::recv) |
107 | /// * [`tokio::io::AsyncReadExt::read`](crate::io::AsyncReadExt::read) on any `AsyncRead` |
108 | /// * [`tokio::io::AsyncReadExt::read_buf`](crate::io::AsyncReadExt::read_buf) on any `AsyncRead` |
109 | /// * [`tokio::io::AsyncWriteExt::write`](crate::io::AsyncWriteExt::write) on any `AsyncWrite` |
110 | /// * [`tokio::io::AsyncWriteExt::write_buf`](crate::io::AsyncWriteExt::write_buf) on any `AsyncWrite` |
111 | /// * [`tokio_stream::StreamExt::next`](https://docs.rs/tokio-stream/0.1/tokio_stream/trait.StreamExt.html#method.next) on any `Stream` |
112 | /// * [`futures::stream::StreamExt::next`](https://docs.rs/futures/0.3/futures/stream/trait.StreamExt.html#method.next) on any `Stream` |
113 | /// |
114 | /// The following methods are not cancellation safe and can lead to loss of data: |
115 | /// |
116 | /// * [`tokio::io::AsyncReadExt::read_exact`](crate::io::AsyncReadExt::read_exact) |
117 | /// * [`tokio::io::AsyncReadExt::read_to_end`](crate::io::AsyncReadExt::read_to_end) |
118 | /// * [`tokio::io::AsyncReadExt::read_to_string`](crate::io::AsyncReadExt::read_to_string) |
119 | /// * [`tokio::io::AsyncWriteExt::write_all`](crate::io::AsyncWriteExt::write_all) |
120 | /// |
121 | /// The following methods are not cancellation safe because they use a queue for |
122 | /// fairness and cancellation makes you lose your place in the queue: |
123 | /// |
124 | /// * [`tokio::sync::Mutex::lock`](crate::sync::Mutex::lock) |
125 | /// * [`tokio::sync::RwLock::read`](crate::sync::RwLock::read) |
126 | /// * [`tokio::sync::RwLock::write`](crate::sync::RwLock::write) |
127 | /// * [`tokio::sync::Semaphore::acquire`](crate::sync::Semaphore::acquire) |
128 | /// * [`tokio::sync::Notify::notified`](crate::sync::Notify::notified) |
129 | /// |
130 | /// To determine whether your own methods are cancellation safe, look for the |
131 | /// location of uses of `.await`. This is because when an asynchronous method is |
132 | /// cancelled, that always happens at an `.await`. If your function behaves |
133 | /// correctly even if it is restarted while waiting at an `.await`, then it is |
134 | /// cancellation safe. |
135 | /// |
136 | /// Cancellation safety can be defined in the following way: If you have a |
137 | /// future that has not yet completed, then it must be a no-op to drop that |
138 | /// future and recreate it. This definition is motivated by the situation where |
139 | /// a `select!` is used in a loop. Without this guarantee, you would lose your |
140 | /// progress when another branch completes and you restart the `select!` by |
141 | /// going around the loop. |
142 | /// |
143 | /// Be aware that cancelling something that is not cancellation safe is not |
144 | /// necessarily wrong. For example, if you are cancelling a task because the |
145 | /// application is shutting down, then you probably don't care that partially |
146 | /// read data is lost. |
147 | /// |
148 | /// # Examples |
149 | /// |
150 | /// Basic select with two branches. |
151 | /// |
152 | /// ``` |
153 | /// async fn do_stuff_async() { |
154 | /// // async work |
155 | /// } |
156 | /// |
157 | /// async fn more_async_work() { |
158 | /// // more here |
159 | /// } |
160 | /// |
161 | /// #[tokio::main] |
162 | /// async fn main() { |
163 | /// tokio::select! { |
164 | /// _ = do_stuff_async() => { |
165 | /// println!("do_stuff_async() completed first") |
166 | /// } |
167 | /// _ = more_async_work() => { |
168 | /// println!("more_async_work() completed first") |
169 | /// } |
170 | /// }; |
171 | /// } |
172 | /// ``` |
173 | /// |
174 | /// Basic stream selecting. |
175 | /// |
176 | /// ``` |
177 | /// use tokio_stream::{self as stream, StreamExt}; |
178 | /// |
179 | /// #[tokio::main] |
180 | /// async fn main() { |
181 | /// let mut stream1 = stream::iter(vec![1, 2, 3]); |
182 | /// let mut stream2 = stream::iter(vec![4, 5, 6]); |
183 | /// |
184 | /// let next = tokio::select! { |
185 | /// v = stream1.next() => v.unwrap(), |
186 | /// v = stream2.next() => v.unwrap(), |
187 | /// }; |
188 | /// |
189 | /// assert!(next == 1 || next == 4); |
190 | /// } |
191 | /// ``` |
192 | /// |
193 | /// Collect the contents of two streams. In this example, we rely on pattern |
194 | /// matching and the fact that `stream::iter` is "fused", i.e. once the stream |
195 | /// is complete, all calls to `next()` return `None`. |
196 | /// |
197 | /// ``` |
198 | /// use tokio_stream::{self as stream, StreamExt}; |
199 | /// |
200 | /// #[tokio::main] |
201 | /// async fn main() { |
202 | /// let mut stream1 = stream::iter(vec![1, 2, 3]); |
203 | /// let mut stream2 = stream::iter(vec![4, 5, 6]); |
204 | /// |
205 | /// let mut values = vec![]; |
206 | /// |
207 | /// loop { |
208 | /// tokio::select! { |
209 | /// Some(v) = stream1.next() => values.push(v), |
210 | /// Some(v) = stream2.next() => values.push(v), |
211 | /// else => break, |
212 | /// } |
213 | /// } |
214 | /// |
215 | /// values.sort(); |
216 | /// assert_eq!(&[1, 2, 3, 4, 5, 6], &values[..]); |
217 | /// } |
218 | /// ``` |
219 | /// |
220 | /// Using the same future in multiple `select!` expressions can be done by passing |
221 | /// a reference to the future. Doing so requires the future to be [`Unpin`]. A |
222 | /// future can be made [`Unpin`] by either using [`Box::pin`] or stack pinning. |
223 | /// |
224 | /// [`Unpin`]: std::marker::Unpin |
225 | /// [`Box::pin`]: std::boxed::Box::pin |
226 | /// |
227 | /// Here, a stream is consumed for at most 1 second. |
228 | /// |
229 | /// ``` |
230 | /// use tokio_stream::{self as stream, StreamExt}; |
231 | /// use tokio::time::{self, Duration}; |
232 | /// |
233 | /// #[tokio::main] |
234 | /// async fn main() { |
235 | /// let mut stream = stream::iter(vec![1, 2, 3]); |
236 | /// let sleep = time::sleep(Duration::from_secs(1)); |
237 | /// tokio::pin!(sleep); |
238 | /// |
239 | /// loop { |
240 | /// tokio::select! { |
241 | /// maybe_v = stream.next() => { |
242 | /// if let Some(v) = maybe_v { |
243 | /// println!("got = {}", v); |
244 | /// } else { |
245 | /// break; |
246 | /// } |
247 | /// } |
248 | /// _ = &mut sleep => { |
249 | /// println!("timeout"); |
250 | /// break; |
251 | /// } |
252 | /// } |
253 | /// } |
254 | /// } |
255 | /// ``` |
256 | /// |
257 | /// Joining two values using `select!`. |
258 | /// |
259 | /// ``` |
260 | /// use tokio::sync::oneshot; |
261 | /// |
262 | /// #[tokio::main] |
263 | /// async fn main() { |
264 | /// let (tx1, mut rx1) = oneshot::channel(); |
265 | /// let (tx2, mut rx2) = oneshot::channel(); |
266 | /// |
267 | /// tokio::spawn(async move { |
268 | /// tx1.send("first").unwrap(); |
269 | /// }); |
270 | /// |
271 | /// tokio::spawn(async move { |
272 | /// tx2.send("second").unwrap(); |
273 | /// }); |
274 | /// |
275 | /// let mut a = None; |
276 | /// let mut b = None; |
277 | /// |
278 | /// while a.is_none() || b.is_none() { |
279 | /// tokio::select! { |
280 | /// v1 = (&mut rx1), if a.is_none() => a = Some(v1.unwrap()), |
281 | /// v2 = (&mut rx2), if b.is_none() => b = Some(v2.unwrap()), |
282 | /// } |
283 | /// } |
284 | /// |
285 | /// let res = (a.unwrap(), b.unwrap()); |
286 | /// |
287 | /// assert_eq!(res.0, "first"); |
288 | /// assert_eq!(res.1, "second"); |
289 | /// } |
290 | /// ``` |
291 | /// |
292 | /// Using the `biased;` mode to control polling order. |
293 | /// |
294 | /// ``` |
295 | /// #[tokio::main] |
296 | /// async fn main() { |
297 | /// let mut count = 0u8; |
298 | /// |
299 | /// loop { |
300 | /// tokio::select! { |
301 | /// // If you run this example without `biased;`, the polling order is |
302 | /// // pseudo-random, and the assertions on the value of count will |
303 | /// // (probably) fail. |
304 | /// biased; |
305 | /// |
306 | /// _ = async {}, if count < 1 => { |
307 | /// count += 1; |
308 | /// assert_eq!(count, 1); |
309 | /// } |
310 | /// _ = async {}, if count < 2 => { |
311 | /// count += 1; |
312 | /// assert_eq!(count, 2); |
313 | /// } |
314 | /// _ = async {}, if count < 3 => { |
315 | /// count += 1; |
316 | /// assert_eq!(count, 3); |
317 | /// } |
318 | /// _ = async {}, if count < 4 => { |
319 | /// count += 1; |
320 | /// assert_eq!(count, 4); |
321 | /// } |
322 | /// |
323 | /// else => { |
324 | /// break; |
325 | /// } |
326 | /// }; |
327 | /// } |
328 | /// } |
329 | /// ``` |
330 | /// |
331 | /// ## Avoid racy `if` preconditions |
332 | /// |
333 | /// Given that `if` preconditions are used to disable `select!` branches, some |
334 | /// caution must be used to avoid missing values. |
335 | /// |
336 | /// For example, here is **incorrect** usage of `sleep` with `if`. The objective |
337 | /// is to repeatedly run an asynchronous task for up to 50 milliseconds. |
338 | /// However, there is a potential for the `sleep` completion to be missed. |
339 | /// |
340 | /// ```no_run,should_panic |
341 | /// use tokio::time::{self, Duration}; |
342 | /// |
343 | /// async fn some_async_work() { |
344 | /// // do work |
345 | /// } |
346 | /// |
347 | /// #[tokio::main] |
348 | /// async fn main() { |
349 | /// let sleep = time::sleep(Duration::from_millis(50)); |
350 | /// tokio::pin!(sleep); |
351 | /// |
352 | /// while !sleep.is_elapsed() { |
353 | /// tokio::select! { |
354 | /// _ = &mut sleep, if !sleep.is_elapsed() => { |
355 | /// println!("operation timed out"); |
356 | /// } |
357 | /// _ = some_async_work() => { |
358 | /// println!("operation completed"); |
359 | /// } |
360 | /// } |
361 | /// } |
362 | /// |
363 | /// panic!("This example shows how not to do it!"); |
364 | /// } |
365 | /// ``` |
366 | /// |
367 | /// In the above example, `sleep.is_elapsed()` may return `true` even if |
368 | /// `sleep.poll()` never returned `Ready`. This opens up a potential race |
369 | /// condition where `sleep` expires between the `while !sleep.is_elapsed()` |
370 | /// check and the call to `select!` resulting in the `some_async_work()` call to |
371 | /// run uninterrupted despite the sleep having elapsed. |
372 | /// |
373 | /// One way to write the above example without the race would be: |
374 | /// |
375 | /// ``` |
376 | /// use tokio::time::{self, Duration}; |
377 | /// |
378 | /// async fn some_async_work() { |
379 | /// # time::sleep(Duration::from_millis(10)).await; |
380 | /// // do work |
381 | /// } |
382 | /// |
383 | /// #[tokio::main] |
384 | /// async fn main() { |
385 | /// let sleep = time::sleep(Duration::from_millis(50)); |
386 | /// tokio::pin!(sleep); |
387 | /// |
388 | /// loop { |
389 | /// tokio::select! { |
390 | /// _ = &mut sleep => { |
391 | /// println!("operation timed out"); |
392 | /// break; |
393 | /// } |
394 | /// _ = some_async_work() => { |
395 | /// println!("operation completed"); |
396 | /// } |
397 | /// } |
398 | /// } |
399 | /// } |
400 | /// ``` |
401 | /// # Alternatives from the Ecosystem |
402 | /// |
403 | /// The `select!` macro is a powerful tool for managing multiple asynchronous |
404 | /// branches, enabling tasks to run concurrently within the same thread. However, |
405 | /// its use can introduce challenges, particularly around cancellation safety, which |
406 | /// can lead to subtle and hard-to-debug errors. For many use cases, ecosystem |
407 | /// alternatives may be preferable as they mitigate these concerns by offering |
408 | /// clearer syntax, more predictable control flow, and reducing the need to manually |
409 | /// handle issues like fuse semantics or cancellation safety. |
410 | /// |
411 | /// ## Merging Streams |
412 | /// |
413 | /// For cases where `loop { select! { ... } }` is used to poll multiple tasks, |
414 | /// stream merging offers a concise alternative, inherently handle cancellation-safe |
415 | /// processing, removing the risk of data loss. Libraries such as [`tokio_stream`], |
416 | /// [`futures::stream`] and [`futures_concurrency`] provide tools for merging |
417 | /// streams and handling their outputs sequentially. |
418 | /// |
419 | /// [`tokio_stream`]: https://docs.rs/tokio-stream/latest/tokio_stream/ |
420 | /// [`futures::stream`]: https://docs.rs/futures/latest/futures/stream/ |
421 | /// [`futures_concurrency`]: https://docs.rs/futures-concurrency/latest/futures_concurrency/ |
422 | /// |
423 | /// ### Example with `select!` |
424 | /// |
425 | /// ``` |
426 | /// struct File; |
427 | /// struct Channel; |
428 | /// struct Socket; |
429 | /// |
430 | /// impl Socket { |
431 | /// async fn read_packet(&mut self) -> Vec<u8> { |
432 | /// vec![] |
433 | /// } |
434 | /// } |
435 | /// |
436 | /// async fn read_send(_file: &mut File, _channel: &mut Channel) { |
437 | /// // do work that is not cancel safe |
438 | /// } |
439 | /// |
440 | /// #[tokio::main] |
441 | /// async fn main() { |
442 | /// // open our IO types |
443 | /// let mut file = File; |
444 | /// let mut channel = Channel; |
445 | /// let mut socket = Socket; |
446 | /// |
447 | /// loop { |
448 | /// tokio::select! { |
449 | /// _ = read_send(&mut file, &mut channel) => { /* ... */ }, |
450 | /// _data = socket.read_packet() => { /* ... */ } |
451 | /// _ = futures::future::ready(()) => break |
452 | /// } |
453 | /// } |
454 | /// } |
455 | /// |
456 | /// ``` |
457 | /// |
458 | /// ### Moving to `merge` |
459 | /// |
460 | /// By using merge, you can unify multiple asynchronous tasks into a single stream, |
461 | /// eliminating the need to manage tasks manually and reducing the risk of |
462 | /// unintended behavior like data loss. |
463 | /// |
464 | /// ``` |
465 | /// use std::pin::pin; |
466 | /// |
467 | /// use futures::stream::unfold; |
468 | /// use tokio_stream::StreamExt; |
469 | /// |
470 | /// struct File; |
471 | /// struct Channel; |
472 | /// struct Socket; |
473 | /// |
474 | /// impl Socket { |
475 | /// async fn read_packet(&mut self) -> Vec<u8> { |
476 | /// vec![] |
477 | /// } |
478 | /// } |
479 | /// |
480 | /// async fn read_send(_file: &mut File, _channel: &mut Channel) { |
481 | /// // do work that is not cancel safe |
482 | /// } |
483 | /// |
484 | /// enum Message { |
485 | /// Stop, |
486 | /// Sent, |
487 | /// Data(Vec<u8>), |
488 | /// } |
489 | /// |
490 | /// #[tokio::main] |
491 | /// async fn main() { |
492 | /// // open our IO types |
493 | /// let file = File; |
494 | /// let channel = Channel; |
495 | /// let socket = Socket; |
496 | /// |
497 | /// let a = unfold((file, channel), |(mut file, mut channel)| async { |
498 | /// read_send(&mut file, &mut channel).await; |
499 | /// Some((Message::Sent, (file, channel))) |
500 | /// }); |
501 | /// let b = unfold(socket, |mut socket| async { |
502 | /// let data = socket.read_packet().await; |
503 | /// Some((Message::Data(data), socket)) |
504 | /// }); |
505 | /// let c = tokio_stream::iter([Message::Stop]); |
506 | /// |
507 | /// let mut s = pin!(a.merge(b).merge(c)); |
508 | /// while let Some(msg) = s.next().await { |
509 | /// match msg { |
510 | /// Message::Data(_data) => { /* ... */ } |
511 | /// Message::Sent => continue, |
512 | /// Message::Stop => break, |
513 | /// } |
514 | /// } |
515 | /// } |
516 | /// ``` |
517 | /// |
518 | /// ## Racing Futures |
519 | /// |
520 | /// If you need to wait for the first completion among several asynchronous tasks, |
521 | /// ecosystem utilities such as |
522 | /// [`futures`](https://docs.rs/futures/latest/futures/), |
523 | /// [`futures-lite`](https://docs.rs/futures-lite/latest/futures_lite/) or |
524 | /// [`futures-concurrency`](https://docs.rs/futures-concurrency/latest/futures_concurrency/) |
525 | /// provide streamlined syntax for racing futures: |
526 | /// |
527 | /// - [`futures_concurrency::future::Race`](https://docs.rs/futures-concurrency/latest/futures_concurrency/future/trait.Race.html) |
528 | /// - [`futures::select`](https://docs.rs/futures/latest/futures/macro.select.html) |
529 | /// - [`futures::stream::select_all`](https://docs.rs/futures/latest/futures/stream/select_all/index.html) (for streams) |
530 | /// - [`futures_lite::future::or`](https://docs.rs/futures-lite/latest/futures_lite/future/fn.or.html) |
531 | /// - [`futures_lite::future::race`](https://docs.rs/futures-lite/latest/futures_lite/future/fn.race.html) |
532 | /// |
533 | /// ``` |
534 | /// use futures_concurrency::future::Race; |
535 | /// |
536 | /// #[tokio::main] |
537 | /// async fn main() { |
538 | /// let task_a = async { Ok("ok") }; |
539 | /// let task_b = async { Err("error") }; |
540 | /// let result = (task_a, task_b).race().await; |
541 | /// |
542 | /// match result { |
543 | /// Ok(output) => println!("First task completed with: {output}"), |
544 | /// Err(err) => eprintln!("Error occurred: {err}"), |
545 | /// } |
546 | /// } |
547 | /// ``` |
548 | #[macro_export] |
549 | #[cfg_attr(docsrs, doc(cfg(feature = "macros" )))] |
550 | $select |
551 | }; |
552 | } |
553 | |
554 | #[cfg (doc)] |
555 | doc! {macro_rules! select { |
556 | { |
557 | $( |
558 | biased; |
559 | )? |
560 | $( |
561 | $bind:pat = $fut:expr $(, if $cond:expr)? => $handler:expr, |
562 | )* |
563 | $( |
564 | else => $els:expr $(,)? |
565 | )? |
566 | } => { |
567 | unimplemented!() |
568 | }; |
569 | }} |
570 | |
571 | #[cfg (not(doc))] |
572 | doc! {macro_rules! select { |
573 | // Uses a declarative macro to do **most** of the work. While it is possible |
574 | // to implement fully with a declarative macro, a procedural macro is used |
575 | // to enable improved error messages. |
576 | // |
577 | // The macro is structured as a tt-muncher. All branches are processed and |
578 | // normalized. Once the input is normalized, it is passed to the top-most |
579 | // rule. When entering the macro, `@{ }` is inserted at the front. This is |
580 | // used to collect the normalized input. |
581 | // |
582 | // The macro only recurses once per branch. This allows using `select!` |
583 | // without requiring the user to increase the recursion limit. |
584 | |
585 | // All input is normalized, now transform. |
586 | (@ { |
587 | // The index of the future to poll first (in bias mode), or the RNG |
588 | // expression to use to pick a future to poll first. |
589 | start=$start:expr; |
590 | |
591 | // One `_` for each branch in the `select!` macro. Passing this to |
592 | // `count!` converts $skip to an integer. |
593 | ( $($count:tt)* ) |
594 | |
595 | // Normalized select branches. `( $skip )` is a set of `_` characters. |
596 | // There is one `_` for each select branch **before** this one. Given |
597 | // that all input futures are stored in a tuple, $skip is useful for |
598 | // generating a pattern to reference the future for the current branch. |
599 | // $skip is also used as an argument to `count!`, returning the index of |
600 | // the current select branch. |
601 | $( ( $($skip:tt)* ) $bind:pat = $fut:expr, if $c:expr => $handle:expr, )+ |
602 | |
603 | // Fallback expression used when all select branches have been disabled. |
604 | ; $else:expr |
605 | |
606 | }) => {{ |
607 | // Enter a context where stable "function-like" proc macros can be used. |
608 | // |
609 | // This module is defined within a scope and should not leak out of this |
610 | // macro. |
611 | #[doc(hidden)] |
612 | mod __tokio_select_util { |
613 | // Generate an enum with one variant per select branch |
614 | $crate::select_priv_declare_output_enum!( ( $($count)* ) ); |
615 | } |
616 | |
617 | // `tokio::macros::support` is a public, but doc(hidden) module |
618 | // including a re-export of all types needed by this macro. |
619 | use $crate::macros::support::Future; |
620 | use $crate::macros::support::Pin; |
621 | use $crate::macros::support::Poll::{Ready, Pending}; |
622 | |
623 | const BRANCHES: u32 = $crate::count!( $($count)* ); |
624 | |
625 | let mut disabled: __tokio_select_util::Mask = Default::default(); |
626 | |
627 | // First, invoke all the pre-conditions. For any that return true, |
628 | // set the appropriate bit in `disabled`. |
629 | $( |
630 | if !$c { |
631 | let mask: __tokio_select_util::Mask = 1 << $crate::count!( $($skip)* ); |
632 | disabled |= mask; |
633 | } |
634 | )* |
635 | |
636 | // Create a scope to separate polling from handling the output. This |
637 | // adds borrow checker flexibility when using the macro. |
638 | let mut output = { |
639 | // Store each future directly first (that is, without wrapping the future in a call to |
640 | // `IntoFuture::into_future`). This allows the `$fut` expression to make use of |
641 | // temporary lifetime extension. |
642 | // |
643 | // https://doc.rust-lang.org/1.58.1/reference/destructors.html#temporary-lifetime-extension |
644 | let futures_init = ($( $fut, )+); |
645 | |
646 | // Safety: Nothing must be moved out of `futures`. This is to |
647 | // satisfy the requirement of `Pin::new_unchecked` called below. |
648 | // |
649 | // We can't use the `pin!` macro for this because `futures` is a |
650 | // tuple and the standard library provides no way to pin-project to |
651 | // the fields of a tuple. |
652 | let mut futures = ($( $crate::macros::support::IntoFuture::into_future( |
653 | $crate::count_field!( futures_init.$($skip)* ) |
654 | ),)+); |
655 | |
656 | // This assignment makes sure that the `poll_fn` closure only has a |
657 | // reference to the futures, instead of taking ownership of them. |
658 | // This mitigates the issue described in |
659 | // <https://internals.rust-lang.org/t/surprising-soundness-trouble-around-pollfn/17484> |
660 | let mut futures = &mut futures; |
661 | |
662 | $crate::macros::support::poll_fn(|cx| { |
663 | // Return `Pending` when the task budget is depleted since budget-aware futures |
664 | // are going to yield anyway and other futures will not cooperate. |
665 | ::std::task::ready!($crate::macros::support::poll_budget_available(cx)); |
666 | |
667 | // Track if any branch returns pending. If no branch completes |
668 | // **or** returns pending, this implies that all branches are |
669 | // disabled. |
670 | let mut is_pending = false; |
671 | |
672 | // Choose a starting index to begin polling the futures at. In |
673 | // practice, this will either be a pseudo-randomly generated |
674 | // number by default, or the constant 0 if `biased;` is |
675 | // supplied. |
676 | let start = $start; |
677 | |
678 | for i in 0..BRANCHES { |
679 | let branch; |
680 | #[allow(clippy::modulo_one)] |
681 | { |
682 | branch = (start + i) % BRANCHES; |
683 | } |
684 | match branch { |
685 | $( |
686 | #[allow(unreachable_code)] |
687 | $crate::count!( $($skip)* ) => { |
688 | // First, if the future has previously been |
689 | // disabled, do not poll it again. This is done |
690 | // by checking the associated bit in the |
691 | // `disabled` bit field. |
692 | let mask = 1 << branch; |
693 | |
694 | if disabled & mask == mask { |
695 | // The future has been disabled. |
696 | continue; |
697 | } |
698 | |
699 | // Extract the future for this branch from the |
700 | // tuple |
701 | let ( $($skip,)* fut, .. ) = &mut *futures; |
702 | |
703 | // Safety: future is stored on the stack above |
704 | // and never moved. |
705 | let mut fut = unsafe { Pin::new_unchecked(fut) }; |
706 | |
707 | // Try polling it |
708 | let out = match Future::poll(fut, cx) { |
709 | Ready(out) => out, |
710 | Pending => { |
711 | // Track that at least one future is |
712 | // still pending and continue polling. |
713 | is_pending = true; |
714 | continue; |
715 | } |
716 | }; |
717 | |
718 | // Disable the future from future polling. |
719 | disabled |= mask; |
720 | |
721 | // The future returned a value, check if matches |
722 | // the specified pattern. |
723 | #[allow(unused_variables)] |
724 | #[allow(unused_mut)] |
725 | match &out { |
726 | $crate::select_priv_clean_pattern!($bind) => {} |
727 | _ => continue, |
728 | } |
729 | |
730 | // The select is complete, return the value |
731 | return Ready($crate::select_variant!(__tokio_select_util::Out, ($($skip)*))(out)); |
732 | } |
733 | )* |
734 | _ => unreachable!("reaching this means there probably is an off by one bug" ), |
735 | } |
736 | } |
737 | |
738 | if is_pending { |
739 | Pending |
740 | } else { |
741 | // All branches have been disabled. |
742 | Ready(__tokio_select_util::Out::Disabled) |
743 | } |
744 | }).await |
745 | }; |
746 | |
747 | match output { |
748 | $( |
749 | $crate::select_variant!(__tokio_select_util::Out, ($($skip)*) ($bind)) => $handle, |
750 | )* |
751 | __tokio_select_util::Out::Disabled => $else, |
752 | _ => unreachable!("failed to match bind" ), |
753 | } |
754 | }}; |
755 | |
756 | // ==== Normalize ===== |
757 | |
758 | // These rules match a single `select!` branch and normalize it for |
759 | // processing by the first rule. |
760 | |
761 | (@ { start=$start:expr; $($t:tt)* } ) => { |
762 | // No `else` branch |
763 | $crate::select!(@{ start=$start; $($t)*; panic!("all branches are disabled and there is no else branch" ) }) |
764 | }; |
765 | (@ { start=$start:expr; $($t:tt)* } else => $else:expr $(,)?) => { |
766 | $crate::select!(@{ start=$start; $($t)*; $else }) |
767 | }; |
768 | (@ { start=$start:expr; ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr, if $c:expr => $h:block, $($r:tt)* ) => { |
769 | $crate::select!(@{ start=$start; ($($s)* _) $($t)* ($($s)*) $p = $f, if $c => $h, } $($r)*) |
770 | }; |
771 | (@ { start=$start:expr; ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr => $h:block, $($r:tt)* ) => { |
772 | $crate::select!(@{ start=$start; ($($s)* _) $($t)* ($($s)*) $p = $f, if true => $h, } $($r)*) |
773 | }; |
774 | (@ { start=$start:expr; ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr, if $c:expr => $h:block $($r:tt)* ) => { |
775 | $crate::select!(@{ start=$start; ($($s)* _) $($t)* ($($s)*) $p = $f, if $c => $h, } $($r)*) |
776 | }; |
777 | (@ { start=$start:expr; ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr => $h:block $($r:tt)* ) => { |
778 | $crate::select!(@{ start=$start; ($($s)* _) $($t)* ($($s)*) $p = $f, if true => $h, } $($r)*) |
779 | }; |
780 | (@ { start=$start:expr; ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr, if $c:expr => $h:expr ) => { |
781 | $crate::select!(@{ start=$start; ($($s)* _) $($t)* ($($s)*) $p = $f, if $c => $h, }) |
782 | }; |
783 | (@ { start=$start:expr; ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr => $h:expr ) => { |
784 | $crate::select!(@{ start=$start; ($($s)* _) $($t)* ($($s)*) $p = $f, if true => $h, }) |
785 | }; |
786 | (@ { start=$start:expr; ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr, if $c:expr => $h:expr, $($r:tt)* ) => { |
787 | $crate::select!(@{ start=$start; ($($s)* _) $($t)* ($($s)*) $p = $f, if $c => $h, } $($r)*) |
788 | }; |
789 | (@ { start=$start:expr; ( $($s:tt)* ) $($t:tt)* } $p:pat = $f:expr => $h:expr, $($r:tt)* ) => { |
790 | $crate::select!(@{ start=$start; ($($s)* _) $($t)* ($($s)*) $p = $f, if true => $h, } $($r)*) |
791 | }; |
792 | |
793 | // ===== Entry point ===== |
794 | |
795 | ($(biased;)? else => $else:expr $(,)? ) => {{ |
796 | $else |
797 | }}; |
798 | |
799 | (biased; $p:pat = $($t:tt)* ) => { |
800 | $crate::select!(@{ start=0; () } $p = $($t)*) |
801 | }; |
802 | |
803 | ( $p:pat = $($t:tt)* ) => { |
804 | // Randomly generate a starting point. This makes `select!` a bit more |
805 | // fair and avoids always polling the first future. |
806 | $crate::select!(@{ start={ $crate::macros::support::thread_rng_n(BRANCHES) }; () } $p = $($t)*) |
807 | }; |
808 | |
809 | () => { |
810 | compile_error!("select! requires at least one branch." ) |
811 | }; |
812 | }} |
813 | |
814 | // And here... we manually list out matches for up to 64 branches... I'm not |
815 | // happy about it either, but this is how we manage to use a declarative macro! |
816 | |
817 | #[macro_export ] |
818 | #[doc (hidden)] |
819 | macro_rules! count { |
820 | () => { |
821 | 0 |
822 | }; |
823 | (_) => { |
824 | 1 |
825 | }; |
826 | (_ _) => { |
827 | 2 |
828 | }; |
829 | (_ _ _) => { |
830 | 3 |
831 | }; |
832 | (_ _ _ _) => { |
833 | 4 |
834 | }; |
835 | (_ _ _ _ _) => { |
836 | 5 |
837 | }; |
838 | (_ _ _ _ _ _) => { |
839 | 6 |
840 | }; |
841 | (_ _ _ _ _ _ _) => { |
842 | 7 |
843 | }; |
844 | (_ _ _ _ _ _ _ _) => { |
845 | 8 |
846 | }; |
847 | (_ _ _ _ _ _ _ _ _) => { |
848 | 9 |
849 | }; |
850 | (_ _ _ _ _ _ _ _ _ _) => { |
851 | 10 |
852 | }; |
853 | (_ _ _ _ _ _ _ _ _ _ _) => { |
854 | 11 |
855 | }; |
856 | (_ _ _ _ _ _ _ _ _ _ _ _) => { |
857 | 12 |
858 | }; |
859 | (_ _ _ _ _ _ _ _ _ _ _ _ _) => { |
860 | 13 |
861 | }; |
862 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
863 | 14 |
864 | }; |
865 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
866 | 15 |
867 | }; |
868 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
869 | 16 |
870 | }; |
871 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
872 | 17 |
873 | }; |
874 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
875 | 18 |
876 | }; |
877 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
878 | 19 |
879 | }; |
880 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
881 | 20 |
882 | }; |
883 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
884 | 21 |
885 | }; |
886 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
887 | 22 |
888 | }; |
889 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
890 | 23 |
891 | }; |
892 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
893 | 24 |
894 | }; |
895 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
896 | 25 |
897 | }; |
898 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
899 | 26 |
900 | }; |
901 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
902 | 27 |
903 | }; |
904 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
905 | 28 |
906 | }; |
907 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
908 | 29 |
909 | }; |
910 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
911 | 30 |
912 | }; |
913 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
914 | 31 |
915 | }; |
916 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
917 | 32 |
918 | }; |
919 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
920 | 33 |
921 | }; |
922 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
923 | 34 |
924 | }; |
925 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
926 | 35 |
927 | }; |
928 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
929 | 36 |
930 | }; |
931 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
932 | 37 |
933 | }; |
934 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
935 | 38 |
936 | }; |
937 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
938 | 39 |
939 | }; |
940 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
941 | 40 |
942 | }; |
943 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
944 | 41 |
945 | }; |
946 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
947 | 42 |
948 | }; |
949 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
950 | 43 |
951 | }; |
952 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
953 | 44 |
954 | }; |
955 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
956 | 45 |
957 | }; |
958 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
959 | 46 |
960 | }; |
961 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
962 | 47 |
963 | }; |
964 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
965 | 48 |
966 | }; |
967 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
968 | 49 |
969 | }; |
970 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
971 | 50 |
972 | }; |
973 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
974 | 51 |
975 | }; |
976 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
977 | 52 |
978 | }; |
979 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
980 | 53 |
981 | }; |
982 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
983 | 54 |
984 | }; |
985 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
986 | 55 |
987 | }; |
988 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
989 | 56 |
990 | }; |
991 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
992 | 57 |
993 | }; |
994 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
995 | 58 |
996 | }; |
997 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
998 | 59 |
999 | }; |
1000 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1001 | 60 |
1002 | }; |
1003 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1004 | 61 |
1005 | }; |
1006 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1007 | 62 |
1008 | }; |
1009 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1010 | 63 |
1011 | }; |
1012 | (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1013 | 64 |
1014 | }; |
1015 | } |
1016 | |
1017 | #[macro_export ] |
1018 | #[doc (hidden)] |
1019 | macro_rules! count_field { |
1020 | ($var:ident. ) => { |
1021 | $var.0 |
1022 | }; |
1023 | ($var:ident. _) => { |
1024 | $var.1 |
1025 | }; |
1026 | ($var:ident. _ _) => { |
1027 | $var.2 |
1028 | }; |
1029 | ($var:ident. _ _ _) => { |
1030 | $var.3 |
1031 | }; |
1032 | ($var:ident. _ _ _ _) => { |
1033 | $var.4 |
1034 | }; |
1035 | ($var:ident. _ _ _ _ _) => { |
1036 | $var.5 |
1037 | }; |
1038 | ($var:ident. _ _ _ _ _ _) => { |
1039 | $var.6 |
1040 | }; |
1041 | ($var:ident. _ _ _ _ _ _ _) => { |
1042 | $var.7 |
1043 | }; |
1044 | ($var:ident. _ _ _ _ _ _ _ _) => { |
1045 | $var.8 |
1046 | }; |
1047 | ($var:ident. _ _ _ _ _ _ _ _ _) => { |
1048 | $var.9 |
1049 | }; |
1050 | ($var:ident. _ _ _ _ _ _ _ _ _ _) => { |
1051 | $var.10 |
1052 | }; |
1053 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _) => { |
1054 | $var.11 |
1055 | }; |
1056 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _) => { |
1057 | $var.12 |
1058 | }; |
1059 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1060 | $var.13 |
1061 | }; |
1062 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1063 | $var.14 |
1064 | }; |
1065 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1066 | $var.15 |
1067 | }; |
1068 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1069 | $var.16 |
1070 | }; |
1071 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1072 | $var.17 |
1073 | }; |
1074 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1075 | $var.18 |
1076 | }; |
1077 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1078 | $var.19 |
1079 | }; |
1080 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1081 | $var.20 |
1082 | }; |
1083 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1084 | $var.21 |
1085 | }; |
1086 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1087 | $var.22 |
1088 | }; |
1089 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1090 | $var.23 |
1091 | }; |
1092 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1093 | $var.24 |
1094 | }; |
1095 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1096 | $var.25 |
1097 | }; |
1098 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1099 | $var.26 |
1100 | }; |
1101 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1102 | $var.27 |
1103 | }; |
1104 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1105 | $var.28 |
1106 | }; |
1107 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1108 | $var.29 |
1109 | }; |
1110 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1111 | $var.30 |
1112 | }; |
1113 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1114 | $var.31 |
1115 | }; |
1116 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1117 | $var.32 |
1118 | }; |
1119 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1120 | $var.33 |
1121 | }; |
1122 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1123 | $var.34 |
1124 | }; |
1125 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1126 | $var.35 |
1127 | }; |
1128 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1129 | $var.36 |
1130 | }; |
1131 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1132 | $var.37 |
1133 | }; |
1134 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1135 | $var.38 |
1136 | }; |
1137 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1138 | $var.39 |
1139 | }; |
1140 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1141 | $var.40 |
1142 | }; |
1143 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1144 | $var.41 |
1145 | }; |
1146 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1147 | $var.42 |
1148 | }; |
1149 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1150 | $var.43 |
1151 | }; |
1152 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1153 | $var.44 |
1154 | }; |
1155 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1156 | $var.45 |
1157 | }; |
1158 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1159 | $var.46 |
1160 | }; |
1161 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1162 | $var.47 |
1163 | }; |
1164 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1165 | $var.48 |
1166 | }; |
1167 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1168 | $var.49 |
1169 | }; |
1170 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1171 | $var.50 |
1172 | }; |
1173 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1174 | $var.51 |
1175 | }; |
1176 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1177 | $var.52 |
1178 | }; |
1179 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1180 | $var.53 |
1181 | }; |
1182 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1183 | $var.54 |
1184 | }; |
1185 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1186 | $var.55 |
1187 | }; |
1188 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1189 | $var.56 |
1190 | }; |
1191 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1192 | $var.57 |
1193 | }; |
1194 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1195 | $var.58 |
1196 | }; |
1197 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1198 | $var.59 |
1199 | }; |
1200 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1201 | $var.60 |
1202 | }; |
1203 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1204 | $var.61 |
1205 | }; |
1206 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1207 | $var.62 |
1208 | }; |
1209 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1210 | $var.63 |
1211 | }; |
1212 | ($var:ident. _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) => { |
1213 | $var.64 |
1214 | }; |
1215 | } |
1216 | |
1217 | #[macro_export ] |
1218 | #[doc (hidden)] |
1219 | macro_rules! select_variant { |
1220 | ($($p:ident)::*, () $($t:tt)*) => { |
1221 | $($p)::*::_0 $($t)* |
1222 | }; |
1223 | ($($p:ident)::*, (_) $($t:tt)*) => { |
1224 | $($p)::*::_1 $($t)* |
1225 | }; |
1226 | ($($p:ident)::*, (_ _) $($t:tt)*) => { |
1227 | $($p)::*::_2 $($t)* |
1228 | }; |
1229 | ($($p:ident)::*, (_ _ _) $($t:tt)*) => { |
1230 | $($p)::*::_3 $($t)* |
1231 | }; |
1232 | ($($p:ident)::*, (_ _ _ _) $($t:tt)*) => { |
1233 | $($p)::*::_4 $($t)* |
1234 | }; |
1235 | ($($p:ident)::*, (_ _ _ _ _) $($t:tt)*) => { |
1236 | $($p)::*::_5 $($t)* |
1237 | }; |
1238 | ($($p:ident)::*, (_ _ _ _ _ _) $($t:tt)*) => { |
1239 | $($p)::*::_6 $($t)* |
1240 | }; |
1241 | ($($p:ident)::*, (_ _ _ _ _ _ _) $($t:tt)*) => { |
1242 | $($p)::*::_7 $($t)* |
1243 | }; |
1244 | ($($p:ident)::*, (_ _ _ _ _ _ _ _) $($t:tt)*) => { |
1245 | $($p)::*::_8 $($t)* |
1246 | }; |
1247 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1248 | $($p)::*::_9 $($t)* |
1249 | }; |
1250 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1251 | $($p)::*::_10 $($t)* |
1252 | }; |
1253 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1254 | $($p)::*::_11 $($t)* |
1255 | }; |
1256 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1257 | $($p)::*::_12 $($t)* |
1258 | }; |
1259 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1260 | $($p)::*::_13 $($t)* |
1261 | }; |
1262 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1263 | $($p)::*::_14 $($t)* |
1264 | }; |
1265 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1266 | $($p)::*::_15 $($t)* |
1267 | }; |
1268 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1269 | $($p)::*::_16 $($t)* |
1270 | }; |
1271 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1272 | $($p)::*::_17 $($t)* |
1273 | }; |
1274 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1275 | $($p)::*::_18 $($t)* |
1276 | }; |
1277 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1278 | $($p)::*::_19 $($t)* |
1279 | }; |
1280 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1281 | $($p)::*::_20 $($t)* |
1282 | }; |
1283 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1284 | $($p)::*::_21 $($t)* |
1285 | }; |
1286 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1287 | $($p)::*::_22 $($t)* |
1288 | }; |
1289 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1290 | $($p)::*::_23 $($t)* |
1291 | }; |
1292 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1293 | $($p)::*::_24 $($t)* |
1294 | }; |
1295 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1296 | $($p)::*::_25 $($t)* |
1297 | }; |
1298 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1299 | $($p)::*::_26 $($t)* |
1300 | }; |
1301 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1302 | $($p)::*::_27 $($t)* |
1303 | }; |
1304 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1305 | $($p)::*::_28 $($t)* |
1306 | }; |
1307 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1308 | $($p)::*::_29 $($t)* |
1309 | }; |
1310 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1311 | $($p)::*::_30 $($t)* |
1312 | }; |
1313 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1314 | $($p)::*::_31 $($t)* |
1315 | }; |
1316 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1317 | $($p)::*::_32 $($t)* |
1318 | }; |
1319 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1320 | $($p)::*::_33 $($t)* |
1321 | }; |
1322 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1323 | $($p)::*::_34 $($t)* |
1324 | }; |
1325 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1326 | $($p)::*::_35 $($t)* |
1327 | }; |
1328 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1329 | $($p)::*::_36 $($t)* |
1330 | }; |
1331 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1332 | $($p)::*::_37 $($t)* |
1333 | }; |
1334 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1335 | $($p)::*::_38 $($t)* |
1336 | }; |
1337 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1338 | $($p)::*::_39 $($t)* |
1339 | }; |
1340 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1341 | $($p)::*::_40 $($t)* |
1342 | }; |
1343 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1344 | $($p)::*::_41 $($t)* |
1345 | }; |
1346 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1347 | $($p)::*::_42 $($t)* |
1348 | }; |
1349 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1350 | $($p)::*::_43 $($t)* |
1351 | }; |
1352 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1353 | $($p)::*::_44 $($t)* |
1354 | }; |
1355 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1356 | $($p)::*::_45 $($t)* |
1357 | }; |
1358 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1359 | $($p)::*::_46 $($t)* |
1360 | }; |
1361 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1362 | $($p)::*::_47 $($t)* |
1363 | }; |
1364 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1365 | $($p)::*::_48 $($t)* |
1366 | }; |
1367 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1368 | $($p)::*::_49 $($t)* |
1369 | }; |
1370 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1371 | $($p)::*::_50 $($t)* |
1372 | }; |
1373 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1374 | $($p)::*::_51 $($t)* |
1375 | }; |
1376 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1377 | $($p)::*::_52 $($t)* |
1378 | }; |
1379 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1380 | $($p)::*::_53 $($t)* |
1381 | }; |
1382 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1383 | $($p)::*::_54 $($t)* |
1384 | }; |
1385 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1386 | $($p)::*::_55 $($t)* |
1387 | }; |
1388 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1389 | $($p)::*::_56 $($t)* |
1390 | }; |
1391 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1392 | $($p)::*::_57 $($t)* |
1393 | }; |
1394 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1395 | $($p)::*::_58 $($t)* |
1396 | }; |
1397 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1398 | $($p)::*::_59 $($t)* |
1399 | }; |
1400 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1401 | $($p)::*::_60 $($t)* |
1402 | }; |
1403 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1404 | $($p)::*::_61 $($t)* |
1405 | }; |
1406 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1407 | $($p)::*::_62 $($t)* |
1408 | }; |
1409 | ($($p:ident)::*, (_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _) $($t:tt)*) => { |
1410 | $($p)::*::_63 $($t)* |
1411 | }; |
1412 | } |
1413 | |