Summary

Class:AsyncEnumeration.AsyncEnumerationExtensions
Assembly:AsyncEnumeration.Implementation.Enumerable
File(s):/repo-dir/contents/Source/Code/AsyncEnumeration.Implementation.Enumerable/FromSynchronous.cs
/repo-dir/contents/Source/Code/AsyncEnumeration.Implementation.Enumerable/Singleton.cs
Covered lines:5
Uncovered lines:0
Coverable lines:5
Total lines:327
Line coverage:100%
Branch coverage:100%
Tag:7d9974899246b95481b7aa9cd3a1462ae2a67c91

Coverage History

Metrics

MethodCyclomatic complexity NPath complexity Sequence coverage Branch coverage
AsAsyncEnumerable(...)201%1%
AsAsyncEnumerable(...)201%1%
AsSingletonAsync(...)101%0%
AsSingletonAsync(...)201%1%
AsSingletonAsync(...)201%1%

File(s)

/repo-dir/contents/Source/Code/AsyncEnumeration.Implementation.Enumerable/FromSynchronous.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   namespace Implementation.Enumerable
 30   {
 31      internal sealed class ArrayEnumerator<T> : IAsyncEnumerator<T>
 32      {
 33         private const Int32 NOT_FETCHED = 0;
 34         private const Int32 FETCHED = 1;
 35
 36         private readonly T[] _array;
 37         private Int32 _index;
 38
 39         public ArrayEnumerator( T[] array )
 40            => this._array = ArgumentValidator.ValidateNotNull( nameof( array ), array );
 41
 42         public Task<Boolean> WaitForNextAsync()
 43            => TaskUtils.TaskFromBoolean( this._index < this._array.Length );
 44
 45         public T TryGetNext( out Boolean success )
 46         {
 47            var array = this._array;
 48            var idx = Interlocked.Increment( ref this._index );
 49            success = idx <= array.Length;
 50            return success ? array[idx - 1] : default;
 51         }
 52
 53         public Task DisposeAsync()
 54            => TaskUtils.CompletedTask;
 55      }
 56
 57      internal sealed class SynchronousEnumerableEnumerator<T> : IAsyncEnumerator<T>
 58      {
 59         private const Int32 STATE_INITIAL = 0;
 60         private const Int32 STATE_MOVENEXT_CALLED = 1;
 61         private const Int32 STATE_ENDED = 2;
 62
 63         private readonly IEnumerator<T> _enumerator;
 64         private Int32 _state;
 65
 66         public SynchronousEnumerableEnumerator( IEnumerator<T> syncEnumerator )
 67            => this._enumerator = ArgumentValidator.ValidateNotNull( nameof( syncEnumerator ), syncEnumerator );
 68
 69         public Task<Boolean> WaitForNextAsync()
 70            => TaskUtils.TaskFromBoolean( Interlocked.CompareExchange( ref this._state, STATE_MOVENEXT_CALLED, STATE_INI
 71
 72         public T TryGetNext( out Boolean success )
 73         {
 74            success = this._state == STATE_MOVENEXT_CALLED;
 75            var retVal = success ? this._enumerator.Current : default;
 76            if ( success && !this._enumerator.MoveNext() )
 77            {
 78               Interlocked.Exchange( ref this._state, STATE_ENDED );
 79            }
 80            return retVal;
 81         }
 82
 83
 84         public Task DisposeAsync()
 85         {
 86            this._enumerator.Dispose();
 87            return TaskUtils.CompletedTask;
 88         }
 89
 90      }
 91   }
 92
 93   /// <summary>
 94   /// This class contains extension methods for types not defined in this assembly.
 95   /// </summary>
 96   public static partial class AsyncEnumerationExtensions
 97   {
 98      /// <summary>
 99      /// This extension method will wrap this array into <see cref="IAsyncEnumerable{T}"/>.
 100      /// </summary>
 101      /// <typeparam name="T">The type of array elements.</typeparam>
 102      /// <param name="array">This array.</param>
 103      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 104      /// <returns><see cref="IAsyncEnumerable{T}"/> which will enumerate over the contents of the array.</returns>
 105      /// <exception cref="NullReferenceException">If this array is <c>null</c>.</exception>
 106      public static IAsyncEnumerable<T> AsAsyncEnumerable<T>(
 107         this T[] array,
 108         IAsyncProvider asyncProvider
 3109         ) => AsyncEnumerationFactory.FromGeneratorCallback( ArgumentValidator.ValidateNotNullReference( array ), a => n
 110
 111      /// <summary>
 112      /// This extension method will wrap this <see cref="IEnumerable{T}"/> into <see cref="IAsyncEnumerable{T}"/>.
 113      /// </summary>
 114      /// <typeparam name="T">The type of <see cref="IEnumerable{T}"/> elements.</typeparam>
 115      /// <param name="enumerable">This <see cref="IEnumerable{T}"/>.</param>
 116      /// <param name="asyncProvider">The <see cref="IAsyncProvider"/> for the returned <see cref="IAsyncEnumerable{T}"/
 117      /// <returns><see cref="IAsyncEnumerable{T}"/> which will enumerate over this <see cref="IEnumerable{T}"/>.</retur
 118      /// <exception cref="NullReferenceException">If this <see cref="IEnumerable{T}"/> is <c>null</c>.</exception>
 119      public static IAsyncEnumerable<T> AsAsyncEnumerable<T>(
 120         this IEnumerable<T> enumerable,
 121         IAsyncProvider asyncProvider
 61122         ) => AsyncEnumerationFactory.FromGeneratorCallback( ArgumentValidator.ValidateNotNullReference( enumerable ), e
 123   }
 124}

/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
 66         public AsyncSingletonEnumerator( Task<T> asyncValue )
 67            => this._asyncValue = ArgumentValidator.ValidateNotNull( nameof( asyncValue ), asyncValue );
 68
 69         public Task<Boolean> WaitForNextAsync()
 70         {
 71            Task<Boolean> retVal;
 72            if ( Interlocked.CompareExchange( ref this._state, STATE_WAIT_CALLED, STATE_INITIAL ) == STATE_INITIAL )
 73            {
 74               if ( this._asyncValue.IsCompleted )
 75               {
 76                  retVal = TaskUtils.True;
 77               }
 78               else
 79               {
 80                  retVal = this.ReallyWaitForNextAsync();
 81               }
 82            }
 83            else
 84            {
 85               retVal = TaskUtils.False;
 86            }
 87            return retVal;
 88         }
 89
 90         public T TryGetNext( out Boolean success )
 91         {
 92            success = Interlocked.CompareExchange( ref this._state, STATE_GET_CALLED, STATE_WAIT_CALLED ) == STATE_WAIT_
 93            return success ? this._asyncValue.Result : default;
 94         }
 95
 96         public Task DisposeAsync()
 97            => TaskUtils.CompletedTask;
 98
 99         private async Task<Boolean> ReallyWaitForNextAsync()
 100         {
 101            await this._asyncValue;
 102            return true;
 103         }
 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      {
 1174         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
 2188         ) => 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
 2200         ) => AsyncEnumerationFactory.FromGeneratorCallback( task, t => new ValueTaskAsyncSingletonEnumerator<T>( t ), a
 201
 202   }
 203}