Summary

Class:AsyncEnumeration.Implementation.Enumerable.AsyncSingletonEnumerator`1
Assembly:AsyncEnumeration.Implementation.Enumerable
File(s):/repo-dir/contents/Source/Code/AsyncEnumeration.Implementation.Enumerable/Singleton.cs
Covered lines:14
Uncovered lines:2
Coverable lines:16
Total lines:203
Line coverage:87.5%
Branch coverage:87.5%
Tag:7d9974899246b95481b7aa9cd3a1462ae2a67c91

Coverage History

Metrics

MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage
.ctor(...)101%0%
WaitForNextAsync()400.75%0.75%
TryGetNext(...)201%1%
DisposeAsync()101%0%
ReallyWaitForNextAsync()201%1%

File(s)

/repo-dir/contents/Source/Code/AsyncEnumeration.Implementation.Enumerable/Singleton.cs

#LineLine coverage
 1/*
 2 * Copyright 2017 Stanislav Muhametsin. All rights Reserved.
 3 *
 4 * Licensed  under the  Apache License,  Version 2.0  (the "License");
 5 * you may not use  this file  except in  compliance with the License.
 6 * You may obtain a copy of the License at
 7 *
 8 *   http://www.apache.org/licenses/LICENSE-2.0
 9 *
 10 * Unless required by applicable law or agreed to in writing, software
 11 * distributed  under the  License is distributed on an "AS IS" BASIS,
 12 * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
 13 * implied.
 14 *
 15 * See the License for the specific language governing permissions and
 16 * limitations under the License.
 17 */
 18using AsyncEnumeration.Abstractions;
 19using AsyncEnumeration.Implementation.Enumerable;
 20using System;
 21using System.Collections.Generic;
 22using System.Text;
 23using System.Threading;
 24using System.Threading.Tasks;
 25using UtilPack;
 26
 27namespace AsyncEnumeration
 28{
 29
 30   namespace Implementation.Enumerable
 31   {
 32      //internal sealed class SingletonEnumerator<T> : IAsyncEnumerator<T>
 33      //{
 34      //   private const Int32 STATE_INITIAL = 0;
 35      //   private const Int32 STATE_WAIT_CALLED = 1;
 36      //   private const Int32 STATE_GET_CALLED = 2;
 37
 38      //   private readonly T _value;
 39      //   private Int32 _state;
 40
 41      //   public SingletonEnumerator( T value )
 42      //      => this._value = value;
 43
 44      //   public Task<Boolean> WaitForNextAsync()
 45      //      => TaskUtils.TaskFromBoolean( Interlocked.CompareExchange( ref this._state, STATE_WAIT_CALLED, STATE_INITI
 46
 47      //   public T TryGetNext( out Boolean success )
 48      //   {
 49      //      success = Interlocked.CompareExchange( ref this._state, STATE_GET_CALLED, STATE_WAIT_CALLED ) == STATE_WAI
 50      //      return success ? this._value : default;
 51      //   }
 52
 53      //   public Task DisposeAsync()
 54      //      => TaskUtils.CompletedTask;
 55      //}
 56
 57      internal sealed class AsyncSingletonEnumerator<T> : IAsyncEnumerator<T>
 58      {
 59         private const Int32 STATE_INITIAL = 0;
 60         private const Int32 STATE_WAIT_CALLED = 1;
 61         private const Int32 STATE_GET_CALLED = 2;
 62
 63         private readonly Task<T> _asyncValue;
 64         private Int32 _state;
 65
 166         public AsyncSingletonEnumerator( Task<T> asyncValue )
 167            => this._asyncValue = ArgumentValidator.ValidateNotNull( nameof( asyncValue ), asyncValue );
 68
 69         public Task<Boolean> WaitForNextAsync()
 70         {
 71            Task<Boolean> retVal;
 272            if ( Interlocked.CompareExchange( ref this._state, STATE_WAIT_CALLED, STATE_INITIAL ) == STATE_INITIAL )
 73            {
 174               if ( this._asyncValue.IsCompleted )
 75               {
 076                  retVal = TaskUtils.True;
 077               }
 78               else
 79               {
 180                  retVal = this.ReallyWaitForNextAsync();
 81               }
 182            }
 83            else
 84            {
 185               retVal = TaskUtils.False;
 86            }
 287            return retVal;
 88         }
 89
 90         public T TryGetNext( out Boolean success )
 91         {
 292            success = Interlocked.CompareExchange( ref this._state, STATE_GET_CALLED, STATE_WAIT_CALLED ) == STATE_WAIT_
 293            return success ? this._asyncValue.Result : default;
 94         }
 95
 96         public Task DisposeAsync()
 197            => TaskUtils.CompletedTask;
 98
 99         private async Task<Boolean> ReallyWaitForNextAsync()
 100         {
 1101            await this._asyncValue;
 1102            return true;
 1103         }
 104      }
 105
 106
 107      internal sealed class ValueTaskAsyncSingletonEnumerator<T> : IAsyncEnumerator<T>
 108      {
 109         private const Int32 STATE_INITIAL = 0;
 110         private const Int32 STATE_WAIT_CALLED = 1;
 111         private const Int32 STATE_GET_CALLED = 2;
 112
 113         private readonly ValueTask<T> _asyncValue;
 114         private Int32 _state;
 115
 116         public ValueTaskAsyncSingletonEnumerator( ValueTask<T> asyncValue )
 117         {
 118            this._asyncValue = asyncValue;
 119         }
 120
 121         public Task<Boolean> WaitForNextAsync()
 122         {
 123            Task<Boolean> retVal;
 124            if ( Interlocked.CompareExchange( ref this._state, STATE_WAIT_CALLED, STATE_INITIAL ) == STATE_INITIAL )
 125            {
 126               if ( this._asyncValue.IsCompleted )
 127               {
 128                  retVal = TaskUtils.True;
 129               }
 130               else
 131               {
 132                  retVal = this.ReallyWaitForNextAsync();
 133               }
 134            }
 135            else
 136            {
 137               retVal = TaskUtils.False;
 138            }
 139            return retVal;
 140         }
 141
 142         public T TryGetNext( out Boolean success )
 143         {
 144            success = Interlocked.CompareExchange( ref this._state, STATE_GET_CALLED, STATE_WAIT_CALLED ) == STATE_WAIT_
 145            return success ? this._asyncValue.Result : default;
 146         }
 147
 148         public Task DisposeAsync() =>
 149            TaskUtils.CompletedTask;
 150
 151         private async Task<Boolean> ReallyWaitForNextAsync()
 152         {
 153            await this._asyncValue;
 154            return true;
 155         }
 156      }
 157   }
 158
 159
 160   public static partial class AsyncEnumerationExtensions
 161   {
 162      /// <summary>
 163      /// Encapsulates this single value as <see cref="IAsyncEnumerable{T}"/> containing only this value.
 164      /// </summary>
 165      /// <typeparam name="T">The type of this value.</typeparam>
 166      /// <param name="value">This value</param>
 167      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 168      /// <returns><see cref="IAsyncEnumerable{T}"/> containing only this value.</returns>
 169      public static IAsyncEnumerable<T> AsSingletonAsync<T>(
 170         this T value,
 171         IAsyncProvider asyncProvider
 172         )
 173      {
 174         return AsyncEnumerable.Repeat( value, 1, asyncProvider );
 175      }
 176
 177      /// <summary>
 178      /// Encapsulates this asynchronous value as <see cref="IAsyncEnumerable{T}"/> containing only this value.
 179      /// </summary>
 180      /// <typeparam name="T">The type of this value.</typeparam>
 181      /// <param name="task">The task acquiring this value.</param>
 182      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 183      /// <returns><see cref="IAsyncEnumerable{T}"/> containing only this value.</returns>
 184      /// <exception cref="NullReferenceException">If this <see cref="Task{TResult}"/> is <c>null</c>.</exception>
 185      public static IAsyncEnumerable<T> AsSingletonAsync<T>(
 186         this Task<T> task,
 187         IAsyncProvider asyncProvider
 188         ) => AsyncEnumerationFactory.FromGeneratorCallback( ArgumentValidator.ValidateNotNullReference( task ), t => ne
 189
 190      /// <summary>
 191      /// Encapsulates this asynchronous value as <see cref="IAsyncEnumerable{T}"/> containing only this value.
 192      /// </summary>
 193      /// <typeparam name="T">The type of this value.</typeparam>
 194      /// <param name="task">The task acquiring this value.</param>
 195      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 196      /// <returns><see cref="IAsyncEnumerable{T}"/> containing only this value.</returns>
 197      public static IAsyncEnumerable<T> AsSingletonAsync<T>(
 198         this ValueTask<T> task,
 199         IAsyncProvider asyncProvider
 200         ) => AsyncEnumerationFactory.FromGeneratorCallback( task, t => new ValueTaskAsyncSingletonEnumerator<T>( t ), a
 201
 202   }
 203}