~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory.CSharp/Resolver/CSharpOperators.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
ļ»æ// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
2
 
// 
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:
8
 
// 
9
 
// The above copyright notice and this permission notice shall be included in all copies or
10
 
// substantial portions of the Software.
11
 
// 
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.
18
 
 
19
 
using System;
20
 
using System.Collections.Generic;
21
 
using System.Linq;
22
 
using System.Text;
23
 
using ICSharpCode.NRefactory.TypeSystem;
24
 
using ICSharpCode.NRefactory.TypeSystem.Implementation;
25
 
using ICSharpCode.NRefactory.Utils;
26
 
 
27
 
namespace ICSharpCode.NRefactory.CSharp.Resolver
28
 
{
29
 
        sealed class CSharpOperators
30
 
        {
31
 
                readonly ICompilation compilation;
32
 
                
33
 
                private CSharpOperators(ICompilation compilation)
34
 
                {
35
 
                        this.compilation = compilation;
36
 
                        InitParameterArrays();
37
 
                }
38
 
                
39
 
                /// <summary>
40
 
                /// Gets the CSharpOperators instance for the specified <see cref="ICompilation"/>.
41
 
                /// This will make use of the context's cache manager (if available) to reuse the CSharpOperators instance.
42
 
                /// </summary>
43
 
                public static CSharpOperators Get(ICompilation compilation)
44
 
                {
45
 
                        CacheManager cache = compilation.CacheManager;
46
 
                        CSharpOperators operators = (CSharpOperators)cache.GetShared(typeof(CSharpOperators));
47
 
                        if (operators == null) {
48
 
                                operators = (CSharpOperators)cache.GetOrAddShared(typeof(CSharpOperators), new CSharpOperators(compilation));
49
 
                        }
50
 
                        return operators;
51
 
                }
52
 
                
53
 
                #region class OperatorMethod
54
 
                OperatorMethod[] Lift(params OperatorMethod[] methods)
55
 
                {
56
 
                        List<OperatorMethod> result = new List<OperatorMethod>(methods);
57
 
                        foreach (OperatorMethod method in methods) {
58
 
                                OperatorMethod lifted = method.Lift(this);
59
 
                                if (lifted != null)
60
 
                                        result.Add(lifted);
61
 
                        }
62
 
                        return result.ToArray();
63
 
                }
64
 
                
65
 
                IParameter[] normalParameters = new IParameter[(int)(TypeCode.String + 1 - TypeCode.Object)];
66
 
                IParameter[] nullableParameters = new IParameter[(int)(TypeCode.Decimal + 1 - TypeCode.Boolean)];
67
 
                
68
 
                void InitParameterArrays()
69
 
                {
70
 
                        for (TypeCode i = TypeCode.Object; i <= TypeCode.String; i++) {
71
 
                                normalParameters[i - TypeCode.Object] = new DefaultParameter(compilation.FindType(i), string.Empty);
72
 
                        }
73
 
                        for (TypeCode i = TypeCode.Boolean; i <= TypeCode.Decimal; i++) {
74
 
                                IType type = NullableType.Create(compilation, compilation.FindType(i));
75
 
                                nullableParameters[i - TypeCode.Boolean] = new DefaultParameter(type, string.Empty);
76
 
                        }
77
 
                }
78
 
                
79
 
                IParameter MakeParameter(TypeCode code)
80
 
                {
81
 
                        return normalParameters[code - TypeCode.Object];
82
 
                }
83
 
                
84
 
                IParameter MakeNullableParameter(IParameter normalParameter)
85
 
                {
86
 
                        for (TypeCode i = TypeCode.Boolean; i <= TypeCode.Decimal; i++) {
87
 
                                if (normalParameter == normalParameters[i - TypeCode.Object])
88
 
                                        return nullableParameters[i - TypeCode.Boolean];
89
 
                        }
90
 
                        throw new ArgumentException();
91
 
                }
92
 
                
93
 
                internal class OperatorMethod : IParameterizedMember
94
 
                {
95
 
                        readonly ICompilation compilation;
96
 
                        readonly IList<IParameter> parameters = new List<IParameter>();
97
 
                        
98
 
                        protected OperatorMethod(ICompilation compilation)
99
 
                        {
100
 
                                this.compilation = compilation;
101
 
                        }
102
 
                        
103
 
                        public IList<IParameter> Parameters {
104
 
                                get { return parameters; }
105
 
                        }
106
 
                        
107
 
                        public IType ReturnType { get; internal set; }
108
 
                        
109
 
                        public ICompilation Compilation {
110
 
                                get { return compilation; }
111
 
                        }
112
 
                        
113
 
                        public virtual OperatorMethod Lift(CSharpOperators operators)
114
 
                        {
115
 
                                return null;
116
 
                        }
117
 
                        
118
 
                        ITypeDefinition IEntity.DeclaringTypeDefinition {
119
 
                                get { return null; }
120
 
                        }
121
 
                        
122
 
                        IType IEntity.DeclaringType {
123
 
                                get { return SpecialType.UnknownType; }
124
 
                        }
125
 
                        
126
 
                        IMember IMember.MemberDefinition {
127
 
                                get { return this; }
128
 
                        }
129
 
                        
130
 
                        IUnresolvedMember IMember.UnresolvedMember {
131
 
                                get { return null; }
132
 
                        }
133
 
                        
134
 
                        IList<IMember> IMember.ImplementedInterfaceMembers {
135
 
                                get { return EmptyList<IMember>.Instance; }
136
 
                        }
137
 
                        
138
 
                        bool IMember.IsVirtual {
139
 
                                get { return false; }
140
 
                        }
141
 
                        
142
 
                        bool IMember.IsOverride {
143
 
                                get { return false; }
144
 
                        }
145
 
                        
146
 
                        bool IMember.IsOverridable {
147
 
                                get { return false; }
148
 
                        }
149
 
                        
150
 
                        EntityType IEntity.EntityType {
151
 
                                get { return EntityType.Operator; }
152
 
                        }
153
 
                        
154
 
                        DomRegion IEntity.Region {
155
 
                                get { return DomRegion.Empty; }
156
 
                        }
157
 
                        
158
 
                        DomRegion IEntity.BodyRegion {
159
 
                                get { return DomRegion.Empty; }
160
 
                        }
161
 
                        
162
 
                        IList<IAttribute> IEntity.Attributes {
163
 
                                get { return EmptyList<IAttribute>.Instance; }
164
 
                        }
165
 
                        
166
 
                        Documentation.DocumentationComment IEntity.Documentation {
167
 
                                get { return null; }
168
 
                        }
169
 
                        
170
 
                        Accessibility IHasAccessibility.Accessibility {
171
 
                                get { return Accessibility.Public; }
172
 
                        }
173
 
                        
174
 
                        bool IEntity.IsStatic {
175
 
                                get { return true; }
176
 
                        }
177
 
                        
178
 
                        bool IEntity.IsAbstract {
179
 
                                get { return false; }
180
 
                        }
181
 
                        
182
 
                        bool IEntity.IsSealed {
183
 
                                get { return false; }
184
 
                        }
185
 
                        
186
 
                        bool IEntity.IsShadowing {
187
 
                                get { return false; }
188
 
                        }
189
 
                        
190
 
                        bool IEntity.IsSynthetic {
191
 
                                get { return true; }
192
 
                        }
193
 
                        
194
 
                        bool IHasAccessibility.IsPrivate {
195
 
                                get { return false; }
196
 
                        }
197
 
                        
198
 
                        bool IHasAccessibility.IsPublic {
199
 
                                get { return true; }
200
 
                        }
201
 
                        
202
 
                        bool IHasAccessibility.IsProtected {
203
 
                                get { return false; }
204
 
                        }
205
 
                        
206
 
                        bool IHasAccessibility.IsInternal {
207
 
                                get { return false; }
208
 
                        }
209
 
                        
210
 
                        bool IHasAccessibility.IsProtectedOrInternal {
211
 
                                get { return false; }
212
 
                        }
213
 
                        
214
 
                        bool IHasAccessibility.IsProtectedAndInternal {
215
 
                                get { return false; }
216
 
                        }
217
 
                        
218
 
                        bool IMember.IsExplicitInterfaceImplementation {
219
 
                                get { return false; }
220
 
                        }
221
 
                        
222
 
                        IAssembly IEntity.ParentAssembly {
223
 
                                get { return compilation.MainAssembly; }
224
 
                        }
225
 
                        
226
 
                        IMemberReference IMember.ToMemberReference()
227
 
                        {
228
 
                                throw new NotSupportedException();
229
 
                        }
230
 
                        
231
 
                        string INamedElement.FullName {
232
 
                                get { return "operator"; }
233
 
                        }
234
 
                        
235
 
                        string INamedElement.Name {
236
 
                                get { return "operator"; }
237
 
                        }
238
 
                        
239
 
                        string INamedElement.Namespace {
240
 
                                get { return string.Empty; }
241
 
                        }
242
 
                        
243
 
                        string INamedElement.ReflectionName {
244
 
                                get { return "operator"; }
245
 
                        }
246
 
                        
247
 
                        public override string ToString()
248
 
                        {
249
 
                                StringBuilder b = new StringBuilder();
250
 
                                b.Append(ReturnType + " operator(");
251
 
                                for (int i = 0; i < parameters.Count; i++) {
252
 
                                        if (i > 0)
253
 
                                                b.Append(", ");
254
 
                                        b.Append(parameters[i].Type);
255
 
                                }
256
 
                                b.Append(')');
257
 
                                return b.ToString();
258
 
                        }
259
 
                }
260
 
                #endregion
261
 
                
262
 
                #region Unary operator class definitions
263
 
                internal class UnaryOperatorMethod : OperatorMethod
264
 
                {
265
 
                        public virtual bool CanEvaluateAtCompileTime { get { return false; } }
266
 
                        
267
 
                        public virtual object Invoke(CSharpResolver resolver, object input)
268
 
                        {
269
 
                                throw new NotSupportedException();
270
 
                        }
271
 
                        
272
 
                        public UnaryOperatorMethod(ICompilation compilaton) : base(compilaton)
273
 
                        {
274
 
                        }
275
 
                }
276
 
                
277
 
                sealed class LambdaUnaryOperatorMethod<T> : UnaryOperatorMethod
278
 
                {
279
 
                        readonly Func<T, T> func;
280
 
                        
281
 
                        public LambdaUnaryOperatorMethod(CSharpOperators operators, Func<T, T> func)
282
 
                                : base(operators.compilation)
283
 
                        {
284
 
                                TypeCode typeCode = Type.GetTypeCode(typeof(T));
285
 
                                this.ReturnType = operators.compilation.FindType(typeCode);
286
 
                                this.Parameters.Add(operators.MakeParameter(typeCode));
287
 
                                this.func = func;
288
 
                        }
289
 
                        
290
 
                        public override bool CanEvaluateAtCompileTime {
291
 
                                get { return true; }
292
 
                        }
293
 
                        
294
 
                        public override object Invoke(CSharpResolver resolver, object input)
295
 
                        {
296
 
                                if (input == null)
297
 
                                        return null;
298
 
                                return func((T)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T)), input));
299
 
                        }
