1 #Region "Microsoft.VisualBasic::b11d660d704e736afcac6dbdfc461d60, Microsoft.VisualBasic.Core\Extensions\Reflection\Marshal\Pointer(Of T).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 Pointer
35     
36     '         Properties: Current, EndRead, Length, NullEnd, Position
37     '                     RawBuffer, UBound
38     
39     '         Constructor: (+4 OverloadsSub New
40     '         Function: MoveNext, PeekNext, stackalloc, ToString
41     '         Operators: (+2 Overloads) -, (+2 Overloads) +, <<, (+2 Overloads) <=, <>
42     '                    =, (+2 Overloads) >=, >>
43     
44     '     Structure SwapHelper
45     
46     '         Sub: Swap
47     
48     
49     ' /********************************************************************************/
50
51 #End Region
52
53 Imports System.Runtime.CompilerServices
54 Imports Microsoft.VisualBasic.ComponentModel
55 Imports Microsoft.VisualBasic.Linq
56
57 Namespace Emit.Marshal
58
59     ''' <summary>
60     ''' <see cref="Array"/> index helper.(在数组的索引基础上封装了数组本身)
61     ''' </summary>
62     ''' <typeparam name="T"></typeparam>
63     Public Class Pointer(Of T) : Inherits DataStructures.Pointer(Of T)
64
65         Protected buffer As T()
66
67         ''' <summary>
68         ''' <see cref="Position"/> -> its current value
69         ''' </summary>
70         ''' <returns></returns>
71         Public Property Current As T
72             <MethodImpl(MethodImplOptions.AggressiveInlining)>
73             Get
74                 Return Value(Scan0)  ' 当前的位置是指相对于当前的位置offset为0的位置就是当前的位置
75             End Get
76             <MethodImpl(MethodImplOptions.AggressiveInlining)>
77             Protected Friend Set(value As T)
78                 Me.Value(Scan0) = value
79             End Set
80         End Property
81
82         ''' <summary>
83         ''' Memory block size
84         ''' </summary>
85         ''' <returns></returns>
86         Public ReadOnly Property Length As Integer
87             <MethodImpl(MethodImplOptions.AggressiveInlining)>
88             Get
89                 Return buffer.Length
90             End Get
91         End Property
92
93         ''' <summary>
94         ''' 返回指定维度的一个数组,最高可用的下标。
95         ''' </summary>
96         ''' <returns>
97         ''' <see cref="Integer"/>。 指定维度的下标可以包含的最大值。 如果 Array 只有一个元素, UBound ,则返回 0。 如果 Array 不包含任何元素,例如,如果它是零长度字符串,
98         ''' UBound 返回-1。</returns>
99         Public ReadOnly Property UBound As Integer
100             <MethodImpl(MethodImplOptions.AggressiveInlining)>
101             Get
102                 Return Information.UBound(buffer)
103             End Get
104         End Property
105
106         ''' <summary>
107         ''' 相对于当前的指针的位置而言的
108         ''' </summary>
109         ''' <param name="p">相对于当前的位置的offset偏移量</param>
110         ''' <returns></returns>
111         ''' <remarks>
112         ''' 这个属性并不会移动当前的指针的位置
113         ''' </remarks>
114         Default Public Property Value(p As IntegerAs T
115             Get
116                 p += index
117
118                 If p < 0 OrElse p >= buffer.Length Then
119                     Return Nothing
120                 Else
121                     Return buffer(p)
122                 End If
123             End Get
124             Set(value As T)
125                 p += index
126
127                 If p < 0 OrElse p >= buffer.Length Then
128                     Throw New MemberAccessException(p & " reference to invalid memory region!")
129                 Else
130                     buffer(p) = value
131                 End If
132             End Set
133         End Property
134
135         ''' <summary>
136         ''' Raw memory of this pointer
137         ''' </summary>
138         ''' <returns></returns>
139         Public ReadOnly Property RawBuffer As T()
140             <MethodImpl(MethodImplOptions.AggressiveInlining)>
141             Get
142                 Return buffer
143             End Get
144         End Property
145
146         Public ReadOnly Property NullEnd(Optional offset As Integer = 0) As Boolean
147             <MethodImpl(MethodImplOptions.AggressiveInlining)>
148             Get
149                 Return index >= (buffer.Length - 1 - offset)
150             End Get
151         End Property
152
153         ''' <summary>
154         ''' Is read to end?
155         ''' </summary>
156         ''' <returns></returns>
157         Public ReadOnly Property EndRead As Boolean
158             <MethodImpl(MethodImplOptions.AggressiveInlining)>
159             Get
160                 Return index >= buffer.Length
161             End Get
162         End Property
163
164         ''' <summary>
165         ''' Current read position
166         ''' </summary>
167         ''' <returns></returns>
168         Public ReadOnly Property Position As Integer
169             <MethodImpl(MethodImplOptions.AggressiveInlining)>
170             Get
171                 Return index
172             End Get
173         End Property
174
175         <MethodImpl(MethodImplOptions.AggressiveInlining)>
176         Sub New(ByRef array As T())
177             buffer = array
178         End Sub
179
180         <MethodImpl(MethodImplOptions.AggressiveInlining)>
181         Sub New(array As List(Of T))
182             buffer = array.ToArray
183         End Sub
184
185         ''' <summary>
186         ''' Create a collection wrapper from a <paramref name="source"/> buffer.
187         ''' </summary>
188         ''' <param name="source">The collection source buffer</param>
189         Sub New(source As IEnumerable(Of T))
190             buffer = source.ToArray
191         End Sub
192
193         Sub New()
194         End Sub
195
196         ''' <summary>
197         ''' Pointer move to next and then returns is <see cref="EndRead"/>
198         ''' </summary>
199         ''' <returns></returns>
200         Public Function MoveNext() As Boolean
201             index += 1
202             Return Not EndRead
203         End Function
204
205         ''' <summary>
206         ''' 获取得到下一个对象而不移动当前的内部指针
207         ''' </summary>
208         ''' <returns></returns>
209         ''' 
210         <MethodImpl(MethodImplOptions.AggressiveInlining)>
211         Public Function PeekNext() As T
212             Return Me(index + 1)
213         End Function
214
215         Public Overrides Function ToString() As String
216             Return $"*{GetType(T).Name}: ({index}) {Current}"
217         End Function
218
219         '''' <summary>
220         '''' 前移<paramref name="offset"/>个单位,然后返回值,这个和Peek的作用一样,不会改变指针位置
221         '''' </summary>
222         '''' <param name="p"></param>
223         '''' <param name="offset"></param>
224         '''' <returns></returns>
225         'Public Overloads Shared Operator <=(p As Pointer(Of T), offset As IntegerAs T
226         '    Return p(-offset)
227         'End Operator
228
229         '''' <summary>
230         '''' 后移<paramref name="offset"/>个单位,然后返回值,这个和Peek的作用一样,不会改变指针位置
231         '''' </summary>
232         '''' <param name="p"></param>
233         '''' <param name="offset"></param>
234         '''' <returns></returns>
235         'Public Overloads Shared Operator >=(p As Pointer(Of T), offset As IntegerAs T
236         '    Return p(offset)
237         'End Operator
238
239         ''' <summary>
240         ''' 获取得到当前的元素
241         ''' </summary>
242         ''' <param name="p"></param>
243         ''' <returns></returns>
244         <MethodImpl(MethodImplOptions.AggressiveInlining)>
245         Public Overloads Shared Narrowing Operator CType(p As Pointer(Of T)) As T
246             Return p.Current
247         End Operator
248
249         ''' <summary>
250         ''' 前移<paramref name="offset"/>个单位,然后返回值,这个和Peek的作用一样,不会改变指针位置
251         ''' </summary>
252         ''' <param name="p"></param>
253         ''' <param name="offset"></param>
254         ''' <returns></returns>
255         <MethodImpl(MethodImplOptions.AggressiveInlining)>
256         Public Overloads Shared Operator <<(p As Pointer(Of T), offset As IntegerAs T
257             Return p(-offset)
258         End Operator
259
260         ''' <summary>
261         ''' 后移<paramref name="offset"/>个单位,然后返回值,这个和Peek的作用一样,不会改变指针位置
262         ''' </summary>
263         ''' <param name="p"></param>
264         ''' <param name="offset"></param>
265         ''' <returns></returns>
266         Public Overloads Shared Operator >>(p As Pointer(Of T), offset As IntegerAs T
267             Return p(offset)
268         End Operator
269
270         Public Overloads Shared Widening Operator CType(raw As T()) As Pointer(Of T)
271             Return New Pointer(Of T)(raw)
272         End Operator
273
274         ''' <summary>
275         ''' Move steps and returns this pointer
276         ''' </summary>
277         ''' <param name="ptr"></param>
278         ''' <param name="d"></param>
279         ''' <returns></returns>
280         Public Overloads Shared Operator +(ptr As Pointer(Of T), d As IntegerAs Pointer(Of T)
281             ptr.index += d
282             Return ptr
283         End Operator
284
285         Public Overloads Shared Operator -(ptr As Pointer(Of T), d As IntegerAs Pointer(Of T)
286             ptr.index -= d
287             Return ptr
288         End Operator
289
290         ''' <summary>
291         ''' Pointer move to next and then returns the previous value
292         ''' </summary>
293         ''' <param name="ptr"></param>
294         ''' <returns></returns>
295         ''' 
296         <MethodImpl(MethodImplOptions.AggressiveInlining)>
297         Public Overloads Shared Operator +(ptr As Pointer(Of T)) As SeqValue(Of T)
298             Dim i% = ptr.index
299             ptr.index += 1
300
301             Return New SeqValue(Of T) With {
302                 .i = i,
303                 .value = ptr.buffer(i)
304             }
305         End Operator
306
307         ''' <summary>
308         ''' The stack trace back operator.
309         ''' (指针的位置往回移动一个单位,然后返回原来的位置的元素的值)
310         ''' </summary>
311         ''' <param name="ptr"></param>
312         ''' <returns></returns>
313         Public Overloads Shared Operator -(ptr As Pointer(Of T)) As SeqValue(Of T)
314             Dim i% = ptr.index
315             ptr.index -= 1
316
317             Return New SeqValue(Of T) With {
318                 .i = i,
319                 .value = ptr.buffer.ElementAtOrDefault(i, Nothing)
320             }
321         End Operator
322
323         <MethodImpl(MethodImplOptions.AggressiveInlining)>
324         Public Overloads Shared Operator <=(a As Pointer(Of T), b As Pointer(Of T)) As SwapHelper(Of T)
325             Return New SwapHelper(Of T) With {.a = a, .b = b}
326         End Operator
327
328         Public Overloads Shared Operator >=(a As Pointer(Of T), b As Pointer(Of T)) As SwapHelper(Of T)
329             Throw New NotSupportedException
330         End Operator
331
332         <MethodImpl(MethodImplOptions.AggressiveInlining)>
333         Public Overloads Shared Operator <=(a As Pointer(Of T), b As IntegerAs SwapHelper(Of T)
334             Return New SwapHelper(Of T) With {.a = a, .i = b}
335         End Operator
336
337         Public Overloads Shared Operator >=(a As Pointer(Of T), b As IntegerAs SwapHelper(Of T)
338             Throw New NotSupportedException
339         End Operator
340
341         <MethodImpl(MethodImplOptions.AggressiveInlining)>
342         Public Shared Function stackalloc(len As IntegerAs Pointer(Of T)
343             Return New Pointer(Of T)(New T(len - 1) {})
344         End Function
345
346         <MethodImpl(MethodImplOptions.AggressiveInlining)>
347         Public Shared Operator =(p As Pointer(Of T), count%) As Boolean
348             Return p.Length = count
349         End Operator
350
351         <MethodImpl(MethodImplOptions.AggressiveInlining)>
352         Public Shared Operator <>(p As Pointer(Of T), count%) As Boolean
353             Return Not p = count
354         End Operator
355     End Class
356
357     Public Structure SwapHelper(Of T)
358
359         Public a As Pointer(Of T)
360         Public b As Pointer(Of T)
361         Public i As Integer
362
363         Public Sub Swap()
364             Dim tmp As T = a.Current
365
366             If b Is Nothing Then
367                 a.Current = a(i)
368                 a(i) = tmp
369             Else
370                 a.Current = b.Current
371                 b.Current = tmp
372             End If
373         End Sub
374     End Structure
375 End Namespace