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 OverloadsSub 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 OverloadsSub 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