300
 
                        
301
 
                        public override OperatorMethod Lift(CSharpOperators operators)
302
 
                        {
303
 
                                return new LiftedUnaryOperatorMethod(operators, this);
304
 
                        }
305
 
                }
306
 
                
307
 
                sealed class LiftedUnaryOperatorMethod : UnaryOperatorMethod, OverloadResolution.ILiftedOperator
308
 
                {
309
 
                        UnaryOperatorMethod baseMethod;
310
 
                        
311
 
                        public LiftedUnaryOperatorMethod(CSharpOperators operators, UnaryOperatorMethod baseMethod) : base(operators.compilation)
312
 
                        {
313
 
                                this.baseMethod = baseMethod;
314
 
                                this.ReturnType = NullableType.Create(baseMethod.Compilation, baseMethod.ReturnType);
315
 
                                this.Parameters.Add(operators.MakeNullableParameter(baseMethod.Parameters[0]));
316
 
                        }
317
 
                        
318
 
                        public IList<IParameter> NonLiftedParameters {
319
 
                                get { return baseMethod.Parameters; }
320
 
                        }
321
 
                }
322
 
                #endregion
323
 
                
324
 
                #region Unary operator definitions
325
 
                // C# 4.0 spec: Ā§7.7.1 Unary plus operator
326
 
                OperatorMethod[] unaryPlusOperators;
