@@ -21,12 +21,16 @@ pub trait Sealed:
2121 /// The zero value of the integer type.
2222 const ZERO : Self ;
2323 /// The one value of the integer type.
24- const ONE : Self ;
25- /// The maximum value of this type.
2624 const MAX : Self ;
2725 /// The maximum value of this type, as a `usize`.
2826 const MAX_USIZE : usize ;
2927
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+
3034 /// An infallible conversion from `usize` to `LenT`.
3135 #[ inline]
3236 fn from_usize ( val : usize ) -> Self {
@@ -55,9 +59,12 @@ macro_rules! impl_lentype {
5559 $( #[ $meta] ) *
5660 impl Sealed for $LenT {
5761 const ZERO : Self = 0 ;
58- const ONE : Self = 1 ;
5962 const MAX : Self = Self :: MAX ;
6063 const MAX_USIZE : usize = Self :: MAX as _;
64+
65+ fn one( ) -> Self {
66+ 1
67+ }
6168 }
6269
6370 $( #[ $meta] ) *
@@ -111,11 +118,153 @@ pub trait SmallestLenType {
111118#[ allow( rustdoc:: private_intra_doc_links) ] // Only publically exposed via `crate::_export`
112119pub type DefaultLenType < const N : usize > = <Const < N > as SmallestLenType >:: Type ;
113120
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 ) ;
115123impl_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 ) ;
116124#[ cfg( any( target_pointer_width = "32" , target_pointer_width = "64" ) ) ]
117125impl_lentodefault ! ( u32 : 65536 , 131072 , 262144 , 524288 , 1048576 , 2097152 , 4194304 , 8388608 , 16777216 , 33554432 , 67108864 , 134217728 , 268435456 , 536870912 , 1073741824 , 2147483648 ) ;
118126
119127pub const fn check_capacity_fits < LenT : LenType , const N : usize > ( ) {
120128 assert ! ( LenT :: MAX_USIZE >= N , "The capacity is larger than `LenT` can hold, increase the size of `LenT` or reduce the capacity" ) ;
121129}
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