1 | #Region "Microsoft.VisualBasic::6cbca453e2ad0186dd0aa5e35dce4f3a, Microsoft.VisualBasic.Core\ComponentModel\DataStructures\LoopArray.vb" |
2 | |
3 | ' Author: |
4 | ' |
5 | ' asuka (amethyst.asuka@gcmodeller.org) |
6 | ' xie (genetics@smrucc.org) |
7 | ' xieguigang (xie.guigang@live.com) |
8 | ' |
9 | ' Copyright (c) 2018 GPL3 Licensed |
10 | ' |
11 | ' |
12 | ' GNU GENERAL PUBLIC LICENSE (GPL3) |
13 | ' |
14 | ' |
15 | ' This program is free software: you can redistribute it and/or modify |
16 | ' it under the terms of the GNU General Public License as published by |
17 | ' the Free Software Foundation, either version 3 of the License, or |
18 | ' (at your option) any later version. |
19 | ' |
20 | ' This program is distributed in the hope that it will be useful, |
21 | ' but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 | ' GNU General Public License for more details. |
24 | ' |
25 | ' You should have received a copy of the GNU General Public License |
26 | ' along with this program. If not, see <http://www.gnu.org/licenses/>. |
27 | |
28 | |
29 | |
30 | ' /********************************************************************************/ |
31 | |
32 | ' Summaries: |
33 | |
34 | ' Class LoopArray |
35 | ' |
36 | ' Properties: Buffer, Current, Length |
37 | ' |
38 | ' Constructor: (+1 Overloads) Sub New |
39 | ' |
40 | ' Function: [GET], [Next], GetEnumerator, IEnumerable_GetEnumerator, ToString |
41 | ' |
42 | ' Sub: [Set], Break, Reset |
43 | ' |
44 | ' Operators: + |
45 | ' |
46 | ' |
47 | ' /********************************************************************************/ |
48 | |
49 | #End Region |
50 | |
51 | Imports System.Runtime.CompilerServices |
52 | Imports Microsoft.VisualBasic.Linq |
53 | Imports Microsoft.VisualBasic.Serialization.JSON |
54 | |
55 | Namespace ComponentModel.DataStructures |
56 | |
57 | ''' <summary> |
58 | ''' Infinite loop iterates of the target element collection. |
59 | ''' </summary> |
60 | ''' <typeparam name="T"></typeparam> |
61 | Public Class LoopArray(Of T) : Implements IEnumerable(Of T) |
62 | |
63 | Dim array As T() |
64 | Dim p% |
65 | |
66 | Public ReadOnly Property Buffer As T() |
67 | <MethodImpl(MethodImplOptions.AggressiveInlining)> |
68 | Get |
69 | Return array |
70 | End Get |
71 | End Property |
72 | |
73 | Public ReadOnly Property Length As Integer |
74 | <MethodImpl(MethodImplOptions.AggressiveInlining)> |
75 | Get |
76 | Return array.Length |
77 | End Get |
78 | End Property |
79 | |
80 | Public ReadOnly Property Current As SeqValue(Of T) |
81 | Get |
82 | Return New SeqValue(Of T)() With { |
83 | .i = p, |
84 | .value = array(.i) |
85 | } |
86 | End Get |
87 | End Property |
88 | |
89 | <MethodImpl(MethodImplOptions.AggressiveInlining)> |
90 | Sub New(source As IEnumerable(Of T)) |
91 | array = source.ToArray |
92 | End Sub |
93 | |
94 | ''' <summary> |
95 | ''' Gets the next elements in the array, is move to end, then the index will |
96 | ''' moves to the array begining position. |
97 | ''' </summary> |
98 | ''' <returns></returns> |
99 | Public Function [Next]() As T |
100 | Dim i As Integer = p |
101 | |
102 | If p < array.Length - 1 Then |
103 | p += 1 |
104 | Else |
105 | p = 0 |
106 | End If |
107 | |
108 | Return array(i) |
109 | End Function |
110 | |
111 | <MethodImpl(MethodImplOptions.AggressiveInlining)> |
112 | Public Sub [Set](i%) |
113 | p = i% |
114 | End Sub |
115 | |
116 | <MethodImpl(MethodImplOptions.AggressiveInlining)> |
117 | Public Sub Reset() |
118 | p = 0 |
119 | End Sub |
120 | |
121 | Public Overrides Function ToString() As String |
122 | Return array.Take(10).ToArray.GetJson |
123 | End Function |
124 | |
125 | ''' <summary> |
126 | ''' |
127 | ''' </summary> |
128 | ''' <param name="delta%">The pointer move delta</param> |
129 | ''' <returns></returns> |
130 | Public Function [GET](delta%) As T |
131 | p += delta |
132 | |
133 | If p >= 0 Then |
134 | If p <= array.Length - 1 Then |
135 | ' 正常的下标范围内,不需要进行任何处理 |
136 | Else |
137 | p = p - array.Length |
138 | End If |
139 | Else |
140 | p = array.Length + p |
141 | End If |
142 | |
143 | Return array(p) |
144 | End Function |
145 | |
146 | Public Shared Narrowing Operator CType(array As LoopArray(Of T)) As T() |
147 | Return array.Buffer |
148 | End Operator |
149 | |
150 | Public Shared Widening Operator CType(array As T()) As LoopArray(Of T) |
151 | Return New LoopArray(Of T)(array) |
152 | End Operator |
153 | |
154 | Public Shared Operator +(array As LoopArray(Of T)) As SeqValue(Of T) |
155 | Call array.Next() |
156 | Return array.Current |
157 | End Operator |
158 | |
159 | Dim _break As Boolean |
160 | |
161 | ''' <summary> |
162 | ''' Exit the Infinite loop iterator <see cref="GetEnumerator()"/> |
163 | ''' </summary> |
164 | Public Sub Break() |
165 | _break = True |
166 | End Sub |
167 | |
168 | ''' <summary> |
169 | ''' Infinite loop iterates of the target element collection. |
170 | ''' </summary> |
171 | ''' <returns></returns> |
172 | Public Iterator Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator |
173 | _break = False |
174 | |
175 | Do While Not _break |
176 | Yield [Next]() |
177 | Loop |
178 | End Function |
179 | |
180 | Private Iterator Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator |
181 | Yield GetEnumerator() |
182 | End Function |
183 | End Class |
184 | End Namespace |