1
ļ»æ// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4
// software and associated documentation files (the "Software"), to deal in the Software
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7
// to whom the Software is furnished to do so, subject to the following conditions:
9
// The above copyright notice and this permission notice shall be included in all copies or
10
// substantial portions of the Software.
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17
// DEALINGS IN THE SOFTWARE.
21
namespace ICSharpCode.NRefactory.Utils
24
/// Static helper method for converting between primitive types.
26
public static class CSharpPrimitiveCast
29
/// Performs a conversion between primitive types.
30
/// Unfortunately we cannot use Convert.ChangeType because it has different semantics
31
/// (e.g. rounding behavior for floats, overflow, etc.), so we write down every possible primitive C# cast
32
/// and let the compiler figure out the exact semantics.
33
/// And we have to do everything twice, once in a checked-block, once in an unchecked-block.
35
public static object Cast(TypeCode targetType, object input, bool checkForOverflow)
40
return CSharpPrimitiveCastChecked(targetType, input);
42
return CSharpPrimitiveCastUnchecked(targetType, input);
45
static object CSharpPrimitiveCastChecked(TypeCode targetType, object input)
48
TypeCode sourceType = Type.GetTypeCode(input.GetType());
49
if (sourceType == targetType)
54
case TypeCode.SByte: return (char)(sbyte)input;
55
case TypeCode.Byte: return (char)(byte)input;
56
case TypeCode.Int16: return (char)(short)input;
57
case TypeCode.UInt16: return (char)(ushort)input;
58
case TypeCode.Int32: return (char)(int)input;
59
case TypeCode.UInt32: return (char)(uint)input;
60
case TypeCode.Int64: return (char)(long)input;
61
case TypeCode.UInt64: return (char)(ulong)input;
62
case TypeCode.Single: return (char)(float)input;
63
case TypeCode.Double: return (char)(double)input;
64
case TypeCode.Decimal: return (char)(decimal)input;
69
case TypeCode.Char: return (sbyte)(char)input;
70
case TypeCode.Byte: return (sbyte)(byte)input;
71
case TypeCode.Int16: return (sbyte)(short)input;
72
case TypeCode.UInt16: return (sbyte)(ushort)input;
73
case TypeCode.Int32: return (sbyte)(int)input;
74
case TypeCode.UInt32: return (sbyte)(uint)input;
75
case TypeCode.Int64: return (sbyte)(long)input;
76
case TypeCode.UInt64: return (sbyte)(ulong)input;
77
case TypeCode.Single: return (sbyte)(float)input;
78
case TypeCode.Double: return (sbyte)(double)input;
79
case TypeCode.Decimal: return (sbyte)(decimal)input;
84
case TypeCode.Char: return (byte)(char)input;
85
case TypeCode.SByte: return (byte)(sbyte)input;
86
case TypeCode.Int16: return (byte)(short)input;
87
case TypeCode.UInt16: return (byte)(ushort)input;
88
case TypeCode.Int32: return (byte)(int)input;
89
case TypeCode.UInt32: return (byte)(uint)input;
90
case TypeCode.Int64: return (byte)(long)input;
91
case TypeCode.UInt64: return (byte)(ulong)input;
92
case TypeCode.Single: return (byte)(float)input;
93
case TypeCode.Double: return (byte)(double)input;
94
case TypeCode.Decimal: return (byte)(decimal)input;
99
case TypeCode.Char: return (short)(char)input;
100
case TypeCode.SByte: return (short)(sbyte)input;
101
case TypeCode.Byte: return (short)(byte)input;
102
case TypeCode.UInt16: return (short)(ushort)input;
103
case TypeCode.Int32: return (short)(int)input;
104
case TypeCode.UInt32: return (short)(uint)input;
105
case TypeCode.Int64: return (short)(long)input;
106
case TypeCode.UInt64: return (short)(ulong)input;
107
case TypeCode.Single: return (short)(float)input;
108
case TypeCode.Double: return (short)(double)input;
109
case TypeCode.Decimal: return (short)(decimal)input;
112
case TypeCode.UInt16:
113
switch (sourceType) {
114
case TypeCode.Char: return (ushort)(char)input;
115
case TypeCode.SByte: return (ushort)(sbyte)input;
116
case TypeCode.Byte: return (ushort)(byte)input;
117
case TypeCode.Int16: return (ushort)(short)input;
118
case TypeCode.Int32: return (ushort)(int)input;
119
case TypeCode.UInt32: return (ushort)(uint)input;
120
case TypeCode.Int64: return (ushort)(long)input;
121
case TypeCode.UInt64: return (ushort)(ulong)input;
122
case TypeCode.Single: return (ushort)(float)input;
123
case TypeCode.Double: return (ushort)(double)input;
124
case TypeCode.Decimal: return (ushort)(decimal)input;
128
switch (sourceType) {
129
case TypeCode.Char: return (int)(char)input;
130
case TypeCode.SByte: return (int)(sbyte)input;
131
case TypeCode.Byte: return (int)(byte)input;
132
case TypeCode.Int16: return (int)(short)input;
133
case TypeCode.UInt16: return (int)(ushort)input;
134
case TypeCode.UInt32: return (int)(uint)input;
135
case TypeCode.Int64: return (int)(long)input;
136
case TypeCode.UInt64: return (int)(ulong)input;
137
case TypeCode.Single: return (int)(float)input;
138
case TypeCode.Double: return (int)(double)input;
139
case TypeCode.Decimal: return (int)(decimal)input;
142
case TypeCode.UInt32:
143
switch (sourceType) {
144
case TypeCode.Char: return (uint)(char)input;
145
case TypeCode.SByte: return (uint)(sbyte)input;
146
case TypeCode.Byte: return (uint)(byte)input;
147
case TypeCode.Int16: return (uint)(short)input;
148
case TypeCode.UInt16: return (uint)(ushort)input;
149
case TypeCode.Int32: return (uint)(int)input;
150
case TypeCode.Int64: return (uint)(long)input;
151
case TypeCode.UInt64: return (uint)(ulong)input;
152
case TypeCode.Single: return (uint)(float)input;
153
case TypeCode.Double: return (uint)(double)input;
154
case TypeCode.Decimal: return (uint)(decimal)input;
158
switch (sourceType) {
159
case TypeCode.Char: return (long)(char)input;
160
case TypeCode.SByte: return (long)(sbyte)input;
161
case TypeCode.Byte: return (long)(byte)input;
162
case TypeCode.Int16: return (long)(short)input;
163
case TypeCode.UInt16: return (long)(ushort)input;
164
case TypeCode.Int32: return (long)(int)input;
165
case TypeCode.UInt32: return (long)(uint)input;
166
case TypeCode.UInt64: return (long)(ulong)input;
167
case TypeCode.Single: return (long)(float)input;
168
case TypeCode.Double: return (long)(double)input;
169
case TypeCode.Decimal: return (long)(decimal)input;
172
case TypeCode.UInt64:
173
switch (sourceType) {
174
case TypeCode.Char: return (ulong)(char)input;
175
case TypeCode.SByte: return (ulong)(sbyte)input;
176
case TypeCode.Byte: return (ulong)(byte)input;
177
case TypeCode.Int16: return (ulong)(short)input;
178
case TypeCode.UInt16: return (ulong)(ushort)input;
179
case TypeCode.Int32: return (ulong)(int)input;
180
case TypeCode.UInt32: return (ulong)(uint)input;
181
case TypeCode.Int64: return (ulong)(long)input;
182
case TypeCode.Single: return (ulong)(float)input;
183
case TypeCode.Double: return (ulong)(double)input;
184
case TypeCode.Decimal: return (ulong)(decimal)input;
187
case TypeCode.Single:
188
switch (sourceType) {
189
case TypeCode.Char: return (float)(char)input;
190
case TypeCode.SByte: return (float)(sbyte)input;
191
case TypeCode.Byte: return (float)(byte)input;
192
case TypeCode.Int16: return (float)(short)input;
193
case TypeCode.UInt16: return (float)(ushort)input;
194
case TypeCode.Int32: return (float)(int)input;
195
case TypeCode.UInt32: return (float)(uint)input;
196
case TypeCode.Int64: return (float)(long)input;
197
case TypeCode.UInt64: return (float)(ulong)input;
198
case TypeCode.Double: return (float)(double)input;
199
case TypeCode.Decimal: return (float)(decimal)input;
202
case TypeCode.Double:
203
switch (sourceType) {
204
case TypeCode.Char: return (double)(char)input;
205
case TypeCode.SByte: return (double)(sbyte)input;
206
case TypeCode.Byte: return (double)(byte)input;
207
case TypeCode.Int16: return (double)(short)input;
208
case TypeCode.UInt16: return (double)(ushort)input;
209
case TypeCode.Int32: return (double)(int)input;
210
case TypeCode.UInt32: return (double)(uint)input;
211
case TypeCode.Int64: return (double)(long)input;
212
case TypeCode.UInt64: return (double)(ulong)input;
213
case TypeCode.Single: return (double)(float)input;
214
case TypeCode.Decimal: return (double)(decimal)input;
217
case TypeCode.Decimal:
218
switch (sourceType) {
219
case TypeCode.Char: return (decimal)(char)input;
220
case TypeCode.SByte: return (decimal)(sbyte)input;
221
case TypeCode.Byte: return (decimal)(byte)input;
222
case TypeCode.Int16: return (decimal)(short)input;
223
case TypeCode.UInt16: return (decimal)(ushort)input;
224
case TypeCode.Int32: return (decimal)(int)input;
225
case TypeCode.UInt32: return (decimal)(uint)input;
226
case TypeCode.Int64: return (decimal)(long)input;
227
case TypeCode.UInt64: return (decimal)(ulong)input;
228
case TypeCode.Single: return (decimal)(float)input;
229
case TypeCode.Double: return (decimal)(double)input;
233
throw new InvalidCastException("Cast from " + sourceType + " to " + targetType + "not supported.");
237
static object CSharpPrimitiveCastUnchecked(TypeCode targetType, object input)
240
TypeCode sourceType = Type.GetTypeCode(input.GetType());
241
if (sourceType == targetType)
243
switch (targetType) {
245
switch (sourceType) {
246
case TypeCode.SByte: return (char)(sbyte)input;
247
case TypeCode.Byte: return (char)(byte)input;
248
case TypeCode.Int16: return (char)(short)input;
249
case TypeCode.UInt16: return (char)(ushort)input;
250
case TypeCode.Int32: return (char)(int)input;
251
case TypeCode.UInt32: return (char)(uint)input;
252
case TypeCode.Int64: return (char)(long)input;
253
case TypeCode.UInt64: return (char)(ulong)input;
254
case TypeCode.Single: return (char)(float)input;
255
case TypeCode.Double: return (char)(double)input;
256
case TypeCode.Decimal: return (char)(decimal)input;
260
switch (sourceType) {
261
case TypeCode.Char: return (sbyte)(char)input;
262
case TypeCode.Byte: return (sbyte)(byte)input;
263
case TypeCode.Int16: return (sbyte)(short)input;
264
case TypeCode.UInt16: return (sbyte)(ushort)input;
265
case TypeCode.Int32: return (sbyte)(int)input;
266
case TypeCode.UInt32: return (sbyte)(uint)input;
267
case TypeCode.Int64: return (sbyte)(long)input;
268
case TypeCode.UInt64: return (sbyte)(ulong)input;
269
case TypeCode.Single: return (sbyte)(float)input;
270
case TypeCode.Double: return (sbyte)(double)input;
271
case TypeCode.Decimal: return (sbyte)(decimal)input;
275
switch (sourceType) {
276
case TypeCode.Char: return (byte)(char)input;
277
case TypeCode.SByte: return (byte)(sbyte)input;
278
case TypeCode.Int16: return (byte)(short)input;
279
case TypeCode.UInt16: return (byte)(ushort)input;
280
case TypeCode.Int32: return (byte)(int)input;
281
case TypeCode.UInt32: return (byte)(uint)input;
282
case TypeCode.Int64: return (byte)(long)input;
283
case TypeCode.UInt64: return (byte)(ulong)input;
284
case TypeCode.Single: return (byte)(float)input;
285
case TypeCode.Double: return (byte)(double)input;
286
case TypeCode.Decimal: return (byte)(decimal)input;
290
switch (sourceType) {
291
case TypeCode.Char: return (short)(char)input;
292
case TypeCode.SByte: return (short)(sbyte)input;
293
case TypeCode.Byte: return (short)(byte)input;
294
case TypeCode.UInt16: return (short)(ushort)input;
295
case TypeCode.Int32: return (short)(int)input;
296
case TypeCode.UInt32: return (short)(uint)input;
297
case TypeCode.Int64: return (short)(long)input;
298
case TypeCode.UInt64: return (short)(ulong)input;
299
case TypeCode.Single: return (short)(float)input;
300
case TypeCode.Double: return (short)(double)input;
301
case TypeCode.Decimal: return (short)(decimal)input;
304
case TypeCode.UInt16:
305
switch (sourceType) {
306
case TypeCode.Char: return (ushort)(char)input;
307
case TypeCode.SByte: return (ushort)(sbyte)input;
308
case TypeCode.Byte: return (ushort)(byte)input;
309
case TypeCode.Int16: return (ushort)(short)input;
310
case TypeCode.Int32: return (ushort)(int)input;
311
case TypeCode.UInt32: return (ushort)(uint)input;
312
case TypeCode.Int64: return (ushort)(long)input;
313
case TypeCode.UInt64: return (ushort)(ulong)input;
314
case TypeCode.Single: return (ushort)(float)input;
315
case TypeCode.Double: return (ushort)(double)input;
316
case TypeCode.Decimal: return (ushort)(decimal)input;
320
switch (sourceType) {
321
case TypeCode.Char: return (int)(char)input;
322
case TypeCode.SByte: return (int)(sbyte)input;
323
case TypeCode.Byte: return (int)(byte)input;
324
case TypeCode.Int16: return (int)(short)input;
325
case TypeCode.UInt16: return (int)(ushort)input;
326
case TypeCode.UInt32: return (int)(uint)input;
327
case TypeCode.Int64: return (int)(long)input;
328
case TypeCode.UInt64: return (int)(ulong)input;
329
case TypeCode.Single: return (int)(float)input;
330
case TypeCode.Double: return (int)(double)input;
331
case TypeCode.Decimal: return (int)(decimal)input;
334
case TypeCode.UInt32:
335
switch (sourceType) {
336
case TypeCode.Char: return (uint)(char)input;
337
case TypeCode.SByte: return (uint)(sbyte)input;
338
case TypeCode.Byte: return (uint)(byte)input;
339
case TypeCode.Int16: return (uint)(short)input;
340
case TypeCode.UInt16: return (uint)(ushort)input;
341
case TypeCode.Int32: return (uint)(int)input;
342
case TypeCode.Int64: return (uint)(long)input;
343
case TypeCode.UInt64: return (uint)(ulong)input;
344
case TypeCode.Single: return (uint)(float)input;
345
case TypeCode.Double: return (uint)(double)input;
346
case TypeCode.Decimal: return (uint)(decimal)input;
350
switch (sourceType) {
351
case TypeCode.Char: return (long)(char)input;
352
case TypeCode.SByte: return (long)(sbyte)input;
353
case TypeCode.Byte: return (long)(byte)input;
354
case TypeCode.Int16: return (long)(short)input;
355
case TypeCode.UInt16: return (long)(ushort)input;
356
case TypeCode.Int32: return (long)(int)input;
357
case TypeCode.UInt32: return (long)(uint)input;
358
case TypeCode.UInt64: return (long)(ulong)input;
359
case TypeCode.Single: return (long)(float)input;
360
case TypeCode.Double: return (long)(double)input;
361
case TypeCode.Decimal: return (long)(decimal)input;
364
case TypeCode.UInt64:
365
switch (sourceType) {
366
case TypeCode.Char: return (ulong)(char)input;
367
case TypeCode.SByte: return (ulong)(sbyte)input;
368
case TypeCode.Byte: return (ulong)(byte)input;
369
case TypeCode.Int16: return (ulong)(short)input;
370
case TypeCode.UInt16: return (ulong)(ushort)input;
371
case TypeCode.Int32: return (ulong)(int)input;
372
case TypeCode.UInt32: return (ulong)(uint)input;
373
case TypeCode.Int64: return (ulong)(long)input;
374
case TypeCode.Single: return (ulong)(float)input;
375
case TypeCode.Double: return (ulong)(double)input;
376
case TypeCode.Decimal: return (ulong)(decimal)input;
379
case TypeCode.Single:
380
switch (sourceType) {
381
case TypeCode.Char: return (float)(char)input;
382
case TypeCode.SByte: return (float)(sbyte)input;
383
case TypeCode.Byte: return (float)(byte)input;
384
case TypeCode.Int16: return (float)(short)input;
385
case TypeCode.UInt16: return (float)(ushort)input;
386
case TypeCode.Int32: return (float)(int)input;
387
case TypeCode.UInt32: return (float)(uint)input;
388
case TypeCode.Int64: return (float)(long)input;
389
case TypeCode.UInt64: return (float)(ulong)input;
390
case TypeCode.Double: return (float)(double)input;
391
case TypeCode.Decimal: return (float)(decimal)input;
394
case TypeCode.Double:
395
switch (sourceType) {
396
case TypeCode.Char: return (double)(char)input;
397
case TypeCode.SByte: return (double)(sbyte)input;
398
case TypeCode.Byte: return (double)(byte)input;
399
case TypeCode.Int16: return (double)(short)input;
400
case TypeCode.UInt16: return (double)(ushort)input;
401
case TypeCode.Int32: return (double)(int)input;
402
case TypeCode.UInt32: return (double)(uint)input;
403
case TypeCode.Int64: return (double)(long)input;
404
case TypeCode.UInt64: return (double)(ulong)input;
405
case TypeCode.Single: return (double)(float)input;
406
case TypeCode.Decimal: return (double)(decimal)input;
409
case TypeCode.Decimal:
410
switch (sourceType) {
411
case TypeCode.Char: return (decimal)(char)input;
412
case TypeCode.SByte: return (decimal)(sbyte)input;
413
case TypeCode.Byte: return (decimal)(byte)input;
414
case TypeCode.Int16: return (decimal)(short)input;
415
case TypeCode.UInt16: return (decimal)(ushort)input;
416
case TypeCode.Int32: return (decimal)(int)input;
417
case TypeCode.UInt32: return (decimal)(uint)input;
418
case TypeCode.Int64: return (decimal)(long)input;
419
case TypeCode.UInt64: return (decimal)(ulong)input;
420
case TypeCode.Single: return (decimal)(float)input;
421
case TypeCode.Double: return (decimal)(double)input;
425
throw new InvalidCastException("Cast from " + sourceType + " to " + targetType + " not supported.");