1#![doc = include_str!("../README.md")]
2
3pub mod hash;
4pub mod iterable;
5pub mod map;
6pub mod referenced_slice;
7pub mod set;
8pub mod slice;
9pub mod sorted_referenced_slice;
10pub mod sorted_slice;
11
12pub use iterable::ScatteredIterable;
13pub use map::ScatteredMap;
14pub use referenced_slice::ScatteredReferencedSlice;
15pub use set::ScatteredSet;
16pub use slice::ScatteredSlice;
17pub use sorted_referenced_slice::ScatteredSortedReferencedSlice;
18pub use sorted_slice::ScatteredSortedSlice;
19
20#[doc(hidden)]
21pub trait ScatteredElementType {
23 type T;
25}
26
27#[doc(hidden)]
28pub trait ScatteredElementTuple {
30 type A;
32 type B;
34}
35
36#[doc(hidden)]
37#[macro_export]
38macro_rules! __scatter_parse {
39 (#[scatter (crate_path = $cp:path , $($meta:tt)*)] $($rest:tt)*) => {
43 $crate::__support::scatter_parse!(#[scatter($($meta)*)] $($rest)*);
44 };
45
46 (#[scatter ($($meta:tt)*)] $(#[$imeta:meta])* $vis:vis static $($item:tt)*) => {
48 $($meta)* ! (
49 ([$($meta)*] =>
50 $(#[$imeta])*
51 $vis static
52 $($item)*
53 )
54 );
55 };
56 (#[scatter ($($meta:tt)*)] $(#[$imeta:meta])* $vis:vis const $($item:tt)*) => {
57 $($meta)* ! (
58 ([$($meta)*] =>
59 $(#[$imeta])*
60 $vis const
61 $($item)*
62 )
63 );
64 };
65 (#[scatter] $($rest:tt)* ) => {
66 compile_error!("Missing collection for #[scatter] attribute. Expected: #[scatter(COLLECTION)] <item>;");
67 };
68
69 (@reorder (#[scatter] $($item:tt)*) ($($rest:tt)*)) => {
70 $crate::__support::scatter_parse!(#[scatter] $($rest)* $($item)*);
71 };
72 (@reorder (#[$top:meta] $($item:tt)*) ($($rest:tt)*)) => {
73 $crate::__support::scatter_parse!(@reorder($($item)*) (#[$top] $($rest)*));
74 };
75 (@reorder ($item:item;) $($rest:tt)*) => {
76 compile_error!("Missing #[scatter] attribute.");
77 };
78 (@reorder $($rest:tt)*) => {
79 compile_error!("Missing #[scatter] attribute.");
80 };
81
82 ($($rest:tt)*) => {
83 $crate::__support::scatter_parse!(@reorder ($($rest)*) ());
84 };
85}
86
87#[doc(hidden)]
88#[macro_export]
89macro_rules! __gather_parse {
90 (@dispatch $macro:ident $(#[$imeta:meta])* $vis:vis static $name:ident $($rest:tt)* ) => {
93 $crate::__support::combine!(output=ident prefix=($crate::__gather_parse!) paren=() paren_prefix=(@unique ) input=(
94 H
95 __LOCATIONHASH__(of=($(#[$imeta])* $vis static $name $($rest)*))
96 ) paren_suffix=($macro $(#[$imeta])* $vis static $name $($rest)*) suffix=(;));
97 };
98
99 (@unique $unique:ident $macro:ident $(#[$imeta:meta])* $vis:vis static $name:ident: ($($collection:tt)*) ($($ty:tt)*);) => {
100 $crate::$macro!(@gather $unique $(#[$imeta])* $vis static $name: ($($collection)*) <$($ty)*>;);
101
102 $crate::__support::combine!(output=ident prefix=(#[doc(hidden)] #[macro_export] macro_rules!) input=(__ $name __ $macro __ $unique) suffix=({
103 ($passthru:tt) => {
104 $crate::$macro!(@scatter [$name :: $unique] $passthru);
105 };
106 }));
107
108 $crate::__support::combine!(output=ident prefix=(#[doc(hidden)] $vis use) input=(__ $name __ $macro __ $unique) suffix=(as $name;));
109 };
110
111 (@done ($($collection:tt)*) #[gather] $(#[$imeta:meta])* $vis:vis static $name:ident: ScatteredSlice < $ty:ty >; ) => {
112 $crate::__support::gather_parse!(@dispatch __slice $(#[$imeta])* $vis static $name: ($($collection)*) ( $ty ););
113 };
114
115 (@done ($($collection:tt)*) #[gather] $(#[$imeta:meta])* $vis:vis static $name:ident: ScatteredSortedSlice < $ty:ty >; ) => {
116 $crate::__support::gather_parse!(@dispatch __sorted_slice $(#[$imeta])* $vis static $name: ($($collection)*) ( $ty ););
117 };
118
119 (@done ($($collection:tt)*) #[gather] $(#[$imeta:meta])* $vis:vis static $name:ident: ScatteredReferencedSlice < $ty:ty >; ) => {
120 $crate::__support::gather_parse!(@dispatch __referenced_slice $(#[$imeta])* $vis static $name: ($($collection)*) ( $ty ););
121 };
122
123 (@done ($($collection:tt)*) #[gather] $(#[$imeta:meta])* $vis:vis static $name:ident: ScatteredSortedReferencedSlice < $ty:ty >; ) => {
124 $crate::__support::gather_parse!(@dispatch __sorted_referenced_slice $(#[$imeta])* $vis static $name: ($($collection)*) ( $ty ););
125 };
126
127 (@done ($($collection:tt)*) #[gather] $(#[$imeta:meta])* $vis:vis static $name:ident: ScatteredMap < $key:ty, $value:ty >; ) => {
128 $crate::__support::gather_parse!(@dispatch __map $(#[$imeta])* $vis static $name: ($($collection)*) ( $key, $value ););
129 };
130
131 (@done ($($collection:tt)*) #[gather] $(#[$imeta:meta])* $vis:vis static $name:ident: ScatteredSet < $key:ty >; ) => {
132 $crate::__support::gather_parse!(@dispatch __set $(#[$imeta])* $vis static $name: ($($collection)*) ( $key ););
133 };
134
135 (@done ($($collection:tt)*) #[gather] $(#[$imeta:meta])* $vis:vis static $name:ident: ScatteredIterable < $ty:ty >; ) => {
136 $crate::__support::gather_parse!(@dispatch __iterable $(#[$imeta])* $vis static $name: ($($collection)*) ( $ty ););
137 };
138
139 (@done #[gather] $($rest:tt)* ) => {
140 compile_error!("Unknown collection type");
141 };
142
143 (@reorder (#[gather] $($item:tt)*) ($($rest:tt)*) $collection:tt) => {
144 $crate::__support::gather_parse!(@done $collection #[gather] $($rest)* $($item)*);
145 };
146 (@reorder (#[$top:meta] $($item:tt)*) ($($rest:tt)*) $collection:tt) => {
147 $crate::__support::gather_parse!(@reorder ($($item)*) (#[$top] $($rest)*) $collection);
148 };
149 (@reorder ($item:item;) $($rest:tt)*) => {
150 compile_error!("Missing #[gather] attribute.");
151 };
152 (@reorder $($rest:tt)*) => {
153 compile_error!("Missing #[gather] attribute.");
154 };
155
156 (@path ($($path_part:tt)*) ($(#$meta:tt)* $vis:vis static $name:ident) ($collection:ident < $($rest:tt)*)) => {
158 $crate::__support::gather_parse!(@reorder ($(#$meta)* $vis static $name: $collection < $($rest)*) () ($($path_part)* $collection));
159 };
160 (@path ($($path_part:tt)*) ($(#$meta:tt)* $vis:vis static $name:ident) ($next_path_part:ident $($rest:tt)*)) => {
161 $crate::__support::gather_parse!(@path ($($path_part)* $next_path_part) ($(#$meta)* $vis static $name) ($($rest)*));
162 };
163 (@path ($($path_part:tt)*) ($(#$meta:tt)* $vis:vis static $name:ident) (:: $($rest:tt)*)) => {
164 $crate::__support::gather_parse!(@path ($($path_part)* ::) ($(#$meta)* $vis static $name) ($($rest)*));
165 };
166 (@path ($($path_part:tt)*) ($(#$meta:tt)* $vis:vis static $name:ident) (:: $($rest:tt)*)) => {
167 compile_error!("Expected: #[gather] name: path::to::collection<generics>;");
168 };
169
170 (#[gather (crate_path = $($cp:tt)*)] $($rest:tt)*) => {
174 $crate::__support::gather_parse!(#[gather] $($rest)*);
175 };
176
177 ($(#$meta:tt)* $vis:vis static $name:ident: $collection:ident < $($rest:tt)* ) => {
178 $crate::__support::gather_parse!(@reorder ($(#$meta)* $vis static $name: $collection < $($rest)*) () ($collection));
179 };
180 ($(#$meta:tt)* $vis:vis static $name:ident: :: $($path:tt)* ) => {
181 $crate::__support::gather_parse!(@path (::) ($(#$meta)* $vis static $name) ($($path)*));
182 };
183 ($(#$meta:tt)* $vis:vis static $name:ident: $path_part:ident $($path:tt)* ) => {
184 $crate::__support::gather_parse!(@path ($path_part) ($(#$meta)* $vis static $name) ($($path)*));
185 };
186}
187
188#[doc(hidden)]
189#[allow(unused)]
190pub mod __support {
191 pub use crate::__gather_parse as gather_parse;
192 pub use crate::__scatter_parse as scatter_parse;
193
194 pub use ctor;
195 pub use link_section;
196 pub use linktime_proc_macro::combine;
197}
198
199pub mod declarative {
224 #[doc(inline)]
246 pub use crate::__gather_brace as gather;
247 #[doc(inline)]
269 pub use crate::__scatter_brace as scatter;
270}
271
272#[doc(inline)]
273pub use linktime_proc_macro::{gather, scatter};
274
275#[doc(hidden)]
276#[macro_export]
277macro_rules! __gather_brace {
278 ($($item:tt)*) => {
279 $crate::__support::gather_parse!($($item)*);
280 };
281}
282
283#[doc(hidden)]
284#[macro_export]
285macro_rules! __scatter_brace {
286 ($($item:tt)*) => {
287 $crate::__support::scatter_parse!($($item)*);
288 };
289}