@@ -21,12 +21,16 @@ pub trait Sealed:
21
21
/// The zero value of the integer type.
22
22
const ZERO : Self ;
23
23
/// The one value of the integer type.
24
- const ONE : Self ;
25
- /// The maximum value of this type.
26
24
const MAX : Self ;
27
25
/// The maximum value of this type, as a `usize`.
28
26
const MAX_USIZE : usize ;
29
27
28
+ /// The one value of the integer type.
29
+ ///
30
+ /// It's a function instead of constant because we want to have implementation which panics for
31
+ /// type `ZeroLenType`
32
+ fn one ( ) -> Self ;
33
+
30
34
/// An infallible conversion from `usize` to `LenT`.
31
35
#[ inline]
32
36
fn from_usize ( val : usize ) -> Self {
@@ -55,9 +59,12 @@ macro_rules! impl_lentype {
55
59
$( #[ $meta] ) *
56
60
impl Sealed for $LenT {
57
61
const ZERO : Self = 0 ;
58
- const ONE : Self = 1 ;
59
62
const MAX : Self = Self :: MAX ;
60
63
const MAX_USIZE : usize = Self :: MAX as _;
64
+
65
+ fn one( ) -> Self {
66
+ 1
67
+ }
61
68
}
62
69
63
70
$( #[ $meta] ) *
@@ -111,11 +118,153 @@ pub trait SmallestLenType {
111
118
#[ allow( rustdoc:: private_intra_doc_links) ] // Only publically exposed via `crate::_export`
112
119
pub type DefaultLenType < const N : usize > = <Const < N > as SmallestLenType >:: Type ;
113
120
114
- impl_lentodefault ! ( u8 : 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 , 64 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , 73 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 81 , 82 , 83 , 84 , 85 , 86 , 87 , 88 , 89 , 90 , 91 , 92 , 93 , 94 , 95 , 96 , 97 , 98 , 99 , 100 , 101 , 102 , 103 , 104 , 105 , 106 , 107 , 108 , 109 , 110 , 111 , 112 , 113 , 114 , 115 , 116 , 117 , 118 , 119 , 120 , 121 , 122 , 123 , 124 , 125 , 126 , 127 , 128 , 129 , 130 , 131 , 132 , 133 , 134 , 135 , 136 , 137 , 138 , 139 , 140 , 141 , 142 , 143 , 144 , 145 , 146 , 147 , 148 , 149 , 150 , 151 , 152 , 153 , 154 , 155 , 156 , 157 , 158 , 159 , 160 , 161 , 162 , 163 , 164 , 165 , 166 , 167 , 168 , 169 , 170 , 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183 , 184 , 185 , 186 , 187 , 188 , 189 , 190 , 191 , 192 , 193 , 194 , 195 , 196 , 197 , 198 , 199 , 200 , 201 , 202 , 203 , 204 , 205 , 206 , 207 , 208 , 209 , 210 , 211 , 212 , 213 , 214 , 215 , 216 , 217 , 218 , 219 , 220 , 221 , 222 , 223 , 224 , 225 , 226 , 227 , 228 , 229 , 230 , 231 , 232 , 233 , 234 , 235 , 236 , 237 , 238 , 239 , 240 , 241 , 242 , 243 , 244 , 245 , 246 , 247 , 248 , 249 , 250 , 251 , 252 , 253 , 254 , 255 ) ;
121
+ impl_lentodefault ! ( ZeroLenType : 0 ) ;
122
+ impl_lentodefault ! ( u8 : 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 , 64 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , 73 , 74 , 75 , 76 , 77 , 78 , 79 , 80 , 81 , 82 , 83 , 84 , 85 , 86 , 87 , 88 , 89 , 90 , 91 , 92 , 93 , 94 , 95 , 96 , 97 , 98 , 99 , 100 , 101 , 102 , 103 , 104 , 105 , 106 , 107 , 108 , 109 , 110 , 111 , 112 , 113 , 114 , 115 , 116 , 117 , 118 , 119 , 120 , 121 , 122 , 123 , 124 , 125 , 126 , 127 , 128 , 129 , 130 , 131 , 132 , 133 , 134 , 135 , 136 , 137 , 138 , 139 , 140 , 141 , 142 , 143 , 144 , 145 , 146 , 147 , 148 , 149 , 150 , 151 , 152 , 153 , 154 , 155 , 156 , 157 , 158 , 159 , 160 , 161 , 162 , 163 , 164 , 165 , 166 , 167 , 168 , 169 , 170 , 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183 , 184 , 185 , 186 , 187 , 188 , 189 , 190 , 191 , 192 , 193 , 194 , 195 , 196 , 197 , 198 , 199 , 200 , 201 , 202 , 203 , 204 , 205 , 206 , 207 , 208 , 209 , 210 , 211 , 212 , 213 , 214 , 215 , 216 , 217 , 218 , 219 , 220 , 221 , 222 , 223 , 224 , 225 , 226 , 227 , 228 , 229 , 230 , 231 , 232 , 233 , 234 , 235 , 236 , 237 , 238 , 239 , 240 , 241 , 242 , 243 , 244 , 245 , 246 , 247 , 248 , 249 , 250 , 251 , 252 , 253 , 254 , 255 ) ;
115
123
impl_lentodefault ! ( u16 : 256 , 300 , 400 , 500 , 512 , 600 , 700 , 800 , 900 , 1000 , 1024 , 2000 , 2048 , 4000 , 4096 , 8000 , 8192 , 16000 , 16384 , 32000 , 32768 , 65000 , 65535 ) ;
116
124
#[ cfg( any( target_pointer_width = "32" , target_pointer_width = "64" ) ) ]
117
125
impl_lentodefault ! ( u32 : 65536 , 131072 , 262144 , 524288 , 1048576 , 2097152 , 4194304 , 8388608 , 16777216 , 33554432 , 67108864 , 134217728 , 268435456 , 536870912 , 1073741824 , 2147483648 ) ;
118
126
119
127
pub const fn check_capacity_fits < LenT : LenType , const N : usize > ( ) {
120
128
assert ! ( LenT :: MAX_USIZE >= N , "The capacity is larger than `LenT` can hold, increase the size of `LenT` or reduce the capacity" ) ;
121
129
}
130
+
131
+ /// Container with 0 capacity always has length 0, so there is no need to track length of such containers at all.
132
+ ///
133
+ /// This type is used as a placeholder for length of container with 0 capacity. It allows optimizing total size of
134
+ /// containers like this to 0 bytes.
135
+ ///
136
+ /// Logically, this type always stores value 0. Because of this ZeroLenType::one() panics and should never be called.
137
+ #[ doc( hidden) ]
138
+ #[ derive( Copy , Clone , PartialEq , PartialOrd ) ]
139
+ pub struct ZeroLenType ;
140
+
141
+ impl Debug for ZeroLenType {
142
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
143
+ write ! ( f, "0" )
144
+ }
145
+ }
146
+
147
+ impl Display for ZeroLenType {
148
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
149
+ write ! ( f, "0" )
150
+ }
151
+ }
152
+
153
+ impl Sealed for ZeroLenType {
154
+ const ZERO : Self = Self ;
155
+
156
+ const MAX : Self = Self ;
157
+ const MAX_USIZE : usize = 0 ;
158
+
159
+ #[ inline]
160
+ fn one ( ) -> Self {
161
+ panic ! ( "ZeroLenType cannot represent value 1" ) ;
162
+ }
163
+ }
164
+
165
+ impl LenType for ZeroLenType { }
166
+
167
+ impl Add for ZeroLenType {
168
+ type Output = Self ;
169
+
170
+ fn add ( self , _rhs : Self ) -> Self :: Output {
171
+ Self :: ZERO
172
+ }
173
+ }
174
+
175
+ impl AddAssign for ZeroLenType {
176
+ fn add_assign ( & mut self , _rhs : Self ) { }
177
+ }
178
+
179
+ impl Sub for ZeroLenType {
180
+ type Output = Self ;
181
+
182
+ fn sub ( self , _rhs : Self ) -> Self :: Output {
183
+ Self :: ZERO
184
+ }
185
+ }
186
+
187
+ impl SubAssign for ZeroLenType {
188
+ fn sub_assign ( & mut self , _rhs : Self ) { }
189
+ }
190
+
191
+ #[ doc( hidden) ]
192
+ #[ derive( Debug , PartialEq ) ]
193
+ pub struct ZeroLenTypeTryFromError ;
194
+
195
+ impl TryFrom < usize > for ZeroLenType {
196
+ type Error = ZeroLenTypeTryFromError ;
197
+
198
+ fn try_from ( value : usize ) -> Result < Self , Self :: Error > {
199
+ if value > 0 {
200
+ return Err ( ZeroLenTypeTryFromError ) ;
201
+ }
202
+
203
+ Ok ( Self :: ZERO )
204
+ }
205
+ }
206
+
207
+ impl TryInto < usize > for ZeroLenType {
208
+ type Error = ( ) ;
209
+
210
+ fn try_into ( self ) -> Result < usize , Self :: Error > {
211
+ Ok ( 0 )
212
+ }
213
+ }
214
+
215
+ #[ cfg( test) ]
216
+ mod tests {
217
+ use crate :: len_type:: { Sealed , ZeroLenType , ZeroLenTypeTryFromError } ;
218
+
219
+ #[ test]
220
+ pub fn test_zero_len_type_conversions ( ) {
221
+ assert_eq ! ( ZeroLenType :: into_usize( ZeroLenType :: ZERO ) , 0_usize ) ;
222
+ assert_eq ! ( ZeroLenType :: from_usize( 0_usize ) , ZeroLenType :: ZERO ) ;
223
+
224
+ assert_eq ! ( ZeroLenType :: ZERO . try_into( ) , Ok ( 0_usize ) ) ;
225
+ assert_eq ! ( ZeroLenType :: try_from( 0_usize ) , Ok ( ZeroLenType :: ZERO ) ) ;
226
+ assert_eq ! ( ZeroLenType :: try_from( 1_usize ) , Err ( ZeroLenTypeTryFromError ) ) ;
227
+ }
228
+
229
+ #[ test]
230
+ #[ should_panic]
231
+ pub fn test_zero_len_type_one ( ) {
232
+ ZeroLenType :: one ( ) ;
233
+ }
234
+
235
+ #[ test]
236
+ #[ should_panic]
237
+ pub fn test_zero_len_type_one_usize ( ) {
238
+ ZeroLenType :: from_usize ( 1 ) ;
239
+ }
240
+
241
+ #[ test]
242
+ pub fn test_zero_len_type_constants ( ) {
243
+ assert_eq ! ( ZeroLenType :: ZERO , ZeroLenType ) ;
244
+ assert_eq ! ( ZeroLenType :: MAX , ZeroLenType ) ;
245
+ assert_eq ! ( ZeroLenType :: MAX_USIZE , 0_usize ) ;
246
+ }
247
+
248
+ #[ test]
249
+ pub fn test_zero_len_type_size ( ) {
250
+ assert_eq ! ( core:: mem:: size_of:: <ZeroLenType >( ) , 0 ) ;
251
+ }
252
+
253
+ #[ test]
254
+ pub fn test_zero_len_type_ops ( ) {
255
+ assert_eq ! ( ZeroLenType :: ZERO + ZeroLenType :: ZERO , ZeroLenType :: ZERO ) ;
256
+ assert_eq ! ( ZeroLenType :: ZERO - ZeroLenType :: ZERO , ZeroLenType :: ZERO ) ;
257
+
258
+ let mut zero = ZeroLenType :: ZERO ;
259
+ zero += ZeroLenType :: ZERO ;
260
+ assert_eq ! ( zero, ZeroLenType :: ZERO ) ;
261
+ zero -= ZeroLenType :: ZERO ;
262
+ assert_eq ! ( zero, ZeroLenType :: ZERO ) ;
263
+ }
264
+
265
+ #[ test]
266
+ pub fn test_zero_len_type_debug ( ) {
267
+ assert_eq ! ( format!( "{}" , ZeroLenType ) , "0" ) ;
268
+ assert_eq ! ( format!( "{:?}" , ZeroLenType ) , "0" ) ;
269
+ }
270
+ }
0 commit comments