Skip to content

Commit 1bfbb32

Browse files
committed
Merge tag '3.0.0' into develop
Release 3.0.0 Clean up naming of units. Add information unit. New: * Add information units for bit, byte, kilobit, kilobyte, kibibit, kibibyte and so on up to exabyte Breaking changes: * Delete OtherUnit.Piece * Move OtherUnit.Table/Teaspoon to Volume * Rename Month30Days Year365Days units to Month and Year * Fix plural naming of Pressure.KilogramsForcePerSquareCentimeterInOnePascal * Fix plural naming of Ratio.PartsPer-units * Custom units added manually via UnitSystem.MapUnitToAbbreviation() Fixes: * Fall back to US English culture when parsing/getting abbreviations * Fall back to custom string if no abbreviation defined for unit Behind the scenes: * Replace T4 templates with PowerShell + JSON templates * Support custom tolerance per unit in tests * Support decimal and long base unit types (decimal used in Information unit) * Move code more consistently into Custom/GeneratedCode folders * Fix misc R# warnings * Match R# cleanup profile in generated code
2 parents 3af6036 + 89308fc commit 1bfbb32

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1480
-660
lines changed

Src/Scripts/GenerateUnits.ps1

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,42 @@
1010
{
1111
$prefixInfo = switch ($prefix)
1212
{
13-
"Kilo" { "k", "1e3"; break; }
14-
"Hecto" { "h", "1e2"; break; }
15-
"Deca" { "da", "1e1"; break; }
16-
"Deci" { "d", "1e-1"; break; }
17-
"Centi" { "c", "1e-2"; break; }
18-
"Milli" { "m", "1e-3"; break; }
19-
"Micro" { "μ", "1e-6"; break; }
20-
"Nano" { "n", "1e-9"; break; }
13+
"Kilo" { "k", "1e3d"; break; }
14+
"Hecto" { "h", "1e2d"; break; }
15+
"Deca" { "da", "1e1d"; break; }
16+
"Deci" { "d", "1e-1d"; break; }
17+
"Centi" { "c", "1e-2d"; break; }
18+
"Milli" { "m", "1e-3d"; break; }
19+
"Micro" { "μ", "1e-6d"; break; }
20+
"Nano" { "n", "1e-9d"; break; }
2121

2222
# Optimization, move less frequently used prefixes to the end
23-
"Pico" { "p", "1e-12"; break; }
24-
"Femto" { "f", "1e-15"; break; }
25-
"Atto" { "a", "1e-18"; break; }
26-
"Zepto" { "z", "1e-21"; break; }
27-
"Yocto" { "y", "1e-24"; break; }
28-
29-
"Yotta" { "Y", "1e24"; break; }
30-
"Zetta" { "Z", "1e21"; break; }
31-
"Exa" { "E", "1e18"; break; }
32-
"Peta" { "P", "1e15"; break; }
33-
"Tera" { "T", "1e12"; break; }
34-
"Giga" { "G", "1e9"; break; }
35-
"Mega" { "M", "1e6"; break; }
36-
37-
}
23+
"Pico" { "p", "1e-12d"; break; }
24+
"Femto" { "f", "1e-15d"; break; }
25+
"Atto" { "a", "1e-18d"; break; }
26+
"Zepto" { "z", "1e-21d"; break; }
27+
"Yocto" { "y", "1e-24d"; break; }
28+
29+
"Yotta" { "Y", "1e24d"; break; }
30+
"Zetta" { "Z", "1e21d"; break; }
31+
"Exa" { "E", "1e18d"; break; }
32+
"Peta" { "P", "1e15d"; break; }
33+
"Tera" { "T", "1e12d"; break; }
34+
"Giga" { "G", "1e9d"; break; }
35+
"Mega" { "M", "1e6d"; break; }
36+
37+
# Binary prefixes
38+
"Kibi" { "Ki", "1024d"; break; }
39+
"Mebi" { "Mi", "(1024d * 1024)"; break; }
40+
"Gibi" { "Gi", "(1024d * 1024 * 1024)"; break; }
41+
"Tebi" { "Ti", "(1024d * 1024 * 1024 * 1024)"; break; }
42+
"Pebi" { "Pi", "(1024d * 1024 * 1024 * 1024 * 1024)"; break; }
43+
"Exbi" { "Ei", "(1024d * 1024 * 1024 * 1024 * 1024 * 1024)"; break; }
44+
}
3845

3946
$prefixAbbreviation = $prefixInfo[0];
4047
$prefixFactor = $prefixInfo[1];
41-
48+
4249
$u = New-Object PsObject -Property @{
4350
SingularName=$prefix+$unit.SingularName.ToLowerInvariant();
4451
PluralName=$prefix+$unit.PluralName.ToLowerInvariant();
@@ -60,6 +67,25 @@
6067
}
6168
}
6269

