Skip to content

Commit 83751e5

Browse files
committed
Added struct ValueNDCoordinatesIncrementor, ValueNDCoordinatesIncrementorAutoResetting
1 parent 5dbb7ba commit 83751e5

1 file changed

Lines changed: 156 additions & 0 deletions

File tree

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
using System;
2+
using System.Runtime.CompilerServices;
3+
4+
namespace NumSharp.Utilities
5+
{
6+
public struct ValueNDCoordinatesIncrementor
7+
{
8+
public delegate void EndCallbackHandler(ref ValueNDCoordinatesIncrementor incr);
9+
private readonly EndCallbackHandler endCallback;
10+
private readonly int[] dimensions;
11+
private readonly int resetto;
12+
public readonly int[] Index;
13+
private int subcursor;
14+
15+
/// <summary>Initializes a new instance of the <see cref="T:System.Object"></see> class.</summary>
16+
public ValueNDCoordinatesIncrementor(ref Shape shape)
17+
{
18+
if (shape.IsEmpty || shape.size == 0)
19+
throw new InvalidOperationException("Can't construct NDCoordinatesIncrementor with an empty shape.");
20+
21+
dimensions = shape.IsScalar ? new[] {1} : shape.dimensions;
22+
Index = new int[dimensions.Length];
23+
resetto = subcursor = dimensions.Length - 1;
24+
endCallback = null;
25+
}
26+
27+
public ValueNDCoordinatesIncrementor(ref Shape shape, EndCallbackHandler endCallback) : this(ref shape)
28+
{
29+
this.endCallback = endCallback;
30+
}
31+
32+
public ValueNDCoordinatesIncrementor(int[] dims)
33+
{
34+
if (dims == null)
35+
throw new InvalidOperationException("Can't construct NDCoordinatesIncrementor with an empty shape.");
36+
37+
if (dims.Length == 0)
38+
dims = new int[] {1};
39+
40+
dimensions = dims;
41+
Index = new int[dims.Length];
42+
resetto = subcursor = dimensions.Length - 1;
43+
endCallback = null;
44+
}
45+
46+
public ValueNDCoordinatesIncrementor(int[] dims, EndCallbackHandler endCallback) : this(dims)
47+
{
48+
this.endCallback = endCallback;
49+
}
50+
51+
public void Reset()
52+
{
53+
Array.Clear(Index, 0, Index.Length);
54+
subcursor = resetto;
55+
}
56+
57+
[MethodImpl((MethodImplOptions)512)]
58+
public int[] Next()
59+
{
60+
if (subcursor <= -1)
61+
return null;
62+
63+
if (++Index[subcursor] >= dimensions[subcursor])
64+
{
65+
_repeat:
66+
Index[subcursor] = 0;
67+
68+
do
69+
{
70+
if (--subcursor <= -1)
71+
{
72+
//TODO somehow can we skip all ones?
73+
endCallback?.Invoke(ref this);
74+
if (subcursor >= 0) //if callback has resetted it
75+
return Index;
76+
return null;
77+
}
78+
} while (dimensions[subcursor] <= 1);
79+
80+
++Index[subcursor];
81+
if (Index[subcursor] >= dimensions[subcursor])
82+
goto _repeat;
83+
84+
subcursor = resetto;
85+
}
86+
87+
return Index;
88+
}
89+
}
90+
91+
public struct ValueNDCoordinatesIncrementorAutoResetting
92+
{
93+
private readonly int[] dimensions;
94+
private readonly int resetto;
95+
public readonly int[] Index;
96+
private int subcursor;
97+
98+
/// <summary>Initializes a new instance of the <see cref="T:System.Object"></see> class.</summary>
99+
public ValueNDCoordinatesIncrementorAutoResetting(ref Shape shape)
100+
{
101+
if (shape.IsEmpty || shape.size == 0)
102+
throw new InvalidOperationException("Can't construct NDCoordinatesIncrementorAutoResetting with an empty shape.");
103+
104+
dimensions = shape.dimensions;
105+
Index = new int[dimensions.Length];
106+
resetto = subcursor = dimensions.Length - 1;
107+
}
108+
109+
public ValueNDCoordinatesIncrementorAutoResetting(int[] dims)
110+
{
111+
if (dims == null)
112+
throw new InvalidOperationException("Can't construct NDCoordinatesIncrementorAutoResetting with an empty shape.");
113+
114+
if (dims.Length == 0)
115+
dims = new int[] {1};
116+
117+
dimensions = dims;
118+
Index = new int[dims.Length];
119+
resetto = subcursor = dimensions.Length - 1;
120+
}
121+
122+
public void Reset()
123+
{
124+
Array.Clear(Index, 0, Index.Length);
125+
subcursor = resetto;
126+
}
127+
128+
[MethodImpl((MethodImplOptions)512)]
129+
public int[] Next()
130+
{
131+
if (++Index[subcursor] >= dimensions[subcursor])
132+
{
133+
_repeat:
134+
Index[subcursor] = 0;
135+
136+
do
137+
{
138+
if (--subcursor <= -1)
139+
{
140+
//TODO somehow can we skip all ones?
141+
Reset();
142+
return Index; //finished
143+
}
144+
} while (dimensions[subcursor] <= 1);
145+
146+
++Index[subcursor];
147+
if (Index[subcursor] >= dimensions[subcursor])
148+
goto _repeat;
149+
150+
subcursor = resetto;
151+
}
152+
153+
return Index;
154+
}
155+
}
156+
}

0 commit comments

Comments
 (0)