Coverage Report

Created: 2025-10-10 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/yoga/yoga/style/Style.h
Line
Count
Source
1
/*
2
 * Copyright (c) Meta Platforms, Inc. and affiliates.
3
 *
4
 * This source code is licensed under the MIT license found in the
5
 * LICENSE file in the root directory of this source tree.
6
 */
7
8
#pragma once
9
10
#include <array>
11
#include <cstdint>
12
#include <type_traits>
13
14
#include <yoga/Yoga.h>
15
16
#include <yoga/algorithm/FlexDirection.h>
17
#include <yoga/enums/Align.h>
18
#include <yoga/enums/BoxSizing.h>
19
#include <yoga/enums/Dimension.h>
20
#include <yoga/enums/Direction.h>
21
#include <yoga/enums/Display.h>
22
#include <yoga/enums/Edge.h>
23
#include <yoga/enums/FlexDirection.h>
24
#include <yoga/enums/Gutter.h>
25
#include <yoga/enums/Justify.h>
26
#include <yoga/enums/Overflow.h>
27
#include <yoga/enums/PhysicalEdge.h>
28
#include <yoga/enums/PositionType.h>
29
#include <yoga/enums/Unit.h>
30
#include <yoga/enums/Wrap.h>
31
#include <yoga/numeric/FloatOptional.h>
32
#include <yoga/style/StyleLength.h>
33
#include <yoga/style/StyleSizeLength.h>
34
#include <yoga/style/StyleValuePool.h>
35
36
namespace facebook::yoga {
37
38
class YG_EXPORT Style {
39
 public:
40
  using Length = StyleLength;
41
  using SizeLength = StyleSizeLength;
42
43
  static constexpr float DefaultFlexGrow = 0.0f;
44
  static constexpr float DefaultFlexShrink = 0.0f;
45
  static constexpr float WebDefaultFlexShrink = 1.0f;
46
47
29.2M
  Direction direction() const {
48
29.2M
    return direction_;
49
29.2M
  }
50
0
  void setDirection(Direction value) {
51
0
    direction_ = value;
52
0
  }
53
54
30.4M
  FlexDirection flexDirection() const {
55
30.4M
    return flexDirection_;
56
30.4M
  }
57
1.56M
  void setFlexDirection(FlexDirection value) {
58
1.56M
    flexDirection_ = value;
59
1.56M
  }
60
61
1.64M
  Justify justifyContent() const {
62
1.64M
    return justifyContent_;
63
1.64M
  }
64
0
  void setJustifyContent(Justify value) {
65
0
    justifyContent_ = value;
66
0
  }
67
68
2.40M
  Align alignContent() const {
69
2.40M
    return alignContent_;
70
2.40M
  }
71
0
  void setAlignContent(Align value) {
72
0
    alignContent_ = value;
73
0
  }
74
75
48.5M
  Align alignItems() const {
76
48.5M
    return alignItems_;
77
48.5M
  }
78
0
  void setAlignItems(Align value) {
79
0
    alignItems_ = value;
80
0
  }
81
82
60.6M
  Align alignSelf() const {
83
60.6M
    return alignSelf_;
84
60.6M
  }
85
0
  void setAlignSelf(Align value) {
86
0
    alignSelf_ = value;
87
0
  }
88
89
90.3M
  PositionType positionType() const {
90
90.3M
    return positionType_;
91
90.3M
  }
92
0
  void setPositionType(PositionType value) {
93
0
    positionType_ = value;
94
0
  }
95
96
4.94M
  Wrap flexWrap() const {
97
4.94M
    return flexWrap_;
98
4.94M
  }
99
0
  void setFlexWrap(Wrap value) {
100
0
    flexWrap_ = value;
101
0
  }
102
103
47.0M
  Overflow overflow() const {
104
47.0M
    return overflow_;
105
47.0M
  }
106
0
  void setOverflow(Overflow value) {
107
0
    overflow_ = value;
108
0
  }
109
110
108M
  Display display() const {
111
108M
    return display_;
112
108M
  }
113
0
  void setDisplay(Display value) {
114
0
    display_ = value;
115
0
  }
116
117
78.0M
  FloatOptional flex() const {
118
78.0M
    return pool_.getNumber(flex_);
119
78.0M
  }
120
0
  void setFlex(FloatOptional value) {
121
0
    pool_.store(flex_, value);
122
0
  }
123
124
26.4M
  FloatOptional flexGrow() const {
125
26.4M
    return pool_.getNumber(flexGrow_);
126
26.4M
  }
127
0
  void setFlexGrow(FloatOptional value) {
128
0
    pool_.store(flexGrow_, value);
129
0
  }
130
131
34.0M
  FloatOptional flexShrink() const {
132
34.0M
    return pool_.getNumber(flexShrink_);
133
34.0M
  }
134
0
  void setFlexShrink(FloatOptional value) {
135
0
    pool_.store(flexShrink_, value);
136
0
  }
137
138
17.4M
  Style::SizeLength flexBasis() const {
139
17.4M
    return pool_.getSize(flexBasis_);
140
17.4M
  }
141
0
  void setFlexBasis(Style::SizeLength value) {
142
0
    pool_.store(flexBasis_, value);
143
0
  }
144
145
0
  Style::Length margin(Edge edge) const {
146
0
    return pool_.getLength(margin_[yoga::to_underlying(edge)]);
147
0
  }
148
0
  void setMargin(Edge edge, Style::Length value) {
149
0
    pool_.store(margin_[yoga::to_underlying(edge)], value);
150
0
  }
151
152
0
  Style::Length position(Edge edge) const {
153
0
    return pool_.getLength(position_[yoga::to_underlying(edge)]);
154
0
  }
155
0
  void setPosition(Edge edge, Style::Length value) {
156
0
    pool_.store(position_[yoga::to_underlying(edge)], value);
157
0
  }
158
159
0
  Style::Length padding(Edge edge) const {
160
0
    return pool_.getLength(padding_[yoga::to_underlying(edge)]);
161
0
  }
162
0
  void setPadding(Edge edge, Style::Length value) {
163
0
    pool_.store(padding_[yoga::to_underlying(edge)], value);
164
0
  }
165
166
0
  Style::Length border(Edge edge) const {
167
0
    return pool_.getLength(border_[yoga::to_underlying(edge)]);
168
0
  }
169
0
  void setBorder(Edge edge, Style::Length value) {
170
0
    pool_.store(border_[yoga::to_underlying(edge)], value);
171
0
  }
172
173
3.82M
  Style::Length gap(Gutter gutter) const {
174
3.82M
    return pool_.getLength(gap_[yoga::to_underlying(gutter)]);
175
3.82M
  }
176
3.82M
  void setGap(Gutter gutter, Style::Length value) {
177
3.82M
    pool_.store(gap_[yoga::to_underlying(gutter)], value);
178
3.82M
  }
179
180
42.6M
  Style::SizeLength dimension(Dimension axis) const {
181
42.6M
    return pool_.getSize(dimensions_[yoga::to_underlying(axis)]);
182
42.6M
  }
183
7.64M
  void setDimension(Dimension axis, Style::SizeLength value) {
184
7.64M
    pool_.store(dimensions_[yoga::to_underlying(axis)], value);
185
7.64M
  }
186
187
101M
  Style::SizeLength minDimension(Dimension axis) const {
188
101M
    return pool_.getSize(minDimensions_[yoga::to_underlying(axis)]);
189
101M
  }
190
0
  void setMinDimension(Dimension axis, Style::SizeLength value) {
191
0
    pool_.store(minDimensions_[yoga::to_underlying(axis)], value);
192
0
  }
193
194
  FloatOptional resolvedMinDimension(
195
      Direction direction,
196
      Dimension axis,
197
      float referenceLength,
198
101M
      float ownerWidth) const {
199
101M
    FloatOptional value = minDimension(axis).resolve(referenceLength);
200
101M
    if (boxSizing() == BoxSizing::BorderBox) {
201
101M
      return value;
202
101M
    }
203
204
0
    FloatOptional dimensionPaddingAndBorder = FloatOptional{
205
0
        computePaddingAndBorderForDimension(direction, axis, ownerWidth)};
206
207
0
    return value +
208
0
        (dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder
209
0
                                               : FloatOptional{0.0});
210
101M
  }
211
212
198M
  Style::SizeLength maxDimension(Dimension axis) const {
213
198M
    return pool_.getSize(maxDimensions_[yoga::to_underlying(axis)]);
214
198M
  }
215
0
  void setMaxDimension(Dimension axis, Style::SizeLength value) {
216
0
    pool_.store(maxDimensions_[yoga::to_underlying(axis)], value);
217
0
  }
218
219
  FloatOptional resolvedMaxDimension(
220
      Direction direction,
221
      Dimension axis,
222
      float referenceLength,
223
163M
      float ownerWidth) const {
224
163M
    FloatOptional value = maxDimension(axis).resolve(referenceLength);
225
163M
    if (boxSizing() == BoxSizing::BorderBox) {
226
163M
      return value;
227
163M
    }
228
229
0
    FloatOptional dimensionPaddingAndBorder = FloatOptional{
230
0
        computePaddingAndBorderForDimension(direction, axis, ownerWidth)};
231
232
0
    return value +
233
0
        (dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder
234
0
                                               : FloatOptional{0.0});
235
163M
  }
236
237
35.5M
  FloatOptional aspectRatio() const {
238
35.5M
    return pool_.getNumber(aspectRatio_);
239
35.5M
  }
240
0
  void setAspectRatio(FloatOptional value) {
241
    // degenerate aspect ratios act as auto.
242
    // see https://drafts.csswg.org/css-sizing-4/#valdef-aspect-ratio-ratio
243
0
    pool_.store(
244
0
        aspectRatio_,
245
0
        value == 0.0f || std::isinf(value.unwrap()) ? FloatOptional{} : value);
246
0
  }
247
248
288M
  BoxSizing boxSizing() const {
249
288M
    return boxSizing_;
250
288M
  }
251
0
  void setBoxSizing(BoxSizing value) {
252
0
    boxSizing_ = value;
253
0
  }
254
255
0
  bool horizontalInsetsDefined() const {
256
0
    return position_[yoga::to_underlying(Edge::Left)].isDefined() ||
257
0
        position_[yoga::to_underlying(Edge::Right)].isDefined() ||
258
0
        position_[yoga::to_underlying(Edge::All)].isDefined() ||
259
0
        position_[yoga::to_underlying(Edge::Horizontal)].isDefined() ||
260
0
        position_[yoga::to_underlying(Edge::Start)].isDefined() ||
261
0
        position_[yoga::to_underlying(Edge::End)].isDefined();
262
0
  }
263
264
0
  bool verticalInsetsDefined() const {
265
0
    return position_[yoga::to_underlying(Edge::Top)].isDefined() ||
266
0
        position_[yoga::to_underlying(Edge::Bottom)].isDefined() ||
267
0
        position_[yoga::to_underlying(Edge::All)].isDefined() ||
268
0
        position_[yoga::to_underlying(Edge::Vertical)].isDefined();
269
0
  }
270
271
  bool isFlexStartPositionDefined(FlexDirection axis, Direction direction)
272
0
      const {
273
0
    return computePosition(flexStartEdge(axis), direction).isDefined();
274
0
  }
275
276
0
  bool isFlexStartPositionAuto(FlexDirection axis, Direction direction) const {
277
0
    return computePosition(flexStartEdge(axis), direction).isAuto();
278
0
  }
279
280
  bool isInlineStartPositionDefined(FlexDirection axis, Direction direction)
281
7.64M
      const {
282
7.64M
    return computePosition(inlineStartEdge(axis, direction), direction)
283
7.64M
        .isDefined();
284
7.64M
  }
285
286
  bool isInlineStartPositionAuto(FlexDirection axis, Direction direction)
287
0
      const {
288
0
    return computePosition(inlineStartEdge(axis, direction), direction)
289
0
        .isAuto();
290
0
  }
291
292
0
  bool isFlexEndPositionDefined(FlexDirection axis, Direction direction) const {
293
0
    return computePosition(flexEndEdge(axis), direction).isDefined();
294
0
  }
295
296
0
  bool isFlexEndPositionAuto(FlexDirection axis, Direction direction) const {
297
0
    return computePosition(flexEndEdge(axis), direction).isAuto();
298
0
  }
299
300
  bool isInlineEndPositionDefined(FlexDirection axis, Direction direction)
301
0
      const {
302
0
    return computePosition(inlineEndEdge(axis, direction), direction)
303
0
        .isDefined();
304
0
  }
305
306
0
  bool isInlineEndPositionAuto(FlexDirection axis, Direction direction) const {
307
0
    return computePosition(inlineEndEdge(axis, direction), direction).isAuto();
308
0
  }
309
310
  float computeFlexStartPosition(
311
      FlexDirection axis,
312
      Direction direction,
313
0
      float axisSize) const {
314
0
    return computePosition(flexStartEdge(axis), direction)
315
0
        .resolve(axisSize)
316
0
        .unwrapOrDefault(0.0f);
317
0
  }
318
319
  float computeInlineStartPosition(
320
      FlexDirection axis,
321
      Direction direction,
322
0
      float axisSize) const {
323
0
    return computePosition(inlineStartEdge(axis, direction), direction)
324
0
        .resolve(axisSize)
325
0
        .unwrapOrDefault(0.0f);
326
0
  }
327
328
  float computeFlexEndPosition(
329
      FlexDirection axis,
330
      Direction direction,
331
0
      float axisSize) const {
332
0
    return computePosition(flexEndEdge(axis), direction)
333
0
        .resolve(axisSize)
334
0
        .unwrapOrDefault(0.0f);
335
0
  }
336
337
  float computeInlineEndPosition(
338
      FlexDirection axis,
339
      Direction direction,
340
7.64M
      float axisSize) const {
341
7.64M
    return computePosition(inlineEndEdge(axis, direction), direction)
342
7.64M
        .resolve(axisSize)
343
7.64M
        .unwrapOrDefault(0.0f);
344
7.64M
  }
345
346
  float computeFlexStartMargin(
347
      FlexDirection axis,
348
      Direction direction,
349
0
      float widthSize) const {
350
0
    return computeMargin(flexStartEdge(axis), direction)
351
0
        .resolve(widthSize)
352
0
        .unwrapOrDefault(0.0f);
353
0
  }
354
355
  float computeInlineStartMargin(
356
      FlexDirection axis,
357
      Direction direction,
358
242M
      float widthSize) const {
359
242M
    return computeMargin(inlineStartEdge(axis, direction), direction)
360
242M
        .resolve(widthSize)
361
242M
        .unwrapOrDefault(0.0f);
362
242M
  }
363
364
  float computeFlexEndMargin(
365
      FlexDirection axis,
366
      Direction direction,
367
0
      float widthSize) const {
368
0
    return computeMargin(flexEndEdge(axis), direction)
369
0
        .resolve(widthSize)
370
0
        .unwrapOrDefault(0.0f);
371
0
  }
372
373
  float computeInlineEndMargin(
374
      FlexDirection axis,
375
      Direction direction,
376
242M
      float widthSize) const {
377
242M
    return computeMargin(inlineEndEdge(axis, direction), direction)
378
242M
        .resolve(widthSize)
379
242M
        .unwrapOrDefault(0.0f);
380
242M
  }
381
382
3.29M
  float computeFlexStartBorder(FlexDirection axis, Direction direction) const {
383
3.29M
    return maxOrDefined(
384
3.29M
        computeBorder(flexStartEdge(axis), direction).resolve(0.0f).unwrap(),
385
3.29M
        0.0f);
386
3.29M
  }
387
388
  float computeInlineStartBorder(FlexDirection axis, Direction direction)
389
120M
      const {
390
120M
    return maxOrDefined(
391
120M
        computeBorder(inlineStartEdge(axis, direction), direction)
392
120M
            .resolve(0.0f)
393
120M
            .unwrap(),
394
120M
        0.0f);
395
120M
  }
396
397
1.64M
  float computeFlexEndBorder(FlexDirection axis, Direction direction) const {
398
1.64M
    return maxOrDefined(
399
1.64M
        computeBorder(flexEndEdge(axis), direction).resolve(0.0f).unwrap(),
400
1.64M
        0.0f);
401
1.64M
  }
402
403
120M
  float computeInlineEndBorder(FlexDirection axis, Direction direction) const {
404
120M
    return maxOrDefined(
405
120M
        computeBorder(inlineEndEdge(axis, direction), direction)
406
120M
            .resolve(0.0f)
407
120M
            .unwrap(),
408
120M
        0.0f);
409
120M
  }
410
411
  float computeFlexStartPadding(
412
      FlexDirection axis,
413
      Direction direction,
414
3.29M
      float widthSize) const {
415
3.29M
    return maxOrDefined(
416
3.29M
        computePadding(flexStartEdge(axis), direction)
417
3.29M
            .resolve(widthSize)
418
3.29M
            .unwrap(),
419
3.29M
        0.0f);
420
3.29M
  }
421
422
  float computeInlineStartPadding(
423
      FlexDirection axis,
424
      Direction direction,
425
120M
      float widthSize) const {
426
120M
    return maxOrDefined(
427
120M
        computePadding(inlineStartEdge(axis, direction), direction)
428
120M
            .resolve(widthSize)
429
120M
            .unwrap(),
430
120M
        0.0f);
431
120M
  }
432
433
  float computeFlexEndPadding(
434
      FlexDirection axis,
435
      Direction direction,
436
1.64M
      float widthSize) const {
437
1.64M
    return maxOrDefined(
438
1.64M
        computePadding(flexEndEdge(axis), direction)
439
1.64M
            .resolve(widthSize)
440
1.64M
            .unwrap(),
441
1.64M
        0.0f);
442
1.64M
  }
443
444
  float computeInlineEndPadding(
445
      FlexDirection axis,
446
      Direction direction,
447
120M
      float widthSize) const {
448
120M
    return maxOrDefined(
449
120M
        computePadding(inlineEndEdge(axis, direction), direction)
450
120M
            .resolve(widthSize)
451
120M
            .unwrap(),
452
120M
        0.0f);
453
120M
  }
454
455
  float computeInlineStartPaddingAndBorder(
456
      FlexDirection axis,
457
      Direction direction,
458
72.7M
      float widthSize) const {
459
72.7M
    return computeInlineStartPadding(axis, direction, widthSize) +
460
72.7M
        computeInlineStartBorder(axis, direction);
461
72.7M
  }
462
463
  float computeFlexStartPaddingAndBorder(
464
      FlexDirection axis,
465
      Direction direction,
466
3.29M
      float widthSize) const {
467
3.29M
    return computeFlexStartPadding(axis, direction, widthSize) +
468
3.29M
        computeFlexStartBorder(axis, direction);
469
3.29M
  }
470
471
  float computeInlineEndPaddingAndBorder(
472
      FlexDirection axis,
473
      Direction direction,
474
72.7M
      float widthSize) const {
475
72.7M
    return computeInlineEndPadding(axis, direction, widthSize) +
476
72.7M
        computeInlineEndBorder(axis, direction);
477
72.7M
  }
478
479
  float computeFlexEndPaddingAndBorder(
480
      FlexDirection axis,
481
      Direction direction,
482
1.64M
      float widthSize) const {
483
1.64M
    return computeFlexEndPadding(axis, direction, widthSize) +
484
1.64M
        computeFlexEndBorder(axis, direction);
485
1.64M
  }
486
487
  float computePaddingAndBorderForDimension(
488
      Direction direction,
489
      Dimension dimension,
490
0
      float widthSize) const {
491
0
    FlexDirection flexDirectionForDimension = dimension == Dimension::Width
492
0
        ? FlexDirection::Row
493
0
        : FlexDirection::Column;
494
495
0
    return computeFlexStartPaddingAndBorder(
496
0
               flexDirectionForDimension, direction, widthSize) +
497
0
        computeFlexEndPaddingAndBorder(
498
0
               flexDirectionForDimension, direction, widthSize);
499
0
  }
500
501
0
  float computeBorderForAxis(FlexDirection axis) const {
502
0
    return computeInlineStartBorder(axis, Direction::LTR) +
503
0
        computeInlineEndBorder(axis, Direction::LTR);
504
0
  }
505
506
187M
  float computeMarginForAxis(FlexDirection axis, float widthSize) const {
507
    // The total margin for a given axis does not depend on the direction
508
    // so hardcoding LTR here to avoid piping direction to this function
509
187M
    return computeInlineStartMargin(axis, Direction::LTR, widthSize) +
510
187M
        computeInlineEndMargin(axis, Direction::LTR, widthSize);
511
187M
  }
512
513
6.44M
  float computeGapForAxis(FlexDirection axis, float ownerSize) const {
514
6.44M
    auto gap = isRow(axis) ? computeColumnGap() : computeRowGap();
515
6.44M
    return maxOrDefined(gap.resolve(ownerSize).unwrap(), 0.0f);
516
6.44M
  }
517
518
52.7M
  bool flexStartMarginIsAuto(FlexDirection axis, Direction direction) const {
519
52.7M
    return computeMargin(flexStartEdge(axis), direction).isAuto();
520
52.7M
  }
521
522
52.7M
  bool flexEndMarginIsAuto(FlexDirection axis, Direction direction) const {
523
52.7M
    return computeMargin(flexEndEdge(axis), direction).isAuto();
524
52.7M
  }
525
526
0
  bool operator==(const Style& other) const {
527
0
    return direction_ == other.direction_ &&
528
0
        flexDirection_ == other.flexDirection_ &&
529
0
        justifyContent_ == other.justifyContent_ &&
530
0
        alignContent_ == other.alignContent_ &&
531
0
        alignItems_ == other.alignItems_ && alignSelf_ == other.alignSelf_ &&
532
0
        positionType_ == other.positionType_ && flexWrap_ == other.flexWrap_ &&
533
0
        overflow_ == other.overflow_ && display_ == other.display_ &&
534
0
        numbersEqual(flex_, pool_, other.flex_, other.pool_) &&
535
0
        numbersEqual(flexGrow_, pool_, other.flexGrow_, other.pool_) &&
536
0
        numbersEqual(flexShrink_, pool_, other.flexShrink_, other.pool_) &&
537
0
        lengthsEqual(flexBasis_, pool_, other.flexBasis_, other.pool_) &&
538
0
        lengthsEqual(margin_, pool_, other.margin_, other.pool_) &&
539
0
        lengthsEqual(position_, pool_, other.position_, other.pool_) &&
540
0
        lengthsEqual(padding_, pool_, other.padding_, other.pool_) &&
541
0
        lengthsEqual(border_, pool_, other.border_, other.pool_) &&
542
0
        lengthsEqual(gap_, pool_, other.gap_, other.pool_) &&
543
0
        lengthsEqual(dimensions_, pool_, other.dimensions_, other.pool_) &&
544
0
        lengthsEqual(
545
0
               minDimensions_, pool_, other.minDimensions_, other.pool_) &&
546
0
        lengthsEqual(
547
0
               maxDimensions_, pool_, other.maxDimensions_, other.pool_) &&
548
0
        numbersEqual(aspectRatio_, pool_, other.aspectRatio_, other.pool_);
549
0
  }
550
551
0
  bool operator!=(const Style& other) const {
552
0
    return !(*this == other);
553
0
  }
554
555
 private:
556
  using Dimensions = std::array<StyleValueHandle, ordinalCount<Dimension>()>;
557
  using Edges = std::array<StyleValueHandle, ordinalCount<Edge>()>;
558
  using Gutters = std::array<StyleValueHandle, ordinalCount<Gutter>()>;
559
560
  static inline bool numbersEqual(
561
      const StyleValueHandle& lhsHandle,
562
      const StyleValuePool& lhsPool,
563
      const StyleValueHandle& rhsHandle,
564
0
      const StyleValuePool& rhsPool) {
565
0
    return (lhsHandle.isUndefined() && rhsHandle.isUndefined()) ||
566
0
        (lhsPool.getNumber(lhsHandle) == rhsPool.getNumber(rhsHandle));
567
0
  }
568
569
  static inline bool lengthsEqual(
570
      const StyleValueHandle& lhsHandle,
571
      const StyleValuePool& lhsPool,
572
      const StyleValueHandle& rhsHandle,
573
0
      const StyleValuePool& rhsPool) {
574
0
    return (lhsHandle.isUndefined() && rhsHandle.isUndefined()) ||
575
0
        (lhsPool.getLength(lhsHandle) == rhsPool.getLength(rhsHandle));
576
0
  }
577
578
  template <size_t N>
579
  static inline bool lengthsEqual(
580
      const std::array<StyleValueHandle, N>& lhs,
581
      const StyleValuePool& lhsPool,
582
      const std::array<StyleValueHandle, N>& rhs,
583
0
      const StyleValuePool& rhsPool) {
584
0
    return std::equal(
585
0
        lhs.begin(),
586
0
        lhs.end(),
587
0
        rhs.begin(),
588
0
        rhs.end(),
589
0
        [&](const auto& lhs, const auto& rhs) {
590
0
          return lengthsEqual(lhs, lhsPool, rhs, rhsPool);
591
0
        });
Unexecuted instantiation: auto facebook::yoga::Style::lengthsEqual<9ul>(std::__1::array<facebook::yoga::StyleValueHandle, 9ul> const&, facebook::yoga::StyleValuePool const&, std::__1::array<facebook::yoga::StyleValueHandle, 9ul> const&, facebook::yoga::StyleValuePool const&)::{lambda(auto:1 const&, auto:2 const&)#1}::operator()<facebook::yoga::StyleValueHandle, facebook::yoga::StyleValueHandle>(facebook::yoga::StyleValueHandle const&, facebook::yoga::StyleValueHandle const&) const
Unexecuted instantiation: auto facebook::yoga::Style::lengthsEqual<3ul>(std::__1::array<facebook::yoga::StyleValueHandle, 3ul> const&, facebook::yoga::StyleValuePool const&, std::__1::array<facebook::yoga::StyleValueHandle, 3ul> const&, facebook::yoga::StyleValuePool const&)::{lambda(auto:1 const&, auto:2 const&)#1}::operator()<facebook::yoga::StyleValueHandle, facebook::yoga::StyleValueHandle>(facebook::yoga::StyleValueHandle const&, facebook::yoga::StyleValueHandle const&) const
Unexecuted instantiation: auto facebook::yoga::Style::lengthsEqual<2ul>(std::__1::array<facebook::yoga::StyleValueHandle, 2ul> const&, facebook::yoga::StyleValuePool const&, std::__1::array<facebook::yoga::StyleValueHandle, 2ul> const&, facebook::yoga::StyleValuePool const&)::{lambda(auto:1 const&, auto:2 const&)#1}::operator()<facebook::yoga::StyleValueHandle, facebook::yoga::StyleValueHandle>(facebook::yoga::StyleValueHandle const&, facebook::yoga::StyleValueHandle const&) const
592
0
  }
Unexecuted instantiation: bool facebook::yoga::Style::lengthsEqual<9ul>(std::__1::array<facebook::yoga::StyleValueHandle, 9ul> const&, facebook::yoga::StyleValuePool const&, std::__1::array<facebook::yoga::StyleValueHandle, 9ul> const&, facebook::yoga::StyleValuePool const&)
Unexecuted instantiation: bool facebook::yoga::Style::lengthsEqual<3ul>(std::__1::array<facebook::yoga::StyleValueHandle, 3ul> const&, facebook::yoga::StyleValuePool const&, std::__1::array<facebook::yoga::StyleValueHandle, 3ul> const&, facebook::yoga::StyleValuePool const&)
Unexecuted instantiation: bool facebook::yoga::Style::lengthsEqual<2ul>(std::__1::array<facebook::yoga::StyleValueHandle, 2ul> const&, facebook::yoga::StyleValuePool const&, std::__1::array<facebook::yoga::StyleValueHandle, 2ul> const&, facebook::yoga::StyleValuePool const&)
593
594
3.72M
  Style::Length computeColumnGap() const {
595
3.72M
    if (gap_[yoga::to_underlying(Gutter::Column)].isDefined()) {
596
0
      return pool_.getLength(gap_[yoga::to_underlying(Gutter::Column)]);
597
3.72M
    } else {
598
3.72M
      return pool_.getLength(gap_[yoga::to_underlying(Gutter::All)]);
599
3.72M
    }
600
3.72M
  }
601
602
2.72M
  Style::Length computeRowGap() const {
603
2.72M
    if (gap_[yoga::to_underlying(Gutter::Row)].isDefined()) {
604
0
      return pool_.getLength(gap_[yoga::to_underlying(Gutter::Row)]);
605
2.72M
    } else {
606
2.72M
      return pool_.getLength(gap_[yoga::to_underlying(Gutter::All)]);
607
2.72M
    }
608
2.72M
  }
609
610
  Style::Length computeLeftEdge(const Edges& edges, Direction layoutDirection)
611
289M
      const {
612
289M
    if (layoutDirection == Direction::LTR &&
613
289M
        edges[yoga::to_underlying(Edge::Start)].isDefined()) {
614
0
      return pool_.getLength(edges[yoga::to_underlying(Edge::Start)]);
615
289M
    } else if (
616
289M
        layoutDirection == Direction::RTL &&
617
0
        edges[yoga::to_underlying(Edge::End)].isDefined()) {
618
0
      return pool_.getLength(edges[yoga::to_underlying(Edge::End)]);
619
289M
    } else if (edges[yoga::to_underlying(Edge::Left)].isDefined()) {
620
0
      return pool_.getLength(edges[yoga::to_underlying(Edge::Left)]);
621
289M
    } else if (edges[yoga::to_underlying(Edge::Horizontal)].isDefined()) {
622
0
      return pool_.getLength(edges[yoga::to_underlying(Edge::Horizontal)]);
623
289M
    } else {
624
289M
      return pool_.getLength(edges[yoga::to_underlying(Edge::All)]);
625
289M
    }
626
289M
  }
627
628
260M
  Style::Length computeTopEdge(const Edges& edges) const {
629
260M
    if (edges[yoga::to_underlying(Edge::Top)].isDefined()) {
630
0
      return pool_.getLength(edges[yoga::to_underlying(Edge::Top)]);
631
260M
    } else if (edges[yoga::to_underlying(Edge::Vertical)].isDefined()) {
632
0
      return pool_.getLength(edges[yoga::to_underlying(Edge::Vertical)]);
633
260M
    } else {
634
260M
      return pool_.getLength(edges[yoga::to_underlying(Edge::All)]);
635
260M
    }
636
260M
  }
637
638
  Style::Length computeRightEdge(const Edges& edges, Direction layoutDirection)
639
288M
      const {
640
288M
    if (layoutDirection == Direction::LTR &&
641
288M
        edges[yoga::to_underlying(Edge::End)].isDefined()) {
642
0
      return pool_.getLength(edges[yoga::to_underlying(Edge::End)]);
643
288M
    } else if (
644
288M
        layoutDirection == Direction::RTL &&
645
0
        edges[yoga::to_underlying(Edge::Start)].isDefined()) {
646
0
      return pool_.getLength(edges[yoga::to_underlying(Edge::Start)]);
647
288M
    } else if (edges[yoga::to_underlying(Edge::Right)].isDefined()) {
648
0
      return pool_.getLength(edges[yoga::to_underlying(Edge::Right)]);
649
288M
    } else if (edges[yoga::to_underlying(Edge::Horizontal)].isDefined()) {
650
0
      return pool_.getLength(edges[yoga::to_underlying(Edge::Horizontal)]);
651
288M
    } else {
652
288M
      return pool_.getLength(edges[yoga::to_underlying(Edge::All)]);
653
288M
    }
654
288M
  }
655
656
258M
  Style::Length computeBottomEdge(const Edges& edges) const {
657
258M
    if (edges[yoga::to_underlying(Edge::Bottom)].isDefined()) {
658
0
      return pool_.getLength(edges[yoga::to_underlying(Edge::Bottom)]);
659
258M
    } else if (edges[yoga::to_underlying(Edge::Vertical)].isDefined()) {
660
0
      return pool_.getLength(edges[yoga::to_underlying(Edge::Vertical)]);
661
258M
    } else {
662
258M
      return pool_.getLength(edges[yoga::to_underlying(Edge::All)]);
663
258M
    }
664
258M
  }
665
666
15.2M
  Style::Length computePosition(PhysicalEdge edge, Direction direction) const {
667
15.2M
    switch (edge) {
668
3.82M
      case PhysicalEdge::Left:
669
3.82M
        return computeLeftEdge(position_, direction);
670
3.82M
      case PhysicalEdge::Top:
671
3.82M
        return computeTopEdge(position_);
672
3.82M
      case PhysicalEdge::Right:
673
3.82M
        return computeRightEdge(position_, direction);
674
3.82M
      case PhysicalEdge::Bottom:
675
3.82M
        return computeBottomEdge(position_);
676
15.2M
    }
677
678
0
    fatalWithMessage("Invalid physical edge");
679
0
  }
680
681
590M
  Style::Length computeMargin(PhysicalEdge edge, Direction direction) const {
682
590M
    switch (edge) {
683
157M
      case PhysicalEdge::Left:
684
157M
        return computeLeftEdge(margin_, direction);
685
138M
      case PhysicalEdge::Top:
686
138M
        return computeTopEdge(margin_);
687
157M
      case PhysicalEdge::Right:
688
157M
        return computeRightEdge(margin_, direction);
689
138M
      case PhysicalEdge::Bottom:
690
138M
        return computeBottomEdge(margin_);
691
590M
    }
692
693
0
    fatalWithMessage("Invalid physical edge");
694
0
  }
695
696
245M
  Style::Length computePadding(PhysicalEdge edge, Direction direction) const {
697
245M
    switch (edge) {
698
64.0M
      case PhysicalEdge::Left:
699
64.0M
        return computeLeftEdge(padding_, direction);
700
59.4M
      case PhysicalEdge::Top:
701
59.4M
        return computeTopEdge(padding_);
702
63.5M
      case PhysicalEdge::Right:
703
63.5M
        return computeRightEdge(padding_, direction);
704
58.3M
      case PhysicalEdge::Bottom:
705
58.3M
        return computeBottomEdge(padding_);
706
245M
    }
707
708
0
    fatalWithMessage("Invalid physical edge");
709
0
  }
710
711
245M
  Style::Length computeBorder(PhysicalEdge edge, Direction direction) const {
712
245M
    switch (edge) {
713
64.0M
      case PhysicalEdge::Left:
714
64.0M
        return computeLeftEdge(border_, direction);
715
59.4M
      case PhysicalEdge::Top:
716
59.4M
        return computeTopEdge(border_);
717
63.5M
      case PhysicalEdge::Right:
718
63.5M
        return computeRightEdge(border_, direction);
719
58.3M
      case PhysicalEdge::Bottom:
720
58.3M
        return computeBottomEdge(border_);
721
245M
    }
722
723
0
    fatalWithMessage("Invalid physical edge");
724
0
  }
725
726
  Direction direction_ : bitCount<Direction>() = Direction::Inherit;
727
  FlexDirection flexDirection_
728
      : bitCount<FlexDirection>() = FlexDirection::Column;
729
  Justify justifyContent_ : bitCount<Justify>() = Justify::FlexStart;
730
  Align alignContent_ : bitCount<Align>() = Align::FlexStart;
731
  Align alignItems_ : bitCount<Align>() = Align::Stretch;
732
  Align alignSelf_ : bitCount<Align>() = Align::Auto;
733
  PositionType positionType_
734
      : bitCount<PositionType>() = PositionType::Relative;
735
  Wrap flexWrap_ : bitCount<Wrap>() = Wrap::NoWrap;
736
  Overflow overflow_ : bitCount<Overflow>() = Overflow::Visible;
737
  Display display_ : bitCount<Display>() = Display::Flex;
738
  BoxSizing boxSizing_ : bitCount<BoxSizing>() = BoxSizing::BorderBox;
739
740
  StyleValueHandle flex_{};
741
  StyleValueHandle flexGrow_{};
742
  StyleValueHandle flexShrink_{};
743
  StyleValueHandle flexBasis_{StyleValueHandle::ofAuto()};
744
  Edges margin_{};
745
  Edges position_{};
746
  Edges padding_{};
747
  Edges border_{};
748
  Gutters gap_{};
749
  Dimensions dimensions_{
750
      StyleValueHandle::ofAuto(),
751
      StyleValueHandle::ofAuto()};
752
  Dimensions minDimensions_{};
753
  Dimensions maxDimensions_{};
754
  StyleValueHandle aspectRatio_{};
755
756
  StyleValuePool pool_;
757
};
758
759
} // namespace facebook::yoga