327
 
                
328
 
                public OperatorMethod[] UnaryPlusOperators {
329
 
                        get {
330
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref unaryPlusOperators);
331
 
                                if (ops != null) {
332
 
                                        return ops;
333
 
                                } else {
334
 
                                        return LazyInit.GetOrSet(ref unaryPlusOperators, Lift(
335
 
                                                new LambdaUnaryOperatorMethod<int>    (this, i => +i),
336
 
                                                new LambdaUnaryOperatorMethod<uint>   (this, i => +i),
337
 
                                                new LambdaUnaryOperatorMethod<long>   (this, i => +i),
338
 
                                                new LambdaUnaryOperatorMethod<ulong>  (this, i => +i),
339
 
                                                new LambdaUnaryOperatorMethod<float>  (this, i => +i),
340
 
                                                new LambdaUnaryOperatorMethod<double> (this, i => +i),
341
 
                                                new LambdaUnaryOperatorMethod<decimal>(this, i => +i)
342
 
                                        ));
343
 
                                }
344
 
                        }
345
 
                }
346
 
                
347
 
                // C# 4.0 spec: Ā§7.7.2 Unary minus operator
348
 
                OperatorMethod[] uncheckedUnaryMinusOperators;
349
 
                
350
 
                public OperatorMethod[] UncheckedUnaryMinusOperators {
351
 
                        get {
352
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref uncheckedUnaryMinusOperators);
353
 
                                if (ops != null) {
354
 
                                        return ops;
355
 
                                } else {
356
 
                                        return LazyInit.GetOrSet(ref uncheckedUnaryMinusOperators, Lift(
357
 
                                                new LambdaUnaryOperatorMethod<int>    (this, i => unchecked(-i)),
358
 
                                                new LambdaUnaryOperatorMethod<long>   (this, i => unchecked(-i)),
359
 
                                                new LambdaUnaryOperatorMethod<float>  (this, i => unchecked(-i)),
360
 
                                                new LambdaUnaryOperatorMethod<double> (this, i => unchecked(-i)),
361
 
                                                new LambdaUnaryOperatorMethod<decimal>(this, i => unchecked(-i))
362
 
                                        ));
363
 
                                }
364
 
                        }
365
 
                }
366
 
                
367
 
                OperatorMethod[] checkedUnaryMinusOperators;
368
 
                
369
 
                public OperatorMethod[] CheckedUnaryMinusOperators {
370
 
                        get {
371
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref checkedUnaryMinusOperators);
372
 
                                if (ops != null) {
373
 
                                        return ops;
374
 
                                } else {
375
 
                                        return LazyInit.GetOrSet(ref checkedUnaryMinusOperators, Lift(
376
 
                                                new LambdaUnaryOperatorMethod<int>    (this, i => checked(-i)),
377
 
                                                new LambdaUnaryOperatorMethod<long>   (this, i => checked(-i)),
378
 
                                                new LambdaUnaryOperatorMethod<float>  (this, i => checked(-i)),
379
 
                                                new LambdaUnaryOperatorMethod<double> (this, i => checked(-i)),
380
 
                                                new LambdaUnaryOperatorMethod<decimal>(this, i => checked(-i))
381
 
                                        ));
382
 
                                }
383
 
                        }
384
 
                }
385
 
                
386
 
                // C# 4.0 spec: Ā§7.7.3 Logical negation operator
387
 
                OperatorMethod[] logicalNegationOperators;
388
 
                
389
 
                public OperatorMethod[] LogicalNegationOperators {
390
 
                        get {
391
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref logicalNegationOperators);
392
 
                                if (ops != null) {
393
 
                                        return ops;
394
 
                                } else {
395
 
                                        return LazyInit.GetOrSet(ref logicalNegationOperators, Lift(
396
 
                                                new LambdaUnaryOperatorMethod<bool>(this, b => !b)
397
 
                                        ));
398
 
                                }
399
 
                        }
400
 
                }
401
 
                
402
 
                // C# 4.0 spec: Ā§7.7.4 Bitwise complement operator
403
 
                OperatorMethod[] bitwiseComplementOperators;
404
 
                
405
 
                public OperatorMethod[] BitwiseComplementOperators {
406
 
                        get {
407
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref bitwiseComplementOperators);
408
 
                                if (ops != null) {
409
 
                                        return ops;
410
 
                                } else {
411
 
                                        return LazyInit.GetOrSet(ref bitwiseComplementOperators, Lift(
412
 
                                                new LambdaUnaryOperatorMethod<int>  (this, i => ~i),
413
 
                                                new LambdaUnaryOperatorMethod<uint> (this, i => ~i),
414
 
                                                new LambdaUnaryOperatorMethod<long> (this, i => ~i),
415
 
                                                new LambdaUnaryOperatorMethod<ulong>(this, i => ~i)
416
 
                                        ));
417
 
                                }
418
 
                        }
419
 
                }
420
 
                #endregion
421
 
                
422
 
                #region Binary operator class definitions
423
 
                internal class BinaryOperatorMethod : OperatorMethod
424
 
                {
425
 
                        public virtual bool CanEvaluateAtCompileTime { get { return false; } }
426
 
                        public virtual object Invoke(CSharpResolver resolver, object lhs, object rhs) {
427
 
                                throw new NotSupportedException();
428
 
                        }
429
 
                        
430
 
                        public BinaryOperatorMethod(ICompilation compilation) : base(compilation) {}
431
 
                }
432
 
                
433
 
                sealed class LambdaBinaryOperatorMethod<T1, T2> : BinaryOperatorMethod
434
 
                {
435
 
                        readonly Func<T1, T2, T1> checkedFunc;
436
 
                        readonly Func<T1, T2, T1> uncheckedFunc;
437
 
                        
438
 
                        public LambdaBinaryOperatorMethod(CSharpOperators operators, Func<T1, T2, T1> func)
439
 
                                : this(operators, func, func)
440
 
                        {
441
 
                        }
442
 
                        
443
 
                        public LambdaBinaryOperatorMethod(CSharpOperators operators, Func<T1, T2, T1> checkedFunc, Func<T1, T2, T1> uncheckedFunc)
444
 
                                : base(operators.compilation)
445
 
                        {
446
 
                                TypeCode t1 = Type.GetTypeCode(typeof(T1));
447
 
                                this.ReturnType = operators.compilation.FindType(t1);
448
 
                                this.Parameters.Add(operators.MakeParameter(t1));
449
 
                                this.Parameters.Add(operators.MakeParameter(Type.GetTypeCode(typeof(T2))));
450
 
                                this.checkedFunc = checkedFunc;
451
 
                                this.uncheckedFunc = uncheckedFunc;
452
 
                        }
453
 
                        
454
 
                        public override bool CanEvaluateAtCompileTime {
455
 
                                get { return true; }
456
 
                        }
457
 
                        
458
 
                        public override object Invoke(CSharpResolver resolver, object lhs, object rhs)
459
 
                        {
460
 
                                if (lhs == null || rhs == null)
461
 
                                        return null;
462
 
                                Func<T1, T2, T1> func = resolver.CheckForOverflow ? checkedFunc : uncheckedFunc;
463
 
                                return func((T1)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T1)), lhs),
