<commit_before>/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
@file:Suppress("NOTHING_TO_INLINE", "EXPERIMENTAL_FEATURE_WARNING")

package androidx.compose.ui.unit

import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable

/**
 * Immutable constraints used for measuring child Layouts or [LayoutModifier]s. A parent layout
 * can measure their children using the measure method on the corresponding [Measurable]s,
 * method which takes the [Constraints] the child has to follow. A measured child is then
 * responsible to choose for themselves and return a size which satisfies the set of [Constraints]
 * received from their parent:
 * - minWidth <= chosenWidth <= maxWidth
 * - minHeight <= chosenHeight <= maxHeight
 * The parent can then access the child chosen size on the resulting [Placeable]. The parent is
 * responsible of defining a valid positioning of the children according to their sizes, so the
 * parent needs to measure the children with appropriate [Constraints], such that whatever valid
 * sizes children choose, they can be laid out in a way that also respects the parent's incoming
 * [Constraints]. Note that different children can be measured with different [Constraints].
 * A child is allowed to choose a size that does not satisfy its constraints. However, when this
 * happens, the parent will not read from the [Placeable] the real size of the child, but rather
 * one that was coerced in the child's constraints; therefore, a parent can assume that its
 * children will always respect the constraints in their layout algorithm. When this does not
 * happen in reality, the position assigned to the child will be automatically offset to be centered
 * on the space assigned by the parent under the assumption that constraints were respected.
 * A set of [Constraints] can have infinite maxWidth and/or maxHeight. This is a trick often
 * used by parents to ask their children for their preferred size: unbounded constraints force
 * children whose default behavior is to fill the available space (always size to
 * maxWidth/maxHeight) to have an opinion about their preferred size. Most commonly, when measured
 * with unbounded [Constraints], these children will fallback to size themselves to wrap their
 * content, instead of expanding to fill the available space (this is not always true
 * as it depends on the child layout model, but is a common behavior for core layout components).
 *
 * [Constraints] uses a [Long] to represent four values, [minWidth], [minHeight], [maxWidth],
 * and [maxHeight]. The range of the values varies to allow for at most 256K in one dimension.
 * There are four possible maximum ranges, 13 bits/18 bits, and 15 bits/16 bits for either width
 * or height, depending on the needs. For example, a width could range up to 18 bits
 * and the height up to 13 bits. Alternatively, the width could range up to 16 bits and the height
 * up to 15 bits. The height and width requirements can be reversed, with a height of up to 18 bits
 * and width of 13 bits or height of 16 bits and width of 15 bits. Any constraints exceeding
 * this range will fail.
 */
