-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEnumerable.cls
156 lines (69 loc) · 3.67 KB
/
Enumerable.cls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "Enumerable"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
'xcom の enumvariant の問題
'自前の EnumVariant は、variant に渡すとハングする?(他の原因の可能性もある)
'VBAクラスと区別がつかなくなってる感じ( value_ に自前の enumvariant を入れとくと、typeof value_ is Class1 で true を返してしまう)
'ので、表立って使用するのは現状やめたい…。
'また現状、select many 他で内部イテレータを .Variable(i) にセットしているが、そこでハングしないのが不思議…。
' ほかの理由なんだろうか
'→ IprovideClassInfo なるインターフェースを要求されていることに気が付いた、現状は暫定で失敗するように修正した。
' 結果、ハングせずにエラーを返すようになった( xcom.queryinterface...() で解説)
' enumerableSource_ が列挙対象外の場合は、空のソースを所持する Enumerator が返る。
Public Function From(enumerableSource_ As Object) As Enumerator
Attribute From.VB_UserMemId = 0
Select Case True
' Case Not IsObject(enumerableSource_) And IsArray(enumerableSource_)
'
' ' 配列は値コピーとなってしまう
'
' Set From = Enumerable(Ary.CopyFrom(enumerableSource_))
'
'
'
Case enumerableSource_ Is Nothing
'ブランクを返す。
Set From = New Enumerator
Case TypeOf enumerableSource_ Is Enumerator
'素通し
Set From = enumerableSource_
Case TypeOf enumerableSource_ Is Ary
' Ary は列挙時に EnumVariant を返せないので、外部からイテレータをデリゲートとして設定してやる。
Set From = New Enumerator
Dim srcAry_ As Ary: Set srcAry_ = enumerableSource_
From.SetIterator srcAry_, Delegate.CNew.SetMethod(New EnumOperatorProcs, "OpIteratorAry")
' Case TypeOf enumerableSource_ Is IUnknown 'TypeOf enumerableSource_ Is Object , TypeOf enumerableSource_ Is IEnumVARIANT
Case TypeOf enumerableSource_ Is Object
' IEnumVariant を variant に渡すと xCom.AddRef_...() でハングするので、やめる。
'普通のオブジェクトは列挙時にCOMオブジェクトとしての EnumVarint を取得するため、オブジェクトだけ渡せばいい。
Set From = New Enumerator
Dim srcUnk_ As IUnknown: Set srcUnk_ = enumerableSource_
From.SetSource srcUnk_
Case Else
'対応できない場合
' Err.Raise 'エラー処理
End Select
End Function
Public Function FromArray(sourceArray_) As Enumerator
If IsArray(sourceArray_) Then
' 配列は値コピーとなってしまう
Set FromArray = Enumerable(Ary.CNew.CopyFrom(sourceArray_))
End If
End Function
'一定範囲を列挙するイテレーターを返す
Public Function Range(start_, count_&, Optional span_ = 1&) As Enumerator
Set Range = New Enumerator
Dim eop_ As New EnumOperatorProcs
eop_.Variable = Array(start_, span_, count_)
Range.SetIterator Enumerable, Delegate.CNew.SetMethod(eop_, "OpGeneratorRange")
End Function
'配列の次元を指定分だけまとめる列挙子を生成する。
Private Function qLot(sourceAry_ As Ary, applyDimensions_&) As Enumerator
End Function