diff --git a/Sources/CoreKit/Guarantee+Validation.swift b/Sources/CoreKit/Guarantee+Validation.swift deleted file mode 100644 index 29ce57a8..00000000 --- a/Sources/CoreKit/Guarantee+Validation.swift +++ /dev/null @@ -1,48 +0,0 @@ -//=----------------------------------------------------------------------------= -// This source file is part of the Ultimathnum open source project. -// -// Copyright (c) 2023 Oscar Byström Ericsson -// Licensed under Apache License, Version 2.0 -// -// See http://www.apache.org/licenses/LICENSE-2.0 for license information. -//=----------------------------------------------------------------------------= - -//*============================================================================* -// MARK: * Guarantee x Validation -//*============================================================================* - -extension Guarantee { - - //=------------------------------------------------------------------------= - // MARK: Initializers - //=------------------------------------------------------------------------= - - /// Creates a new instance by trapping on failure. - /// - /// - Requires: `Self.predicate(value)` must be `true` to succeed. - /// - @inlinable public init(_ value: consuming Value) { - self.init(exactly: value)! - } - - /// Creates a new instance by returning `nil` on failure. - /// - /// - Requires: `Self.predicate(value)` must be `true` to succeed. - /// - @inlinable public init?(exactly value: consuming Value) { - guard Self.predicate(value) else { return nil } - self.init(unchecked: value) - } - - /// Creates a new instance by throwing the `error()` on failure. - /// - /// - Requires: `Self.predicate(value)` must be `true` to succeed. - /// - @inlinable public init( - _ value: consuming Value, - prune error: @autoclosure () -> Failure - ) throws where Failure: Swift.Error { - guard Self.predicate(value) else { throw error() } - self.init(unchecked: value) - } -} diff --git a/Sources/CoreKit/Guarantee.swift b/Sources/CoreKit/Guarantee.swift deleted file mode 100644 index 2197779e..00000000 --- a/Sources/CoreKit/Guarantee.swift +++ /dev/null @@ -1,45 +0,0 @@ -//=----------------------------------------------------------------------------= -// This source file is part of the Ultimathnum open source project. -// -// Copyright (c) 2023 Oscar Byström Ericsson -// Licensed under Apache License, Version 2.0 -// -// See http://www.apache.org/licenses/LICENSE-2.0 for license information. -//=----------------------------------------------------------------------------= - -//*============================================================================* -// MARK: * Guarantee -//*============================================================================* - -/// A *trusted input* type. -public protocol Guarantee { - - associatedtype Value - - //=------------------------------------------------------------------------= - // MARK: Metadata - //=------------------------------------------------------------------------= - - /// Indicates whether the given `value` can be trusted. - @inlinable static func predicate(_ value: borrowing Value) -> Bool - - //=------------------------------------------------------------------------= - // MARK: Initializers - //=------------------------------------------------------------------------= - - /// Creates a new instance without validation in release mode. - /// - /// - Requires: `Self.predicate(value)` must be `true` to succeed. - /// - /// - Warning: Only use this method when you know the `value` is valid. - /// - @_disfavoredOverload // collection.map(Self.init) - @inlinable init(unchecked value: consuming Value) - - //=------------------------------------------------------------------------= - // MARK: Utilities - //=------------------------------------------------------------------------= - - /// The value of this trusted input. - @inlinable var value: Value { get } -} diff --git a/Sources/CoreKit/Models/Guarantees/Finite.swift b/Sources/CoreKit/Models/Guarantees/Finite.swift index 821c7906..ec819884 100644 --- a/Sources/CoreKit/Models/Guarantees/Finite.swift +++ b/Sources/CoreKit/Models/Guarantees/Finite.swift @@ -24,12 +24,18 @@ /// init(unchecked:) // error: unchecked /// ``` /// -@frozen public struct Finite: Equatable, Guarantee where Value: BinaryInteger { +@frozen public struct Finite: Equatable where Value: BinaryInteger { + + public typealias Value = Value //=------------------------------------------------------------------------= // MARK: Metadata //=------------------------------------------------------------------------= + /// Indicates whether the given `value` can be trusted. + /// + /// - Returns: `value ∈ ℤ` + /// @inlinable public static func predicate(_ value: /* borrowing */ Value) -> Bool { !value.isInfinite // await borrowing fix } @@ -44,16 +50,53 @@ // MARK: Initializers //=------------------------------------------------------------------------= + /// Creates a new instance without validation in release mode. + /// + /// - Requires: `value ∈ ℤ` + /// + /// - Warning: Only use this method when you know the `value` is valid. + /// @_disfavoredOverload // collection.map(Self.init) @inlinable public init(unchecked value: consuming Value) { Swift.assert(Self.predicate(value), String.brokenInvariant()) self.value = value } + /// Creates a new instance by trapping on failure. + /// + /// - Requires: `value ∈ ℤ` + /// + @inlinable public init(_ value: consuming Value) { + precondition(Self.predicate(value), String.brokenInvariant()) + self.value = value + } + + /// Creates a new instance by returning `nil` on failure. + /// + /// - Requires: `value ∈ ℤ` + /// + @inlinable public init?(exactly value: consuming Value) { + guard Self.predicate(value) else { return nil } + self.value = value + } + + /// Creates a new instance by throwing the `error()` on failure. + /// + /// - Requires: `value ∈ ℤ` + /// + @inlinable public init( + _ value: consuming Value, + prune error: @autoclosure () -> Failure + ) throws where Failure: Swift.Error { + guard Self.predicate(value) else { throw error() } + self.value = value + } + //=------------------------------------------------------------------------= // MARK: Transformations //=------------------------------------------------------------------------= + /// The `magnitude` of `self`. @inlinable public consuming func magnitude() -> Finite { Finite(unchecked: self.value.magnitude()) } diff --git a/Sources/CoreKit/Models/Guarantees/Natural.swift b/Sources/CoreKit/Models/Guarantees/Natural.swift index 48287d70..10e641f2 100644 --- a/Sources/CoreKit/Models/Guarantees/Natural.swift +++ b/Sources/CoreKit/Models/Guarantees/Natural.swift @@ -31,12 +31,18 @@ /// however, that the inverse case is not as simple. `U8(255)` is natural, /// for example, but it becomes negative when you reinterpret it as `I8(-1)`. /// -@frozen public struct Natural: Equatable, Guarantee where Value: BinaryInteger { +@frozen public struct Natural: Equatable where Value: BinaryInteger { + + public typealias Value = Value //=------------------------------------------------------------------------= // MARK: Metadata //=------------------------------------------------------------------------= + /// Indicates whether the given `value` can be trusted. + /// + /// - Returns: `value ∈ ℕ` + /// @inlinable public static func predicate(_ value: /* borrowing */ Value) -> Bool { !Bool(value.appendix) // await borrowing fix } @@ -51,17 +57,53 @@ // MARK: Initializers //=------------------------------------------------------------------------= - @_disfavoredOverload // enables: elements.map(Self.init) + /// Creates a new instance without validation in release mode. + /// + /// - Requires: `value ∈ ℕ` + /// + /// - Warning: Only use this method when you know the `value` is valid. + /// + @_disfavoredOverload // collection.map(Self.init) @inlinable public init(unchecked value: consuming Value) { Swift.assert(Self.predicate(value), String.brokenInvariant()) self.value = value } + /// Creates a new instance by trapping on failure. + /// + /// - Requires: `value ∈ ℕ` + /// + @inlinable public init(_ value: consuming Value) { + precondition(Self.predicate(value), String.brokenInvariant()) + self.value = value + } + + /// Creates a new instance by returning `nil` on failure. + /// + /// - Requires: `value ∈ ℕ` + /// + @inlinable public init?(exactly value: consuming Value) { + guard Self.predicate(value) else { return nil } + self.value = value + } + + /// Creates a new instance by throwing the `error()` on failure. + /// + /// - Requires: `value ∈ ℕ` + /// + @inlinable public init( + _ value: consuming Value, + prune error: @autoclosure () -> Failure + ) throws where Failure: Swift.Error { + guard Self.predicate(value) else { throw error() } + self.value = value + } + //=------------------------------------------------------------------------= // MARK: Transformations //=------------------------------------------------------------------------= - /// The magnitude of this value. + /// The `magnitude` of `self`. /// /// - Note: This is a bit cast because `self ∈ ℕ → unsigned`. /// diff --git a/Sources/CoreKit/Models/Guarantees/Nonzero.swift b/Sources/CoreKit/Models/Guarantees/Nonzero.swift index ab6cf557..cc830c18 100644 --- a/Sources/CoreKit/Models/Guarantees/Nonzero.swift +++ b/Sources/CoreKit/Models/Guarantees/Nonzero.swift @@ -24,7 +24,9 @@ /// init(unchecked:) // error: unchecked /// ``` /// -@frozen public struct Nonzero: BitCastable, Equatable, Guarantee where Value: BinaryInteger { +@frozen public struct Nonzero: BitCastable, Equatable where Value: BinaryInteger { + + public typealias Value = Value public typealias BitPattern = Nonzero @@ -32,6 +34,10 @@ // MARK: Metadata //=------------------------------------------------------------------------= + /// Indicates whether the given `value` can be trusted. + /// + /// - Returns: `value ≠ 0` + /// @inlinable public static func predicate(_ value: /* borrowing */ Value) -> Bool { !value.isZero // await borrowing fix } @@ -46,12 +52,48 @@ // MARK: Initializers //=------------------------------------------------------------------------= + /// Creates a new instance without validation in release mode. + /// + /// - Requires: `value ≠ 0` + /// + /// - Warning: Only use this method when you know the `value` is valid. + /// @_disfavoredOverload // collection.map(Self.init) @inlinable public init(unchecked value: consuming Value) { Swift.assert(Self.predicate(value), String.brokenInvariant()) self.value = value } + /// Creates a new instance by trapping on failure. + /// + /// - Requires: `value ≠ 0` + /// + @inlinable public init(_ value: consuming Value) { + precondition(Self.predicate(value), String.brokenInvariant()) + self.value = value + } + + /// Creates a new instance by returning `nil` on failure. + /// + /// - Requires: `value ≠ 0` + /// + @inlinable public init?(exactly value: consuming Value) { + guard Self.predicate(value) else { return nil } + self.value = value + } + + /// Creates a new instance by throwing the `error()` on failure. + /// + /// - Requires: `value ≠ 0` + /// + @inlinable public init( + _ value: consuming Value, + prune error: @autoclosure () -> Failure + ) throws where Failure: Swift.Error { + guard Self.predicate(value) else { throw error() } + self.value = value + } + //=------------------------------------------------------------------------= // MARK: Initializers //=------------------------------------------------------------------------= @@ -68,10 +110,12 @@ // MARK: Transformations //=------------------------------------------------------------------------= + /// The `complement` of `self`. @inlinable public consuming func complement() -> Nonzero { Self(unchecked: self.value.complement()) } + /// The `magnitude` of `self`. @inlinable public consuming func magnitude() -> Nonzero { Nonzero(unchecked: self.value.magnitude()) } diff --git a/Sources/CoreKit/Models/Guarantees/Shift.swift b/Sources/CoreKit/Models/Guarantees/Shift.swift index f08d8316..125ae009 100644 --- a/Sources/CoreKit/Models/Guarantees/Shift.swift +++ b/Sources/CoreKit/Models/Guarantees/Shift.swift @@ -24,7 +24,7 @@ /// init(unchecked:) // error: unchecked /// ``` /// -@frozen public struct Shift: Equatable, Guarantee where Target: UnsignedInteger { +@frozen public struct Shift: Equatable where Target: UnsignedInteger { public typealias Target = Target @@ -34,6 +34,10 @@ // MARK: Metadata //=------------------------------------------------------------------------= + /// Indicates whether the given `value` can be trusted. + /// + /// - Returns: `value ∈ 0 up to Value.size` + /// @inlinable public static func predicate(_ value: borrowing Value) -> Bool { value < Target.size } @@ -77,12 +81,48 @@ // MARK: Initializers //=------------------------------------------------------------------------= + /// Creates a new instance without validation in release mode. + /// + /// - Requires: `value ∈ 0 up to Value.size` + /// + /// - Warning: Only use this method when you know the `value` is valid. + /// @_disfavoredOverload // collection.map(Self.init) @inlinable public init(unchecked value: consuming Value) { Swift.assert(Self.predicate(value), String.brokenInvariant()) self.value = value } + /// Creates a new instance by trapping on failure. + /// + /// - Requires: `value ∈ 0 up to Value.size` + /// + @inlinable public init(_ value: consuming Value) { + precondition(Self.predicate(value), String.brokenInvariant()) + self.value = value + } + + /// Creates a new instance by returning `nil` on failure. + /// + /// - Requires: `value ∈ 0 up to Value.size` + /// + @inlinable public init?(exactly value: consuming Value) { + guard Self.predicate(value) else { return nil } + self.value = value + } + + /// Creates a new instance by throwing the `error()` on failure. + /// + /// - Requires: `value ∈ 0 up to Value.size` + /// + @inlinable public init( + _ value: consuming Value, + prune error: @autoclosure () -> Failure + ) throws where Failure: Swift.Error { + guard Self.predicate(value) else { throw error() } + self.value = value + } + //=------------------------------------------------------------------------= // MARK: Utilities //=------------------------------------------------------------------------=