464
 
                                            (T2)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T2)), rhs));
465
 
                        }
466
 
                        
467
 
                        public override OperatorMethod Lift(CSharpOperators operators)
468
 
                        {
469
 
                                return new LiftedBinaryOperatorMethod(operators, this);
470
 
                        }
471
 
                }
472
 
                
473
 
                sealed class LiftedBinaryOperatorMethod : BinaryOperatorMethod, OverloadResolution.ILiftedOperator
474
 
                {
475
 
                        readonly BinaryOperatorMethod baseMethod;
476
 
                        
477
 
                        public LiftedBinaryOperatorMethod(CSharpOperators operators, BinaryOperatorMethod baseMethod)
478
 
                                : base(operators.compilation)
479
 
                        {
480
 
                                this.baseMethod = baseMethod;
481
 
                                this.ReturnType = NullableType.Create(operators.compilation, baseMethod.ReturnType);
482
 
                                this.Parameters.Add(operators.MakeNullableParameter(baseMethod.Parameters[0]));
483
 
                                this.Parameters.Add(operators.MakeNullableParameter(baseMethod.Parameters[1]));
484
 
                        }
485
 
                        
486
 
                        public IList<IParameter> NonLiftedParameters {
487
 
                                get { return baseMethod.Parameters; }
488
 
                        }
489
 
                }
490
 
                #endregion
491
 
                
492
 
                #region Arithmetic operators
493
 
                // C# 4.0 spec: Ā§7.8.1 Multiplication operator
494
 
                
495
 
                OperatorMethod[] multiplicationOperators;
496
 
                
497
 
                public OperatorMethod[] MultiplicationOperators {
498
 
                        get {
499
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref multiplicationOperators);
500
 
                                if (ops != null) {
501
 
                                        return ops;
502
 
                                } else {
503
 
                                        return LazyInit.GetOrSet(ref multiplicationOperators, Lift(
504
 
                                                new LambdaBinaryOperatorMethod<int,     int>    (this, (a, b) => checked(a * b), (a, b) => unchecked(a * b)),
505
 
                                                new LambdaBinaryOperatorMethod<uint,    uint>   (this, (a, b) => checked(a * b), (a, b) => unchecked(a * b)),
506
 
                                                new LambdaBinaryOperatorMethod<long,    long>   (this, (a, b) => checked(a * b), (a, b) => unchecked(a * b)),
507
 
                                                new LambdaBinaryOperatorMethod<ulong,   ulong>  (this, (a, b) => checked(a * b), (a, b) => unchecked(a * b)),
508
 
                                                new LambdaBinaryOperatorMethod<float,   float>  (this, (a, b) => checked(a * b), (a, b) => unchecked(a * b)),
509
 
                                                new LambdaBinaryOperatorMethod<double,  double> (this, (a, b) => checked(a * b), (a, b) => unchecked(a * b)),
510
 
                                                new LambdaBinaryOperatorMethod<decimal, decimal>(this, (a, b) => checked(a * b), (a, b) => unchecked(a * b))
511
 
                                        ));
512
 
                                }
513
 
                        }
514
 
                }
515
 
                
516
 
                // C# 4.0 spec: Ā§7.8.2 Division operator
517
 
                OperatorMethod[] divisionOperators;
518
 
                
519
 
                public OperatorMethod[] DivisionOperators {
520
 
                        get {
521
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref divisionOperators);
522
 
                                if (ops != null) {
523
 
                                        return ops;
524
 
                                } else {
525
 
                                        return LazyInit.GetOrSet(ref divisionOperators, Lift(
526
 
                                                new LambdaBinaryOperatorMethod<int,     int>    (this, (a, b) => checked(a / b), (a, b) => unchecked(a / b)),
527
 
                                                new LambdaBinaryOperatorMethod<uint,    uint>   (this, (a, b) => checked(a / b), (a, b) => unchecked(a / b)),
528
 
                                                new LambdaBinaryOperatorMethod<long,    long>   (this, (a, b) => checked(a / b), (a, b) => unchecked(a / b)),
529
 
                                                new LambdaBinaryOperatorMethod<ulong,   ulong>  (this, (a, b) => checked(a / b), (a, b) => unchecked(a / b)),
530
 
                                                new LambdaBinaryOperatorMethod<float,   float>  (this, (a, b) => checked(a / b), (a, b) => unchecked(a / b)),
531
 
                                                new LambdaBinaryOperatorMethod<double,  double> (this, (a, b) => checked(a / b), (a, b) => unchecked(a / b)),
532
 
                                                new LambdaBinaryOperatorMethod<decimal, decimal>(this, (a, b) => checked(a / b), (a, b) => unchecked(a / b))
533
 
                                        ));
534
 
                                }
535
 
                        }
536
 
                }
537
 
                
538
 
                // C# 4.0 spec: Ā§7.8.3 Remainder operator
539
 
                OperatorMethod[] remainderOperators;
540
 
                
541
 
                public OperatorMethod[] RemainderOperators {
542
 
                        get {
543
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref remainderOperators);
544
 
                                if (ops != null) {
545
 
                                        return ops;
546
 
                                } else {
547
 
                                        return LazyInit.GetOrSet(ref remainderOperators, Lift(
548
 
                                                new LambdaBinaryOperatorMethod<int,     int>    (this, (a, b) => checked(a % b), (a, b) => unchecked(a % b)),
549
 
                                                new LambdaBinaryOperatorMethod<uint,    uint>   (this, (a, b) => checked(a % b), (a, b) => unchecked(a % b)),
550
 
                                                new LambdaBinaryOperatorMethod<long,    long>   (this, (a, b) => checked(a % b), (a, b) => unchecked(a % b)),
551
 
                                                new LambdaBinaryOperatorMethod<ulong,   ulong>  (this, (a, b) => checked(a % b), (a, b) => unchecked(a % b)),
552
 
                                                new LambdaBinaryOperatorMethod<float,   float>  (this, (a, b) => checked(a % b), (a, b) => unchecked(a % b)),
553
 
                                                new LambdaBinaryOperatorMethod<double,  double> (this, (a, b) => checked(a % b), (a, b) => unchecked(a % b)),
554
 
                                                new LambdaBinaryOperatorMethod<decimal, decimal>(this, (a, b) => checked(a % b), (a, b) => unchecked(a % b))
555
 
                                        ));
556
 
                                }
557
 
                        }
