SelectMany.cs 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the Apache 2.0 License.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8. namespace System.Linq
  9. {
  10. public static partial class AsyncEnumerable
  11. {
  12. public static IAsyncEnumerable<TResult> SelectMany<TSource, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, IAsyncEnumerable<TResult>> selector)
  13. {
  14. if (source == null)
  15. throw Error.ArgumentNull(nameof(source));
  16. if (selector == null)
  17. throw Error.ArgumentNull(nameof(selector));
  18. return new SelectManyAsyncIterator<TSource, TResult>(source, selector);
  19. }
  20. public static IAsyncEnumerable<TResult> SelectMany<TSource, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<IAsyncEnumerable<TResult>>> selector)
  21. {
  22. if (source == null)
  23. throw Error.ArgumentNull(nameof(source));
  24. if (selector == null)
  25. throw Error.ArgumentNull(nameof(selector));
  26. return new SelectManyAsyncIteratorWithTask<TSource, TResult>(source, selector);
  27. }
  28. #if !NO_DEEP_CANCELLATION
  29. public static IAsyncEnumerable<TResult> SelectMany<TSource, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<IAsyncEnumerable<TResult>>> selector)
  30. {
  31. if (source == null)
  32. throw Error.ArgumentNull(nameof(source));
  33. if (selector == null)
  34. throw Error.ArgumentNull(nameof(selector));
  35. return new SelectManyAsyncIteratorWithTaskAndCancellation<TSource, TResult>(source, selector);
  36. }
  37. #endif
  38. public static IAsyncEnumerable<TResult> SelectMany<TSource, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, int, IAsyncEnumerable<TResult>> selector)
  39. {
  40. if (source == null)
  41. throw Error.ArgumentNull(nameof(source));
  42. if (selector == null)
  43. throw Error.ArgumentNull(nameof(selector));
  44. return new SelectManyWithIndexAsyncIterator<TSource, TResult>(source, selector);
  45. }
  46. public static IAsyncEnumerable<TResult> SelectMany<TSource, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, int, ValueTask<IAsyncEnumerable<TResult>>> selector)
  47. {
  48. if (source == null)
  49. throw Error.ArgumentNull(nameof(source));
  50. if (selector == null)
  51. throw Error.ArgumentNull(nameof(selector));
  52. return new SelectManyWithIndexAsyncIteratorWithTask<TSource, TResult>(source, selector);
  53. }
  54. #if !NO_DEEP_CANCELLATION
  55. public static IAsyncEnumerable<TResult> SelectMany<TSource, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, int, CancellationToken, ValueTask<IAsyncEnumerable<TResult>>> selector)
  56. {
  57. if (source == null)
  58. throw Error.ArgumentNull(nameof(source));
  59. if (selector == null)
  60. throw Error.ArgumentNull(nameof(selector));
  61. return new SelectManyWithIndexAsyncIteratorWithTaskAndCancellation<TSource, TResult>(source, selector);
  62. }
  63. #endif
  64. public static IAsyncEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, IAsyncEnumerable<TCollection>> selector, Func<TSource, TCollection, TResult> resultSelector)
  65. {
  66. if (source == null)
  67. throw Error.ArgumentNull(nameof(source));
  68. if (selector == null)
  69. throw Error.ArgumentNull(nameof(selector));
  70. if (resultSelector == null)
  71. throw Error.ArgumentNull(nameof(resultSelector));
  72. return new SelectManyAsyncIterator<TSource, TCollection, TResult>(source, selector, resultSelector);
  73. }
  74. public static IAsyncEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<IAsyncEnumerable<TCollection>>> selector, Func<TSource, TCollection, ValueTask<TResult>> resultSelector)
  75. {
  76. if (source == null)
  77. throw Error.ArgumentNull(nameof(source));
  78. if (selector == null)
  79. throw Error.ArgumentNull(nameof(selector));
  80. if (resultSelector == null)
  81. throw Error.ArgumentNull(nameof(resultSelector));
  82. return new SelectManyAsyncIteratorWithTask<TSource, TCollection, TResult>(source, selector, resultSelector);
  83. }
  84. #if !NO_DEEP_CANCELLATION
  85. public static IAsyncEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<IAsyncEnumerable<TCollection>>> selector, Func<TSource, TCollection, CancellationToken, ValueTask<TResult>> resultSelector)
  86. {
  87. if (source == null)
  88. throw Error.ArgumentNull(nameof(source));
  89. if (selector == null)
  90. throw Error.ArgumentNull(nameof(selector));
  91. if (resultSelector == null)
  92. throw Error.ArgumentNull(nameof(resultSelector));
  93. return new SelectManyAsyncIteratorWithTaskAndCancellation<TSource, TCollection, TResult>(source, selector, resultSelector);
  94. }
  95. #endif
  96. public static IAsyncEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, int, IAsyncEnumerable<TCollection>> selector, Func<TSource, TCollection, TResult> resultSelector)
  97. {
  98. if (source == null)
  99. throw Error.ArgumentNull(nameof(source));
  100. if (selector == null)
  101. throw Error.ArgumentNull(nameof(selector));
  102. if (resultSelector == null)
  103. throw Error.ArgumentNull(nameof(resultSelector));
  104. return new SelectManyWithIndexAsyncIterator<TSource, TCollection, TResult>(source, selector, resultSelector);
  105. }
  106. public static IAsyncEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, int, ValueTask<IAsyncEnumerable<TCollection>>> selector, Func<TSource, TCollection, ValueTask<TResult>> resultSelector)
  107. {
  108. if (source == null)
  109. throw Error.ArgumentNull(nameof(source));
  110. if (selector == null)
  111. throw Error.ArgumentNull(nameof(selector));
  112. if (resultSelector == null)
  113. throw Error.ArgumentNull(nameof(resultSelector));
  114. return new SelectManyWithIndexAsyncIteratorWithTask<TSource, TCollection, TResult>(source, selector, resultSelector);
  115. }
  116. #if !NO_DEEP_CANCELLATION
  117. public static IAsyncEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IAsyncEnumerable<TSource> source, Func<TSource, int, CancellationToken, ValueTask<IAsyncEnumerable<TCollection>>> selector, Func<TSource, TCollection, CancellationToken, ValueTask<TResult>> resultSelector)
  118. {
  119. if (source == null)
  120. throw Error.ArgumentNull(nameof(source));
  121. if (selector == null)
  122. throw Error.ArgumentNull(nameof(selector));
  123. if (resultSelector == null)
  124. throw Error.ArgumentNull(nameof(resultSelector));
  125. return new SelectManyWithIndexAsyncIteratorWithTaskAndCancellation<TSource, TCollection, TResult>(source, selector, resultSelector);
  126. }
  127. #endif
  128. private sealed class SelectManyAsyncIterator<TSource, TResult> : AsyncIterator<TResult>
  129. {
  130. private const int State_Source = 1;
  131. private const int State_Result = 2;
  132. private readonly Func<TSource, IAsyncEnumerable<TResult>> _selector;
  133. private readonly IAsyncEnumerable<TSource> _source;
  134. private int _mode;
  135. private IAsyncEnumerator<TResult> _resultEnumerator;
  136. private IAsyncEnumerator<TSource> _sourceEnumerator;
  137. public SelectManyAsyncIterator(IAsyncEnumerable<TSource> source, Func<TSource, IAsyncEnumerable<TResult>> selector)
  138. {
  139. Debug.Assert(source != null);
  140. Debug.Assert(selector != null);
  141. _source = source;
  142. _selector = selector;
  143. }
  144. public override AsyncIteratorBase<TResult> Clone()
  145. {
  146. return new SelectManyAsyncIterator<TSource, TResult>(_source, _selector);
  147. }
  148. public override async ValueTask DisposeAsync()
  149. {
  150. if (_resultEnumerator != null)
  151. {
  152. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  153. _resultEnumerator = null;
  154. }
  155. if (_sourceEnumerator != null)
  156. {
  157. await _sourceEnumerator.DisposeAsync().ConfigureAwait(false);
  158. _sourceEnumerator = null;
  159. }
  160. await base.DisposeAsync().ConfigureAwait(false);
  161. }
  162. protected override async ValueTask<bool> MoveNextCore()
  163. {
  164. switch (_state)
  165. {
  166. case AsyncIteratorState.Allocated:
  167. _sourceEnumerator = _source.GetAsyncEnumerator(_cancellationToken);
  168. _mode = State_Source;
  169. _state = AsyncIteratorState.Iterating;
  170. goto case AsyncIteratorState.Iterating;
  171. case AsyncIteratorState.Iterating:
  172. switch (_mode)
  173. {
  174. case State_Source:
  175. if (await _sourceEnumerator.MoveNextAsync().ConfigureAwait(false))
  176. {
  177. if (_resultEnumerator != null)
  178. {
  179. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  180. }
  181. var inner = _selector(_sourceEnumerator.Current);
  182. _resultEnumerator = inner.GetAsyncEnumerator(_cancellationToken);
  183. _mode = State_Result;
  184. goto case State_Result;
  185. }
  186. break;
  187. case State_Result:
  188. if (await _resultEnumerator.MoveNextAsync().ConfigureAwait(false))
  189. {
  190. _current = _resultEnumerator.Current;
  191. return true;
  192. }
  193. _mode = State_Source;
  194. goto case State_Source; // loop
  195. }
  196. break;
  197. }
  198. await DisposeAsync().ConfigureAwait(false);
  199. return false;
  200. }
  201. }
  202. private sealed class SelectManyAsyncIteratorWithTask<TSource, TResult> : AsyncIterator<TResult>
  203. {
  204. private const int State_Source = 1;
  205. private const int State_Result = 2;
  206. private readonly Func<TSource, ValueTask<IAsyncEnumerable<TResult>>> _selector;
  207. private readonly IAsyncEnumerable<TSource> _source;
  208. private int _mode;
  209. private IAsyncEnumerator<TResult> _resultEnumerator;
  210. private IAsyncEnumerator<TSource> _sourceEnumerator;
  211. public SelectManyAsyncIteratorWithTask(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<IAsyncEnumerable<TResult>>> selector)
  212. {
  213. Debug.Assert(source != null);
  214. Debug.Assert(selector != null);
  215. _source = source;
  216. _selector = selector;
  217. }
  218. public override AsyncIteratorBase<TResult> Clone()
  219. {
  220. return new SelectManyAsyncIteratorWithTask<TSource, TResult>(_source, _selector);
  221. }
  222. public override async ValueTask DisposeAsync()
  223. {
  224. if (_resultEnumerator != null)
  225. {
  226. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  227. _resultEnumerator = null;
  228. }
  229. if (_sourceEnumerator != null)
  230. {
  231. await _sourceEnumerator.DisposeAsync().ConfigureAwait(false);
  232. _sourceEnumerator = null;
  233. }
  234. await base.DisposeAsync().ConfigureAwait(false);
  235. }
  236. protected override async ValueTask<bool> MoveNextCore()
  237. {
  238. switch (_state)
  239. {
  240. case AsyncIteratorState.Allocated:
  241. _sourceEnumerator = _source.GetAsyncEnumerator(_cancellationToken);
  242. _mode = State_Source;
  243. _state = AsyncIteratorState.Iterating;
  244. goto case AsyncIteratorState.Iterating;
  245. case AsyncIteratorState.Iterating:
  246. switch (_mode)
  247. {
  248. case State_Source:
  249. if (await _sourceEnumerator.MoveNextAsync().ConfigureAwait(false))
  250. {
  251. if (_resultEnumerator != null)
  252. {
  253. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  254. }
  255. var inner = await _selector(_sourceEnumerator.Current).ConfigureAwait(false);
  256. _resultEnumerator = inner.GetAsyncEnumerator(_cancellationToken);
  257. _mode = State_Result;
  258. goto case State_Result;
  259. }
  260. break;
  261. case State_Result:
  262. if (await _resultEnumerator.MoveNextAsync().ConfigureAwait(false))
  263. {
  264. _current = _resultEnumerator.Current;
  265. return true;
  266. }
  267. _mode = State_Source;
  268. goto case State_Source; // loop
  269. }
  270. break;
  271. }
  272. await DisposeAsync().ConfigureAwait(false);
  273. return false;
  274. }
  275. }
  276. #if !NO_DEEP_CANCELLATION
  277. private sealed class SelectManyAsyncIteratorWithTaskAndCancellation<TSource, TResult> : AsyncIterator<TResult>
  278. {
  279. private const int State_Source = 1;
  280. private const int State_Result = 2;
  281. private readonly Func<TSource, CancellationToken, ValueTask<IAsyncEnumerable<TResult>>> _selector;
  282. private readonly IAsyncEnumerable<TSource> _source;
  283. private int _mode;
  284. private IAsyncEnumerator<TResult> _resultEnumerator;
  285. private IAsyncEnumerator<TSource> _sourceEnumerator;
  286. public SelectManyAsyncIteratorWithTaskAndCancellation(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<IAsyncEnumerable<TResult>>> selector)
  287. {
  288. Debug.Assert(source != null);
  289. Debug.Assert(selector != null);
  290. _source = source;
  291. _selector = selector;
  292. }
  293. public override AsyncIteratorBase<TResult> Clone()
  294. {
  295. return new SelectManyAsyncIteratorWithTaskAndCancellation<TSource, TResult>(_source, _selector);
  296. }
  297. public override async ValueTask DisposeAsync()
  298. {
  299. if (_resultEnumerator != null)
  300. {
  301. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  302. _resultEnumerator = null;
  303. }
  304. if (_sourceEnumerator != null)
  305. {
  306. await _sourceEnumerator.DisposeAsync().ConfigureAwait(false);
  307. _sourceEnumerator = null;
  308. }
  309. await base.DisposeAsync().ConfigureAwait(false);
  310. }
  311. protected override async ValueTask<bool> MoveNextCore()
  312. {
  313. switch (_state)
  314. {
  315. case AsyncIteratorState.Allocated:
  316. _sourceEnumerator = _source.GetAsyncEnumerator(_cancellationToken);
  317. _mode = State_Source;
  318. _state = AsyncIteratorState.Iterating;
  319. goto case AsyncIteratorState.Iterating;
  320. case AsyncIteratorState.Iterating:
  321. switch (_mode)
  322. {
  323. case State_Source:
  324. if (await _sourceEnumerator.MoveNextAsync().ConfigureAwait(false))
  325. {
  326. if (_resultEnumerator != null)
  327. {
  328. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  329. }
  330. var inner = await _selector(_sourceEnumerator.Current, _cancellationToken).ConfigureAwait(false);
  331. _resultEnumerator = inner.GetAsyncEnumerator(_cancellationToken);
  332. _mode = State_Result;
  333. goto case State_Result;
  334. }
  335. break;
  336. case State_Result:
  337. if (await _resultEnumerator.MoveNextAsync().ConfigureAwait(false))
  338. {
  339. _current = _resultEnumerator.Current;
  340. return true;
  341. }
  342. _mode = State_Source;
  343. goto case State_Source; // loop
  344. }
  345. break;
  346. }
  347. await DisposeAsync().ConfigureAwait(false);
  348. return false;
  349. }
  350. }
  351. #endif
  352. private sealed class SelectManyAsyncIterator<TSource, TCollection, TResult> : AsyncIterator<TResult>
  353. {
  354. private const int State_Source = 1;
  355. private const int State_Result = 2;
  356. private readonly Func<TSource, IAsyncEnumerable<TCollection>> _collectionSelector;
  357. private readonly Func<TSource, TCollection, TResult> _resultSelector;
  358. private readonly IAsyncEnumerable<TSource> _source;
  359. private TSource _currentSource;
  360. private int _mode;
  361. private IAsyncEnumerator<TCollection> _resultEnumerator;
  362. private IAsyncEnumerator<TSource> _sourceEnumerator;
  363. public SelectManyAsyncIterator(IAsyncEnumerable<TSource> source, Func<TSource, IAsyncEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
  364. {
  365. Debug.Assert(source != null);
  366. Debug.Assert(collectionSelector != null);
  367. Debug.Assert(resultSelector != null);
  368. _source = source;
  369. _collectionSelector = collectionSelector;
  370. _resultSelector = resultSelector;
  371. }
  372. public override AsyncIteratorBase<TResult> Clone()
  373. {
  374. return new SelectManyAsyncIterator<TSource, TCollection, TResult>(_source, _collectionSelector, _resultSelector);
  375. }
  376. public override async ValueTask DisposeAsync()
  377. {
  378. if (_resultEnumerator != null)
  379. {
  380. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  381. _resultEnumerator = null;
  382. }
  383. if (_sourceEnumerator != null)
  384. {
  385. await _sourceEnumerator.DisposeAsync().ConfigureAwait(false);
  386. _sourceEnumerator = null;
  387. }
  388. _currentSource = default;
  389. await base.DisposeAsync().ConfigureAwait(false);
  390. }
  391. protected override async ValueTask<bool> MoveNextCore()
  392. {
  393. switch (_state)
  394. {
  395. case AsyncIteratorState.Allocated:
  396. _sourceEnumerator = _source.GetAsyncEnumerator(_cancellationToken);
  397. _mode = State_Source;
  398. _state = AsyncIteratorState.Iterating;
  399. goto case AsyncIteratorState.Iterating;
  400. case AsyncIteratorState.Iterating:
  401. switch (_mode)
  402. {
  403. case State_Source:
  404. if (await _sourceEnumerator.MoveNextAsync().ConfigureAwait(false))
  405. {
  406. if (_resultEnumerator != null)
  407. {
  408. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  409. }
  410. _currentSource = _sourceEnumerator.Current;
  411. var inner = _collectionSelector(_currentSource);
  412. _resultEnumerator = inner.GetAsyncEnumerator(_cancellationToken);
  413. _mode = State_Result;
  414. goto case State_Result;
  415. }
  416. break;
  417. case State_Result:
  418. if (await _resultEnumerator.MoveNextAsync().ConfigureAwait(false))
  419. {
  420. _current = _resultSelector(_currentSource, _resultEnumerator.Current);
  421. return true;
  422. }
  423. _mode = State_Source;
  424. goto case State_Source; // loop
  425. }
  426. break;
  427. }
  428. await DisposeAsync().ConfigureAwait(false);
  429. return false;
  430. }
  431. }
  432. private sealed class SelectManyAsyncIteratorWithTask<TSource, TCollection, TResult> : AsyncIterator<TResult>
  433. {
  434. private const int State_Source = 1;
  435. private const int State_Result = 2;
  436. private readonly Func<TSource, ValueTask<IAsyncEnumerable<TCollection>>> _collectionSelector;
  437. private readonly Func<TSource, TCollection, ValueTask<TResult>> _resultSelector;
  438. private readonly IAsyncEnumerable<TSource> _source;
  439. private TSource _currentSource;
  440. private int _mode;
  441. private IAsyncEnumerator<TCollection> _resultEnumerator;
  442. private IAsyncEnumerator<TSource> _sourceEnumerator;
  443. public SelectManyAsyncIteratorWithTask(IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<IAsyncEnumerable<TCollection>>> collectionSelector, Func<TSource, TCollection, ValueTask<TResult>> resultSelector)
  444. {
  445. Debug.Assert(source != null);
  446. Debug.Assert(collectionSelector != null);
  447. Debug.Assert(resultSelector != null);
  448. _source = source;
  449. _collectionSelector = collectionSelector;
  450. _resultSelector = resultSelector;
  451. }
  452. public override AsyncIteratorBase<TResult> Clone()
  453. {
  454. return new SelectManyAsyncIteratorWithTask<TSource, TCollection, TResult>(_source, _collectionSelector, _resultSelector);
  455. }
  456. public override async ValueTask DisposeAsync()
  457. {
  458. if (_resultEnumerator != null)
  459. {
  460. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  461. _resultEnumerator = null;
  462. }
  463. if (_sourceEnumerator != null)
  464. {
  465. await _sourceEnumerator.DisposeAsync().ConfigureAwait(false);
  466. _sourceEnumerator = null;
  467. }
  468. _currentSource = default;
  469. await base.DisposeAsync().ConfigureAwait(false);
  470. }
  471. protected override async ValueTask<bool> MoveNextCore()
  472. {
  473. switch (_state)
  474. {
  475. case AsyncIteratorState.Allocated:
  476. _sourceEnumerator = _source.GetAsyncEnumerator(_cancellationToken);
  477. _mode = State_Source;
  478. _state = AsyncIteratorState.Iterating;
  479. goto case AsyncIteratorState.Iterating;
  480. case AsyncIteratorState.Iterating:
  481. switch (_mode)
  482. {
  483. case State_Source:
  484. if (await _sourceEnumerator.MoveNextAsync().ConfigureAwait(false))
  485. {
  486. if (_resultEnumerator != null)
  487. {
  488. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  489. }
  490. _currentSource = _sourceEnumerator.Current;
  491. var inner = await _collectionSelector(_currentSource).ConfigureAwait(false);
  492. _resultEnumerator = inner.GetAsyncEnumerator(_cancellationToken);
  493. _mode = State_Result;
  494. goto case State_Result;
  495. }
  496. break;
  497. case State_Result:
  498. if (await _resultEnumerator.MoveNextAsync().ConfigureAwait(false))
  499. {
  500. _current = await _resultSelector(_currentSource, _resultEnumerator.Current).ConfigureAwait(false);
  501. return true;
  502. }
  503. _mode = State_Source;
  504. goto case State_Source; // loop
  505. }
  506. break;
  507. }
  508. await DisposeAsync().ConfigureAwait(false);
  509. return false;
  510. }
  511. }
  512. #if !NO_DEEP_CANCELLATION
  513. private sealed class SelectManyAsyncIteratorWithTaskAndCancellation<TSource, TCollection, TResult> : AsyncIterator<TResult>
  514. {
  515. private const int State_Source = 1;
  516. private const int State_Result = 2;
  517. private readonly Func<TSource, CancellationToken, ValueTask<IAsyncEnumerable<TCollection>>> _collectionSelector;
  518. private readonly Func<TSource, TCollection, CancellationToken, ValueTask<TResult>> _resultSelector;
  519. private readonly IAsyncEnumerable<TSource> _source;
  520. private TSource _currentSource;
  521. private int _mode;
  522. private IAsyncEnumerator<TCollection> _resultEnumerator;
  523. private IAsyncEnumerator<TSource> _sourceEnumerator;
  524. public SelectManyAsyncIteratorWithTaskAndCancellation(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<IAsyncEnumerable<TCollection>>> collectionSelector, Func<TSource, TCollection, CancellationToken, ValueTask<TResult>> resultSelector)
  525. {
  526. Debug.Assert(source != null);
  527. Debug.Assert(collectionSelector != null);
  528. Debug.Assert(resultSelector != null);
  529. _source = source;
  530. _collectionSelector = collectionSelector;
  531. _resultSelector = resultSelector;
  532. }
  533. public override AsyncIteratorBase<TResult> Clone()
  534. {
  535. return new SelectManyAsyncIteratorWithTaskAndCancellation<TSource, TCollection, TResult>(_source, _collectionSelector, _resultSelector);
  536. }
  537. public override async ValueTask DisposeAsync()
  538. {
  539. if (_resultEnumerator != null)
  540. {
  541. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  542. _resultEnumerator = null;
  543. }
  544. if (_sourceEnumerator != null)
  545. {
  546. await _sourceEnumerator.DisposeAsync().ConfigureAwait(false);
  547. _sourceEnumerator = null;
  548. }
  549. _currentSource = default;
  550. await base.DisposeAsync().ConfigureAwait(false);
  551. }
  552. protected override async ValueTask<bool> MoveNextCore()
  553. {
  554. switch (_state)
  555. {
  556. case AsyncIteratorState.Allocated:
  557. _sourceEnumerator = _source.GetAsyncEnumerator(_cancellationToken);
  558. _mode = State_Source;
  559. _state = AsyncIteratorState.Iterating;
  560. goto case AsyncIteratorState.Iterating;
  561. case AsyncIteratorState.Iterating:
  562. switch (_mode)
  563. {
  564. case State_Source:
  565. if (await _sourceEnumerator.MoveNextAsync().ConfigureAwait(false))
  566. {
  567. if (_resultEnumerator != null)
  568. {
  569. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  570. }
  571. _currentSource = _sourceEnumerator.Current;
  572. var inner = await _collectionSelector(_currentSource, _cancellationToken).ConfigureAwait(false);
  573. _resultEnumerator = inner.GetAsyncEnumerator(_cancellationToken);
  574. _mode = State_Result;
  575. goto case State_Result;
  576. }
  577. break;
  578. case State_Result:
  579. if (await _resultEnumerator.MoveNextAsync().ConfigureAwait(false))
  580. {
  581. _current = await _resultSelector(_currentSource, _resultEnumerator.Current, _cancellationToken).ConfigureAwait(false);
  582. return true;
  583. }
  584. _mode = State_Source;
  585. goto case State_Source; // loop
  586. }
  587. break;
  588. }
  589. await DisposeAsync().ConfigureAwait(false);
  590. return false;
  591. }
  592. }
  593. #endif
  594. private sealed class SelectManyWithIndexAsyncIterator<TSource, TCollection, TResult> : AsyncIterator<TResult>
  595. {
  596. private const int State_Source = 1;
  597. private const int State_Result = 2;
  598. private readonly Func<TSource, int, IAsyncEnumerable<TCollection>> _collectionSelector;
  599. private readonly Func<TSource, TCollection, TResult> _resultSelector;
  600. private readonly IAsyncEnumerable<TSource> _source;
  601. private TSource _currentSource;
  602. private int _index;
  603. private int _mode;
  604. private IAsyncEnumerator<TCollection> _resultEnumerator;
  605. private IAsyncEnumerator<TSource> _sourceEnumerator;
  606. public SelectManyWithIndexAsyncIterator(IAsyncEnumerable<TSource> source, Func<TSource, int, IAsyncEnumerable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
  607. {
  608. Debug.Assert(source != null);
  609. Debug.Assert(collectionSelector != null);
  610. Debug.Assert(resultSelector != null);
  611. _source = source;
  612. _collectionSelector = collectionSelector;
  613. _resultSelector = resultSelector;
  614. }
  615. public override AsyncIteratorBase<TResult> Clone()
  616. {
  617. return new SelectManyWithIndexAsyncIterator<TSource, TCollection, TResult>(_source, _collectionSelector, _resultSelector);
  618. }
  619. public override async ValueTask DisposeAsync()
  620. {
  621. if (_resultEnumerator != null)
  622. {
  623. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  624. _resultEnumerator = null;
  625. }
  626. if (_sourceEnumerator != null)
  627. {
  628. await _sourceEnumerator.DisposeAsync().ConfigureAwait(false);
  629. _sourceEnumerator = null;
  630. }
  631. _currentSource = default;
  632. await base.DisposeAsync().ConfigureAwait(false);
  633. }
  634. protected override async ValueTask<bool> MoveNextCore()
  635. {
  636. switch (_state)
  637. {
  638. case AsyncIteratorState.Allocated:
  639. _sourceEnumerator = _source.GetAsyncEnumerator(_cancellationToken);
  640. _index = -1;
  641. _mode = State_Source;
  642. _state = AsyncIteratorState.Iterating;
  643. goto case AsyncIteratorState.Iterating;
  644. case AsyncIteratorState.Iterating:
  645. switch (_mode)
  646. {
  647. case State_Source:
  648. if (await _sourceEnumerator.MoveNextAsync().ConfigureAwait(false))
  649. {
  650. if (_resultEnumerator != null)
  651. {
  652. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  653. }
  654. _currentSource = _sourceEnumerator.Current;
  655. checked
  656. {
  657. _index++;
  658. }
  659. var inner = _collectionSelector(_currentSource, _index);
  660. _resultEnumerator = inner.GetAsyncEnumerator(_cancellationToken);
  661. _mode = State_Result;
  662. goto case State_Result;
  663. }
  664. break;
  665. case State_Result:
  666. if (await _resultEnumerator.MoveNextAsync().ConfigureAwait(false))
  667. {
  668. _current = _resultSelector(_currentSource, _resultEnumerator.Current);
  669. return true;
  670. }
  671. _mode = State_Source;
  672. goto case State_Source; // loop
  673. }
  674. break;
  675. }
  676. await DisposeAsync().ConfigureAwait(false);
  677. return false;
  678. }
  679. }
  680. private sealed class SelectManyWithIndexAsyncIteratorWithTask<TSource, TCollection, TResult> : AsyncIterator<TResult>
  681. {
  682. private const int State_Source = 1;
  683. private const int State_Result = 2;
  684. private readonly Func<TSource, int, ValueTask<IAsyncEnumerable<TCollection>>> _collectionSelector;
  685. private readonly Func<TSource, TCollection, ValueTask<TResult>> _resultSelector;
  686. private readonly IAsyncEnumerable<TSource> _source;
  687. private TSource _currentSource;
  688. private int _index;
  689. private int _mode;
  690. private IAsyncEnumerator<TCollection> _resultEnumerator;
  691. private IAsyncEnumerator<TSource> _sourceEnumerator;
  692. public SelectManyWithIndexAsyncIteratorWithTask(IAsyncEnumerable<TSource> source, Func<TSource, int, ValueTask<IAsyncEnumerable<TCollection>>> collectionSelector, Func<TSource, TCollection, ValueTask<TResult>> resultSelector)
  693. {
  694. Debug.Assert(source != null);
  695. Debug.Assert(collectionSelector != null);
  696. Debug.Assert(resultSelector != null);
  697. _source = source;
  698. _collectionSelector = collectionSelector;
  699. _resultSelector = resultSelector;
  700. }
  701. public override AsyncIteratorBase<TResult> Clone()
  702. {
  703. return new SelectManyWithIndexAsyncIteratorWithTask<TSource, TCollection, TResult>(_source, _collectionSelector, _resultSelector);
  704. }
  705. public override async ValueTask DisposeAsync()
  706. {
  707. if (_resultEnumerator != null)
  708. {
  709. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  710. _resultEnumerator = null;
  711. }
  712. if (_sourceEnumerator != null)
  713. {
  714. await _sourceEnumerator.DisposeAsync().ConfigureAwait(false);
  715. _sourceEnumerator = null;
  716. }
  717. _currentSource = default;
  718. await base.DisposeAsync().ConfigureAwait(false);
  719. }
  720. protected override async ValueTask<bool> MoveNextCore()
  721. {
  722. switch (_state)
  723. {
  724. case AsyncIteratorState.Allocated:
  725. _sourceEnumerator = _source.GetAsyncEnumerator(_cancellationToken);
  726. _index = -1;
  727. _mode = State_Source;
  728. _state = AsyncIteratorState.Iterating;
  729. goto case AsyncIteratorState.Iterating;
  730. case AsyncIteratorState.Iterating:
  731. switch (_mode)
  732. {
  733. case State_Source:
  734. if (await _sourceEnumerator.MoveNextAsync().ConfigureAwait(false))
  735. {
  736. if (_resultEnumerator != null)
  737. {
  738. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  739. }
  740. _currentSource = _sourceEnumerator.Current;
  741. checked
  742. {
  743. _index++;
  744. }
  745. var inner = await _collectionSelector(_currentSource, _index).ConfigureAwait(false);
  746. _resultEnumerator = inner.GetAsyncEnumerator(_cancellationToken);
  747. _mode = State_Result;
  748. goto case State_Result;
  749. }
  750. break;
  751. case State_Result:
  752. if (await _resultEnumerator.MoveNextAsync().ConfigureAwait(false))
  753. {
  754. _current = await _resultSelector(_currentSource, _resultEnumerator.Current).ConfigureAwait(false);
  755. return true;
  756. }
  757. _mode = State_Source;
  758. goto case State_Source; // loop
  759. }
  760. break;
  761. }
  762. await DisposeAsync().ConfigureAwait(false);
  763. return false;
  764. }
  765. }
  766. #if !NO_DEEP_CANCELLATION
  767. private sealed class SelectManyWithIndexAsyncIteratorWithTaskAndCancellation<TSource, TCollection, TResult> : AsyncIterator<TResult>
  768. {
  769. private const int State_Source = 1;
  770. private const int State_Result = 2;
  771. private readonly Func<TSource, int, CancellationToken, ValueTask<IAsyncEnumerable<TCollection>>> _collectionSelector;
  772. private readonly Func<TSource, TCollection, CancellationToken, ValueTask<TResult>> _resultSelector;
  773. private readonly IAsyncEnumerable<TSource> _source;
  774. private TSource _currentSource;
  775. private int _index;
  776. private int _mode;
  777. private IAsyncEnumerator<TCollection> _resultEnumerator;
  778. private IAsyncEnumerator<TSource> _sourceEnumerator;
  779. public SelectManyWithIndexAsyncIteratorWithTaskAndCancellation(IAsyncEnumerable<TSource> source, Func<TSource, int, CancellationToken, ValueTask<IAsyncEnumerable<TCollection>>> collectionSelector, Func<TSource, TCollection, CancellationToken, ValueTask<TResult>> resultSelector)
  780. {
  781. Debug.Assert(source != null);
  782. Debug.Assert(collectionSelector != null);
  783. Debug.Assert(resultSelector != null);
  784. _source = source;
  785. _collectionSelector = collectionSelector;
  786. _resultSelector = resultSelector;
  787. }
  788. public override AsyncIteratorBase<TResult> Clone()
  789. {
  790. return new SelectManyWithIndexAsyncIteratorWithTaskAndCancellation<TSource, TCollection, TResult>(_source, _collectionSelector, _resultSelector);
  791. }
  792. public override async ValueTask DisposeAsync()
  793. {
  794. if (_resultEnumerator != null)
  795. {
  796. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  797. _resultEnumerator = null;
  798. }
  799. if (_sourceEnumerator != null)
  800. {
  801. await _sourceEnumerator.DisposeAsync().ConfigureAwait(false);
  802. _sourceEnumerator = null;
  803. }
  804. _currentSource = default;
  805. await base.DisposeAsync().ConfigureAwait(false);
  806. }
  807. protected override async ValueTask<bool> MoveNextCore()
  808. {
  809. switch (_state)
  810. {
  811. case AsyncIteratorState.Allocated:
  812. _sourceEnumerator = _source.GetAsyncEnumerator(_cancellationToken);
  813. _index = -1;
  814. _mode = State_Source;
  815. _state = AsyncIteratorState.Iterating;
  816. goto case AsyncIteratorState.Iterating;
  817. case AsyncIteratorState.Iterating:
  818. switch (_mode)
  819. {
  820. case State_Source:
  821. if (await _sourceEnumerator.MoveNextAsync().ConfigureAwait(false))
  822. {
  823. if (_resultEnumerator != null)
  824. {
  825. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  826. }
  827. _currentSource = _sourceEnumerator.Current;
  828. checked
  829. {
  830. _index++;
  831. }
  832. var inner = await _collectionSelector(_currentSource, _index, _cancellationToken).ConfigureAwait(false);
  833. _resultEnumerator = inner.GetAsyncEnumerator(_cancellationToken);
  834. _mode = State_Result;
  835. goto case State_Result;
  836. }
  837. break;
  838. case State_Result:
  839. if (await _resultEnumerator.MoveNextAsync().ConfigureAwait(false))
  840. {
  841. _current = await _resultSelector(_currentSource, _resultEnumerator.Current, _cancellationToken).ConfigureAwait(false);
  842. return true;
  843. }
  844. _mode = State_Source;
  845. goto case State_Source; // loop
  846. }
  847. break;
  848. }
  849. await DisposeAsync().ConfigureAwait(false);
  850. return false;
  851. }
  852. }
  853. #endif
  854. private sealed class SelectManyWithIndexAsyncIterator<TSource, TResult> : AsyncIterator<TResult>
  855. {
  856. private const int State_Source = 1;
  857. private const int State_Result = 2;
  858. private readonly Func<TSource, int, IAsyncEnumerable<TResult>> _selector;
  859. private readonly IAsyncEnumerable<TSource> _source;
  860. private int _index;
  861. private int _mode;
  862. private IAsyncEnumerator<TResult> _resultEnumerator;
  863. private IAsyncEnumerator<TSource> _sourceEnumerator;
  864. public SelectManyWithIndexAsyncIterator(IAsyncEnumerable<TSource> source, Func<TSource, int, IAsyncEnumerable<TResult>> selector)
  865. {
  866. Debug.Assert(source != null);
  867. Debug.Assert(selector != null);
  868. _source = source;
  869. _selector = selector;
  870. }
  871. public override AsyncIteratorBase<TResult> Clone()
  872. {
  873. return new SelectManyWithIndexAsyncIterator<TSource, TResult>(_source, _selector);
  874. }
  875. public override async ValueTask DisposeAsync()
  876. {
  877. if (_resultEnumerator != null)
  878. {
  879. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  880. _resultEnumerator = null;
  881. }
  882. if (_sourceEnumerator != null)
  883. {
  884. await _sourceEnumerator.DisposeAsync().ConfigureAwait(false);
  885. _sourceEnumerator = null;
  886. }
  887. await base.DisposeAsync().ConfigureAwait(false);
  888. }
  889. protected override async ValueTask<bool> MoveNextCore()
  890. {
  891. switch (_state)
  892. {
  893. case AsyncIteratorState.Allocated:
  894. _sourceEnumerator = _source.GetAsyncEnumerator(_cancellationToken);
  895. _index = -1;
  896. _mode = State_Source;
  897. _state = AsyncIteratorState.Iterating;
  898. goto case AsyncIteratorState.Iterating;
  899. case AsyncIteratorState.Iterating:
  900. switch (_mode)
  901. {
  902. case State_Source:
  903. if (await _sourceEnumerator.MoveNextAsync().ConfigureAwait(false))
  904. {
  905. if (_resultEnumerator != null)
  906. {
  907. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  908. }
  909. checked
  910. {
  911. _index++;
  912. }
  913. var inner = _selector(_sourceEnumerator.Current, _index);
  914. _resultEnumerator = inner.GetAsyncEnumerator(_cancellationToken);
  915. _mode = State_Result;
  916. goto case State_Result;
  917. }
  918. break;
  919. case State_Result:
  920. if (await _resultEnumerator.MoveNextAsync().ConfigureAwait(false))
  921. {
  922. _current = _resultEnumerator.Current;
  923. return true;
  924. }
  925. _mode = State_Source;
  926. goto case State_Source; // loop
  927. }
  928. break;
  929. }
  930. await DisposeAsync().ConfigureAwait(false);
  931. return false;
  932. }
  933. }
  934. private sealed class SelectManyWithIndexAsyncIteratorWithTask<TSource, TResult> : AsyncIterator<TResult>
  935. {
  936. private const int State_Source = 1;
  937. private const int State_Result = 2;
  938. private readonly Func<TSource, int, ValueTask<IAsyncEnumerable<TResult>>> _selector;
  939. private readonly IAsyncEnumerable<TSource> _source;
  940. private int _index;
  941. private int _mode;
  942. private IAsyncEnumerator<TResult> _resultEnumerator;
  943. private IAsyncEnumerator<TSource> _sourceEnumerator;
  944. public SelectManyWithIndexAsyncIteratorWithTask(IAsyncEnumerable<TSource> source, Func<TSource, int, ValueTask<IAsyncEnumerable<TResult>>> selector)
  945. {
  946. Debug.Assert(source != null);
  947. Debug.Assert(selector != null);
  948. _source = source;
  949. _selector = selector;
  950. }
  951. public override AsyncIteratorBase<TResult> Clone()
  952. {
  953. return new SelectManyWithIndexAsyncIteratorWithTask<TSource, TResult>(_source, _selector);
  954. }
  955. public override async ValueTask DisposeAsync()
  956. {
  957. if (_resultEnumerator != null)
  958. {
  959. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  960. _resultEnumerator = null;
  961. }
  962. if (_sourceEnumerator != null)
  963. {
  964. await _sourceEnumerator.DisposeAsync().ConfigureAwait(false);
  965. _sourceEnumerator = null;
  966. }
  967. await base.DisposeAsync().ConfigureAwait(false);
  968. }
  969. protected override async ValueTask<bool> MoveNextCore()
  970. {
  971. switch (_state)
  972. {
  973. case AsyncIteratorState.Allocated:
  974. _sourceEnumerator = _source.GetAsyncEnumerator(_cancellationToken);
  975. _index = -1;
  976. _mode = State_Source;
  977. _state = AsyncIteratorState.Iterating;
  978. goto case AsyncIteratorState.Iterating;
  979. case AsyncIteratorState.Iterating:
  980. switch (_mode)
  981. {
  982. case State_Source:
  983. if (await _sourceEnumerator.MoveNextAsync().ConfigureAwait(false))
  984. {
  985. if (_resultEnumerator != null)
  986. {
  987. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  988. }
  989. checked
  990. {
  991. _index++;
  992. }
  993. var inner = await _selector(_sourceEnumerator.Current, _index).ConfigureAwait(false);
  994. _resultEnumerator = inner.GetAsyncEnumerator(_cancellationToken);
  995. _mode = State_Result;
  996. goto case State_Result;
  997. }
  998. break;
  999. case State_Result:
  1000. if (await _resultEnumerator.MoveNextAsync().ConfigureAwait(false))
  1001. {
  1002. _current = _resultEnumerator.Current;
  1003. return true;
  1004. }
  1005. _mode = State_Source;
  1006. goto case State_Source; // loop
  1007. }
  1008. break;
  1009. }
  1010. await DisposeAsync().ConfigureAwait(false);
  1011. return false;
  1012. }
  1013. }
  1014. #if !NO_DEEP_CANCELLATION
  1015. private sealed class SelectManyWithIndexAsyncIteratorWithTaskAndCancellation<TSource, TResult> : AsyncIterator<TResult>
  1016. {
  1017. private const int State_Source = 1;
  1018. private const int State_Result = 2;
  1019. private readonly Func<TSource, int, CancellationToken, ValueTask<IAsyncEnumerable<TResult>>> _selector;
  1020. private readonly IAsyncEnumerable<TSource> _source;
  1021. private int _index;
  1022. private int _mode;
  1023. private IAsyncEnumerator<TResult> _resultEnumerator;
  1024. private IAsyncEnumerator<TSource> _sourceEnumerator;
  1025. public SelectManyWithIndexAsyncIteratorWithTaskAndCancellation(IAsyncEnumerable<TSource> source, Func<TSource, int, CancellationToken, ValueTask<IAsyncEnumerable<TResult>>> selector)
  1026. {
  1027. Debug.Assert(source != null);
  1028. Debug.Assert(selector != null);
  1029. _source = source;
  1030. _selector = selector;
  1031. }
  1032. public override AsyncIteratorBase<TResult> Clone()
  1033. {
  1034. return new SelectManyWithIndexAsyncIteratorWithTaskAndCancellation<TSource, TResult>(_source, _selector);
  1035. }
  1036. public override async ValueTask DisposeAsync()
  1037. {
  1038. if (_resultEnumerator != null)
  1039. {
  1040. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  1041. _resultEnumerator = null;
  1042. }
  1043. if (_sourceEnumerator != null)
  1044. {
  1045. await _sourceEnumerator.DisposeAsync().ConfigureAwait(false);
  1046. _sourceEnumerator = null;
  1047. }
  1048. await base.DisposeAsync().ConfigureAwait(false);
  1049. }
  1050. protected override async ValueTask<bool> MoveNextCore()
  1051. {
  1052. switch (_state)
  1053. {
  1054. case AsyncIteratorState.Allocated:
  1055. _sourceEnumerator = _source.GetAsyncEnumerator(_cancellationToken);
  1056. _index = -1;
  1057. _mode = State_Source;
  1058. _state = AsyncIteratorState.Iterating;
  1059. goto case AsyncIteratorState.Iterating;
  1060. case AsyncIteratorState.Iterating:
  1061. switch (_mode)
  1062. {
  1063. case State_Source:
  1064. if (await _sourceEnumerator.MoveNextAsync().ConfigureAwait(false))
  1065. {
  1066. if (_resultEnumerator != null)
  1067. {
  1068. await _resultEnumerator.DisposeAsync().ConfigureAwait(false);
  1069. }
  1070. checked
  1071. {
  1072. _index++;
  1073. }
  1074. var inner = await _selector(_sourceEnumerator.Current, _index, _cancellationToken).ConfigureAwait(false);
  1075. _resultEnumerator = inner.GetAsyncEnumerator(_cancellationToken);
  1076. _mode = State_Result;
  1077. goto case State_Result;
  1078. }
  1079. break;
  1080. case State_Result:
  1081. if (await _resultEnumerator.MoveNextAsync().ConfigureAwait(false))
  1082. {
  1083. _current = _resultEnumerator.Current;
  1084. return true;
  1085. }
  1086. _mode = State_Source;
  1087. goto case State_Source; // loop
  1088. }
  1089. break;
  1090. }
  1091. await DisposeAsync().ConfigureAwait(false);
  1092. return false;
  1093. }
  1094. }
  1095. #endif
  1096. }
  1097. }