@@ -1549,6 +1549,156 @@ public struct _LayoutTrait<K>: _ViewTraitKey where K: LayoutValueKey {
1549
1549
@available ( * , unavailable)
1550
1550
extension _LayoutTrait : Sendable { }
1551
1551
1552
+ // MARK: - Layout + View
1553
+
1554
+ extension Layout {
1555
+ /// Combines the specified views into a single composite view using
1556
+ /// the layout algorithms of the custom layout container.
1557
+ ///
1558
+ /// Don't call this method directly. SwiftUI calls it when you
1559
+ /// instantiate a custom layout that conforms to the ``Layout``
1560
+ /// protocol:
1561
+ ///
1562
+ /// BasicVStack { // Implicitly calls callAsFunction.
1563
+ /// Text("A View")
1564
+ /// Text("Another View")
1565
+ /// }
1566
+ ///
1567
+ /// For information about how Swift uses the `callAsFunction()` method to
1568
+ /// simplify call site syntax, see
1569
+ /// [Methods with Special Names](https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID622)
1570
+ /// in *The Swift Programming Language*.
1571
+ ///
1572
+ /// - Parameter content: A ``ViewBuilder`` that contains the views to
1573
+ /// lay out.
1574
+ ///
1575
+ /// - Returns: A composite view that combines all the input views.
1576
+ @_alwaysEmitIntoClient
1577
+ @_disfavoredOverload
1578
+ public func callAsFunction< V> ( @ViewBuilder _ content: ( ) -> V ) -> some View where V: View {
1579
+ return _VariadicView. Tree ( _LayoutRoot ( self ) ) { content ( ) }
1580
+ }
1581
+
1582
+ @_spi ( _)
1583
+ @available ( * , deprecated, message: " replaced by implicit function call " )
1584
+ @_alwaysEmitIntoClient
1585
+ public func content< V> ( @ViewBuilder _ content: ( ) -> V ) -> some View where V: View {
1586
+ return callAsFunction ( content)
1587
+ }
1588
+ }
1589
+
1590
+ // MARK: - LayoutRoot
1591
+
1592
+ @frozen
1593
+ public struct _LayoutRoot < L> : _VariadicView . UnaryViewRoot where L: Layout {
1594
+ @usableFromInline
1595
+ var layout : L
1596
+
1597
+ @inlinable package init ( _ layout: L ) { self . layout = layout }
1598
+
1599
+ nonisolated public static func _makeView(
1600
+ root: _GraphValue < _LayoutRoot < L > > ,
1601
+ inputs: _ViewInputs ,
1602
+ body: ( _Graph , _ViewInputs ) -> _ViewListOutputs
1603
+ ) -> _ViewOutputs {
1604
+ L . _makeLayoutView (
1605
+ root: root [ offset: { . of( & $0. layout) } ] ,
1606
+ inputs: inputs,
1607
+ body: body
1608
+ )
1609
+ }
1610
+ }
1611
+
1612
+ @available ( * , unavailable)
1613
+ extension _LayoutRoot : Sendable { }
1614
+
1615
+ // MARK: - AnyLayoutProperties
1616
+
1617
+ package struct AnyLayoutProperties : Rule , AsyncAttribute {
1618
+ @Attribute var layout : AnyLayout
1619
+
1620
+ package var value : Axis ? {
1621
+ layout. storage. layoutProperties. stackOrientation
1622
+ }
1623
+
1624
+ package init ( layout: Attribute < AnyLayout > ) {
1625
+ _layout = layout
1626
+ }
1627
+ }
1628
+
1629
+ // MARK: - ViewSizeCache
1630
+
1631
+ /// A cache for storing and retrieving view sizes based on proposed size values.
1632
+ ///
1633
+ /// `ViewSizeCache` provides an efficient way to cache calculated sizes for views,
1634
+ /// avoiding redundant size calculations when the same proposed size is requested multiple times.
1635
+ package struct ViewSizeCache {
1636
+ private var cache : Cache3 < ProposedViewSize , CGSize >
1637
+
1638
+ /// Creates a new view size cache.
1639
+ ///
1640
+ /// - Parameter cache: An optional pre-configured cache. If not provided, a new cache will be created.
1641
+ package init ( cache: Cache3 < ProposedViewSize , CGSize > = . init( ) ) {
1642
+ self . cache = cache
1643
+ }
1644
+
1645
+ /// Retrieves a cached size for the given proposed size, computing it if not already cached.
1646
+ ///
1647
+ /// This method returns a cached value if available. If the value isn't cached,
1648
+ /// it calls the provided closure to compute the value, caches it, and then returns it.
1649
+ ///
1650
+ /// - Parameters:
1651
+ /// - k: The proposed size to use as a key for the cache lookup.
1652
+ /// - makeValue: A closure that computes the size when no cached value is available.
1653
+ /// - Returns: The cached or newly computed size.
1654
+ @inline ( __always)
1655
+ package mutating func get( _ k: _ProposedSize , makeValue: ( ) -> CGSize ) -> CGSize {
1656
+ cache. get ( ProposedViewSize ( k) , makeValue: makeValue)
1657
+ }
1658
+ }
1659
+
1660
+ // MARK: - _GraphInputs / _ViewInputs + needsDynamicLayout
1661
+
1662
+ extension _GraphInputs {
1663
+ package var needsDynamicLayout : Bool {
1664
+ get { options. contains ( . needsDynamicLayout) }
1665
+ set { options. setValue ( newValue, for: . needsDynamicLayout) }
1666
+ }
1667
+ }
1668
+
1669
+ extension _ViewInputs {
1670
+ package var needsDynamicLayout : Bool {
1671
+ get { base. needsDynamicLayout }
1672
+ set { base. needsDynamicLayout = newValue }
1673
+ }
1674
+ }
1675
+
1676
+ // MARK: - Deprecated types for @spi(_)
1677
+
1678
+ @_spi ( _)
1679
+ @available ( * , deprecated, renamed: " Layout " )
1680
+ public typealias ViewLayout = Layout
1681
+
1682
+ @_spi ( _)
1683
+ @available ( * , deprecated, renamed: " LayoutSubview " )
1684
+ public typealias ViewLayoutSubview = LayoutSubview
1685
+
1686
+ @_spi ( _)
1687
+ @available ( * , deprecated, renamed: " LayoutSubviews " )
1688
+ public typealias ViewLayoutSubviews = LayoutSubviews
1689
+
1690
+ @_spi ( _)
1691
+ @available ( * , deprecated, renamed: " LayoutProperties " )
1692
+ public typealias ViewLayoutProperties = LayoutProperties
1693
+
1694
+ @_spi ( _)
1695
+ @available ( * , deprecated, renamed: " LayoutValueKey " )
1696
+ public typealias ViewLayoutKey = LayoutValueKey
1697
+
1698
+ @_spi ( _)
1699
+ @available ( * , deprecated, renamed: " _LayoutRoot " )
1700
+ public typealias _ViewLayoutRoot < L> = _LayoutRoot < L > where L : Layout
1701
+
1552
1702
// MARK: - threadLayoutData
1553
1703
1554
1704
@_transparent
0 commit comments