1 | #Region "Microsoft.VisualBasic::b5a894d43b06e70fd5b9d602bddc7221, Microsoft.VisualBasic.Core\ComponentModel\Ranges\Unit.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 Convertor |
35 | ' |
36 | ' Properties: UnitType |
37 | ' Delegate Function |
38 | ' |
39 | ' Constructor: (+1 Overloads) Sub New |
40 | ' |
41 | ' Module UnitConvertorExtensions |
42 | ' |
43 | ' Function: Base, GetUnitConvertor, IndexOf, Unit |
44 | ' |
45 | ' Enum ByteSize |
46 | ' |
47 | ' |
48 | ' |
49 | ' |
50 | ' Class UnitValue |
51 | ' |
52 | ' Properties: Unit |
53 | ' |
54 | ' Constructor: (+2 Overloads) Sub New |
55 | ' Function: ScaleTo, ToString |
56 | ' Operators: <>, = |
57 | ' |
58 | ' |
59 | ' /********************************************************************************/ |
60 | |
61 | #End Region |
62 | |
63 | Imports System.Runtime.CompilerServices |
64 | Imports Microsoft.VisualBasic.Language |
65 | |
66 | Namespace ComponentModel.Ranges |
67 | |
68 | Public Class Convertor : Inherits Attribute |
69 | |
70 | Public ReadOnly Property UnitType As Type |
71 | |
72 | ''' <summary> |
73 | ''' |
74 | ''' </summary> |
75 | ''' <typeparam name="TUnit">枚举类型?</typeparam> |
76 | ''' <param name="value"></param> |
77 | ''' <param name="toUnit"></param> |
78 | ''' <returns></returns> |
79 | Public Delegate Function Convertor(Of TUnit As Structure)(value As UnitValue(Of TUnit), toUnit As TUnit) As UnitValue(Of TUnit) |
80 | |
81 | Sub New(type As Type) |
82 | UnitType = type |
83 | End Sub |
84 | End Class |
85 | |
86 | Public Module UnitConvertorExtensions |
87 | |
88 | <MethodImpl(MethodImplOptions.AggressiveInlining)> |
89 | Public Function GetUnitConvertor(Of T As Structure)() As (unit As T, value As Double)() |
90 | Return Enums(Of T)() _ |
91 | .Select(Function(e) |
92 | Dim size As Double = CDbl(CObj(e)) |
93 | Return (e, size) |
94 | End Function) _ |
95 | .OrderBy(Function(u) u.Item2) _ |
96 | .ToArray |
97 | End Function |
98 | |
99 | <MethodImpl(MethodImplOptions.AggressiveInlining)> |
100 | <Extension> |
101 | Friend Function Base(Of T)(convertors As IEnumerable(Of (unit As T, value As Double))) As (unit As T, value As Double) |
102 | Return convertors.Where(Function(u) u.value = 1.0#).FirstOrDefault |
103 | End Function |
104 | |
105 | <Extension> |
106 | Friend Function IndexOf(Of T)(convertors As (unit As T, value As Double)(), target As T) As Integer |
107 | For i As Integer = 0 To convertors.Length - 1 |
108 | If (convertors(i).unit.Equals(target)) Then |
109 | Return i |
110 | End If |
111 | Next |
112 | |
113 | Return -1 |
114 | End Function |
115 | |
116 | <MethodImpl(MethodImplOptions.AggressiveInlining)> |
117 | <Extension> |
118 | Public Function Unit(Of T As Structure)(value#, unitVal As T) As UnitValue(Of T) |
119 | Return New UnitValue(Of T)(value, unitVal) |
120 | End Function |
121 | End Module |
122 | |
123 | Public Enum ByteSize As Long |
124 | B = 1 |
125 | KB = 1024 |
126 | MB = KB * 1024 |
127 | GB = MB * 1024 |
128 | TB = GB * 1024 |
129 | End Enum |
130 | |
131 | ''' <summary> |
132 | ''' |
133 | ''' </summary> |
134 | ''' <typeparam name="TUnit">枚举类型,基础类型必须是值等于1</typeparam> |
135 | Public Class UnitValue(Of TUnit As Structure) : Inherits float |
136 | |
137 | ''' <summary> |
138 | ''' 分(d) ``10^-1`` |
139 | ''' </summary> |
140 | Public Const d = 10 ^ -1 |
141 | ''' <summary> |
142 | ''' 厘(c) ``10^-2`` |
143 | ''' </summary> |
144 | Public Const c = 10 ^ -2 |
145 | ''' <summary> |
146 | ''' 毫(m) ``10^-3`` |
147 | ''' </summary> |
148 | Public Const m = 10 ^ -3 |
149 | ''' <summary> |
150 | ''' 微(μ) ``10^-6`` |
151 | ''' </summary> |
152 | Public Const u = 10 ^ -6 |
153 | ''' <summary> |
154 | ''' 纳(n) ``10^-9`` |
155 | ''' </summary> |
156 | Public Const n = 10 ^ -9 |
157 | ''' <summary> |
158 | ''' 皮(p) ``10^-12`` |
159 | ''' </summary> |
160 | Public Const p = 10 ^ -12 |
161 | ''' <summary> |
162 | ''' 飞(f) ``10^-15`` |
163 | ''' </summary> |
164 | Public Const f = 10 ^ -15 |
165 | ''' <summary> |
166 | ''' 阿(a) ``10^-18`` |
167 | ''' </summary> |
168 | Public Const a = 10 ^ -18 |
169 | |
170 | Public Property Unit As TUnit |
171 | |
172 | Sub New(value#, unit As TUnit) |
173 | Me.Value = value |
174 | Me.Unit = unit |
175 | End Sub |
176 | |
177 | Sub New() |
178 | End Sub |
179 | |
180 | ''' <summary> |
181 | ''' Unit convert |
182 | ''' </summary> |
183 | ''' <param name="convert"></param> |
184 | ''' <returns></returns> |
185 | Public Function ScaleTo(convert As TUnit) As UnitValue(Of TUnit) |
186 | Return Me = convert |
187 | End Function |
188 | |
189 | <MethodImpl(MethodImplOptions.AggressiveInlining)> |
190 | Public Overrides Function ToString() As String |
191 | Return $"{Value} ({DirectCast(CObj(Unit), [Enum]).Description})" |
192 | End Function |
193 | |
194 | Shared ReadOnly converts As (unit As TUnit, value#)() = UnitConvertorExtensions.GetUnitConvertor(Of TUnit) |
195 | |
196 | ''' <summary> |
197 | ''' 将当前的单位值转换为目标<paramref name="unit"/>单位制 |
198 | ''' </summary> |
199 | ''' <param name="value"></param> |
200 | ''' <param name="unit"></param> |
201 | ''' <returns></returns> |
202 | Public Overloads Shared Operator =(value As UnitValue(Of TUnit), unit As TUnit) As UnitValue(Of TUnit) |
203 | ' 先计算出当前的单位值对基础单位值的结果 |
204 | Dim index% = converts.IndexOf(value.Unit) |
205 | Dim index2 = converts.IndexOf(unit) |
206 | ' 计算出对基底的结果值 |
207 | Dim val# = value * converts(index).value / converts(index2).value |
208 | |
209 | Return New UnitValue(Of TUnit)(val, unit) |
210 | End Operator |
211 | |
212 | Public Overloads Shared Operator <>(value As UnitValue(Of TUnit), unit As TUnit) As UnitValue(Of TUnit) |
213 | Throw New NotImplementedException |
214 | End Operator |
215 | End Class |
216 | End Namespace |