558
 
                }
559
 
                
560
 
                // C# 4.0 spec: Ā§7.8.3 Addition operator
561
 
                OperatorMethod[] additionOperators;
562
 
                
563
 
                public OperatorMethod[] AdditionOperators {
564
 
                        get {
565
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref additionOperators);
566
 
                                if (ops != null) {
567
 
                                        return ops;
568
 
                                } else {
569
 
                                        return LazyInit.GetOrSet(ref additionOperators, Lift(
570
 
                                                new LambdaBinaryOperatorMethod<int,     int>    (this, (a, b) => checked(a + b), (a, b) => unchecked(a + b)),
571
 
                                                new LambdaBinaryOperatorMethod<uint,    uint>   (this, (a, b) => checked(a + b), (a, b) => unchecked(a + b)),
572
 
                                                new LambdaBinaryOperatorMethod<long,    long>   (this, (a, b) => checked(a + b), (a, b) => unchecked(a + b)),
573
 
                                                new LambdaBinaryOperatorMethod<ulong,   ulong>  (this, (a, b) => checked(a + b), (a, b) => unchecked(a + b)),
574
 
                                                new LambdaBinaryOperatorMethod<float,   float>  (this, (a, b) => checked(a + b), (a, b) => unchecked(a + b)),
575
 
                                                new LambdaBinaryOperatorMethod<double,  double> (this, (a, b) => checked(a + b), (a, b) => unchecked(a + b)),
576
 
                                                new LambdaBinaryOperatorMethod<decimal, decimal>(this, (a, b) => checked(a + b), (a, b) => unchecked(a + b)),
577
 
                                                new StringConcatenation(this, TypeCode.String, TypeCode.String),
578
 
                                                new StringConcatenation(this, TypeCode.String, TypeCode.Object),
579
 
                                                new StringConcatenation(this, TypeCode.Object, TypeCode.String)
580
 
                                        ));
581
 
                                }
582
 
                        }
583
 
                }
584
 
                
585
 
                // not in this list, but handled manually: enum addition, delegate combination
586
 
                sealed class StringConcatenation : BinaryOperatorMethod
587
 
                {
588
 
                        bool canEvaluateAtCompileTime;
589
 
                        
590
 
                        public StringConcatenation(CSharpOperators operators, TypeCode p1, TypeCode p2)
591
 
                                : base(operators.compilation)
592
 
                        {
593
 
                                this.canEvaluateAtCompileTime = p1 == TypeCode.String && p2 == TypeCode.String;
594
 
                                this.ReturnType = operators.compilation.FindType(KnownTypeCode.String);
595
 
                                this.Parameters.Add(operators.MakeParameter(p1));
596
 
                                this.Parameters.Add(operators.MakeParameter(p2));
597
 
                        }
598
 
                        
599
 
                        public override bool CanEvaluateAtCompileTime {
600
 
                                get { return canEvaluateAtCompileTime; }
601
 
                        }
602
 
                        
603
 
                        public override object Invoke(CSharpResolver resolver, object lhs, object rhs)
604
 
                        {
605
 
                                return string.Concat(lhs, rhs);
606
 
                        }
607
 
                }
608
 
                
609
 
                // C# 4.0 spec: Ā§7.8.4 Subtraction operator
610
 
                OperatorMethod[] subtractionOperators;
611
 
                
612
 
                public OperatorMethod[] SubtractionOperators {
613
 
                        get {
614
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref subtractionOperators);
615
 
                                if (ops != null) {
616
 
                                        return ops;
617
 
                                } else {
618
 
                                        return LazyInit.GetOrSet(ref subtractionOperators, Lift(
619
 
                                                new LambdaBinaryOperatorMethod<int,     int>    (this, (a, b) => checked(a - b), (a, b) => unchecked(a - b)),
620
 
                                                new LambdaBinaryOperatorMethod<uint,    uint>   (this, (a, b) => checked(a - b), (a, b) => unchecked(a - b)),
621
 
                                                new LambdaBinaryOperatorMethod<long,    long>   (this, (a, b) => checked(a - b), (a, b) => unchecked(a - b)),
622
 
                                                new LambdaBinaryOperatorMethod<ulong,   ulong>  (this, (a, b) => checked(a - b), (a, b) => unchecked(a - b)),
623
 
                                                new LambdaBinaryOperatorMethod<float,   float>  (this, (a, b) => checked(a - b), (a, b) => unchecked(a - b)),
624
 
                                                new LambdaBinaryOperatorMethod<double,  double> (this, (a, b) => checked(a - b), (a, b) => unchecked(a - b)),
625
 
                                                new LambdaBinaryOperatorMethod<decimal, decimal>(this, (a, b) => checked(a - b), (a, b) => unchecked(a - b))
626
 
                                        ));
627
 
                                }
628
 
                        }
629
 
                }
630
 
                
631
 
                // C# 4.0 spec: Ā§7.8.5 Shift operators
632
 
                OperatorMethod[] shiftLeftOperators;
633
 
                
634
 
                public OperatorMethod[] ShiftLeftOperators {
635
 
                        get {
636
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref shiftLeftOperators);
637
 
                                if (ops != null) {
638
 
                                        return ops;
639
 
                                } else {
640
 
                                        return LazyInit.GetOrSet(ref shiftLeftOperators, Lift(
641
 
                                                new LambdaBinaryOperatorMethod<int,   int>(this, (a, b) => a << b),
642
 
                                                new LambdaBinaryOperatorMethod<uint,  int>(this, (a, b) => a << b),
643
 
                                                new LambdaBinaryOperatorMethod<long,  int>(this, (a, b) => a << b),
644
 
                                                new LambdaBinaryOperatorMethod<ulong, int>(this, (a, b) => a << b)
645
 
                                        ));
646
 
                                }
647
 
                        }