@Immutable
// This can be made inline after b/155690960 is fixed.
inline class Constraints(
    @PublishedApi internal val value: Long
) {
    /**
     * Indicates how the bits are assigned. One of:
     * * MinFocusWidth
     * * MaxFocusWidth
     * * MinFocusHeight
     * * MaxFocusHeight
     */
    private val focusIndex
        get() = (value and FocusMask).toInt()

    /**
     * The minimum width that the measurement can take.
     */
    val minWidth: Int
        get() {
            val mask = WidthMask[focusIndex]
            return ((value shr 2).toInt() and mask)
        }

    /**
     * The maximum width that the measurement can take. This will either be
     * a positive value greater than or equal to [minWidth] or [Constraints.Infinity].
     */
    val maxWidth: Int
        get() {
            val mask = WidthMask[focusIndex]
            val width = ((value shr 33).toInt() and mask)
            return if (width == 0) Infinity else width - 1
        }

    /**
     * The minimum height that the measurement can take.
     */
    val minHeight: Int
        get() {
            val focus = focusIndex
            val mask = HeightMask[focus]
            val offset = MinHeightOffsets[focus]
            return (value shr offset).toInt() and mask
        }

    /**
     * The maximum height that the measurement can take. This will either be
     * a positive value greater than or equal to [minHeight] or [Constraints.Infinity].
     */
    val maxHeight: Int
        get() {
            val focus = focusIndex
            val mask = HeightMask[focus]
            val offset = MinHeightOffsets[focus] + 31
            val height = (value shr offset).toInt() and mask
            return if (height == 0) Infinity else height - 1
        }

    /**
     * Whether or not the upper bound on the maximum width.
     * @see hasBoundedHeight
     */
    val hasBoundedWidth: Boolean
        get() {
            val mask = WidthMask[focusIndex]
            return ((value shr 33).toInt() and mask) != 0
        }

    /**
     * Whether or not the upper bound on the maximum height.
     * @see hasBoundedWidth
     */
    val hasBoundedHeight: Boolean
        get() {
            val focus = focusIndex
            val mask = HeightMask[focus]
            val offset = MinHeightOffsets[focus] + 31
            return ((value shr offset).toInt() and mask) != 0
        }

    /**
     * Copies the existing [Constraints], replacing some of [minWidth], [minHeight], [maxWidth],
     * or [maxHeight] as desired. [minWidth] and [minHeight] must be positive and
     * [maxWidth] and [maxHeight] must be greater than or equal to [minWidth] and [minHeight],
     * respectively, or [Infinity].
     */
    fun copy(
        minWidth: Int = this.minWidth,
        maxWidth: Int = this.maxWidth,
        minHeight: Int = this.minHeight,
        maxHeight: Int = this.maxHeight
    ): Constraints {
        require(minHeight >= 0 && minWidth >= 0) {
            "minHeight($minHeight) and minWidth($minWidth) must be >= 0"
        }
        require(maxWidth >= minWidth || maxWidth == Infinity) {
            "maxWidth($maxWidth) must be >= minWidth($minWidth)"
        }
        require(maxHeight >= minHeight || maxHeight == Infinity) {<commit_msg>Improve documentation on Constraints.<commit_after>/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
@file:Suppress("NOTHING_TO_INLINE", "EXPERIMENTAL_FEATURE_WARNING")

package androidx.compose.ui.unit

import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable

/**
 * Immutable constraints used for measuring child Layouts or [LayoutModifier]s. A parent layout
 * can measure their children using the measure method on the corresponding [Measurable]s,
 * method which takes the [Constraints] the child has to follow. A measured child is then
 * responsible to choose for themselves and return a size which satisfies the set of [Constraints]
 * received from their parent:
 * - minWidth <= chosenWidth <= maxWidth
 * - minHeight <= chosenHeight <= maxHeight
 * The parent can then access the child chosen size on the resulting [Placeable]. The parent is
 * responsible of defining a valid positioning of the children according to their sizes, so the
 * parent needs to measure the children with appropriate [Constraints], such that whatever valid
 * sizes children choose, they can be laid out in a way that also respects the parent's incoming
 * [Constraints]. Note that different children can be measured with different [Constraints].
 * A child is allowed to choose a size that does not satisfy its constraints. However, when this
 * happens, the parent will not read from the [Placeable] the real size of the child, but rather
 * one that was coerced in the child's constraints; therefore, a parent can assume that its
 * children will always respect the constraints in their layout algorithm. When this does not
 * happen in reality, the position assigned to the child will be automatically offset to be centered
 * on the space assigned by the parent under the assumption that constraints were respected.
 * A set of [Constraints] can have infinite maxWidth and/or maxHeight. This is a trick often
 * used by parents to ask their children for their preferred size: unbounded constraints force
 * children whose default behavior is to fill the available space (always size to
 * maxWidth/maxHeight) to have an opinion about their preferred size. Most commonly, when measured
 * with unbounded [Constraints], these children will fallback to size themselves to wrap their
 * content, instead of expanding to fill the available space (this is not always true
 * as it depends on the child layout model, but is a common behavior for core layout components).
 *
 * [Constraints] uses a [Long] to represent four values, [minWidth], [minHeight], [maxWidth],
 * and [maxHeight]. The range of the values varies to allow for at most 256K in one dimension.
 * There are four possible maximum ranges, 13 bits/18 bits, and 15 bits/16 bits for either width
 * or height, depending on the needs. For example, a width could range up to 18 bits
 * and the height up to 13 bits. Alternatively, the width could range up to 16 bits and the height
 * up to 15 bits. The height and width requirements can be reversed, with a height of up to 18 bits
 * and width of 13 bits or height of 16 bits and width of 15 bits. Any constraints exceeding
 * this range will fail.
 */
@Immutable
// This can be made inline after b/155690960 is fixed.
inline class Constraints(
    @PublishedApi internal val value: Long
) {
    /**
     * Indicates how the bits are assigned. One of:
     * * MinFocusWidth
     * * MaxFocusWidth
     * * MinFocusHeight
     * * MaxFocusHeight
     */
    private val focusIndex
        get() = (value and FocusMask).toInt()

    /**
     * The minimum width that the measurement can take.
     */
    val minWidth: Int
        get() {
            val mask = WidthMask[focusIndex]
            return ((value shr 2).toInt() and mask)
        }

    /**
     * The maximum width that the measurement can take. This will either be
     * a positive value greater than or equal to [minWidth] or [Constraints.Infinity].
     */
    val maxWidth: Int
        get() {
            val mask = WidthMask[focusIndex]
            val width = ((value shr 33).toInt() and mask)
            return if (width == 0) Infinity else width - 1
        }

    /**
     * The minimum height that the measurement can take.
     */
    val minHeight: Int
        get() {
            val focus = focusIndex
            val mask = HeightMask[focus]
            val offset = MinHeightOffsets[focus]
            return (value shr offset).toInt() and mask
        }

    /**
     * The maximum height that the measurement can take. This will either be
     * a positive value greater than or equal to [minHeight] or [Constraints.Infinity].
     */
    val maxHeight: Int
        get() {
            val focus = focusIndex
            val mask = HeightMask[focus]
            val offset = MinHeightOffsets[focus] + 31
            val height = (value shr offset).toInt() and mask
            return if (height == 0) Infinity else height - 1
        }

    /**
     * `false` when [maxWidth] is [Infinity] and `true` if [maxWidth] is a non-[Infinity] value.
     * @see hasBoundedHeight
     */
    val hasBoundedWidth: Boolean
        get() {
            val mask = WidthMask[focusIndex]
            return ((value shr 33).toInt() and mask) != 0
        }

    /**
     * `false` when [maxHeight] is [Infinity] and `true` if [maxWidth] is a non-[Infinity] value.
     * @see hasBoundedWidth
     */
    val hasBoundedHeight: Boolean
        get() {
            val focus = focusIndex
            val mask = HeightMask[focus]
            val offset = MinHeightOffsets[focus] + 31
            return ((value shr offset).toInt() and mask) != 0
        }

    /**
     * Copies the existing [Constraints], replacing some of [minWidth], [minHeight], [maxWidth],
     * or [maxHeight] as desired. [minWidth] and [minHeight] must be positive and
     * [maxWidth] and [maxHeight] must be greater than or equal to [minWidth] and [minHeight],
     * respectively, or [Infinity].
     */
    fun copy(
        minWidth: Int = this.minWidth,
        maxWidth: Int = this.maxWidth,
        minHeight: Int = this.minHeight,
        maxHeight: Int = this.maxHeight
    ): Constraints {
        require(minHeight >= 0 && minWidth >= 0) {
            "minHeight($minHeight) and minWidth($minWidth) must be >= 0"
        }
        require(maxWidth >= minWidth || maxWidth == Infinity) {
            "maxWidth($maxWidth) must be >= minWidth($minWidth)"
        }
        require(maxHeight >= minHeight || maxHeight == Infinity) {
{'fraction_non_alphanumeric': 0.07567990887085291, 'fraction_numerical': 0.008828136124163463, 'mean_word_length': 2.84954782132091, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7490814', 'n_tokens_mistral': 3653, 'n_tokens_neox': 3497, 'n_words': 1725}