Skip to content

Commit

Permalink
Fix ValueTupleExtensions and Remove ForEachAttribute
Browse files Browse the repository at this point in the history
  • Loading branch information
kochounoyume committed Jan 4, 2025
1 parent 5ed4d09 commit 2e83f9b
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 300 deletions.
4 changes: 2 additions & 2 deletions Assets/Editor/Test/MinimalTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public void CompileCheckTest()
public void XEnumTest()
{
var fruits = Fruits.Apple | Fruits.Banana | Fruits.Orange;
foreach (var fruit in fruits)
foreach (var fruit in fruits.Enumerate())
{
TestContext.Out.WriteLine(XEnum.GetName(fruit));
}
Expand All @@ -99,7 +99,7 @@ private static IEnumerator PackageRemoveTest(string packageName)
}
}

[Flags, ForEach]
[Flags]
public enum Fruits
{
Apple = 1 << 0,
Expand Down
1 change: 0 additions & 1 deletion Documentation/docs/foreach-attribute.md

This file was deleted.

2 changes: 1 addition & 1 deletion Documentation/docs/foreach-extensions.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# foreach拡張
本来foreachできないものを拡張実装でforeachできるようになっている。
MemoryExtensions, ValueTupleExtensions
若干ForEach属性を使った列挙体のforeach対応も軽く触れられたらよいが、これの詳しい内容はSourceGeneratorでまとめて書く予定。
若干XEnum<T>.Enumerate()を使った列挙体のforeach対応も軽く触れられたらよいが、これの詳しい内容はSourceGeneratorでまとめて書く予定。
4 changes: 1 addition & 3 deletions Documentation/docs/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,4 @@
- name: SourceGeneratorプロジェクト概要
href: source-generator.md
- name: XEnum
href: xenum.md
- name: ForEach属性
href: foreach-attribute.md
href: xenum.md
65 changes: 0 additions & 65 deletions Packages/MinimalUtility/Runtime/ForEachAttribute.cs

This file was deleted.

3 changes: 0 additions & 3 deletions Packages/MinimalUtility/Runtime/ForEachAttribute.cs.meta

This file was deleted.

Binary file not shown.
114 changes: 39 additions & 75 deletions Packages/MinimalUtility/Runtime/ValueTupleExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,151 +15,115 @@ public static class ValueTupleExtensions
/// </summary>
/// <param name="tuple">対象の<see cref="ValueTuple{T1, T2}"/>.</param>
/// <typeparam name="T">要素の型.</typeparam>
/// <returns>要素を列挙する<see cref="Enumerator{T, TTuple}"/>.</returns>
/// <returns>要素を列挙する<see cref="Enumerator{T}"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Enumerator<T, (T, T)> GetEnumerator<T>(in this (T, T) tuple)
public static Enumerator<T> GetEnumerator<T>(in this (T, T) tuple)
{
return new (tuple, static (t, i) => i switch
{
0 => t.Item1,
1 => t.Item2,
_ => throw new IndexOutOfRangeException(),
});
return new ((tuple.Item1, tuple.Item2, default, default, default, default, default)!, 2);
}

/// <summary>
/// <see cref="ValueTuple{T1, T2, T3}"/>のforeach対応.
/// </summary>
/// <param name="tuple">対象の<see cref="ValueTuple{T1, T2, T3}"/>.</param>
/// <typeparam name="T">要素の型.</typeparam>
/// <returns>要素を列挙する<see cref="Enumerator{T, TTuple}"/>.</returns>
/// <returns>要素を列挙する<see cref="Enumerator{T}"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Enumerator<T, (T, T, T)> GetEnumerator<T>(in this (T, T, T) tuple)
public static Enumerator<T> GetEnumerator<T>(in this (T, T, T) tuple)
{
return new (tuple, static (t, i) => i switch
{
0 => t.Item1,
1 => t.Item2,
2 => t.Item3,
_ => throw new IndexOutOfRangeException(),
});
return new ((tuple.Item1, tuple.Item2, tuple.Item3, default, default, default, default)!, 3);
}

/// <summary>
/// <see cref="ValueTuple{T1, T2, T3, T4}"/>のforeach対応.
/// </summary>
/// <param name="tuple">対象の<see cref="ValueTuple{T1, T2, T3, T4}"/>.</param>
/// <typeparam name="T">要素の型.</typeparam>
/// <returns>要素を列挙する<see cref="Enumerator{T, TTuple}"/>.</returns>
/// <returns>要素を列挙する<see cref="Enumerator{T}"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Enumerator<T, (T, T, T, T)> GetEnumerator<T>(in this (T, T, T, T) tuple)
public static Enumerator<T> GetEnumerator<T>(in this (T, T, T, T) tuple)
{
return new (tuple, static (t, i) => i switch
{
0 => t.Item1,
1 => t.Item2,
2 => t.Item3,
3 => t.Item4,
_ => throw new IndexOutOfRangeException(),
});
return new ((tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4, default, default, default)!, 4);
}

/// <summary>
/// <see cref="ValueTuple{T1, T2, T3, T4, T5}"/>のforeach対応.
/// </summary>
/// <param name="tuple">対象の<see cref="ValueTuple{T1, T2, T3, T4, T5}"/>.</param>
/// <typeparam name="T">要素の型.</typeparam>
/// <returns>要素を列挙する<see cref="Enumerator{T, TTuple}"/>.</returns>
/// <returns>要素を列挙する<see cref="Enumerator{T}"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Enumerator<T, (T, T, T, T, T)> GetEnumerator<T>(in this (T, T, T, T, T) tuple)
public static Enumerator<T> GetEnumerator<T>(in this (T, T, T, T, T) tuple)
{
return new (tuple, static (t, i) => i switch
{
0 => t.Item1,
1 => t.Item2,
2 => t.Item3,
3 => t.Item4,
4 => t.Item5,
_ => throw new IndexOutOfRangeException(),
});
return new ((tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4, tuple.Item5, default, default)!, 5);
}

/// <summary>
/// <see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/>のforeach対応.
/// </summary>
/// <param name="tuple">対象の<see cref="ValueTuple{T1, T2, T3, T4, T5, T6}"/>.</param>
/// <typeparam name="T">要素の型.</typeparam>
/// <returns>要素を列挙する<see cref="Enumerator{T, TTuple}"/>.</returns>
/// <returns>要素を列挙する<see cref="Enumerator{T}"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Enumerator<T, (T, T, T, T, T, T)> GetEnumerator<T>(in this (T, T, T, T, T, T) tuple)
public static Enumerator<T> GetEnumerator<T>(in this (T, T, T, T, T, T) tuple)
{
return new (tuple, static (t, i) => i switch
{
0 => t.Item1,
1 => t.Item2,
2 => t.Item3,
3 => t.Item4,
4 => t.Item5,
5 => t.Item6,
_ => throw new IndexOutOfRangeException(),
});
return new ((tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4, tuple.Item5, tuple.Item6, default)!, 6);
}

/// <summary>
/// <see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/>のforeach対応.
/// </summary>
/// <param name="tuple">対象の<see cref="ValueTuple{T1, T2, T3, T4, T5, T6, T7}"/>.</param>
/// <typeparam name="T">要素の型.</typeparam>
/// <returns>要素を列挙する<see cref="Enumerator{T, TTuple}"/>.</returns>
/// <returns>要素を列挙する<see cref="Enumerator{T}"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Enumerator<T, (T, T, T, T, T, T, T)> GetEnumerator<T>(in this (T, T, T, T, T, T, T) tuple)
public static Enumerator<T> GetEnumerator<T>(in this (T, T, T, T, T, T, T) tuple)
{
return new (tuple, static (t, i) => i switch
{
0 => t.Item1,
1 => t.Item2,
2 => t.Item3,
3 => t.Item4,
4 => t.Item5,
5 => t.Item6,
6 => t.Item7,
_ => throw new IndexOutOfRangeException(),
});
return new (tuple, 7);
}

/// <summary>
/// ValueTupleのforeach対応.
/// </summary>
/// <typeparam name="T">要素の型.</typeparam>
/// <typeparam name="TTuple">ValueTupleの型.</typeparam>
public struct Enumerator<T, TTuple> where TTuple : struct, ITuple
public struct Enumerator<T>
{
private readonly TTuple _tuple;
private readonly Func<TTuple, int, T> _current;
private readonly (T, T, T, T, T, T, T) _tuple;
private readonly int _length;
private int _index;

/// <summary>
/// <see cref="System.Collections.Generic.IEnumerator{T}.Current"/>に同じ.
/// </summary>
public T Current => _current(_tuple, _index);
public T Current => _index switch
{
0 => _tuple.Item1,
1 => _tuple.Item2,
2 => _tuple.Item3,
3 => _tuple.Item4,
4 => _tuple.Item5,
5 => _tuple.Item6,
6 => _tuple.Item7,
_ => throw new IndexOutOfRangeException(),
};

/// <summary>
/// Initializes a new instance of the <see cref="ValueTupleExtensions.Enumerator{T, Tuple}"/> struct.
/// Initializes a new instance of the <see cref="Enumerator{T}"/> struct.
/// </summary>
/// <param name="tuple">ValueTuple.</param>
/// <param name="current"><see cref="Current"/>で実行する処理.</param>
internal Enumerator(in TTuple tuple, Func<TTuple, int, T> current)
/// <param name="tuple"></param>
/// <param name="length"></param>
internal Enumerator(in (T, T, T, T, T, T, T) tuple, int length)
{
this._tuple = tuple;
this._current = current;
_index = -1;
this._length = length;
this._index = -1;
}

/// <summary>
/// <see cref="System.Collections.Generic.IEnumerator{T}.MoveNext"/>に同じ.
/// </summary>
/// <returns>列挙が可能な場合はtrue.</returns>
public bool MoveNext() => _index < _tuple.Length && ++_index < _tuple.Length;
public bool MoveNext() => _index < _length && ++_index < _length;
}
}
}
Loading

0 comments on commit 2e83f9b

Please sign in to comment.