648
 
                }
649
 
                
650
 
                OperatorMethod[] shiftRightOperators;
651
 
                
652
 
                public OperatorMethod[] ShiftRightOperators {
653
 
                        get {
654
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref shiftRightOperators);
655
 
                                if (ops != null) {
656
 
                                        return ops;
657
 
                                } else {
658
 
                                        return LazyInit.GetOrSet(ref shiftRightOperators, Lift(
659
 
                                                new LambdaBinaryOperatorMethod<int,   int>(this, (a, b) => a >> b),
660
 
                                                new LambdaBinaryOperatorMethod<uint,  int>(this, (a, b) => a >> b),
661
 
                                                new LambdaBinaryOperatorMethod<long,  int>(this, (a, b) => a >> b),
662
 
                                                new LambdaBinaryOperatorMethod<ulong, int>(this, (a, b) => a >> b)
663
 
                                        ));
664
 
                                }
665
 
                        }
666
 
                }
667
 
                #endregion
668
 
                
669
 
                #region Equality operators
670
 
                sealed class EqualityOperatorMethod : BinaryOperatorMethod
671
 
                {
672
 
                        public readonly TypeCode Type;
673
 
                        public readonly bool Negate;
674
 
                        
675
 
                        public EqualityOperatorMethod(CSharpOperators operators, TypeCode type, bool negate)
676
 
                                : base(operators.compilation)
677
 
                        {
678
 
                                this.Negate = negate;
679
 
                                this.Type = type;
680
 
                                this.ReturnType = operators.compilation.FindType(KnownTypeCode.Boolean);
681
 
                                this.Parameters.Add(operators.MakeParameter(type));
682
 
                                this.Parameters.Add(operators.MakeParameter(type));
683
 
                        }
684
 
                        
685
 
                        public override bool CanEvaluateAtCompileTime {
686
 
                                get { return Type != TypeCode.Object; }
687
 
                        }
688
 
                        
689
 
                        public override object Invoke(CSharpResolver resolver, object lhs, object rhs)
690
 
                        {
691
 
                                if (lhs == null && rhs == null)
692
 
                                        return !Negate; // ==: true; !=: false
693
 
                                if (lhs == null || rhs == null)
694
 
                                        return Negate; // ==: false; !=: true
695
 
                                lhs = resolver.CSharpPrimitiveCast(Type, lhs);
696
 
                                rhs = resolver.CSharpPrimitiveCast(Type, rhs);
697
 
                                bool equal;
698
 
                                if (Type == TypeCode.Single) {
699
 
                                        equal = (float)lhs == (float)rhs;
700
 
                                } else if (Type == TypeCode.Double) {
701
 
                                        equal = (double)lhs == (double)rhs;
702
 
                                } else {
703
 
                                        equal = object.Equals(lhs, rhs);
704
 
                                }
705
 
                                return equal ^ Negate;
706
 
                        }
707
 
                        
708
 
                        public override OperatorMethod Lift(CSharpOperators operators)
709
 
                        {
710
 
                                if (Type == TypeCode.Object || Type == TypeCode.String)
711
 
                                        return null;
712
 
                                else
713
 
                                        return new LiftedEqualityOperatorMethod(operators, this);
714
 
                        }
715
 
                }
716
 
                
717
 
                sealed class LiftedEqualityOperatorMethod : BinaryOperatorMethod, OverloadResolution.ILiftedOperator
718
 
                {
719
 
                        readonly EqualityOperatorMethod baseMethod;
720
 
                        
721
 
                        public LiftedEqualityOperatorMethod(CSharpOperators operators, EqualityOperatorMethod baseMethod)
722
 
                                : base(operators.compilation)
723
 
                        {
724
 
                                this.baseMethod = baseMethod;
725
 
                                this.ReturnType = baseMethod.ReturnType;
726
 
                                IParameter p = operators.MakeNullableParameter(baseMethod.Parameters[0]);
727
 
                                this.Parameters.Add(p);
728
 
                                this.Parameters.Add(p);
729
 
                        }
730
 
                        
731
 
                        public override bool CanEvaluateAtCompileTime {
732
 
                                get { return baseMethod.CanEvaluateAtCompileTime; }
733
 
                        }
734
 
                        
735
 
                        public override object Invoke(CSharpResolver resolver, object lhs, object rhs)
736
 
                        {
737
 
                                return baseMethod.Invoke(resolver, lhs, rhs);
738
 
                        }
739
 
                        
740
 
                        public IList<IParameter> NonLiftedParameters {
741
 
                                get { return baseMethod.Parameters; }
742
 
                        }
743
 
                }
744
 
                
745
 
                // C# 4.0 spec: Ā§7.10 Relational and type-testing operators
746
 
                static readonly TypeCode[] valueEqualityOperatorsFor = {
747
 
                        TypeCode.Int32, TypeCode.UInt32,
748
 
                        TypeCode.Int64, TypeCode.UInt64,
749
 
                        TypeCode.Single, TypeCode.Double,
750
 
                        TypeCode.Decimal,
751
 
                        TypeCode.Boolean
752
 
                };
753
 
                
754
 
                OperatorMethod[] valueEqualityOperators;
755
 
                
756
 
                public OperatorMethod[] ValueEqualityOperators {
757
 
                        get {
758
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref valueEqualityOperators);
759
 
                                if (ops != null) {
760
 
                                        return ops;
761
 
                                } else {
762
 
                                        return LazyInit.GetOrSet(ref valueEqualityOperators, Lift(
763
 
                                                valueEqualityOperatorsFor.Select(c => new EqualityOperatorMethod(this, c, false)).ToArray()
764
 
                                        ));
765
 
                                }
766
 
                        }
767
 
                }
768
 
                
769
 
                OperatorMethod[] valueInequalityOperators;
770
 
                
771
 
                public OperatorMethod[] ValueInequalityOperators {
772
 
                        get {
773
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref valueInequalityOperators);
774
 
                                if (ops != null) {
775
 
                                        return ops;
776
 
                                } else {
777
 
                                        return LazyInit.GetOrSet(ref valueInequalityOperators, Lift(
778
 
                                                valueEqualityOperatorsFor.Select(c => new EqualityOperatorMethod(this, c, true)).ToArray()
779
 
                                        ));
780
 
                                }
781
 
                        }
782
 
                }
