Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / System.Core / System / Linq / Parallel / Enumerables / EmptyEnumerable.cs
1 // ==++==
2 //
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 // =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
7 //
8 // EmptyEnumerable.cs
9 //
10 // <OWNER>Microsoft</OWNER>
11 //
12 // =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
13
14 using System.Collections;
15 using System.Collections.Generic;
16
17 namespace System.Linq.Parallel
18 {
19     /// <summary>
20     /// We occ----ionally need a no-op enumerator to stand-in when we don't have data left
21     /// within a partition's data stream. These are simple enumerable and enumerator
22     /// implementations that always and consistently yield no elements.
23     /// </summary>
24     /// <typeparam name="T"></typeparam>
25     internal class EmptyEnumerable<T> : ParallelQuery<T>
26     {
27         private EmptyEnumerable()
28             : base(QuerySettings.Empty)
29         {
30         }
31
32         // A singleton cached and shared among callers.
33         private static volatile EmptyEnumerable<T> s_instance;
34         private static volatile EmptyEnumerator<T> s_enumeratorInstance;
35
36         internal static EmptyEnumerable<T> Instance
37         {
38             get
39             {
40                 if (s_instance == null)
41                 {
42                     // There is no need for thread safety here.
43                     s_instance = new EmptyEnumerable<T>();
44                 }
45
46                 return s_instance;
47             }
48         }
49
50         public override IEnumerator<T> GetEnumerator()
51         {
52             if (s_enumeratorInstance == null)
53             {
54                 // There is no need for thread safety here.
55                 s_enumeratorInstance = new EmptyEnumerator<T>();
56             }
57
58             return s_enumeratorInstance;
59         }
60     }
61
62     internal class EmptyEnumerator<T> : QueryOperatorEnumerator<T, int>, IEnumerator<T>
63     {
64         internal override bool MoveNext(ref T currentElement, ref int currentKey)
65         {
66             return false;
67         }
68
69         // IEnumerator<T> methods.
70         public T Current { get { return default(T); } }
71         object IEnumerator.Current { get { return null; } }
72         public bool MoveNext() { return false; }
73         void Collections.IEnumerator.Reset() { }
74     }
75 }