70+
foreach ($u in $units) {
71+
# Use decimal for internal calculations if base type is not double, such as for long or int.
72+
if ($unitClass.BaseType -ne "double") {
73+
$u.FromUnitToBaseFunc = $u.FromUnitToBaseFunc -replace "m", "d";
74+
$u.FromBaseToUnitFunc = $u.FromBaseToUnitFunc -replace "d", "m";
75+
}
76+
77+
# Convert to/from double for other base types
78+
if ($unitClass.BaseType -eq "decimal") {
79+
$u.FromUnitToBaseFunc = "Convert.ToDecimal($($u.FromUnitToBaseFunc))";
80+
$u.FromBaseToUnitFunc = "Convert.ToDouble($($u.FromBaseToUnitFunc))";
81+
} else {
82+
if ($unitClass.BaseType -eq "long") {
83+
$u.FromUnitToBaseFunc = "Convert.ToInt64($($u.FromUnitToBaseFunc))";
84+
$u.FromBaseToUnitFunc = "Convert.ToDouble($($u.FromBaseToUnitFunc))";
85+
}
86+
}
87+
}
88+
6389
return $units | sort SingularName;
6490
}
6591

@@ -136,6 +162,11 @@ get-childitem -path $templatesDir -filter "*.json" | % {
136162
$json = (Get-Content $templateFile | Out-String)
137163
$unitClass = $json | ConvertFrom-Json
138164

165+
# Set default values
166+
if (!$unitClass.BaseType) {
167+
$unitClass | Add-Member BaseType "double";
168+
}
169+
139170
# Expand unit prefixes into units
140171
$unitClass.Units = GetUnits $unitClass;
141172

Src/Scripts/Include-GenerateUnitClassSourceCode.ps1

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ function GenerateUnitClassSourceCode($unitClass)
22
{
33
$className = $unitClass.Name;
44
$units = $unitClass.Units;
5+
$baseType = $unitClass.BaseType;
56
$baseUnit = $units | where { $_.SingularName -eq $unitClass.BaseUnit }
67
$baseUnitSingularName = $baseUnit.SingularName
78
$baseUnitPluralName = $baseUnit.PluralName
8-
$baseUnitPluralNameLower = $baseUnitPluralName.ToLowerInvariant()
9-
$baseUnitFieldName = $baseUnitPluralName;
9+
$baseUnitPluralNameLower = $baseUnitPluralName.ToLowerInvariant()
1010
$unitEnumName = "$className" + "Unit";
11+
$baseUnitFieldName = "_"+[Char]::ToLowerInvariant($baseUnitPluralName[0]) + $baseUnitPluralName.Substring(1);
1112

1213
@"
1314
// Copyright © 2007 by Initial Force AS. All rights reserved.
@@ -50,20 +51,16 @@ namespace UnitsNet
5051
/// <summary>
5152
/// Base unit of $className.
5253
/// </summary>
53-
[UsedImplicitly] public readonly double $baseUnitPluralName;
54+
private readonly $baseType $baseUnitFieldName;
5455
55-
public $className(double $baseUnitPluralNameLower) : this()
56+
public $className($baseType $baseUnitPluralNameLower) : this()
5657
{
57-
$baseUnitPluralName = $baseUnitPluralNameLower;
58+
$baseUnitFieldName = $baseUnitPluralNameLower;
5859
}
5960
6061
#region Properties
6162
"@; foreach ($unit in $units) {
62-
# Base unit already has a public readonly field
63-
if ($unit.SingularName -eq $baseUnitSingularName) { continue; }
64-
65-
$propertyName = $unit.PluralName;
66-
$baseUnitPluralNameLower = $baseUnitPluralName.ToLowerInvariant();
63+
$propertyName = $unit.PluralName;
6764
$fromBaseToUnitFunc = $unit.FromBaseToUnitFunc.Replace("x", $baseUnitFieldName);@"
6865
6966
/// <summary>
@@ -73,7 +70,7 @@ namespace UnitsNet
7370
{
7471
get { return $fromBaseToUnitFunc; }
7572
}
76-
"@; }@"
73+
"@; }@"
7774
7875
#endregion
7976
@@ -85,7 +82,7 @@ namespace UnitsNet
8582
}
8683
8784
"@; foreach ($unit in $units) {
88-
$valueParamName = $unit.PluralName.ToLowerInvariant();
85+
$valueParamName = $unit.PluralName.ToLowerInvariant();
8986
$func = $unit.FromUnitToBaseFunc.Replace("x", $valueParamName);@"
9087
/// <summary>
9188
/// Get $className from $($unit.PluralName).
@@ -95,7 +92,7 @@ namespace UnitsNet
9592
return new $className($func);
9693
}
9794
98-
"@; }@"
95+
"@; }@"
9996
10097
/// <summary>
10198
/// Dynamically convert from value and unit enum <see cref="$unitEnumName" /> to <see cref="$className" />.
@@ -110,7 +107,7 @@ namespace UnitsNet
110107
"@; foreach ($unit in $units) {@"
111108
case $unitEnumName.$($unit.SingularName):
112109
return From$($unit.PluralName)(value);
113-
"@; }@"
110+
"@; }@"
114111
115112
default:
116113
throw new NotImplementedException("fromUnit: " + fromUnit);
@@ -135,37 +132,37 @@ namespace UnitsNet
135132
136133
public static $className operator -($className right)
137134
{
138-
return new $className(-right.$baseUnitPluralName);
135+
return new $className(-right.$baseUnitFieldName);
139136
}
140137
141138
public static $className operator +($className left, $className right)
142139
{
143-
return new $className(left.$baseUnitPluralName + right.$baseUnitPluralName);
140+
return new $className(left.$baseUnitFieldName + right.$baseUnitFieldName);
144141
}
145142
146143
public static $className operator -($className left, $className right)
147144
{
148-
return new $className(left.$baseUnitPluralName - right.$baseUnitPluralName);
145+
return new $className(left.$baseUnitFieldName - right.$baseUnitFieldName);
149146
}
150147
151-
public static $className operator *(double left, $className right)
148+
public static $className operator *($baseType left, $className right)
152149
{
153-
return new $className(left*right.$baseUnitPluralName);
150+
return new $className(left*right.$baseUnitFieldName);
154151
}
155152
156153
public static $className operator *($className left, double right)
157154
{
158-
return new $className(left.$baseUnitPluralName*right);
155+
return new $className(left.$baseUnitFieldName*($baseType)right);
159156
}
160157
161158
public static $className operator /($className left, double right)
162159
{
163-
return new $className(left.$baseUnitPluralName/right);
160+
return new $className(left.$baseUnitFieldName/($baseType)right);
164161
}
165162
166163
public static double operator /($className left, $className right)
167164
{
168-
return left.$baseUnitPluralName/right.$baseUnitPluralName;
165+
return Convert.ToDouble(left.$baseUnitFieldName/right.$baseUnitFieldName);
169166
}
170167
171168
#endregion
@@ -181,39 +178,39 @@ namespace UnitsNet
181178
182179
public int CompareTo($className other)
183180
{
184-
return $baseUnitPluralName.CompareTo(other.$baseUnitPluralName);
181+
return $baseUnitFieldName.CompareTo(other.$baseUnitFieldName);
185182
}
186183
187184
public static bool operator <=($className left, $className right)
188185
{
189-
return left.$baseUnitPluralName <= right.$baseUnitPluralName;
186+
return left.$baseUnitFieldName <= right.$baseUnitFieldName;
190187
}
191188
192189
public static bool operator >=($className left, $className right)
193190
{
194-
return left.$baseUnitPluralName >= right.$baseUnitPluralName;
191+
return left.$baseUnitFieldName >= right.$baseUnitFieldName;
195192
}
196193
197194
public static bool operator <($className left, $className right)
198195
{
199-
return left.$baseUnitPluralName < right.$baseUnitPluralName;
196+
return left.$baseUnitFieldName < right.$baseUnitFieldName;
200197
}
201198
202199
public static bool operator >($className left, $className right)
203200
{
204-
return left.$baseUnitPluralName > right.$baseUnitPluralName;
201+
return left.$baseUnitFieldName > right.$baseUnitFieldName;
205202
}
206203
207204
public static bool operator ==($className left, $className right)
208205
{
209206
// ReSharper disable once CompareOfFloatsByEqualityOperator
210-
return left.$baseUnitPluralName == right.$baseUnitPluralName;
207+
return left.$baseUnitFieldName == right.$baseUnitFieldName;
211208
}
212209
213210
public static bool operator !=($className left, $className right)
214211
{
215212
// ReSharper disable once CompareOfFloatsByEqualityOperator
216-
return left.$baseUnitPluralName != right.$baseUnitPluralName;
213+
return left.$baseUnitFieldName != right.$baseUnitFieldName;
217214
}
218215
219216
public override bool Equals(object obj)
@@ -223,12 +220,12 @@ namespace UnitsNet
223220
return false;
224221
}
225222
226-
return $baseUnitPluralName.Equals((($className) obj).$baseUnitPluralName);
223+
return $baseUnitFieldName.Equals((($className) obj).$baseUnitFieldName);
227224
}
228225
229226
public override int GetHashCode()
230227
{
231-
return $baseUnitPluralName.GetHashCode();
228+
return $baseUnitFieldName.GetHashCode();
232229
}
233230
234231
#endregion
@@ -244,7 +241,7 @@ namespace UnitsNet
244241
{
245242
switch (unit)
246243
{
247-
"@; foreach ($unit in $units) {@"
244+
"@; foreach ($unit in $units) {@"
248245
case $unitEnumName.$($unit.SingularName):
249246
return $($unit.PluralName);
250247
"@; }@"

Src/Scripts/Include-GenerateUnitTestBaseClassSourceCode.ps1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
function GenerateUnitTestBaseClassSourceCode($unitClass)
22
{
33
$className = $unitClass.Name;
4+
$baseType = $unitClass.BaseType;
45
$units = $unitClass.Units;
56
$baseUnit = $units | where { $_.SingularName -eq $unitClass.BaseUnit }
67
$baseUnitPluralName = $baseUnit.PluralName
@@ -52,7 +53,7 @@ namespace UnitsNet.Tests
5253
5354
// ReSharper disable VirtualMemberNeverOverriden.Global
5455
"@; foreach ($unit in $units) {@"
55-
protected virtual double $($unit.PluralName)Tolerance { get { return 1E-5; } }
56+
protected virtual double $($unit.PluralName)Tolerance { get { return 1e-5; } }
5657
"@; }@"
5758
// ReSharper restore VirtualMemberNeverOverriden.Global
5859

Src/Scripts/UnitDefinitions/Information.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
{
22
"Name": "Information",
33
"BaseUnit": "Bit",
4+
"BaseType": "decimal",
45
"XmlDoc": "In computing and telecommunications, a unit of information is the capacity of some standard data storage system or communication channel, used to measure the capacities of other systems and channels. In information theory, units of information are also used to measure the information contents or entropy of random variables.",
56
"Units": [
67
{
78
"SingularName": "Byte",
89
"PluralName": "Bytes",
9-
"FromUnitToBaseFunc": "x*8",
10-
"FromBaseToUnitFunc": "x/8",
11-
"Prefixes": ["Kilo","Mega","Giga","Tera","Peta","Exa"],
10+
"FromUnitToBaseFunc": "x*8m",
11+
"FromBaseToUnitFunc": "x/8m",
12+
"Prefixes": ["Kilo","Mega","Giga","Tera","Peta","Exa","Kibi","Mebi","Gibi","Tebi","Pebi","Exbi"],
1213
"Localization": [
1314
{
1415
"Culture": "en-US",
@@ -21,6 +22,7 @@
2122
"PluralName": "Bits",
2223
"FromUnitToBaseFunc": "x",
2324
"FromBaseToUnitFunc": "x",
25+
"Prefixes": ["Kilo","Mega","Giga","Tera","Peta","Exa","Kibi","Mebi","Gibi","Tebi","Pebi","Exbi"],
2426
"Localization": [
2527
{
2628
"Culture": "en-US",

Src/UnitsNet/CustomCode/UnitSystem.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ namespace UnitsNet
3434
public partial class UnitSystem
3535
{
3636
private static readonly Dictionary<CultureInfo, UnitSystem> CultureToInstance;
37-
private static readonly CultureInfo DefaultCulture = CultureInfo.GetCultureInfo("en-US");
37+
private static readonly CultureInfo DefaultCulture = new CultureInfo("en-US");
3838

3939
/// <summary>
4040
/// The culture of which this unit system is based on. Either passed in to constructor or the default culture.
@@ -243,7 +243,7 @@ public string[] GetAllAbbreviations<TUnit>(TUnit unit)
243243
{
244244
if (IsDefaultCulture)
245245
{
246-
return new[] {string.Format("(no abbreviation for {0})", unit.ToString())};
246+
return new[] {string.Format("(no abbreviation for {0}.{1})", unitType.Name, unit)};
247247
}
248248

249249
// Fall back to default culture

Src/UnitsNet/GeneratedCode/Enums/InformationUnit.g.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,29 @@ public enum InformationUnit
2727
Undefined = 0,
2828
Bit,
2929
Byte,
30+
Exabit,
3031
Exabyte,
32+
Exbibit,
33+
Exbibyte,
34+
Gibibit,
35+
Gibibyte,
36+
Gigabit,
3137
Gigabyte,
38+
Kibibit,
39+
Kibibyte,
40+
Kilobit,
3241
Kilobyte,
42+
Mebibit,
43+
Mebibyte,
44+
Megabit,
3345
Megabyte,
46+
Pebibit,
47+
Pebibyte,
48+
Petabit,
3449
Petabyte,
50+
Tebibit,
51+
Tebibyte,
52+
Terabit,
3553
Terabyte,
3654
}
3755
}

0 commit comments

Comments
 (0)