783
 
                
784
 
                OperatorMethod[] referenceEqualityOperators;
785
 
                
786
 
                public OperatorMethod[] ReferenceEqualityOperators {
787
 
                        get {
788
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref referenceEqualityOperators);
789
 
                                if (ops != null) {
790
 
                                        return ops;
791
 
                                } else {
792
 
                                        return LazyInit.GetOrSet(ref referenceEqualityOperators, Lift(
793
 
                                                new EqualityOperatorMethod(this, TypeCode.Object, false),
794
 
                                                new EqualityOperatorMethod(this, TypeCode.String, false)
795
 
                                        ));
796
 
                                }
797
 
                        }
798
 
                }
799
 
                
800
 
                OperatorMethod[] referenceInequalityOperators;
801
 
                
802
 
                public OperatorMethod[] ReferenceInequalityOperators {
803
 
                        get {
804
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref referenceInequalityOperators);
805
 
                                if (ops != null) {
806
 
                                        return ops;
807
 
                                } else {
808
 
                                        return LazyInit.GetOrSet(ref referenceInequalityOperators, Lift(
809
 
                                                new EqualityOperatorMethod(this, TypeCode.Object, true),
810
 
                                                new EqualityOperatorMethod(this, TypeCode.String, true)
811
 
                                        ));
812
 
                                }
813
 
                        }
814
 
                }
815
 
                #endregion
816
 
                
817
 
                #region Relational Operators
818
 
                sealed class RelationalOperatorMethod<T1, T2> : BinaryOperatorMethod
819
 
                {
820
 
                        readonly Func<T1, T2, bool> func;
821
 
                        
822
 
                        public RelationalOperatorMethod(CSharpOperators operators, Func<T1, T2, bool> func)
823
 
                                : base(operators.compilation)
824
 
                        {
825
 
                                this.ReturnType = operators.compilation.FindType(KnownTypeCode.Boolean);
826
 
                                this.Parameters.Add(operators.MakeParameter(Type.GetTypeCode(typeof(T1))));
827
 
                                this.Parameters.Add(operators.MakeParameter(Type.GetTypeCode(typeof(T2))));
828
 
                                this.func = func;
829
 
                        }
830
 
                        
831
 
                        public override bool CanEvaluateAtCompileTime {
832
 
                                get { return true; }
833
 
                        }
834
 
                        
835
 
                        public override object Invoke(CSharpResolver resolver, object lhs, object rhs)
836
 
                        {
837
 
                                if (lhs == null || rhs == null)
838
 
                                        return null;
839
 
                                return func((T1)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T1)), lhs),
840
 
                                            (T2)resolver.CSharpPrimitiveCast(Type.GetTypeCode(typeof(T2)), rhs));
841
 
                        }
842
 
                        
843
 
                        public override OperatorMethod Lift(CSharpOperators operators)
844
 
                        {
845
 
                                var lifted = new LiftedBinaryOperatorMethod(operators, this);
846
 
                                lifted.ReturnType = this.ReturnType; // don't lift the return type for relational operators
847
 
                                return lifted;
848
 
                        }
849
 
                }
850
 
                
851
 
                OperatorMethod[] lessThanOperators;
852
 
                
853
 
                public OperatorMethod[] LessThanOperators {
854
 
                        get {
855
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref lessThanOperators);
856
 
                                if (ops != null) {
857
 
                                        return ops;
858
 
                                } else {
859
 
                                        return LazyInit.GetOrSet(ref lessThanOperators, Lift(
860
 
                                                new RelationalOperatorMethod<int, int>        (this, (a, b) => a < b),
861
 
                                                new RelationalOperatorMethod<uint, uint>      (this, (a, b) => a < b),
862
 
                                                new RelationalOperatorMethod<long, long>      (this, (a, b) => a < b),
863
 
                                                new RelationalOperatorMethod<ulong, ulong>    (this, (a, b) => a < b),
864
 
                                                new RelationalOperatorMethod<float, float>    (this, (a, b) => a < b),
865
 
                                                new RelationalOperatorMethod<double, double>  (this, (a, b) => a < b),
866
 
                                                new RelationalOperatorMethod<decimal, decimal>(this, (a, b) => a < b)
867
 
                                        ));
868
 
                                }
869
 
                        }
870
 
                }
871
 
                
872
 
                OperatorMethod[] lessThanOrEqualOperators;
873
 
                
874
 
                public OperatorMethod[] LessThanOrEqualOperators {
875
 
                        get {
876
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref lessThanOrEqualOperators);
877
 
                                if (ops != null) {
878
 
                                        return ops;
879
 
                                } else {
880
 
                                        return LazyInit.GetOrSet(ref lessThanOrEqualOperators, Lift(
881
 
                                                new RelationalOperatorMethod<int, int>        (this, (a, b) => a <= b),
882
 
                                                new RelationalOperatorMethod<uint, uint>      (this, (a, b) => a <= b),
883
 
                                                new RelationalOperatorMethod<long, long>      (this, (a, b) => a <= b),
884
 
                                                new RelationalOperatorMethod<ulong, ulong>    (this, (a, b) => a <= b),
885
 
                                                new RelationalOperatorMethod<float, float>    (this, (a, b) => a <= b),
886
 
                                                new RelationalOperatorMethod<double, double>  (this, (a, b) => a <= b),
887
 
                                                new RelationalOperatorMethod<decimal, decimal>(this, (a, b) => a <= b)
888
 
                                        ));
889
 
                                }
890
 
                        }
891
 
                }
892
 
                
893
 
                OperatorMethod[] greaterThanOperators;
894
 
                
895
 
                public OperatorMethod[] GreaterThanOperators {
896
 
                        get {
897
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref greaterThanOperators);
898
 
                                if (ops != null) {
899
 
                                        return ops;
900
 
                                } else {
901
 
                                        return LazyInit.GetOrSet(ref greaterThanOperators, Lift(
902
 
                                                new RelationalOperatorMethod<int, int>        (this, (a, b) => a > b),
903
 
                                                new RelationalOperatorMethod<uint, uint>      (this, (a, b) => a > b),
904
 
                                                new RelationalOperatorMethod<long, long>      (this, (a, b) => a > b),
905
 
                                                new RelationalOperatorMethod<ulong, ulong>    (this, (a, b) => a > b),
906
 
                                                new RelationalOperatorMethod<float, float>    (this, (a, b) => a > b),
907
 
                                                new RelationalOperatorMethod<double, double>  (this, (a, b) => a > b),
908
 
                                                new RelationalOperatorMethod<decimal, decimal>(this, (a, b) => a > b)
909
 
                                        ));
910
 
                                }
911
 
                        }
