Repository navigation
Fix Paths, Color, Quantities, C++ prelude and Strings bugs - #486
Merged
Merged
Conversation
…h; skip unrepresentable entries in GetContents IsRoot is now true exactly when Parent returns the path itself, so walking upwards from /home/.. stops (#479). DirectoryPath.Parent resolves rooted paths and normalizes relative ones as the typed paths do (#478). Depth counts directories below the root of the resolved path, or levels below the first segment of the normalized relative path, instead of separator characters (#466). GetContents skips an entry whose path fails validation rather than throwing for the whole listing (#445). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RjhaUGAEJWfvbkaV4MjYkY
…klab mixes NamedColors.Green is CSS's #008000 and the new Lime is #00FF00 (#449). CompositeOver blends source-over in gamma sRGB; ContrastRatio, AccessibilityLevelAgainst and AdjustForContrast measure a translucent color as it looks over the background (#393). AdjustForContrast gamut-maps its lightness candidates by reducing chroma instead of clipping, and falls back to mixing towards black or white, so it reaches the target whenever black or white does (#351). MixOklab and Gradient return in-gamut colors, and Hsl/Hsv.FromSrgb clamp their input and treat a rounding-error spread as gray (#355). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RjhaUGAEJWfvbkaV4MjYkY
…s, division by zero, scaled vector lengths, bounded roots - domains.json: AbsoluteZeroInCelsius is -273.15, WaterIonProduct is 1e-14 and MolarVolumeSTP is in m3/mol; mu0/epsilon0 no longer claim to be exact (#386). - Each physical constant is its own lazily filled field, so one that a storage type cannot hold throws alone, and one that would lose its precision throws instead of reading as zero (#392). - Logarithmic conversions throw ArgumentOutOfRangeException for a level the storage type cannot hold (a linear zero with decimal or integer storage) and OverflowException going back, as documented (#352). - Wavelength, Period and HalfLife keep EnsurePositive through scaling, narrowing and subtraction (#354). - Every generated division throws DivideByZeroException for a zero divisor, including vector / scalar, cross-dimension operators and Normalize() of a zero vector (#480). - Vector Length() and Distance() go through StorageMath.Hypot, scaled by the largest component, so int, decimal and float vectors whose squares overflow still have a length (#327). - Cbrt/RootN stop for PreciseNumber instead of hanging (#457). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RjhaUGAEJWfvbkaV4MjYkY
…tors (#456) Distance / Duration, Width * Width, Weight * Height and WindVelocity3D * Duration now compile. Each overload declares a copy of every relationship operator its base has with itself on the left; results stay base types. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RjhaUGAEJWfvbkaV4MjYkY
…nly explicitly (#451) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RjhaUGAEJWfvbkaV4MjYkY
…ributes and the WeakString setter cached per type (#443, #444) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RjhaUGAEJWfvbkaV4MjYkY
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RjhaUGAEJWfvbkaV4MjYkY
… explicit Where Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RjhaUGAEJWfvbkaV4MjYkY
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Requested by Matt · project thread
Fixes the open non-music bugs in Paths, Color, Quantities, the C++ prelude and Strings. One commit per area.
Paths
AbsoluteDirectoryPath.IsRootis true exactly whenParentreturns the path itself, sowhile (!d.IsRoot) d = d.Parent;from/home/..stops.DirectoryPath.Parentresolves a rooted path (/home/user/..→/) and normalizes a relative one lexically asRelativeDirectoryPath.Parentdoes (a/..→..,..→../..). A root still gives the empty path, as documented before.Depthcounts directories, not separator characters. Absolute: segments below the root of the resolved path (/is 0,/homeand/home/are 1). Relative: levels below the first segment of the normalized path (aand./aare 0,a/bis 1), so the existing tests keep their values.GetContents()skips an entry whose path fails validation instead of throwing for the whole listing. Tested on every platform with a directory type that rejects one name, plus a Windows-only test using the real 256-character limit.#385 is already fixed on main by c00d0cd (segment-wise
GetRelativePathBySegments, tested againstPath.GetRelativePathfor every row in that issue); it can be closed.Color
NamedColors.Greenis CSS's#008000and a newLimeis#00FF00. Behavior change:GreenandTryGet("green")return a darker color than before. A test pins every entry to CSS Color 4.CompositeOver(background)(source-over, in gamma sRGB so ratios agree with axe and DevTools).ContrastRatio,AccessibilityLevelAgainstandAdjustForContrastmeasure a translucent foreground as it looks over the background; the background's own alpha is ignored. Opaque pairs are unchanged.Transparenton white now rates 1:1 / Fail.Color.AdjustForContrastreturns the original failing colour for saturated foregrounds (blue on #777777 stays at 1.92:1 though black reaches 4.69:1) #351:AdjustForContrastgamut-maps each lightness candidate by reducing chroma at the same hue instead of clipping, and falls back to mixing towards black or white. Whenever black or white meets the level, the result does. All five rows from the issue are tests.MixOklabandGradientreturn in-gamut colors, andHsl.FromSrgb/Hsv.FromSrgbclamp their input and treat a spread under 1e-6 as gray.FromOklab(White.ToOklab()).DarkenBy(0.5)is#7F7F7Fagain.FromOklab/FromOklchstay exact and now document that they can leave the gamut. NewSrgb.Clamp().The color commit is tagged
[minor]for the new public members.Quantities
AbsoluteZeroInCelsiusis -273.15,WaterIonProductis 1e-14 andMolarVolumeSTPis in m³/mol; μ0 and ε0 no longer claim to be exact.decimal) throws instead of reading as zero.OverflowExceptionfor zero withdecimal/integer storage:Gain<decimal>.Silence.ToDecibels()crashes despite docs promising negative infinity #352: logarithmic conversions throwArgumentOutOfRangeExceptionfor a level the storage type cannot hold, andOverflowExceptiongoing back, as documented.Wavelength/Period/HalfLifereach zero viaw - w,w * 0andWavelength.From(Length.Zero): the strictly-positive guard only coversFrom{Unit}#354:Wavelength,PeriodandHalfLifekeep their positive guard through scaling, narrowing and subtraction.DivideByZeroExceptionfor a zero divisor, including vector / scalar, cross-dimension operators andNormalize()of a zero vector.Length()/Magnitude()/Distance()square the components before rooting:Position3D<int>.FromMeter(65536, 0, 0).Length()is 0, and adecimalvector past ~2.8e14 throws #327: vectorLength()andDistance()go throughStorageMath.Hypot, scaled by the largest component, so int, decimal and float vectors whose squares overflow still have a length.StorageMath.Cbrt/RootNnever return for PreciseNumber:Cbrt(27)andRootN(3, 4)run for minutes, with the digit count doubling every Newton step #457:Cbrt/RootNstop forPreciseNumberinstead of hanging.Distance / Duration,Width * ForceMagnitude,Weight * Lengthdo not compile #456: every semantic overload declares forwarding copies of its base's relationship operators with the base on the left, sodistance / duration,width * width,weight * heightandwindVelocity * durationcompile. Results stay base types, and products of two overloads stay unambiguous. The three docs that promised this now describe how it works.C++ prelude
Quantityrepresentation converts implicitly only where list-initialisation would (float to double), and narrowing needs an explicit constructor.Quantity<D, float> + Quantity<D, double>now resolves todoubleinstead of being ambiguous. Two compile tests cover both directions.Strings
TryCreaterejects a value by its return value, without throwing, catching or building the error message.Createthrows the sameArgumentExceptionas before.WeakStringsetter is a cached delegate instead of a per-callGetProperty/SetValue. Not benchmarked here; the next benchmark-history point will show it.Breaking fixes (#482, #481, #391, #310) are left for a 6.0 PR, pending Matt's call.
Testing
The full
Semantics.Testsuite passes locally on Linux (net10.0): 1821 tests, 0 failed.Semantics.Cpp.Testpasses with g++: 45 tests. Generated sources are regenerated and committed. Windows-only tests are written but were not run here.https://claude.ai/code/session_01RjhaUGAEJWfvbkaV4MjYkY
Generated by Claude Code