912
 
                }
913
 
                
914
 
                OperatorMethod[] greaterThanOrEqualOperators;
915
 
                
916
 
                public OperatorMethod[] GreaterThanOrEqualOperators {
917
 
                        get {
918
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref greaterThanOrEqualOperators);
919
 
                                if (ops != null) {
920
 
                                        return ops;
921
 
                                } else {
922
 
                                        return LazyInit.GetOrSet(ref greaterThanOrEqualOperators, Lift(
923
 
                                                new RelationalOperatorMethod<int, int>        (this, (a, b) => a >= b),
924
 
                                                new RelationalOperatorMethod<uint, uint>      (this, (a, b) => a >= b),
925
 
                                                new RelationalOperatorMethod<long, long>      (this, (a, b) => a >= b),
926
 
                                                new RelationalOperatorMethod<ulong, ulong>    (this, (a, b) => a >= b),
927
 
                                                new RelationalOperatorMethod<float, float>    (this, (a, b) => a >= b),
928
 
                                                new RelationalOperatorMethod<double, double>  (this, (a, b) => a >= b),
929
 
                                                new RelationalOperatorMethod<decimal, decimal>(this, (a, b) => a >= b)
930
 
                                        ));
931
 
                                }
932
 
                        }
933
 
                }
934
 
                #endregion
935
 
                
936
 
                #region Bitwise operators
937
 
                OperatorMethod[] logicalAndOperators;
938
 
                
939
 
                public OperatorMethod[] LogicalAndOperators {
940
 
                        get {
941
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref logicalAndOperators);
942
 
                                if (ops != null) {
943
 
                                        return ops;
944
 
                                } else {
945
 
                                        return LazyInit.GetOrSet(ref logicalAndOperators, new OperatorMethod[] {
946
 
                                                                        new LambdaBinaryOperatorMethod<bool, bool>(this, (a, b) => a & b)
947
 
                                                                 });
948
 
                                }
949
 
                        }
950
 
                }
951
 
                
952
 
                
953
 
                OperatorMethod[] bitwiseAndOperators;
954
 
                
955
 
                public OperatorMethod[] BitwiseAndOperators {
956
 
                        get {
957
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref bitwiseAndOperators);
958
 
                                if (ops != null) {
959
 
                                        return ops;
960
 
                                } else {
961
 
                                        return LazyInit.GetOrSet(ref bitwiseAndOperators, Lift(
962
 
                                                new LambdaBinaryOperatorMethod<int, int>    (this, (a, b) => a & b),
963
 
                                                new LambdaBinaryOperatorMethod<uint, uint>  (this, (a, b) => a & b),
964
 
                                                new LambdaBinaryOperatorMethod<long, long>  (this, (a, b) => a & b),
965
 
                                                new LambdaBinaryOperatorMethod<ulong, ulong>(this, (a, b) => a & b),
966
 
                                                this.LogicalAndOperators[0]
967
 
                                        ));
968
 
                                }
969
 
                        }
970
 
                }
971
 
                
972
 
                
973
 
                OperatorMethod[] logicalOrOperators;
974
 
                
975
 
                public OperatorMethod[] LogicalOrOperators {
976
 
                        get {
977
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref logicalOrOperators);
978
 
                                if (ops != null) {
979
 
                                        return ops;
980
 
                                } else {
981
 
                                        return LazyInit.GetOrSet(ref logicalOrOperators, new OperatorMethod[] {
982
 
                                                                        new LambdaBinaryOperatorMethod<bool, bool>(this, (a, b) => a | b)
983
 
                                                                 });
984
 
                                }
985
 
                        }
986
 
                }
987
 
                
988
 
                OperatorMethod[] bitwiseOrOperators;
989
 
                
990
 
                public OperatorMethod[] BitwiseOrOperators {
991
 
                        get {
992
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref bitwiseOrOperators);
993
 
                                if (ops != null) {
994
 
                                        return ops;
995
 
                                } else {
996
 
                                        return LazyInit.GetOrSet(ref bitwiseOrOperators, Lift(
997
 
                                                new LambdaBinaryOperatorMethod<int, int>    (this, (a, b) => a | b),
998
 
                                                new LambdaBinaryOperatorMethod<uint, uint>  (this, (a, b) => a | b),
999
 
                                                new LambdaBinaryOperatorMethod<long, long>  (this, (a, b) => a | b),
1000
 
                                                new LambdaBinaryOperatorMethod<ulong, ulong>(this, (a, b) => a | b),
1001
 
                                                this.LogicalOrOperators[0]
1002
 
                                        ));
1003
 
                                }
1004
 
                        }
1005
 
                }
1006
 
                
1007
 
                // Note: the logic for the lifted bool? bitwise operators is wrong;
1008
 
                // we produce "true | null" = "null" when it should be true. However, this is irrelevant
1009
 
                // because bool? cannot be a compile-time type.
1010
 
                
1011
 
                OperatorMethod[] bitwiseXorOperators;
1012
 
 
1013
 
                public OperatorMethod[] BitwiseXorOperators {
1014
 
                        get {
1015
 
                                OperatorMethod[] ops = LazyInit.VolatileRead(ref bitwiseXorOperators);
1016
 
                                if (ops != null) {
1017
 
                                        return ops;
1018
 
                                } else {
1019
 
                                        return LazyInit.GetOrSet(ref bitwiseXorOperators, Lift(
1020
 
                                                new LambdaBinaryOperatorMethod<int, int>    (this, (a, b) => a ^ b),
1021
 
                                                new LambdaBinaryOperatorMethod<uint, uint>  (this, (a, b) => a ^ b),
1022
 
                                                new LambdaBinaryOperatorMethod<long, long>  (this, (a, b) => a ^ b),
1023
 
                                                new LambdaBinaryOperatorMethod<ulong, ulong>(this, (a, b) => a ^ b),
1024
 
                                                new LambdaBinaryOperatorMethod<bool, bool>  (this, (a, b) => a ^ b)
1025
 
                                        ));
1026
 
                                }
1027
 
                        }
1028
 
                }
1029
 
                #endregion
1030
 
        }
1031
 
}