diff --git a/compiler/back_end/cpp/header_generator.py b/compiler/back_end/cpp/header_generator.py index 22e1523..21f9a6a 100644 --- a/compiler/back_end/cpp/header_generator.py +++ b/compiler/back_end/cpp/header_generator.py @@ -836,8 +836,16 @@ def _render_expression(expression, ir, field_reader=None, subexpressions=None): # will fit into C++ types, or that operator arguments and return types can fit # in the same type: expressions like `-0x8000_0000_0000_0000` and # `0x1_0000_0000_0000_0000 - 1` can appear. + # A value that can be undefined must not be folded to a compile-time literal, + # even when its *defined* range collapses to a single value (modulus == + # "infinity" / a fixed boolean): at runtime it may be Unknown (e.g. a + # division by zero), which only the real Maybe<>-returning computation can + # represent. if expression.type.which_type == "integer": - if expression.type.integer.modulus == "infinity": + if ( + expression.type.integer.modulus == "infinity" + and not expression.type.integer.can_be_undefined + ): return _ExpressionResult( _render_integer_for_expression( int(expression.type.integer.modular_value) @@ -845,7 +853,10 @@ def _render_expression(expression, ir, field_reader=None, subexpressions=None): True, ) elif expression.type.which_type == "boolean": - if expression.type.boolean.has_field("value"): + if ( + expression.type.boolean.has_field("value") + and not expression.type.boolean.can_be_undefined + ): if expression.type.boolean.value: return _ExpressionResult(_maybe_type("bool") + "(true)", True) else: @@ -1415,9 +1426,15 @@ def _is_discriminant_provably_known(discrim_expr, fields): if ir_util.field_is_virtual(f): return False cond = f.existence_condition + # An existence condition that can be undefined is not provably known at + # runtime, so the Known() guard on the discriminant read must be kept. + # (In practice the boolean folder never sets `value` on a + # can-be-undefined condition, so this is belt-and-suspenders; it keeps + # the elision sound regardless of how folding evolves.) return ( cond.type.which_type == "boolean" and cond.type.boolean.has_field("value") + and not cond.type.boolean.can_be_undefined and bool(cond.type.boolean.value) ) return False diff --git a/compiler/back_end/cpp/testcode/division_modulus_test.cc b/compiler/back_end/cpp/testcode/division_modulus_test.cc index 6c6d390..4f0aac4 100644 --- a/compiler/back_end/cpp/testcode/division_modulus_test.cc +++ b/compiler/back_end/cpp/testcode/division_modulus_test.cc @@ -89,6 +89,77 @@ TEST(ChunkedPayload, RoundsUpToMultipleOfFour) { EXPECT_EQ(8U, view.padded().ElementCount()); } +// A field whose size uses a `//` with a possibly-zero divisor works normally +// when the divisor is nonzero. +TEST(PayloadSizedByDivision, NonzeroDivisor) { + static constexpr ::std::array kBuf = {{ + 0x04, // divisor = 4 -> 16 // 4 = 4 payload bytes + 0xaa, 0xbb, 0xcc, 0xdd, // payload + }}; + auto view = MakePayloadSizedByDivisionView(&kBuf); + ASSERT_TRUE(view.Ok()); + EXPECT_EQ(5U, view.SizeInBytes()); + EXPECT_EQ(4U, view.payload().ElementCount()); +} + +// When the divisor is zero the payload size is undefined, so the structure's +// size is unknown and Ok() is false -- with no division-by-zero UB. +TEST(PayloadSizedByDivision, ZeroDivisorIsNotOk) { + static constexpr ::std::array kBuf = {{ + 0x00, // divisor = 0 -> 16 // 0 undefined + 0xaa, 0xbb, 0xcc, 0xdd, + }}; + auto view = MakePayloadSizedByDivisionView(&kBuf); + EXPECT_FALSE(view.Ok()); + EXPECT_FALSE(view.SizeIsKnown()); + EXPECT_FALSE(view.IntrinsicSizeInBytes().Ok()); +} + +// A field guarded by an existence condition that divides by a field: the +// condition (and therefore Ok()) is well-defined for nonzero divisors... +TEST(FieldGatedByDivision, ConditionTrueAndFalse) { + // divisor = 4 -> 12 // 4 == 3 -> gated present. + static constexpr ::std::array kPresent = {{0x04, 0x77}}; + auto present = MakeFieldGatedByDivisionView(&kPresent); + ASSERT_TRUE(present.Ok()); + EXPECT_TRUE(present.has_gated().ValueOr(false)); + EXPECT_EQ(0x77U, present.gated().Read()); + + // divisor = 5 -> 12 // 5 == 2 != 3 -> gated absent (only 1 byte needed). + static constexpr ::std::array kAbsent = {{0x05}}; + auto absent = MakeFieldGatedByDivisionView(&kAbsent); + ASSERT_TRUE(absent.Ok()); + EXPECT_FALSE(absent.has_gated().ValueOr(true)); +} + +// ...and is *undefined* for a zero divisor. The existence condition is Unknown, +// so the field's presence is unknown and Ok() must return false. This is the +// soundness guard for the Ok()/switch discriminant optimization: an undefined +// existence condition must never be folded to a provably-known value. +TEST(FieldGatedByDivision, ZeroDivisorIsNotOk) { + static constexpr ::std::array kBuf = {{0x00, 0x77}}; + auto view = MakeFieldGatedByDivisionView(&kBuf); + EXPECT_FALSE(view.Ok()); + EXPECT_FALSE(view.has_gated().Known()); +} + +// `0 // divisor` collapses to the single value {0}, but must not be folded to a +// literal: it is undefined when the divisor is zero. +TEST(CollapsingQuotient, DefinedForNonzeroDivisor) { + static constexpr ::std::array kBuf = {{0x07}}; + auto view = MakeCollapsingQuotientView(&kBuf); + ASSERT_TRUE(view.Ok()); + EXPECT_TRUE(view.zero_or_undefined().Ok()); + EXPECT_EQ(0, view.zero_or_undefined().Read()); +} + +TEST(CollapsingQuotient, UndefinedForZeroDivisor) { + static constexpr ::std::array kBuf = {{0x00}}; + auto view = MakeCollapsingQuotientView(&kBuf); + // The accessor is Unknown -- not a bogus literal 0. + EXPECT_FALSE(view.zero_or_undefined().Ok()); +} + } // namespace } // namespace test } // namespace emboss diff --git a/compiler/front_end/constraints.py b/compiler/front_end/constraints.py index e99bd2e..02b1f55 100644 --- a/compiler/front_end/constraints.py +++ b/compiler/front_end/constraints.py @@ -713,13 +713,15 @@ def _check_bounds_on_runtime_integer_expressions( def _check_division_and_modulus_have_nonzero_divisors( expression, source_file_name, errors ): - """Rejects `l // r` and `l % r` whose divisor range could contain zero. - - This is the initial, strict rollout of `//` and `%`: because the expression - type system does not yet track an `undefined` value, the only sound option - for a divisor whose range includes zero is to reject it at compile time. A - later change will loosen this to allow a *possibly*-zero divisor to propagate - an `undefined` value, keeping the error only for a *provably*-zero divisor. + """Rejects `l // r` and `l % r` whose divisor is *provably always* zero. + + A divisor that is provably zero (its range is exactly {0}, e.g. `x // 0`) + has no defined result and is rejected at compile time. A divisor that is + merely *possibly* zero (a non-constant range that includes zero, e.g. + `x // d` for a byte `d`) is allowed: the expression type system propagates an + `undefined` value (tracked by IntegerType.can_be_undefined) and the runtime + yields an Unknown result for a `// 0`, so the field's `Ok()` becomes false + rather than the whole schema failing to compile. """ if expression.which_expression != "function": return @@ -734,9 +736,10 @@ def _check_division_and_modulus_have_nonzero_divisors( return rmin = divisor.type.integer.minimum_value rmax = divisor.type.integer.maximum_value - rmin_le_zero = rmin == "-infinity" or int(rmin) <= 0 - rmax_ge_zero = rmax == "infinity" or int(rmax) >= 0 - if rmin_le_zero and rmax_ge_zero: + # Provably always zero iff the divisor's range is exactly {0}. (The bounds + # invariant guarantees minimum_value == maximum_value implies the value is a + # constant.) + if rmin == "0" and rmax == "0": op_text = expression.function.function_name.text errors.append( [ @@ -748,9 +751,7 @@ def _check_division_and_modulus_have_nonzero_divisors( error.note( source_file_name, divisor.source_location, - "Divisor range is {} to {}, which includes zero.".format( - rmin, rmax - ), + "Divisor is always zero.", ), ] ) diff --git a/compiler/front_end/constraints_test.py b/compiler/front_end/constraints_test.py index 8f54543..b82e1a1 100644 --- a/compiler/front_end/constraints_test.py +++ b/compiler/front_end/constraints_test.py @@ -80,31 +80,50 @@ def test_no_error_on_modulus_by_positive_constant(self): ) self.assertEqual([], constraints.check_constraints(ir)) - def test_error_on_division_with_divisor_range_including_zero(self): + def test_no_error_on_division_with_divisor_range_including_zero(self): + # A *possibly*-zero divisor is now allowed: it propagates an `undefined` + # value (IntegerType.can_be_undefined) and yields an Unknown result at + # runtime rather than failing to compile. ir = _make_ir_from_emb( "struct Foo:\n" " 0 [+1] UInt divisor\n" " 1 [+1] UInt dividend\n" " let q = dividend // divisor\n" ) - errors = error.filter_errors(constraints.check_constraints(ir)) - self.assertEqual(1, len(errors)) - self.assertIn("Right argument of '//' cannot be zero.", errors[0][0].message) + self.assertEqual([], constraints.check_constraints(ir)) - def test_error_on_modulus_with_divisor_range_including_zero(self): + def test_no_error_on_modulus_with_divisor_range_including_zero(self): ir = _make_ir_from_emb( "struct Foo:\n" " 0 [+1] UInt divisor\n" " 1 [+1] UInt dividend\n" " let r = dividend % divisor\n" ) + self.assertEqual([], constraints.check_constraints(ir)) + + def test_error_on_division_by_zero_literal(self): + # A *provably*-always-zero divisor is still a hard compile error. + ir = _make_ir_from_emb( + "struct Foo:\n" " 0 [+1] UInt x\n" " let q = x // 0\n" + ) + errors = error.filter_errors(constraints.check_constraints(ir)) + self.assertEqual(1, len(errors)) + self.assertIn("Right argument of '//' cannot be zero.", errors[0][0].message) + + def test_error_on_modulus_by_zero_literal(self): + ir = _make_ir_from_emb( + "struct Foo:\n" " 0 [+1] UInt x\n" " let r = x % 0\n" + ) errors = error.filter_errors(constraints.check_constraints(ir)) self.assertEqual(1, len(errors)) self.assertIn("Right argument of '%' cannot be zero.", errors[0][0].message) - def test_error_on_division_by_zero_literal(self): + def test_error_on_division_by_provably_zero_expression(self): + # A divisor that folds to a constant zero (range exactly {0}) is + # provably always zero, so it is rejected even though it is not a bare + # `0` literal. ir = _make_ir_from_emb( - "struct Foo:\n" " 0 [+1] UInt x\n" " let q = x // 0\n" + "struct Foo:\n" " 0 [+1] UInt x\n" " let q = x // (3 - 3)\n" ) errors = error.filter_errors(constraints.check_constraints(ir)) self.assertEqual(1, len(errors)) diff --git a/compiler/front_end/expression_bounds.py b/compiler/front_end/expression_bounds.py index d04ef2e..7f898d8 100644 --- a/compiler/front_end/expression_bounds.py +++ b/compiler/front_end/expression_bounds.py @@ -368,6 +368,34 @@ def _min(a): return min(int(n) for n in a if not _is_infinite(n)) +def _range_includes_zero(minimum_value, maximum_value): + """Returns True if the closed range [minimum_value, maximum_value] holds 0. + + minimum_value and maximum_value are ints, stringified ints, "-infinity", or + "infinity". + """ + min_le_zero = minimum_value == "-infinity" or int(minimum_value) <= 0 + max_ge_zero = maximum_value == "infinity" or int(maximum_value) >= 0 + return min_le_zero and max_ge_zero + + +def _any_can_be_undefined(operands): + """Returns True if any of the given operand expressions can be undefined.""" + for operand in operands: + operand_type = operand.type + if ( + operand_type.which_type == "integer" + and operand_type.integer.can_be_undefined + ): + return True + if ( + operand_type.which_type == "boolean" + and operand_type.boolean.can_be_undefined + ): + return True + return False + + def _compute_constraints_of_additive_operator(expression): """Computes the modular value of an additive expression.""" funcs = { @@ -402,6 +430,8 @@ def _compute_constraints_of_additive_operator(expression): rmin = right.type.integer.minimum_value expression.type.integer.minimum_value = str(func(lmin, rmin)) expression.type.integer.maximum_value = str(func(lmax, rmax)) + if _any_can_be_undefined(args): + expression.type.integer.can_be_undefined = True def _compute_constraints_of_multiplicative_operator(expression): @@ -439,6 +469,8 @@ def _compute_constraints_of_multiplicative_operator(expression): ] expression.type.integer.minimum_value = str(_min(extrema)) expression.type.integer.maximum_value = str(_max(extrema)) + if _any_can_be_undefined(expression.function.args): + expression.type.integer.can_be_undefined = True if all(bound.modulus == "infinity" for bound in bounds): # If both sides are constant, the result is constant. @@ -557,6 +589,15 @@ def _compute_constraints_of_division_operator(expression): """Computes the bounds of a `//` (flooring integer division) expression.""" left, right = (arg.type.integer for arg in expression.function.args) + # `//` introduces undefined-ness: the result can be undefined if either + # operand can be undefined, or if the divisor's range includes zero (a + # runtime `// 0`). The constraints pass rejects a *provably*-zero divisor; + # a merely *possibly*-zero divisor is allowed and carries this flag. + if _any_can_be_undefined(expression.function.args) or _range_includes_zero( + right.minimum_value, right.maximum_value + ): + expression.type.integer.can_be_undefined = True + # Both sides constant: compute the exact result. if left.modulus == "infinity" and right.modulus == "infinity": r_val = int(right.modular_value) @@ -610,6 +651,13 @@ def _compute_constraints_of_modulus_operator(expression): """Computes the bounds of a `%` (flooring modulus) expression.""" left, right = (arg.type.integer for arg in expression.function.args) + # As with `//`, `%` introduces undefined-ness when the divisor's range + # includes zero (or an operand is already undefined). + if _any_can_be_undefined(expression.function.args) or _range_includes_zero( + right.minimum_value, right.maximum_value + ): + expression.type.integer.can_be_undefined = True + if left.modulus == "infinity" and right.modulus == "infinity": r_val = int(right.modular_value) if r_val == 0: @@ -693,6 +741,12 @@ def _compute_constant_value_of_comparison_operator(expression): expression.type.boolean.value = func( *[ir_util.constant_value(arg) for arg in args] ) + # An operand that can be undefined poisons the result. Note that an operand + # that can be undefined is never a compile-time constant (see + # ir_util.constant_value), so the branch above never sets a boolean `value` + # in that case -- the two are mutually exclusive. + if _any_can_be_undefined(args): + expression.type.boolean.can_be_undefined = True def _compute_constraints_of_bound_function(expression): @@ -723,6 +777,8 @@ def _compute_constraints_of_maximum_function(expression): expression.type.integer.maximum_value = str( _max([arg.type.integer.maximum_value for arg in args]) ) + if _any_can_be_undefined(args): + expression.type.integer.can_be_undefined = True # If the expression is dominated by a constant factor, then the result is # constant. I (bolms@) believe this is the only case where # _compute_constraints_of_maximum_function might violate the assertions in @@ -865,6 +921,17 @@ def _compute_constraints_of_choice_operator(expression): "boolean", "enumeration", ), "Unknown type {} for expression".format(if_true.type.which_type) + # The result can be undefined if the condition or the selected branch can be + # undefined. Conservatively, if any of the three operands can be undefined, + # the result can be too. (An `enumeration` result cannot carry the flag, but + # a non-constant choice is never treated as a constant enum, so it stays + # correctly un-foldable regardless.) + if _any_can_be_undefined((condition, if_true, if_false)): + # The choice's result type matches if_true's (and if_false's) type. + if if_true.type.which_type == "integer": + expression.type.integer.can_be_undefined = True + elif if_true.type.which_type == "boolean": + expression.type.boolean.can_be_undefined = True def _greatest_common_divisor(a, b): diff --git a/compiler/front_end/expression_bounds_test.py b/compiler/front_end/expression_bounds_test.py index fb9b639..22ed605 100644 --- a/compiler/front_end/expression_bounds_test.py +++ b/compiler/front_end/expression_bounds_test.py @@ -418,6 +418,84 @@ def test_non_constant_modulus_by_negative_constant(self): self.assertEqual("-3", r.minimum_value) self.assertEqual("0", r.maximum_value) + def test_division_by_maybe_zero_divisor_can_be_undefined(self): + # A non-constant divisor whose range includes zero introduces an + # undefined value; it does NOT error here (constraints only rejects a + # provably-always-zero divisor). + ir = self._make_ir( + "struct Foo:\n" + " 0 [+1] UInt d\n" + " 1 [+1] UInt n\n" + " let q = n // d\n" + ) + self.assertEqual([], expression_bounds.compute_constants(ir)) + self.assertTrue(self._virtual_fields(ir)["q"].can_be_undefined) + + def test_modulus_by_maybe_zero_divisor_can_be_undefined(self): + ir = self._make_ir( + "struct Foo:\n" + " 0 [+1] UInt d\n" + " 1 [+1] UInt n\n" + " let r = n % d\n" + ) + self.assertEqual([], expression_bounds.compute_constants(ir)) + self.assertTrue(self._virtual_fields(ir)["r"].can_be_undefined) + + def test_division_by_nonzero_constant_is_not_undefined(self): + ir = self._make_ir( + "struct Foo:\n" " 0 [+1] UInt x\n" " let half = x // 2\n" + ) + self.assertEqual([], expression_bounds.compute_constants(ir)) + # None (or False) -- not can_be_undefined. + self.assertFalse(self._virtual_fields(ir)["half"].can_be_undefined) + + def test_undefined_propagates_through_arithmetic(self): + # `(n // d)` is undefined, so `(n // d) + 1` and `(n // d) * 2` are too. + ir = self._make_ir( + "struct Foo:\n" + " 0 [+1] UInt d\n" + " 1 [+1] UInt n\n" + " let sum = (n // d) + 1\n" + " let product = (n // d) * 2\n" + ) + self.assertEqual([], expression_bounds.compute_constants(ir)) + fields = self._virtual_fields(ir) + self.assertTrue(fields["sum"].can_be_undefined) + self.assertTrue(fields["product"].can_be_undefined) + + def test_undefined_collapsing_quotient_stays_non_constant(self): + # `0 // d` collapses to the single value {0} (modulus == "infinity"), + # but can be undefined, so it must not be treated as a constant. + ir = self._make_ir("struct Foo:\n" " 0 [+1] UInt d\n" " let z = 0 // d\n") + self.assertEqual([], expression_bounds.compute_constants(ir)) + z = self._virtual_fields(ir)["z"] + self.assertEqual("infinity", z.modulus) + self.assertEqual("0", z.modular_value) + self.assertTrue(z.can_be_undefined) + + def test_undefined_propagates_into_boolean_comparison(self): + # A comparison against an undefined operand yields an undefined boolean, + # and -- crucially -- is NOT folded to a constant boolean `value`, so the + # existence condition's Known() guard cannot be elided. + ir = self._make_ir( + "struct Foo:\n" + " 0 [+1] UInt d\n" + " if 12 // d == 3:\n" + " 1 [+1] UInt gated\n" + ) + self.assertEqual([], expression_bounds.compute_constants(ir)) + condition = ir.module[0].type[0].structure.field[1].existence_condition + self.assertEqual("boolean", condition.type.which_type) + self.assertTrue(condition.type.boolean.can_be_undefined) + self.assertFalse(condition.type.boolean.has_field("value")) + + def test_provably_zero_divisor_can_be_undefined(self): + # `x // 0` is provably undefined; bounds still computes (constraints + # reports the error), and the flag is set. + ir = self._make_ir("struct Foo:\n" " 0 [+1] UInt x\n" " let q = x // 0\n") + self.assertEqual([], expression_bounds.compute_constants(ir)) + self.assertTrue(self._virtual_fields(ir)["q"].can_be_undefined) + def test_nested_constant_expression(self): ir = self._make_ir( "struct Foo:\n" " if 7*(3+1) == 28:\n" " 0 [+1] UInt x\n" diff --git a/compiler/util/ir_data.py b/compiler/util/ir_data.py index ab19593..2a71829 100644 --- a/compiler/util/ir_data.py +++ b/compiler/util/ir_data.py @@ -444,10 +444,23 @@ class IntegerType(Message): minimum_value: Optional[str] = None maximum_value: Optional[str] = None + # Whether the expression's value can be "undefined" -- that is, whether it + # can be the result of a division or modulus by zero. This is tracked as a + # separate boolean flag (never an in-band "undefined" value for + # minimum_value/maximum_value/modulus/modular_value) so that the many places + # that parse those fields as integers do not have to special-case a sentinel + # string. When can_be_undefined is true, minimum_value/maximum_value/modulus + # /modular_value describe the range of the *defined* results; the value may + # additionally be undefined at runtime (surfacing as an Unknown Maybe<>). + can_be_undefined: Optional[bool] = None + @dataclasses.dataclass class BooleanType(Message): value: Optional[bool] = None + # See IntegerType.can_be_undefined. A boolean expression can be undefined + # if it is derived (e.g. via a comparison) from an undefined integer. + can_be_undefined: Optional[bool] = None @dataclasses.dataclass diff --git a/compiler/util/ir_util.py b/compiler/util/ir_util.py index 54aca90..758367b 100644 --- a/compiler/util/ir_util.py +++ b/compiler/util/ir_util.py @@ -85,6 +85,16 @@ def is_constant(expression, bindings=None): def is_constant_type(expression_type): """Returns True if expression_type is inhabited by a single value.""" expression_type = ir_data_utils.reader(expression_type) + # A value that can be undefined is not a compile-time constant, even if its + # *defined* range collapses to a single value (e.g. `0 // d` for a byte `d` + # folds to {0} but is undefined when d == 0). Treating it as constant would + # let codegen emit a bogus literal instead of the real (possibly Unknown) + # runtime computation. + if ( + expression_type.integer.can_be_undefined + or expression_type.boolean.can_be_undefined + ): + return False return ( expression_type.integer.modulus == "infinity" or expression_type.boolean.has_field("value") @@ -104,9 +114,15 @@ def constant_value(expression, bindings=None): # constant_value is called, the actual values should have been propagated to # the type information. if expression.type.which_type == "integer": + # A value that can be undefined has no single constant value, even + # when its defined range collapses to one (modulus == "infinity"). + if expression.type.integer.can_be_undefined: + return None assert expression.type.integer.modulus == "infinity" return int(expression.type.integer.modular_value) elif expression.type.which_type == "boolean": + if expression.type.boolean.can_be_undefined: + return None assert expression.type.boolean.has_field("value") return expression.type.boolean.value elif expression.type.which_type == "enumeration": diff --git a/compiler/util/ir_util_test.py b/compiler/util/ir_util_test.py index 5033123..e4718e7 100644 --- a/compiler/util/ir_util_test.py +++ b/compiler/util/ir_util_test.py @@ -97,6 +97,52 @@ def test_is_constant_boolean_type(self): ) ) + def test_undefined_integer_type_is_not_constant(self): + # Even with modulus == "infinity" (a single defined value), a value that + # can be undefined is not a compile-time constant. + self.assertFalse( + ir_util.is_constant_type( + ir_data.ExpressionType( + integer=ir_data.IntegerType( + modulus="infinity", + modular_value="0", + minimum_value="0", + maximum_value="0", + can_be_undefined=True, + ) + ) + ) + ) + + def test_undefined_boolean_type_is_not_constant(self): + self.assertFalse( + ir_util.is_constant_type( + ir_data.ExpressionType( + boolean=ir_data.BooleanType(value=True, can_be_undefined=True) + ) + ) + ) + + def test_constant_value_of_undefined_reference_is_none(self): + # A constant_reference to an integer value that can be undefined has no + # single constant value, even when its defined range collapses to one. + self.assertIsNone( + ir_util.constant_value( + ir_data.Expression( + constant_reference=ir_data.Reference(), + type=ir_data.ExpressionType( + integer=ir_data.IntegerType( + modulus="infinity", + modular_value="0", + minimum_value="0", + maximum_value="0", + can_be_undefined=True, + ) + ), + ) + ) + ) + def test_is_constant_enumeration_type(self): self.assertFalse( ir_util.is_constant_type( diff --git a/runtime/cpp/emboss_arithmetic.h b/runtime/cpp/emboss_arithmetic.h index c33dc75..ef57b8e 100644 --- a/runtime/cpp/emboss_arithmetic.h +++ b/runtime/cpp/emboss_arithmetic.h @@ -362,6 +362,42 @@ inline constexpr Maybe Choice(Maybe condition, : Maybe(); } +// MaybeDivideOrModulo implements the shared logic for `//` and `%`: like +// MaybeDo it unwraps Known() operands, casts to IntermediateT, applies +// OperatorT, and rewraps -- but it is a *special op* (like And/Or/Choice) +// because Known() operands do not guarantee a Known() result: a zero divisor +// yields an Unknown result instead. Returning Unknown (rather than dividing) +// both avoids C++ undefined behavior on divide-by-zero and lets a runtime +// `// 0` poison the enclosing expression (e.g. $size_in_bytes -> Ok()) with no +// crash, matching the Emboss expression type system's `undefined` value. +template +inline constexpr Maybe MaybeDivideOrModulo(Maybe l, + Maybe r) { + return (!l.Known() || !r.Known() || + static_cast(r.ValueOrDefault()) == IntermediateT{0}) + ? Maybe() + : Maybe(static_cast(OperatorT::template Do<>( + static_cast(l.ValueOrDefault()), + static_cast(r.ValueOrDefault())))); +} + +template +inline constexpr Maybe FlooringQuotient(Maybe l, + Maybe r) { + return MaybeDivideOrModulo(l, r); +} + +template +inline constexpr Maybe FlooringRemainder(Maybe l, + Maybe r) { + return MaybeDivideOrModulo(l, r); +} + //// From here down: boilerplate instantiations of the various operations, which //// only forward to MaybeDo: @@ -384,22 +420,6 @@ inline constexpr Maybe Product(Maybe l, Maybe r) { return MaybeDo(l, r); } -template -inline constexpr Maybe FlooringQuotient(Maybe l, - Maybe r) { - return MaybeDo(l, r); -} - -template -inline constexpr Maybe FlooringRemainder(Maybe l, - Maybe r) { - return MaybeDo(l, r); -} - template inline constexpr Maybe Equal(Maybe l, Maybe r) { diff --git a/runtime/cpp/test/emboss_arithmetic_test.cc b/runtime/cpp/test/emboss_arithmetic_test.cc index f650e4e..d55851e 100644 --- a/runtime/cpp/test/emboss_arithmetic_test.cc +++ b/runtime/cpp/test/emboss_arithmetic_test.cc @@ -161,6 +161,18 @@ TEST(FlooringQuotient, FlooringQuotient) { (FlooringQuotient(Maybe(), Maybe(3)))); + // A zero divisor yields Unknown even when both operands are Known -- this is + // the "undefined" result of `// 0`, avoiding C++ undefined behavior. + EXPECT_EQ( + Maybe(), + (FlooringQuotient(Maybe(8), + Maybe(0)))); + EXPECT_EQ(Maybe(), + (FlooringQuotient( + Maybe(8), + Maybe(0)))); } TEST(FlooringRemainder, FlooringRemainder) { @@ -200,6 +212,17 @@ TEST(FlooringRemainder, FlooringRemainder) { (FlooringRemainder(Maybe(8), Maybe()))); + // A zero divisor yields Unknown even when both operands are Known. + EXPECT_EQ( + Maybe(), + (FlooringRemainder(Maybe(8), + Maybe(0)))); + EXPECT_EQ(Maybe(), + (FlooringRemainder( + Maybe(8), + Maybe(0)))); } TEST(Equal, Equal) { diff --git a/testdata/division_modulus.emb b/testdata/division_modulus.emb index 08d17f6..56edf77 100644 --- a/testdata/division_modulus.emb +++ b/testdata/division_modulus.emb @@ -43,3 +43,30 @@ struct Constants: let chained_div = 100 // 5 // 2 let chained_mod = 17 % 7 % 4 let mixed_divmod = 17 % 7 // 2 + + +# A field whose size depends on a runtime `//` with a *possibly*-zero divisor. +# When divisor == 0 the payload size -- and therefore the whole structure's +# size -- is undefined, so Ok() is false. A nonzero divisor works normally. +struct PayloadSizedByDivision: + 0 [+1] UInt divisor + 1 [+16 // divisor] UInt:8[] payload + + +# A field guarded by an existence condition that involves a possibly-zero +# divisor. This exercises the interaction with the Ok()/switch discriminant +# optimization: when divisor == 0 the condition `12 // divisor == 3` is +# undefined, so `gated`'s presence is unknown and Ok() must be false. +struct FieldGatedByDivision: + 0 [+1] UInt divisor + if 12 // divisor == 3: + 1 [+1] UInt gated + + +# A virtual field whose `//` result *collapses* to a single defined value ({0}) +# yet can be undefined when the divisor is zero. Without special handling, +# codegen would fold it to a bogus literal 0; instead the accessor must return +# an Unknown result when divisor == 0. +struct CollapsingQuotient: + 0 [+1] UInt divisor + let zero_or_undefined = 0 // divisor diff --git a/testdata/golden_cpp/division_modulus.emb.h b/testdata/golden_cpp/division_modulus.emb.h index dae4fd8..267295e 100644 --- a/testdata/golden_cpp/division_modulus.emb.h +++ b/testdata/golden_cpp/division_modulus.emb.h @@ -33,6 +33,21 @@ namespace Constants {} // namespace Constants template class GenericConstantsView; +namespace PayloadSizedByDivision {} // namespace PayloadSizedByDivision + +template +class GenericPayloadSizedByDivisionView; + +namespace FieldGatedByDivision {} // namespace FieldGatedByDivision + +template +class GenericFieldGatedByDivisionView; + +namespace CollapsingQuotient {} // namespace CollapsingQuotient + +template +class GenericCollapsingQuotientView; + namespace ArrayOfUint16BySizeInBytes {} // namespace ArrayOfUint16BySizeInBytes template @@ -2020,209 +2035,2242 @@ MakeAlignedConstantsView(T* emboss_reserved_local_data, emboss_reserved_local_data, emboss_reserved_local_size); } -namespace ArrayOfUint16BySizeInBytes {} // namespace ArrayOfUint16BySizeInBytes +namespace PayloadSizedByDivision {} // namespace PayloadSizedByDivision + +template +struct EmbossReservedInternalIsGenericPayloadSizedByDivisionView; template -inline typename ::emboss::prelude::UIntView< - /**/ ::emboss::support::FixedSizeViewParameters< - 8, ::emboss::support::AllValuesAreOk>, - typename ::emboss::support::BitBlock< - /**/ ::emboss::support::LittleEndianByteOrderer< - typename Storage::template OffsetStorageType>, - 8>> +class GenericPayloadSizedByDivisionView final { + public: + GenericPayloadSizedByDivisionView() : backing_() {} + explicit GenericPayloadSizedByDivisionView( + Storage emboss_reserved_local_bytes) + : backing_(emboss_reserved_local_bytes) {} -GenericArrayOfUint16BySizeInBytesView::size_in_bytes() const { - if (has_size_in_bytes().ValueOr(false)) { - auto emboss_reserved_local_size = - ::emboss::support::Maybe( - static_cast(1LL)); - auto emboss_reserved_local_offset = - ::emboss::support::Maybe( - static_cast(0LL)); - if (emboss_reserved_local_size.Known() && - emboss_reserved_local_size.ValueOr(0) >= 0 && - emboss_reserved_local_offset.Known() && - emboss_reserved_local_offset.ValueOr(0) >= 0) { - return ::emboss::prelude::UIntView< - /**/ ::emboss::support::FixedSizeViewParameters< - 8, ::emboss::support::AllValuesAreOk>, - typename ::emboss::support::BitBlock< - /**/ ::emboss::support::LittleEndianByteOrderer< - typename Storage::template OffsetStorageType>, - 8>> + template + GenericPayloadSizedByDivisionView( + const GenericPayloadSizedByDivisionView& + emboss_reserved_local_other) + : backing_{emboss_reserved_local_other.BackingStorage()} {} - (backing_.template GetOffsetStorage<0, 0>( - emboss_reserved_local_offset.ValueOrDefault(), - emboss_reserved_local_size.ValueOrDefault())); - } - } - return ::emboss::prelude::UIntView< - /**/ ::emboss::support::FixedSizeViewParameters< - 8, ::emboss::support::AllValuesAreOk>, - typename ::emboss::support::BitBlock< - /**/ ::emboss::support::LittleEndianByteOrderer< - typename Storage::template OffsetStorageType>, - 8>> + template ::type>::type>::value>::type> + explicit GenericPayloadSizedByDivisionView(Arg&& emboss_reserved_local_arg) + : backing_(::std::forward(emboss_reserved_local_arg)) {} + template + explicit GenericPayloadSizedByDivisionView( + Arg0&& emboss_reserved_local_arg0, Arg1&& emboss_reserved_local_arg1, + Args&&... emboss_reserved_local_args) + : backing_(::std::forward(emboss_reserved_local_arg0), + ::std::forward(emboss_reserved_local_arg1), + ::std::forward(emboss_reserved_local_args)...) {} - (); -} + template + GenericPayloadSizedByDivisionView& operator=( + const GenericPayloadSizedByDivisionView& + emboss_reserved_local_other) { + backing_ = emboss_reserved_local_other.BackingStorage(); + return *this; + } -template -inline ::emboss::support::Maybe -GenericArrayOfUint16BySizeInBytesView::has_size_in_bytes() const { - return ::emboss::support::Maybe(true); -} + bool Ok() const { + if (!IsComplete()) return false; -template -inline typename ::emboss::support::GenericArrayView< - typename ::emboss::prelude::UIntView< - /**/ ::emboss::support::FixedSizeViewParameters< - 16, ::emboss::support::AllValuesAreOk>, - typename ::emboss::support::BitBlock< - /**/ ::emboss::support::LittleEndianByteOrderer< - typename Storage::template OffsetStorageType< - /**/ 0, 1>::template OffsetStorageType>, - 16>> + if (!has_divisor().Known()) return false; + if (has_divisor().ValueOrDefault() && !divisor().Ok()) return false; - , - typename Storage::template OffsetStorageType, 2, 8> + if (!has_payload().Known()) return false; + if (has_payload().ValueOrDefault() && !payload().Ok()) return false; -GenericArrayOfUint16BySizeInBytesView::elements() const { - if (has_elements().ValueOr(false)) { - const auto emboss_reserved_local_subexpr_1 = size_in_bytes(); - const auto emboss_reserved_local_subexpr_2 = - (emboss_reserved_local_subexpr_1.Ok() - ? ::emboss::support::Maybe( - static_cast( - emboss_reserved_local_subexpr_1.UncheckedRead())) - : ::emboss::support::Maybe()); - const auto emboss_reserved_local_subexpr_3 = - ::emboss::support::FlooringQuotient( - emboss_reserved_local_subexpr_2, - ::emboss::support::Maybe( - static_cast(2LL))); - const auto emboss_reserved_local_subexpr_4 = - ::emboss::support::Product( - emboss_reserved_local_subexpr_3, - ::emboss::support::Maybe( - static_cast(2LL))); + if (!has_IntrinsicSizeInBytes().Known()) return false; + if (has_IntrinsicSizeInBytes().ValueOrDefault() && + !IntrinsicSizeInBytes().Ok()) + return false; - auto emboss_reserved_local_size = emboss_reserved_local_subexpr_4; - auto emboss_reserved_local_offset = - ::emboss::support::Maybe( - static_cast(1LL)); - if (emboss_reserved_local_size.Known() && - emboss_reserved_local_size.ValueOr(0) >= 0 && - emboss_reserved_local_offset.Known() && - emboss_reserved_local_offset.ValueOr(0) >= 0) { - return ::emboss::support::GenericArrayView< - typename ::emboss::prelude::UIntView< - /**/ ::emboss::support::FixedSizeViewParameters< - 16, ::emboss::support::AllValuesAreOk>, - typename ::emboss::support::BitBlock< - /**/ ::emboss::support::LittleEndianByteOrderer< - typename Storage::template OffsetStorageType< - /**/ 0, 1>::template OffsetStorageType>, - 16>> + if (!has_MaxSizeInBytes().Known()) return false; + if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) + return false; - , - typename Storage::template OffsetStorageType, 2, 8> + if (!has_MinSizeInBytes().Known()) return false; + if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) + return false; - (backing_.template GetOffsetStorage<0, 1>( - emboss_reserved_local_offset.ValueOrDefault(), - emboss_reserved_local_size.ValueOrDefault())); - } + return true; } - return ::emboss::support::GenericArrayView< - typename ::emboss::prelude::UIntView< - /**/ ::emboss::support::FixedSizeViewParameters< - 16, ::emboss::support::AllValuesAreOk>, - typename ::emboss::support::BitBlock< - /**/ ::emboss::support::LittleEndianByteOrderer< - typename Storage::template OffsetStorageType< - /**/ 0, 1>::template OffsetStorageType>, - 16>> + Storage BackingStorage() const { return backing_; } + bool IsComplete() const { + return backing_.Ok() && IntrinsicSizeInBytes().Ok() && + backing_.SizeInBytes() >= + static_cast( + IntrinsicSizeInBytes().UncheckedRead()); + } + ::std::size_t SizeInBytes() const { + return static_cast(IntrinsicSizeInBytes().Read()); + } + bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); } - , - typename Storage::template OffsetStorageType, 2, 8> + template + bool Equals(GenericPayloadSizedByDivisionView + emboss_reserved_local_other) const { + if (!has_divisor().Known()) return false; + if (!emboss_reserved_local_other.has_divisor().Known()) return false; - (); -} + if (emboss_reserved_local_other.has_divisor().ValueOrDefault() && + !has_divisor().ValueOrDefault()) + return false; + if (has_divisor().ValueOrDefault() && + !emboss_reserved_local_other.has_divisor().ValueOrDefault()) + return false; -template -inline ::emboss::support::Maybe -GenericArrayOfUint16BySizeInBytesView::has_elements() const { - return ::emboss::support::Maybe(true); -} + if (emboss_reserved_local_other.has_divisor().ValueOrDefault() && + has_divisor().ValueOrDefault() && + !divisor().Equals(emboss_reserved_local_other.divisor())) + return false; -template -inline typename GenericArrayOfUint16BySizeInBytesView< - Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView -GenericArrayOfUint16BySizeInBytesView::IntrinsicSizeInBytes() const { - return typename GenericArrayOfUint16BySizeInBytesView< - Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(*this); -} + if (!has_payload().Known()) return false; + if (!emboss_reserved_local_other.has_payload().Known()) return false; -template -inline ::emboss::support::Maybe GenericArrayOfUint16BySizeInBytesView< - Storage>::has_IntrinsicSizeInBytes() const { - return ::emboss::support::Maybe(true); -} + if (emboss_reserved_local_other.has_payload().ValueOrDefault() && + !has_payload().ValueOrDefault()) + return false; + if (has_payload().ValueOrDefault() && + !emboss_reserved_local_other.has_payload().ValueOrDefault()) + return false; -namespace ArrayOfUint16BySizeInBytes { -inline constexpr ::std::int32_t MaxSizeInBytes() { - return ::emboss::support::Maybe( - static_cast(255LL)) - .ValueOrDefault(); -} -} // namespace ArrayOfUint16BySizeInBytes + if (emboss_reserved_local_other.has_payload().ValueOrDefault() && + has_payload().ValueOrDefault() && + !payload().Equals(emboss_reserved_local_other.payload())) + return false; -template -inline constexpr ::std::int32_t GenericArrayOfUint16BySizeInBytesView< - Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() { - return ArrayOfUint16BySizeInBytes::MaxSizeInBytes(); -} + return true; + } + template + bool UncheckedEquals(GenericPayloadSizedByDivisionView + emboss_reserved_local_other) const { + if (emboss_reserved_local_other.has_divisor().ValueOr(false) && + !has_divisor().ValueOr(false)) + return false; + if (has_divisor().ValueOr(false) && + !emboss_reserved_local_other.has_divisor().ValueOr(false)) + return false; -template -inline constexpr ::std::int32_t GenericArrayOfUint16BySizeInBytesView< - Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() { - return ArrayOfUint16BySizeInBytes::MaxSizeInBytes(); -} + if (emboss_reserved_local_other.has_divisor().ValueOr(false) && + has_divisor().ValueOr(false) && + !divisor().UncheckedEquals(emboss_reserved_local_other.divisor())) + return false; -namespace ArrayOfUint16BySizeInBytes { -inline constexpr ::std::int32_t MinSizeInBytes() { - return ::emboss::support::Maybe( - static_cast(1LL)) - .ValueOrDefault(); -} -} // namespace ArrayOfUint16BySizeInBytes + if (emboss_reserved_local_other.has_payload().ValueOr(false) && + !has_payload().ValueOr(false)) + return false; + if (has_payload().ValueOr(false) && + !emboss_reserved_local_other.has_payload().ValueOr(false)) + return false; -template -inline constexpr ::std::int32_t GenericArrayOfUint16BySizeInBytesView< - Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() { - return ArrayOfUint16BySizeInBytes::MinSizeInBytes(); -} + if (emboss_reserved_local_other.has_payload().ValueOr(false) && + has_payload().ValueOr(false) && + !payload().UncheckedEquals(emboss_reserved_local_other.payload())) + return false; -template -inline constexpr ::std::int32_t GenericArrayOfUint16BySizeInBytesView< - Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() { - return ArrayOfUint16BySizeInBytes::MinSizeInBytes(); -} -namespace ChunkedPayload {} // namespace ChunkedPayload + return true; + } + template + void UncheckedCopyFrom(GenericPayloadSizedByDivisionView + emboss_reserved_local_other) const { + backing_.UncheckedCopyFrom( + emboss_reserved_local_other.BackingStorage(), + emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead()); + } -template -inline typename ::emboss::prelude::UIntView< - /**/ ::emboss::support::FixedSizeViewParameters< - 8, ::emboss::support::AllValuesAreOk>, - typename ::emboss::support::BitBlock< - /**/ ::emboss::support::LittleEndianByteOrderer< + template + void CopyFrom(GenericPayloadSizedByDivisionView + emboss_reserved_local_other) const { + backing_.CopyFrom( + emboss_reserved_local_other.BackingStorage(), + emboss_reserved_local_other.IntrinsicSizeInBytes().Read()); + } + template + bool TryToCopyFrom(GenericPayloadSizedByDivisionView + emboss_reserved_local_other) const { + return emboss_reserved_local_other.Ok() && + backing_.TryToCopyFrom( + emboss_reserved_local_other.BackingStorage(), + emboss_reserved_local_other.IntrinsicSizeInBytes().Read()); + } + + template + bool UpdateFromTextStream(Stream* emboss_reserved_local_stream) const { + ::std::string emboss_reserved_local_brace; + if (!::emboss::support::ReadToken(emboss_reserved_local_stream, + &emboss_reserved_local_brace)) + return false; + if (emboss_reserved_local_brace != "{") return false; + for (;;) { + ::std::string emboss_reserved_local_name; + if (!::emboss::support::ReadToken(emboss_reserved_local_stream, + &emboss_reserved_local_name)) + return false; + if (emboss_reserved_local_name == ",") + if (!::emboss::support::ReadToken(emboss_reserved_local_stream, + &emboss_reserved_local_name)) + return false; + if (emboss_reserved_local_name == "}") return true; + ::std::string emboss_reserved_local_colon; + if (!::emboss::support::ReadToken(emboss_reserved_local_stream, + &emboss_reserved_local_colon)) + return false; + if (emboss_reserved_local_colon != ":") return false; + if (emboss_reserved_local_name == "divisor") { + if (!divisor().UpdateFromTextStream(emboss_reserved_local_stream)) { + return false; + } + continue; + } + + if (emboss_reserved_local_name == "payload") { + if (!payload().UpdateFromTextStream(emboss_reserved_local_stream)) { + return false; + } + continue; + } + + return false; + } + } + + template + void WriteToTextStream( + Stream* emboss_reserved_local_stream, + ::emboss::TextOutputOptions emboss_reserved_local_options) const { + ::emboss::TextOutputOptions emboss_reserved_local_field_options = + emboss_reserved_local_options.PlusOneIndent(); + if (emboss_reserved_local_options.multiline()) { + emboss_reserved_local_stream->Write("{\n"); + } else { + emboss_reserved_local_stream->Write("{"); + } + bool emboss_reserved_local_wrote_field = false; + if (has_divisor().ValueOr(false)) { + if (!emboss_reserved_local_field_options.allow_partial_output() || + divisor().IsAggregate() || divisor().Ok()) { + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_field_options.current_indent()); + } else { + if (emboss_reserved_local_wrote_field) { + emboss_reserved_local_stream->Write(","); + } + emboss_reserved_local_stream->Write(" "); + } + emboss_reserved_local_stream->Write("divisor: "); + divisor().WriteToTextStream(emboss_reserved_local_stream, + emboss_reserved_local_field_options); + emboss_reserved_local_wrote_field = true; + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write("\n"); + } + } else if (emboss_reserved_local_field_options.allow_partial_output() && + emboss_reserved_local_field_options.comments() && + !divisor().IsAggregate() && !divisor().Ok()) { + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_field_options.current_indent()); + } + emboss_reserved_local_stream->Write("# divisor: UNREADABLE\n"); + } + } + + if (has_payload().ValueOr(false)) { + if (!emboss_reserved_local_field_options.allow_partial_output() || + payload().IsAggregate() || payload().Ok()) { + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_field_options.current_indent()); + } else { + if (emboss_reserved_local_wrote_field) { + emboss_reserved_local_stream->Write(","); + } + emboss_reserved_local_stream->Write(" "); + } + emboss_reserved_local_stream->Write("payload: "); + payload().WriteToTextStream(emboss_reserved_local_stream, + emboss_reserved_local_field_options); + emboss_reserved_local_wrote_field = true; + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write("\n"); + } + } else if (emboss_reserved_local_field_options.allow_partial_output() && + emboss_reserved_local_field_options.comments() && + !payload().IsAggregate() && !payload().Ok()) { + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_field_options.current_indent()); + } + emboss_reserved_local_stream->Write("# payload: UNREADABLE\n"); + } + } + + (void)emboss_reserved_local_wrote_field; + if (emboss_reserved_local_options.multiline()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_options.current_indent()); + emboss_reserved_local_stream->Write("}"); + } else { + emboss_reserved_local_stream->Write(" }"); + } + } + + static constexpr bool IsAggregate() { return true; } + + public: + typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + + divisor() const; + ::emboss::support::Maybe has_divisor() const; + + public: + typename ::emboss::support::GenericArrayView< + typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType< + /**/ 0, 1>::template OffsetStorageType>, + 8>> + + , + typename Storage::template OffsetStorageType, 1, 8> + + payload() const; + ::emboss::support::Maybe has_payload() const; + + public: + class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final { + public: + using ValueType = ::std::int32_t; + + explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView( + const GenericPayloadSizedByDivisionView& emboss_reserved_local_view) + : view_(emboss_reserved_local_view) {} + EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete; + EmbossReservedDollarVirtualIntrinsicSizeInBytesView( + const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default; + EmbossReservedDollarVirtualIntrinsicSizeInBytesView( + EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default; + EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=( + const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default; + EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=( + EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default; + ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default; + + ::std::int32_t Read() const { + EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false)); + auto emboss_reserved_local_value = MaybeRead(); + EMBOSS_CHECK(emboss_reserved_local_value.Known()); + EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault())); + return emboss_reserved_local_value.ValueOrDefault(); + } + ::std::int32_t UncheckedRead() const { + return MaybeRead().ValueOrDefault(); + } + bool Ok() const { + auto emboss_reserved_local_value = MaybeRead(); + return emboss_reserved_local_value.Known() && + ValueIsOk(emboss_reserved_local_value.ValueOrDefault()); + } + template + void WriteToTextStream(Stream* emboss_reserved_local_stream, + const ::emboss::TextOutputOptions& + emboss_reserved_local_options) const { + ::emboss::support::WriteIntegerViewToTextStream( + this, emboss_reserved_local_stream, emboss_reserved_local_options); + } + + static constexpr bool IsAggregate() { return false; } + + private: + ::emboss::support::Maybe MaybeRead() const { + const auto emboss_reserved_local_subexpr_1 = view_.divisor(); + const auto emboss_reserved_local_subexpr_2 = + (emboss_reserved_local_subexpr_1.Ok() + ? ::emboss::support::Maybe( + static_cast( + emboss_reserved_local_subexpr_1.UncheckedRead())) + : ::emboss::support::Maybe()); + const auto emboss_reserved_local_subexpr_3 = + ::emboss::support::FlooringQuotient( + ::emboss::support::Maybe( + static_cast(16LL)), + emboss_reserved_local_subexpr_2); + const auto emboss_reserved_local_subexpr_4 = + ::emboss::support::Sum( + ::emboss::support::Maybe( + static_cast(1LL)), + emboss_reserved_local_subexpr_3); + const auto emboss_reserved_local_subexpr_5 = + ::emboss::support::Choice( + ::emboss::support::Maybe(true), + emboss_reserved_local_subexpr_4, + ::emboss::support::Maybe( + static_cast(0LL))); + const auto emboss_reserved_local_subexpr_6 = + ::emboss::support::Maximum( + ::emboss::support::Maybe( + static_cast(0LL)), + ::emboss::support::Maybe( + static_cast(1LL)), + emboss_reserved_local_subexpr_5); + + return emboss_reserved_local_subexpr_6; + } + + static constexpr bool ValueIsOk( + ::std::int32_t emboss_reserved_local_value) { + return (void)emboss_reserved_local_value, // Silence -Wunused-parameter + ::emboss::support::Maybe(true).ValueOr(false); + } + + const GenericPayloadSizedByDivisionView view_; + }; + EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() + const; + ::emboss::support::Maybe has_IntrinsicSizeInBytes() const; + + public: + class EmbossReservedDollarVirtualMaxSizeInBytesView final { + public: + using ValueType = ::std::int32_t; + + constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {} + EmbossReservedDollarVirtualMaxSizeInBytesView( + const EmbossReservedDollarVirtualMaxSizeInBytesView&) = default; + EmbossReservedDollarVirtualMaxSizeInBytesView( + EmbossReservedDollarVirtualMaxSizeInBytesView&&) = default; + EmbossReservedDollarVirtualMaxSizeInBytesView& operator=( + const EmbossReservedDollarVirtualMaxSizeInBytesView&) = default; + EmbossReservedDollarVirtualMaxSizeInBytesView& operator=( + EmbossReservedDollarVirtualMaxSizeInBytesView&&) = default; + ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default; + + static constexpr ::std::int32_t Read(); + static constexpr ::std::int32_t UncheckedRead(); + static constexpr bool Ok() { return true; } + template + void WriteToTextStream(Stream* emboss_reserved_local_stream, + const ::emboss::TextOutputOptions& + emboss_reserved_local_options) const { + ::emboss::support::WriteIntegerViewToTextStream( + this, emboss_reserved_local_stream, emboss_reserved_local_options); + } + + static constexpr bool IsAggregate() { return false; } + }; + + static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView + MaxSizeInBytes() { + return EmbossReservedDollarVirtualMaxSizeInBytesView(); + } + static constexpr ::emboss::support::Maybe has_MaxSizeInBytes() { + return ::emboss::support::Maybe(true); + } + + public: + class EmbossReservedDollarVirtualMinSizeInBytesView final { + public: + using ValueType = ::std::int32_t; + + constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {} + EmbossReservedDollarVirtualMinSizeInBytesView( + const EmbossReservedDollarVirtualMinSizeInBytesView&) = default; + EmbossReservedDollarVirtualMinSizeInBytesView( + EmbossReservedDollarVirtualMinSizeInBytesView&&) = default; + EmbossReservedDollarVirtualMinSizeInBytesView& operator=( + const EmbossReservedDollarVirtualMinSizeInBytesView&) = default; + EmbossReservedDollarVirtualMinSizeInBytesView& operator=( + EmbossReservedDollarVirtualMinSizeInBytesView&&) = default; + ~EmbossReservedDollarVirtualMinSizeInBytesView() = default; + + static constexpr ::std::int32_t Read(); + static constexpr ::std::int32_t UncheckedRead(); + static constexpr bool Ok() { return true; } + template + void WriteToTextStream(Stream* emboss_reserved_local_stream, + const ::emboss::TextOutputOptions& + emboss_reserved_local_options) const { + ::emboss::support::WriteIntegerViewToTextStream( + this, emboss_reserved_local_stream, emboss_reserved_local_options); + } + + static constexpr bool IsAggregate() { return false; } + }; + + static constexpr EmbossReservedDollarVirtualMinSizeInBytesView + MinSizeInBytes() { + return EmbossReservedDollarVirtualMinSizeInBytesView(); + } + static constexpr ::emboss::support::Maybe has_MinSizeInBytes() { + return ::emboss::support::Maybe(true); + } + + private: + Storage backing_; + + template + friend class GenericPayloadSizedByDivisionView; +}; +using PayloadSizedByDivisionView = GenericPayloadSizedByDivisionView< + /**/ ::emboss::support::ReadOnlyContiguousBuffer>; +using PayloadSizedByDivisionWriter = GenericPayloadSizedByDivisionView< + /**/ ::emboss::support::ReadWriteContiguousBuffer>; + +template +struct EmbossReservedInternalIsGenericPayloadSizedByDivisionView { + static constexpr const bool value = false; +}; + +template +struct EmbossReservedInternalIsGenericPayloadSizedByDivisionView< + GenericPayloadSizedByDivisionView> { + static constexpr const bool value = true; +}; + +template +inline GenericPayloadSizedByDivisionView< + /**/ ::emboss::support::ContiguousBuffer< + typename ::std::remove_reference< + decltype(*::std::declval()->data())>::type, + 1, 0>> +MakePayloadSizedByDivisionView(T&& emboss_reserved_local_arg) { + return GenericPayloadSizedByDivisionView< + /**/ ::emboss::support::ContiguousBuffer< + typename ::std::remove_reference< + decltype(*::std::declval()->data())>::type, + 1, 0>>(::std::forward(emboss_reserved_local_arg)); +} + +template +inline GenericPayloadSizedByDivisionView< + /**/ ::emboss::support::ContiguousBuffer> +MakePayloadSizedByDivisionView(T* emboss_reserved_local_data, + ::std::size_t emboss_reserved_local_size) { + return GenericPayloadSizedByDivisionView< + /**/ ::emboss::support::ContiguousBuffer>( + emboss_reserved_local_data, emboss_reserved_local_size); +} + +template +inline GenericPayloadSizedByDivisionView< + /**/ ::emboss::support::ContiguousBuffer> +MakeAlignedPayloadSizedByDivisionView( + T* emboss_reserved_local_data, ::std::size_t emboss_reserved_local_size) { + return GenericPayloadSizedByDivisionView< + /**/ ::emboss::support::ContiguousBuffer>( + emboss_reserved_local_data, emboss_reserved_local_size); +} + +namespace FieldGatedByDivision {} // namespace FieldGatedByDivision + +template +struct EmbossReservedInternalIsGenericFieldGatedByDivisionView; + +template +class GenericFieldGatedByDivisionView final { + public: + GenericFieldGatedByDivisionView() : backing_() {} + explicit GenericFieldGatedByDivisionView(Storage emboss_reserved_local_bytes) + : backing_(emboss_reserved_local_bytes) {} + + template + GenericFieldGatedByDivisionView( + const GenericFieldGatedByDivisionView& + emboss_reserved_local_other) + : backing_{emboss_reserved_local_other.BackingStorage()} {} + + template ::type>::type>::value>::type> + explicit GenericFieldGatedByDivisionView(Arg&& emboss_reserved_local_arg) + : backing_(::std::forward(emboss_reserved_local_arg)) {} + template + explicit GenericFieldGatedByDivisionView(Arg0&& emboss_reserved_local_arg0, + Arg1&& emboss_reserved_local_arg1, + Args&&... emboss_reserved_local_args) + : backing_(::std::forward(emboss_reserved_local_arg0), + ::std::forward(emboss_reserved_local_arg1), + ::std::forward(emboss_reserved_local_args)...) {} + + template + GenericFieldGatedByDivisionView& operator=( + const GenericFieldGatedByDivisionView& + emboss_reserved_local_other) { + backing_ = emboss_reserved_local_other.BackingStorage(); + return *this; + } + + bool Ok() const { + if (!IsComplete()) return false; + + if (!has_divisor().Known()) return false; + if (has_divisor().ValueOrDefault() && !divisor().Ok()) return false; + + if (!has_IntrinsicSizeInBytes().Known()) return false; + if (has_IntrinsicSizeInBytes().ValueOrDefault() && + !IntrinsicSizeInBytes().Ok()) + return false; + + if (!has_MaxSizeInBytes().Known()) return false; + if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) + return false; + + if (!has_MinSizeInBytes().Known()) return false; + if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) + return false; + + if (!has_gated().Known()) return false; + if (has_gated().ValueOrDefault() && !gated().Ok()) return false; + + return true; + } + Storage BackingStorage() const { return backing_; } + bool IsComplete() const { + return backing_.Ok() && IntrinsicSizeInBytes().Ok() && + backing_.SizeInBytes() >= + static_cast( + IntrinsicSizeInBytes().UncheckedRead()); + } + ::std::size_t SizeInBytes() const { + return static_cast(IntrinsicSizeInBytes().Read()); + } + bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); } + + template + bool Equals(GenericFieldGatedByDivisionView + emboss_reserved_local_other) const { + if (!has_divisor().Known()) return false; + if (!emboss_reserved_local_other.has_divisor().Known()) return false; + + if (emboss_reserved_local_other.has_divisor().ValueOrDefault() && + !has_divisor().ValueOrDefault()) + return false; + if (has_divisor().ValueOrDefault() && + !emboss_reserved_local_other.has_divisor().ValueOrDefault()) + return false; + + if (emboss_reserved_local_other.has_divisor().ValueOrDefault() && + has_divisor().ValueOrDefault() && + !divisor().Equals(emboss_reserved_local_other.divisor())) + return false; + + if (!has_gated().Known()) return false; + if (!emboss_reserved_local_other.has_gated().Known()) return false; + + if (emboss_reserved_local_other.has_gated().ValueOrDefault() && + !has_gated().ValueOrDefault()) + return false; + if (has_gated().ValueOrDefault() && + !emboss_reserved_local_other.has_gated().ValueOrDefault()) + return false; + + if (emboss_reserved_local_other.has_gated().ValueOrDefault() && + has_gated().ValueOrDefault() && + !gated().Equals(emboss_reserved_local_other.gated())) + return false; + + return true; + } + template + bool UncheckedEquals(GenericFieldGatedByDivisionView + emboss_reserved_local_other) const { + if (emboss_reserved_local_other.has_divisor().ValueOr(false) && + !has_divisor().ValueOr(false)) + return false; + if (has_divisor().ValueOr(false) && + !emboss_reserved_local_other.has_divisor().ValueOr(false)) + return false; + + if (emboss_reserved_local_other.has_divisor().ValueOr(false) && + has_divisor().ValueOr(false) && + !divisor().UncheckedEquals(emboss_reserved_local_other.divisor())) + return false; + + if (emboss_reserved_local_other.has_gated().ValueOr(false) && + !has_gated().ValueOr(false)) + return false; + if (has_gated().ValueOr(false) && + !emboss_reserved_local_other.has_gated().ValueOr(false)) + return false; + + if (emboss_reserved_local_other.has_gated().ValueOr(false) && + has_gated().ValueOr(false) && + !gated().UncheckedEquals(emboss_reserved_local_other.gated())) + return false; + + return true; + } + template + void UncheckedCopyFrom(GenericFieldGatedByDivisionView + emboss_reserved_local_other) const { + backing_.UncheckedCopyFrom( + emboss_reserved_local_other.BackingStorage(), + emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead()); + } + + template + void CopyFrom(GenericFieldGatedByDivisionView + emboss_reserved_local_other) const { + backing_.CopyFrom( + emboss_reserved_local_other.BackingStorage(), + emboss_reserved_local_other.IntrinsicSizeInBytes().Read()); + } + template + bool TryToCopyFrom(GenericFieldGatedByDivisionView + emboss_reserved_local_other) const { + return emboss_reserved_local_other.Ok() && + backing_.TryToCopyFrom( + emboss_reserved_local_other.BackingStorage(), + emboss_reserved_local_other.IntrinsicSizeInBytes().Read()); + } + + template + bool UpdateFromTextStream(Stream* emboss_reserved_local_stream) const { + ::std::string emboss_reserved_local_brace; + if (!::emboss::support::ReadToken(emboss_reserved_local_stream, + &emboss_reserved_local_brace)) + return false; + if (emboss_reserved_local_brace != "{") return false; + for (;;) { + ::std::string emboss_reserved_local_name; + if (!::emboss::support::ReadToken(emboss_reserved_local_stream, + &emboss_reserved_local_name)) + return false; + if (emboss_reserved_local_name == ",") + if (!::emboss::support::ReadToken(emboss_reserved_local_stream, + &emboss_reserved_local_name)) + return false; + if (emboss_reserved_local_name == "}") return true; + ::std::string emboss_reserved_local_colon; + if (!::emboss::support::ReadToken(emboss_reserved_local_stream, + &emboss_reserved_local_colon)) + return false; + if (emboss_reserved_local_colon != ":") return false; + if (emboss_reserved_local_name == "divisor") { + if (!divisor().UpdateFromTextStream(emboss_reserved_local_stream)) { + return false; + } + continue; + } + + if (emboss_reserved_local_name == "gated") { + if (!gated().UpdateFromTextStream(emboss_reserved_local_stream)) { + return false; + } + continue; + } + + return false; + } + } + + template + void WriteToTextStream( + Stream* emboss_reserved_local_stream, + ::emboss::TextOutputOptions emboss_reserved_local_options) const { + ::emboss::TextOutputOptions emboss_reserved_local_field_options = + emboss_reserved_local_options.PlusOneIndent(); + if (emboss_reserved_local_options.multiline()) { + emboss_reserved_local_stream->Write("{\n"); + } else { + emboss_reserved_local_stream->Write("{"); + } + bool emboss_reserved_local_wrote_field = false; + if (has_divisor().ValueOr(false)) { + if (!emboss_reserved_local_field_options.allow_partial_output() || + divisor().IsAggregate() || divisor().Ok()) { + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_field_options.current_indent()); + } else { + if (emboss_reserved_local_wrote_field) { + emboss_reserved_local_stream->Write(","); + } + emboss_reserved_local_stream->Write(" "); + } + emboss_reserved_local_stream->Write("divisor: "); + divisor().WriteToTextStream(emboss_reserved_local_stream, + emboss_reserved_local_field_options); + emboss_reserved_local_wrote_field = true; + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write("\n"); + } + } else if (emboss_reserved_local_field_options.allow_partial_output() && + emboss_reserved_local_field_options.comments() && + !divisor().IsAggregate() && !divisor().Ok()) { + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_field_options.current_indent()); + } + emboss_reserved_local_stream->Write("# divisor: UNREADABLE\n"); + } + } + + if (has_gated().ValueOr(false)) { + if (!emboss_reserved_local_field_options.allow_partial_output() || + gated().IsAggregate() || gated().Ok()) { + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_field_options.current_indent()); + } else { + if (emboss_reserved_local_wrote_field) { + emboss_reserved_local_stream->Write(","); + } + emboss_reserved_local_stream->Write(" "); + } + emboss_reserved_local_stream->Write("gated: "); + gated().WriteToTextStream(emboss_reserved_local_stream, + emboss_reserved_local_field_options); + emboss_reserved_local_wrote_field = true; + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write("\n"); + } + } else if (emboss_reserved_local_field_options.allow_partial_output() && + emboss_reserved_local_field_options.comments() && + !gated().IsAggregate() && !gated().Ok()) { + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_field_options.current_indent()); + } + emboss_reserved_local_stream->Write("# gated: UNREADABLE\n"); + } + } + + (void)emboss_reserved_local_wrote_field; + if (emboss_reserved_local_options.multiline()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_options.current_indent()); + emboss_reserved_local_stream->Write("}"); + } else { + emboss_reserved_local_stream->Write(" }"); + } + } + + static constexpr bool IsAggregate() { return true; } + + public: + typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + + divisor() const; + ::emboss::support::Maybe has_divisor() const; + + public: + typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + + gated() const; + ::emboss::support::Maybe has_gated() const; + + public: + class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final { + public: + using ValueType = ::std::int32_t; + + explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView( + const GenericFieldGatedByDivisionView& emboss_reserved_local_view) + : view_(emboss_reserved_local_view) {} + EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete; + EmbossReservedDollarVirtualIntrinsicSizeInBytesView( + const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default; + EmbossReservedDollarVirtualIntrinsicSizeInBytesView( + EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default; + EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=( + const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default; + EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=( + EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default; + ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default; + + ::std::int32_t Read() const { + EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().ValueOr(false)); + auto emboss_reserved_local_value = MaybeRead(); + EMBOSS_CHECK(emboss_reserved_local_value.Known()); + EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault())); + return emboss_reserved_local_value.ValueOrDefault(); + } + ::std::int32_t UncheckedRead() const { + return MaybeRead().ValueOrDefault(); + } + bool Ok() const { + auto emboss_reserved_local_value = MaybeRead(); + return emboss_reserved_local_value.Known() && + ValueIsOk(emboss_reserved_local_value.ValueOrDefault()); + } + template + void WriteToTextStream(Stream* emboss_reserved_local_stream, + const ::emboss::TextOutputOptions& + emboss_reserved_local_options) const { + ::emboss::support::WriteIntegerViewToTextStream( + this, emboss_reserved_local_stream, emboss_reserved_local_options); + } + + static constexpr bool IsAggregate() { return false; } + + private: + ::emboss::support::Maybe MaybeRead() const { + const auto emboss_reserved_local_subexpr_1 = view_.divisor(); + const auto emboss_reserved_local_subexpr_2 = + (emboss_reserved_local_subexpr_1.Ok() + ? ::emboss::support::Maybe( + static_cast( + emboss_reserved_local_subexpr_1.UncheckedRead())) + : ::emboss::support::Maybe()); + const auto emboss_reserved_local_subexpr_3 = + ::emboss::support::FlooringQuotient( + ::emboss::support::Maybe( + static_cast(12LL)), + emboss_reserved_local_subexpr_2); + const auto emboss_reserved_local_subexpr_4 = + ::emboss::support::Equal( + emboss_reserved_local_subexpr_3, + ::emboss::support::Maybe( + static_cast(3LL))); + const auto emboss_reserved_local_subexpr_5 = + ::emboss::support::Choice( + emboss_reserved_local_subexpr_4, + ::emboss::support::Maybe( + static_cast(2LL)), + ::emboss::support::Maybe( + static_cast(0LL))); + const auto emboss_reserved_local_subexpr_6 = + ::emboss::support::Maximum( + ::emboss::support::Maybe( + static_cast(0LL)), + ::emboss::support::Maybe( + static_cast(1LL)), + emboss_reserved_local_subexpr_5); + + return emboss_reserved_local_subexpr_6; + } + + static constexpr bool ValueIsOk( + ::std::int32_t emboss_reserved_local_value) { + return (void)emboss_reserved_local_value, // Silence -Wunused-parameter + ::emboss::support::Maybe(true).ValueOr(false); + } + + const GenericFieldGatedByDivisionView view_; + }; + EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes() + const; + ::emboss::support::Maybe has_IntrinsicSizeInBytes() const; + + public: + class EmbossReservedDollarVirtualMaxSizeInBytesView final { + public: + using ValueType = ::std::int32_t; + + constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {} + EmbossReservedDollarVirtualMaxSizeInBytesView( + const EmbossReservedDollarVirtualMaxSizeInBytesView&) = default; + EmbossReservedDollarVirtualMaxSizeInBytesView( + EmbossReservedDollarVirtualMaxSizeInBytesView&&) = default; + EmbossReservedDollarVirtualMaxSizeInBytesView& operator=( + const EmbossReservedDollarVirtualMaxSizeInBytesView&) = default; + EmbossReservedDollarVirtualMaxSizeInBytesView& operator=( + EmbossReservedDollarVirtualMaxSizeInBytesView&&) = default; + ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default; + + static constexpr ::std::int32_t Read(); + static constexpr ::std::int32_t UncheckedRead(); + static constexpr bool Ok() { return true; } + template + void WriteToTextStream(Stream* emboss_reserved_local_stream, + const ::emboss::TextOutputOptions& + emboss_reserved_local_options) const { + ::emboss::support::WriteIntegerViewToTextStream( + this, emboss_reserved_local_stream, emboss_reserved_local_options); + } + + static constexpr bool IsAggregate() { return false; } + }; + + static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView + MaxSizeInBytes() { + return EmbossReservedDollarVirtualMaxSizeInBytesView(); + } + static constexpr ::emboss::support::Maybe has_MaxSizeInBytes() { + return ::emboss::support::Maybe(true); + } + + public: + class EmbossReservedDollarVirtualMinSizeInBytesView final { + public: + using ValueType = ::std::int32_t; + + constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {} + EmbossReservedDollarVirtualMinSizeInBytesView( + const EmbossReservedDollarVirtualMinSizeInBytesView&) = default; + EmbossReservedDollarVirtualMinSizeInBytesView( + EmbossReservedDollarVirtualMinSizeInBytesView&&) = default; + EmbossReservedDollarVirtualMinSizeInBytesView& operator=( + const EmbossReservedDollarVirtualMinSizeInBytesView&) = default; + EmbossReservedDollarVirtualMinSizeInBytesView& operator=( + EmbossReservedDollarVirtualMinSizeInBytesView&&) = default; + ~EmbossReservedDollarVirtualMinSizeInBytesView() = default; + + static constexpr ::std::int32_t Read(); + static constexpr ::std::int32_t UncheckedRead(); + static constexpr bool Ok() { return true; } + template + void WriteToTextStream(Stream* emboss_reserved_local_stream, + const ::emboss::TextOutputOptions& + emboss_reserved_local_options) const { + ::emboss::support::WriteIntegerViewToTextStream( + this, emboss_reserved_local_stream, emboss_reserved_local_options); + } + + static constexpr bool IsAggregate() { return false; } + }; + + static constexpr EmbossReservedDollarVirtualMinSizeInBytesView + MinSizeInBytes() { + return EmbossReservedDollarVirtualMinSizeInBytesView(); + } + static constexpr ::emboss::support::Maybe has_MinSizeInBytes() { + return ::emboss::support::Maybe(true); + } + + private: + Storage backing_; + + template + friend class GenericFieldGatedByDivisionView; +}; +using FieldGatedByDivisionView = GenericFieldGatedByDivisionView< + /**/ ::emboss::support::ReadOnlyContiguousBuffer>; +using FieldGatedByDivisionWriter = GenericFieldGatedByDivisionView< + /**/ ::emboss::support::ReadWriteContiguousBuffer>; + +template +struct EmbossReservedInternalIsGenericFieldGatedByDivisionView { + static constexpr const bool value = false; +}; + +template +struct EmbossReservedInternalIsGenericFieldGatedByDivisionView< + GenericFieldGatedByDivisionView> { + static constexpr const bool value = true; +}; + +template +inline GenericFieldGatedByDivisionView< + /**/ ::emboss::support::ContiguousBuffer< + typename ::std::remove_reference< + decltype(*::std::declval()->data())>::type, + 1, 0>> +MakeFieldGatedByDivisionView(T&& emboss_reserved_local_arg) { + return GenericFieldGatedByDivisionView< + /**/ ::emboss::support::ContiguousBuffer< + typename ::std::remove_reference< + decltype(*::std::declval()->data())>::type, + 1, 0>>(::std::forward(emboss_reserved_local_arg)); +} + +template +inline GenericFieldGatedByDivisionView< + /**/ ::emboss::support::ContiguousBuffer> +MakeFieldGatedByDivisionView(T* emboss_reserved_local_data, + ::std::size_t emboss_reserved_local_size) { + return GenericFieldGatedByDivisionView< + /**/ ::emboss::support::ContiguousBuffer>( + emboss_reserved_local_data, emboss_reserved_local_size); +} + +template +inline GenericFieldGatedByDivisionView< + /**/ ::emboss::support::ContiguousBuffer> +MakeAlignedFieldGatedByDivisionView(T* emboss_reserved_local_data, + ::std::size_t emboss_reserved_local_size) { + return GenericFieldGatedByDivisionView< + /**/ ::emboss::support::ContiguousBuffer>( + emboss_reserved_local_data, emboss_reserved_local_size); +} + +namespace CollapsingQuotient {} // namespace CollapsingQuotient + +template +struct EmbossReservedInternalIsGenericCollapsingQuotientView; + +template +class GenericCollapsingQuotientView final { + public: + GenericCollapsingQuotientView() : backing_() {} + explicit GenericCollapsingQuotientView(Storage emboss_reserved_local_bytes) + : backing_(emboss_reserved_local_bytes) {} + + template + GenericCollapsingQuotientView( + const GenericCollapsingQuotientView& + emboss_reserved_local_other) + : backing_{emboss_reserved_local_other.BackingStorage()} {} + + template ::type>::type>::value>::type> + explicit GenericCollapsingQuotientView(Arg&& emboss_reserved_local_arg) + : backing_(::std::forward(emboss_reserved_local_arg)) {} + template + explicit GenericCollapsingQuotientView(Arg0&& emboss_reserved_local_arg0, + Arg1&& emboss_reserved_local_arg1, + Args&&... emboss_reserved_local_args) + : backing_(::std::forward(emboss_reserved_local_arg0), + ::std::forward(emboss_reserved_local_arg1), + ::std::forward(emboss_reserved_local_args)...) {} + + template + GenericCollapsingQuotientView& operator=( + const GenericCollapsingQuotientView& + emboss_reserved_local_other) { + backing_ = emboss_reserved_local_other.BackingStorage(); + return *this; + } + + bool Ok() const { + if (!IsComplete()) return false; + + if (!has_divisor().Known()) return false; + if (has_divisor().ValueOrDefault() && !divisor().Ok()) return false; + + if (!has_zero_or_undefined().Known()) return false; + if (has_zero_or_undefined().ValueOrDefault() && !zero_or_undefined().Ok()) + return false; + + if (!has_IntrinsicSizeInBytes().Known()) return false; + if (has_IntrinsicSizeInBytes().ValueOrDefault() && + !IntrinsicSizeInBytes().Ok()) + return false; + + if (!has_MaxSizeInBytes().Known()) return false; + if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok()) + return false; + + if (!has_MinSizeInBytes().Known()) return false; + if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok()) + return false; + + return true; + } + Storage BackingStorage() const { return backing_; } + bool IsComplete() const { + return backing_.Ok() && IntrinsicSizeInBytes().Ok() && + backing_.SizeInBytes() >= + static_cast( + IntrinsicSizeInBytes().UncheckedRead()); + } + static constexpr ::std::size_t SizeInBytes() { + return static_cast(IntrinsicSizeInBytes().Read()); + } + static constexpr bool SizeIsKnown() { return IntrinsicSizeInBytes().Ok(); } + + template + bool Equals(GenericCollapsingQuotientView + emboss_reserved_local_other) const { + if (!has_divisor().Known()) return false; + if (!emboss_reserved_local_other.has_divisor().Known()) return false; + + if (emboss_reserved_local_other.has_divisor().ValueOrDefault() && + !has_divisor().ValueOrDefault()) + return false; + if (has_divisor().ValueOrDefault() && + !emboss_reserved_local_other.has_divisor().ValueOrDefault()) + return false; + + if (emboss_reserved_local_other.has_divisor().ValueOrDefault() && + has_divisor().ValueOrDefault() && + !divisor().Equals(emboss_reserved_local_other.divisor())) + return false; + + return true; + } + template + bool UncheckedEquals(GenericCollapsingQuotientView + emboss_reserved_local_other) const { + if (emboss_reserved_local_other.has_divisor().ValueOr(false) && + !has_divisor().ValueOr(false)) + return false; + if (has_divisor().ValueOr(false) && + !emboss_reserved_local_other.has_divisor().ValueOr(false)) + return false; + + if (emboss_reserved_local_other.has_divisor().ValueOr(false) && + has_divisor().ValueOr(false) && + !divisor().UncheckedEquals(emboss_reserved_local_other.divisor())) + return false; + + return true; + } + template + void UncheckedCopyFrom(GenericCollapsingQuotientView + emboss_reserved_local_other) const { + backing_.UncheckedCopyFrom( + emboss_reserved_local_other.BackingStorage(), + emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead()); + } + + template + void CopyFrom(GenericCollapsingQuotientView + emboss_reserved_local_other) const { + backing_.CopyFrom( + emboss_reserved_local_other.BackingStorage(), + emboss_reserved_local_other.IntrinsicSizeInBytes().Read()); + } + template + bool TryToCopyFrom(GenericCollapsingQuotientView + emboss_reserved_local_other) const { + return emboss_reserved_local_other.Ok() && + backing_.TryToCopyFrom( + emboss_reserved_local_other.BackingStorage(), + emboss_reserved_local_other.IntrinsicSizeInBytes().Read()); + } + + template + bool UpdateFromTextStream(Stream* emboss_reserved_local_stream) const { + ::std::string emboss_reserved_local_brace; + if (!::emboss::support::ReadToken(emboss_reserved_local_stream, + &emboss_reserved_local_brace)) + return false; + if (emboss_reserved_local_brace != "{") return false; + for (;;) { + ::std::string emboss_reserved_local_name; + if (!::emboss::support::ReadToken(emboss_reserved_local_stream, + &emboss_reserved_local_name)) + return false; + if (emboss_reserved_local_name == ",") + if (!::emboss::support::ReadToken(emboss_reserved_local_stream, + &emboss_reserved_local_name)) + return false; + if (emboss_reserved_local_name == "}") return true; + ::std::string emboss_reserved_local_colon; + if (!::emboss::support::ReadToken(emboss_reserved_local_stream, + &emboss_reserved_local_colon)) + return false; + if (emboss_reserved_local_colon != ":") return false; + if (emboss_reserved_local_name == "divisor") { + if (!divisor().UpdateFromTextStream(emboss_reserved_local_stream)) { + return false; + } + continue; + } + + return false; + } + } + + template + void WriteToTextStream( + Stream* emboss_reserved_local_stream, + ::emboss::TextOutputOptions emboss_reserved_local_options) const { + ::emboss::TextOutputOptions emboss_reserved_local_field_options = + emboss_reserved_local_options.PlusOneIndent(); + if (emboss_reserved_local_options.multiline()) { + emboss_reserved_local_stream->Write("{\n"); + } else { + emboss_reserved_local_stream->Write("{"); + } + bool emboss_reserved_local_wrote_field = false; + if (has_divisor().ValueOr(false)) { + if (!emboss_reserved_local_field_options.allow_partial_output() || + divisor().IsAggregate() || divisor().Ok()) { + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_field_options.current_indent()); + } else { + if (emboss_reserved_local_wrote_field) { + emboss_reserved_local_stream->Write(","); + } + emboss_reserved_local_stream->Write(" "); + } + emboss_reserved_local_stream->Write("divisor: "); + divisor().WriteToTextStream(emboss_reserved_local_stream, + emboss_reserved_local_field_options); + emboss_reserved_local_wrote_field = true; + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write("\n"); + } + } else if (emboss_reserved_local_field_options.allow_partial_output() && + emboss_reserved_local_field_options.comments() && + !divisor().IsAggregate() && !divisor().Ok()) { + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_field_options.current_indent()); + } + emboss_reserved_local_stream->Write("# divisor: UNREADABLE\n"); + } + } + + if (has_zero_or_undefined().ValueOr(false) && + emboss_reserved_local_field_options.comments()) { + if (!emboss_reserved_local_field_options.allow_partial_output() || + zero_or_undefined().IsAggregate() || zero_or_undefined().Ok()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_field_options.current_indent()); + emboss_reserved_local_stream->Write("# zero_or_undefined: "); + zero_or_undefined().WriteToTextStream( + emboss_reserved_local_stream, emboss_reserved_local_field_options); + emboss_reserved_local_stream->Write("\n"); + } else { + if (emboss_reserved_local_field_options.multiline()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_field_options.current_indent()); + } + emboss_reserved_local_stream->Write( + "# zero_or_undefined: UNREADABLE\n"); + } + } + + (void)emboss_reserved_local_wrote_field; + if (emboss_reserved_local_options.multiline()) { + emboss_reserved_local_stream->Write( + emboss_reserved_local_options.current_indent()); + emboss_reserved_local_stream->Write("}"); + } else { + emboss_reserved_local_stream->Write(" }"); + } + } + + static constexpr bool IsAggregate() { return true; } + + public: + typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + + divisor() const; + ::emboss::support::Maybe has_divisor() const; + + public: + class EmbossReservedVirtualZeroOrUndefinedView final { + public: + using ValueType = ::std::int32_t; + + explicit EmbossReservedVirtualZeroOrUndefinedView( + const GenericCollapsingQuotientView& emboss_reserved_local_view) + : view_(emboss_reserved_local_view) {} + EmbossReservedVirtualZeroOrUndefinedView() = delete; + EmbossReservedVirtualZeroOrUndefinedView( + const EmbossReservedVirtualZeroOrUndefinedView&) = default; + EmbossReservedVirtualZeroOrUndefinedView( + EmbossReservedVirtualZeroOrUndefinedView&&) = default; + EmbossReservedVirtualZeroOrUndefinedView& operator=( + const EmbossReservedVirtualZeroOrUndefinedView&) = default; + EmbossReservedVirtualZeroOrUndefinedView& operator=( + EmbossReservedVirtualZeroOrUndefinedView&&) = default; + ~EmbossReservedVirtualZeroOrUndefinedView() = default; + + ::std::int32_t Read() const { + EMBOSS_CHECK(view_.has_zero_or_undefined().ValueOr(false)); + auto emboss_reserved_local_value = MaybeRead(); + EMBOSS_CHECK(emboss_reserved_local_value.Known()); + EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault())); + return emboss_reserved_local_value.ValueOrDefault(); + } + ::std::int32_t UncheckedRead() const { + return MaybeRead().ValueOrDefault(); + } + bool Ok() const { + auto emboss_reserved_local_value = MaybeRead(); + return emboss_reserved_local_value.Known() && + ValueIsOk(emboss_reserved_local_value.ValueOrDefault()); + } + template + void WriteToTextStream(Stream* emboss_reserved_local_stream, + const ::emboss::TextOutputOptions& + emboss_reserved_local_options) const { + ::emboss::support::WriteIntegerViewToTextStream( + this, emboss_reserved_local_stream, emboss_reserved_local_options); + } + + static constexpr bool IsAggregate() { return false; } + + private: + ::emboss::support::Maybe MaybeRead() const { + const auto emboss_reserved_local_subexpr_1 = view_.divisor(); + const auto emboss_reserved_local_subexpr_2 = + (emboss_reserved_local_subexpr_1.Ok() + ? ::emboss::support::Maybe( + static_cast( + emboss_reserved_local_subexpr_1.UncheckedRead())) + : ::emboss::support::Maybe()); + const auto emboss_reserved_local_subexpr_3 = + ::emboss::support::FlooringQuotient( + ::emboss::support::Maybe( + static_cast(0LL)), + emboss_reserved_local_subexpr_2); + + return emboss_reserved_local_subexpr_3; + } + + static constexpr bool ValueIsOk( + ::std::int32_t emboss_reserved_local_value) { + return (void)emboss_reserved_local_value, // Silence -Wunused-parameter + ::emboss::support::Maybe(true).ValueOr(false); + } + + const GenericCollapsingQuotientView view_; + }; + EmbossReservedVirtualZeroOrUndefinedView zero_or_undefined() const; + ::emboss::support::Maybe has_zero_or_undefined() const; + + public: + class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final { + public: + using ValueType = ::std::int32_t; + + constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView() {} + EmbossReservedDollarVirtualIntrinsicSizeInBytesView( + const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default; + EmbossReservedDollarVirtualIntrinsicSizeInBytesView( + EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default; + EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=( + const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default; + EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=( + EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default; + ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default; + + static constexpr ::std::int32_t Read(); + static constexpr ::std::int32_t UncheckedRead(); + static constexpr bool Ok() { return true; } + template + void WriteToTextStream(Stream* emboss_reserved_local_stream, + const ::emboss::TextOutputOptions& + emboss_reserved_local_options) const { + ::emboss::support::WriteIntegerViewToTextStream( + this, emboss_reserved_local_stream, emboss_reserved_local_options); + } + + static constexpr bool IsAggregate() { return false; } + }; + + static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView + IntrinsicSizeInBytes() { + return EmbossReservedDollarVirtualIntrinsicSizeInBytesView(); + } + static constexpr ::emboss::support::Maybe has_IntrinsicSizeInBytes() { + return ::emboss::support::Maybe(true); + } + + public: + class EmbossReservedDollarVirtualMaxSizeInBytesView final { + public: + using ValueType = ::std::int32_t; + + constexpr EmbossReservedDollarVirtualMaxSizeInBytesView() {} + EmbossReservedDollarVirtualMaxSizeInBytesView( + const EmbossReservedDollarVirtualMaxSizeInBytesView&) = default; + EmbossReservedDollarVirtualMaxSizeInBytesView( + EmbossReservedDollarVirtualMaxSizeInBytesView&&) = default; + EmbossReservedDollarVirtualMaxSizeInBytesView& operator=( + const EmbossReservedDollarVirtualMaxSizeInBytesView&) = default; + EmbossReservedDollarVirtualMaxSizeInBytesView& operator=( + EmbossReservedDollarVirtualMaxSizeInBytesView&&) = default; + ~EmbossReservedDollarVirtualMaxSizeInBytesView() = default; + + static constexpr ::std::int32_t Read(); + static constexpr ::std::int32_t UncheckedRead(); + static constexpr bool Ok() { return true; } + template + void WriteToTextStream(Stream* emboss_reserved_local_stream, + const ::emboss::TextOutputOptions& + emboss_reserved_local_options) const { + ::emboss::support::WriteIntegerViewToTextStream( + this, emboss_reserved_local_stream, emboss_reserved_local_options); + } + + static constexpr bool IsAggregate() { return false; } + }; + + static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView + MaxSizeInBytes() { + return EmbossReservedDollarVirtualMaxSizeInBytesView(); + } + static constexpr ::emboss::support::Maybe has_MaxSizeInBytes() { + return ::emboss::support::Maybe(true); + } + + public: + class EmbossReservedDollarVirtualMinSizeInBytesView final { + public: + using ValueType = ::std::int32_t; + + constexpr EmbossReservedDollarVirtualMinSizeInBytesView() {} + EmbossReservedDollarVirtualMinSizeInBytesView( + const EmbossReservedDollarVirtualMinSizeInBytesView&) = default; + EmbossReservedDollarVirtualMinSizeInBytesView( + EmbossReservedDollarVirtualMinSizeInBytesView&&) = default; + EmbossReservedDollarVirtualMinSizeInBytesView& operator=( + const EmbossReservedDollarVirtualMinSizeInBytesView&) = default; + EmbossReservedDollarVirtualMinSizeInBytesView& operator=( + EmbossReservedDollarVirtualMinSizeInBytesView&&) = default; + ~EmbossReservedDollarVirtualMinSizeInBytesView() = default; + + static constexpr ::std::int32_t Read(); + static constexpr ::std::int32_t UncheckedRead(); + static constexpr bool Ok() { return true; } + template + void WriteToTextStream(Stream* emboss_reserved_local_stream, + const ::emboss::TextOutputOptions& + emboss_reserved_local_options) const { + ::emboss::support::WriteIntegerViewToTextStream( + this, emboss_reserved_local_stream, emboss_reserved_local_options); + } + + static constexpr bool IsAggregate() { return false; } + }; + + static constexpr EmbossReservedDollarVirtualMinSizeInBytesView + MinSizeInBytes() { + return EmbossReservedDollarVirtualMinSizeInBytesView(); + } + static constexpr ::emboss::support::Maybe has_MinSizeInBytes() { + return ::emboss::support::Maybe(true); + } + + private: + Storage backing_; + + template + friend class GenericCollapsingQuotientView; +}; +using CollapsingQuotientView = GenericCollapsingQuotientView< + /**/ ::emboss::support::ReadOnlyContiguousBuffer>; +using CollapsingQuotientWriter = GenericCollapsingQuotientView< + /**/ ::emboss::support::ReadWriteContiguousBuffer>; + +template +struct EmbossReservedInternalIsGenericCollapsingQuotientView { + static constexpr const bool value = false; +}; + +template +struct EmbossReservedInternalIsGenericCollapsingQuotientView< + GenericCollapsingQuotientView> { + static constexpr const bool value = true; +}; + +template +inline GenericCollapsingQuotientView< + /**/ ::emboss::support::ContiguousBuffer< + typename ::std::remove_reference< + decltype(*::std::declval()->data())>::type, + 1, 0>> +MakeCollapsingQuotientView(T&& emboss_reserved_local_arg) { + return GenericCollapsingQuotientView< + /**/ ::emboss::support::ContiguousBuffer< + typename ::std::remove_reference< + decltype(*::std::declval()->data())>::type, + 1, 0>>(::std::forward(emboss_reserved_local_arg)); +} + +template +inline GenericCollapsingQuotientView< + /**/ ::emboss::support::ContiguousBuffer> +MakeCollapsingQuotientView(T* emboss_reserved_local_data, + ::std::size_t emboss_reserved_local_size) { + return GenericCollapsingQuotientView< + /**/ ::emboss::support::ContiguousBuffer>( + emboss_reserved_local_data, emboss_reserved_local_size); +} + +template +inline GenericCollapsingQuotientView< + /**/ ::emboss::support::ContiguousBuffer> +MakeAlignedCollapsingQuotientView(T* emboss_reserved_local_data, + ::std::size_t emboss_reserved_local_size) { + return GenericCollapsingQuotientView< + /**/ ::emboss::support::ContiguousBuffer>( + emboss_reserved_local_data, emboss_reserved_local_size); +} + +namespace ArrayOfUint16BySizeInBytes {} // namespace ArrayOfUint16BySizeInBytes + +template +inline typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + +GenericArrayOfUint16BySizeInBytesView::size_in_bytes() const { + if (has_size_in_bytes().ValueOr(false)) { + auto emboss_reserved_local_size = + ::emboss::support::Maybe( + static_cast(1LL)); + auto emboss_reserved_local_offset = + ::emboss::support::Maybe( + static_cast(0LL)); + if (emboss_reserved_local_size.Known() && + emboss_reserved_local_size.ValueOr(0) >= 0 && + emboss_reserved_local_offset.Known() && + emboss_reserved_local_offset.ValueOr(0) >= 0) { + return ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + + (backing_.template GetOffsetStorage<0, 0>( + emboss_reserved_local_offset.ValueOrDefault(), + emboss_reserved_local_size.ValueOrDefault())); + } + } + return ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + + (); +} + +template +inline ::emboss::support::Maybe +GenericArrayOfUint16BySizeInBytesView::has_size_in_bytes() const { + return ::emboss::support::Maybe(true); +} + +template +inline typename ::emboss::support::GenericArrayView< + typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 16, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType< + /**/ 0, 1>::template OffsetStorageType>, + 16>> + + , + typename Storage::template OffsetStorageType, 2, 8> + +GenericArrayOfUint16BySizeInBytesView::elements() const { + if (has_elements().ValueOr(false)) { + const auto emboss_reserved_local_subexpr_1 = size_in_bytes(); + const auto emboss_reserved_local_subexpr_2 = + (emboss_reserved_local_subexpr_1.Ok() + ? ::emboss::support::Maybe( + static_cast( + emboss_reserved_local_subexpr_1.UncheckedRead())) + : ::emboss::support::Maybe()); + const auto emboss_reserved_local_subexpr_3 = + ::emboss::support::FlooringQuotient( + emboss_reserved_local_subexpr_2, + ::emboss::support::Maybe( + static_cast(2LL))); + const auto emboss_reserved_local_subexpr_4 = + ::emboss::support::Product( + emboss_reserved_local_subexpr_3, + ::emboss::support::Maybe( + static_cast(2LL))); + + auto emboss_reserved_local_size = emboss_reserved_local_subexpr_4; + auto emboss_reserved_local_offset = + ::emboss::support::Maybe( + static_cast(1LL)); + if (emboss_reserved_local_size.Known() && + emboss_reserved_local_size.ValueOr(0) >= 0 && + emboss_reserved_local_offset.Known() && + emboss_reserved_local_offset.ValueOr(0) >= 0) { + return ::emboss::support::GenericArrayView< + typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 16, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType< + /**/ 0, 1>::template OffsetStorageType>, + 16>> + + , + typename Storage::template OffsetStorageType, 2, 8> + + (backing_.template GetOffsetStorage<0, 1>( + emboss_reserved_local_offset.ValueOrDefault(), + emboss_reserved_local_size.ValueOrDefault())); + } + } + return ::emboss::support::GenericArrayView< + typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 16, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType< + /**/ 0, 1>::template OffsetStorageType>, + 16>> + + , + typename Storage::template OffsetStorageType, 2, 8> + + (); +} + +template +inline ::emboss::support::Maybe +GenericArrayOfUint16BySizeInBytesView::has_elements() const { + return ::emboss::support::Maybe(true); +} + +template +inline typename GenericArrayOfUint16BySizeInBytesView< + Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView +GenericArrayOfUint16BySizeInBytesView::IntrinsicSizeInBytes() const { + return typename GenericArrayOfUint16BySizeInBytesView< + Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(*this); +} + +template +inline ::emboss::support::Maybe GenericArrayOfUint16BySizeInBytesView< + Storage>::has_IntrinsicSizeInBytes() const { + return ::emboss::support::Maybe(true); +} + +namespace ArrayOfUint16BySizeInBytes { +inline constexpr ::std::int32_t MaxSizeInBytes() { + return ::emboss::support::Maybe( + static_cast(255LL)) + .ValueOrDefault(); +} +} // namespace ArrayOfUint16BySizeInBytes + +template +inline constexpr ::std::int32_t GenericArrayOfUint16BySizeInBytesView< + Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() { + return ArrayOfUint16BySizeInBytes::MaxSizeInBytes(); +} + +template +inline constexpr ::std::int32_t GenericArrayOfUint16BySizeInBytesView< + Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() { + return ArrayOfUint16BySizeInBytes::MaxSizeInBytes(); +} + +namespace ArrayOfUint16BySizeInBytes { +inline constexpr ::std::int32_t MinSizeInBytes() { + return ::emboss::support::Maybe( + static_cast(1LL)) + .ValueOrDefault(); +} +} // namespace ArrayOfUint16BySizeInBytes + +template +inline constexpr ::std::int32_t GenericArrayOfUint16BySizeInBytesView< + Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() { + return ArrayOfUint16BySizeInBytes::MinSizeInBytes(); +} + +template +inline constexpr ::std::int32_t GenericArrayOfUint16BySizeInBytesView< + Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() { + return ArrayOfUint16BySizeInBytes::MinSizeInBytes(); +} +namespace ChunkedPayload {} // namespace ChunkedPayload + +template +inline typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + +GenericChunkedPayloadView::chunk_count() const { + if (has_chunk_count().ValueOr(false)) { + auto emboss_reserved_local_size = + ::emboss::support::Maybe( + static_cast(1LL)); + auto emboss_reserved_local_offset = + ::emboss::support::Maybe( + static_cast(0LL)); + if (emboss_reserved_local_size.Known() && + emboss_reserved_local_size.ValueOr(0) >= 0 && + emboss_reserved_local_offset.Known() && + emboss_reserved_local_offset.ValueOr(0) >= 0) { + return ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + + (backing_.template GetOffsetStorage<0, 0>( + emboss_reserved_local_offset.ValueOrDefault(), + emboss_reserved_local_size.ValueOrDefault())); + } + } + return ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + + (); +} + +template +inline ::emboss::support::Maybe +GenericChunkedPayloadView::has_chunk_count() const { + return ::emboss::support::Maybe(true); +} + +template +inline typename ::emboss::support::GenericArrayView< + typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType< + /**/ 0, 1>::template OffsetStorageType>, + 8>> + + , + typename Storage::template OffsetStorageType, 1, 8> + +GenericChunkedPayloadView::padded() const { + if (has_padded().ValueOr(false)) { + const auto emboss_reserved_local_subexpr_1 = chunk_count(); + const auto emboss_reserved_local_subexpr_2 = + (emboss_reserved_local_subexpr_1.Ok() + ? ::emboss::support::Maybe( + static_cast( + emboss_reserved_local_subexpr_1.UncheckedRead())) + : ::emboss::support::Maybe()); + const auto emboss_reserved_local_subexpr_3 = + ::emboss::support::Sum( + emboss_reserved_local_subexpr_2, + ::emboss::support::Maybe( + static_cast(3LL))); + const auto emboss_reserved_local_subexpr_4 = + ::emboss::support::FlooringQuotient( + emboss_reserved_local_subexpr_3, + ::emboss::support::Maybe( + static_cast(4LL))); + const auto emboss_reserved_local_subexpr_5 = + ::emboss::support::Product( + emboss_reserved_local_subexpr_4, + ::emboss::support::Maybe( + static_cast(4LL))); + + auto emboss_reserved_local_size = emboss_reserved_local_subexpr_5; + auto emboss_reserved_local_offset = + ::emboss::support::Maybe( + static_cast(1LL)); + if (emboss_reserved_local_size.Known() && + emboss_reserved_local_size.ValueOr(0) >= 0 && + emboss_reserved_local_offset.Known() && + emboss_reserved_local_offset.ValueOr(0) >= 0) { + return ::emboss::support::GenericArrayView< + typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType< + /**/ 0, 1>::template OffsetStorageType>, + 8>> + + , + typename Storage::template OffsetStorageType, 1, 8> + + (backing_.template GetOffsetStorage<0, 1>( + emboss_reserved_local_offset.ValueOrDefault(), + emboss_reserved_local_size.ValueOrDefault())); + } + } + return ::emboss::support::GenericArrayView< + typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType< + /**/ 0, 1>::template OffsetStorageType>, + 8>> + + , + typename Storage::template OffsetStorageType, 1, 8> + + (); +} + +template +inline ::emboss::support::Maybe +GenericChunkedPayloadView::has_padded() const { + return ::emboss::support::Maybe(true); +} + +template +inline typename GenericChunkedPayloadView< + Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView +GenericChunkedPayloadView::IntrinsicSizeInBytes() const { + return typename GenericChunkedPayloadView< + Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(*this); +} + +template +inline ::emboss::support::Maybe +GenericChunkedPayloadView::has_IntrinsicSizeInBytes() const { + return ::emboss::support::Maybe(true); +} + +namespace ChunkedPayload { +inline constexpr ::std::int32_t MaxSizeInBytes() { + return ::emboss::support::Maybe( + static_cast(257LL)) + .ValueOrDefault(); +} +} // namespace ChunkedPayload + +template +inline constexpr ::std::int32_t GenericChunkedPayloadView< + Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() { + return ChunkedPayload::MaxSizeInBytes(); +} + +template +inline constexpr ::std::int32_t GenericChunkedPayloadView< + Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() { + return ChunkedPayload::MaxSizeInBytes(); +} + +namespace ChunkedPayload { +inline constexpr ::std::int32_t MinSizeInBytes() { + return ::emboss::support::Maybe( + static_cast(1LL)) + .ValueOrDefault(); +} +} // namespace ChunkedPayload + +template +inline constexpr ::std::int32_t GenericChunkedPayloadView< + Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() { + return ChunkedPayload::MinSizeInBytes(); +} + +template +inline constexpr ::std::int32_t GenericChunkedPayloadView< + Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() { + return ChunkedPayload::MinSizeInBytes(); +} +namespace Constants {} // namespace Constants + +namespace Constants { +inline constexpr ::std::int32_t exact_quotient() { + return ::emboss::support::Maybe( + static_cast(20LL)) + .ValueOrDefault(); +} +} // namespace Constants + +template +inline constexpr ::std::int32_t +GenericConstantsView::EmbossReservedVirtualExactQuotientView::Read() { + return Constants::exact_quotient(); +} + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedVirtualExactQuotientView::UncheckedRead() { + return Constants::exact_quotient(); +} + +namespace Constants { +inline constexpr ::std::int32_t truncating_quotient() { + return ::emboss::support::Maybe( + static_cast(14LL)) + .ValueOrDefault(); +} +} // namespace Constants + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedVirtualTruncatingQuotientView::Read() { + return Constants::truncating_quotient(); +} + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedVirtualTruncatingQuotientView::UncheckedRead() { + return Constants::truncating_quotient(); +} + +namespace Constants { +inline constexpr ::std::int32_t negative_quotient() { + return ::emboss::support::Maybe( + static_cast(-4LL)) + .ValueOrDefault(); +} +} // namespace Constants + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedVirtualNegativeQuotientView::Read() { + return Constants::negative_quotient(); +} + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedVirtualNegativeQuotientView::UncheckedRead() { + return Constants::negative_quotient(); +} + +namespace Constants { +inline constexpr ::std::int32_t exact_modulus() { + return ::emboss::support::Maybe( + static_cast(0LL)) + .ValueOrDefault(); +} +} // namespace Constants + +template +inline constexpr ::std::int32_t +GenericConstantsView::EmbossReservedVirtualExactModulusView::Read() { + return Constants::exact_modulus(); +} + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedVirtualExactModulusView::UncheckedRead() { + return Constants::exact_modulus(); +} + +namespace Constants { +inline constexpr ::std::int32_t truncating_modulus() { + return ::emboss::support::Maybe( + static_cast(2LL)) + .ValueOrDefault(); +} +} // namespace Constants + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedVirtualTruncatingModulusView::Read() { + return Constants::truncating_modulus(); +} + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedVirtualTruncatingModulusView::UncheckedRead() { + return Constants::truncating_modulus(); +} + +namespace Constants { +inline constexpr ::std::int32_t negative_modulus() { + return ::emboss::support::Maybe( + static_cast(1LL)) + .ValueOrDefault(); +} +} // namespace Constants + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedVirtualNegativeModulusView::Read() { + return Constants::negative_modulus(); +} + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedVirtualNegativeModulusView::UncheckedRead() { + return Constants::negative_modulus(); +} + +namespace Constants { +inline constexpr ::std::int32_t chained_div() { + return ::emboss::support::Maybe( + static_cast(10LL)) + .ValueOrDefault(); +} +} // namespace Constants + +template +inline constexpr ::std::int32_t +GenericConstantsView::EmbossReservedVirtualChainedDivView::Read() { + return Constants::chained_div(); +} + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedVirtualChainedDivView::UncheckedRead() { + return Constants::chained_div(); +} + +namespace Constants { +inline constexpr ::std::int32_t chained_mod() { + return ::emboss::support::Maybe( + static_cast(3LL)) + .ValueOrDefault(); +} +} // namespace Constants + +template +inline constexpr ::std::int32_t +GenericConstantsView::EmbossReservedVirtualChainedModView::Read() { + return Constants::chained_mod(); +} + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedVirtualChainedModView::UncheckedRead() { + return Constants::chained_mod(); +} + +namespace Constants { +inline constexpr ::std::int32_t mixed_divmod() { + return ::emboss::support::Maybe( + static_cast(1LL)) + .ValueOrDefault(); +} +} // namespace Constants + +template +inline constexpr ::std::int32_t +GenericConstantsView::EmbossReservedVirtualMixedDivmodView::Read() { + return Constants::mixed_divmod(); +} + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedVirtualMixedDivmodView::UncheckedRead() { + return Constants::mixed_divmod(); +} + +namespace Constants { +inline constexpr ::std::int32_t IntrinsicSizeInBytes() { + return ::emboss::support::Maybe( + static_cast(0LL)) + .ValueOrDefault(); +} +} // namespace Constants + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() { + return Constants::IntrinsicSizeInBytes(); +} + +template +inline constexpr ::std::int32_t GenericConstantsView:: + EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() { + return Constants::IntrinsicSizeInBytes(); +} + +namespace Constants { +inline constexpr ::std::int32_t MaxSizeInBytes() { + return ::emboss::support::Maybe( + static_cast(0LL)) + .ValueOrDefault(); +} +} // namespace Constants + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() { + return Constants::MaxSizeInBytes(); +} + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() { + return Constants::MaxSizeInBytes(); +} + +namespace Constants { +inline constexpr ::std::int32_t MinSizeInBytes() { + return ::emboss::support::Maybe( + static_cast(0LL)) + .ValueOrDefault(); +} +} // namespace Constants + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() { + return Constants::MinSizeInBytes(); +} + +template +inline constexpr ::std::int32_t GenericConstantsView< + Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() { + return Constants::MinSizeInBytes(); +} +namespace PayloadSizedByDivision {} // namespace PayloadSizedByDivision + +template +inline typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< typename Storage::template OffsetStorageType>, 8>> -GenericChunkedPayloadView::chunk_count() const { - if (has_chunk_count().ValueOr(false)) { +GenericPayloadSizedByDivisionView::divisor() const { + if (has_divisor().ValueOr(false)) { auto emboss_reserved_local_size = ::emboss::support::Maybe( static_cast(1LL)); @@ -2259,7 +4307,7 @@ GenericChunkedPayloadView::chunk_count() const { template inline ::emboss::support::Maybe -GenericChunkedPayloadView::has_chunk_count() const { +GenericPayloadSizedByDivisionView::has_divisor() const { return ::emboss::support::Maybe(true); } @@ -2277,9 +4325,9 @@ inline typename ::emboss::support::GenericArrayView< , typename Storage::template OffsetStorageType, 1, 8> -GenericChunkedPayloadView::padded() const { - if (has_padded().ValueOr(false)) { - const auto emboss_reserved_local_subexpr_1 = chunk_count(); +GenericPayloadSizedByDivisionView::payload() const { + if (has_payload().ValueOr(false)) { + const auto emboss_reserved_local_subexpr_1 = divisor(); const auto emboss_reserved_local_subexpr_2 = (emboss_reserved_local_subexpr_1.Ok() ? ::emboss::support::Maybe( @@ -2287,25 +4335,13 @@ GenericChunkedPayloadView::padded() const { emboss_reserved_local_subexpr_1.UncheckedRead())) : ::emboss::support::Maybe()); const auto emboss_reserved_local_subexpr_3 = - ::emboss::support::Sum( - emboss_reserved_local_subexpr_2, - ::emboss::support::Maybe( - static_cast(3LL))); - const auto emboss_reserved_local_subexpr_4 = ::emboss::support::FlooringQuotient( - emboss_reserved_local_subexpr_3, - ::emboss::support::Maybe( - static_cast(4LL))); - const auto emboss_reserved_local_subexpr_5 = - ::emboss::support::Product( - emboss_reserved_local_subexpr_4, ::emboss::support::Maybe( - static_cast(4LL))); + static_cast(16LL)), + emboss_reserved_local_subexpr_2); - auto emboss_reserved_local_size = emboss_reserved_local_subexpr_5; + auto emboss_reserved_local_size = emboss_reserved_local_subexpr_3; auto emboss_reserved_local_offset = ::emboss::support::Maybe( static_cast(1LL)); @@ -2349,303 +4385,356 @@ GenericChunkedPayloadView::padded() const { template inline ::emboss::support::Maybe -GenericChunkedPayloadView::has_padded() const { - return ::emboss::support::Maybe(true); -} - -template -inline typename GenericChunkedPayloadView< - Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView -GenericChunkedPayloadView::IntrinsicSizeInBytes() const { - return typename GenericChunkedPayloadView< - Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(*this); -} - -template -inline ::emboss::support::Maybe -GenericChunkedPayloadView::has_IntrinsicSizeInBytes() const { +GenericPayloadSizedByDivisionView::has_payload() const { return ::emboss::support::Maybe(true); } -namespace ChunkedPayload { -inline constexpr ::std::int32_t MaxSizeInBytes() { - return ::emboss::support::Maybe( - static_cast(257LL)) - .ValueOrDefault(); -} -} // namespace ChunkedPayload - -template -inline constexpr ::std::int32_t GenericChunkedPayloadView< - Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() { - return ChunkedPayload::MaxSizeInBytes(); -} - -template -inline constexpr ::std::int32_t GenericChunkedPayloadView< - Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() { - return ChunkedPayload::MaxSizeInBytes(); -} - -namespace ChunkedPayload { -inline constexpr ::std::int32_t MinSizeInBytes() { - return ::emboss::support::Maybe( - static_cast(1LL)) - .ValueOrDefault(); -} -} // namespace ChunkedPayload - -template -inline constexpr ::std::int32_t GenericChunkedPayloadView< - Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() { - return ChunkedPayload::MinSizeInBytes(); -} - -template -inline constexpr ::std::int32_t GenericChunkedPayloadView< - Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() { - return ChunkedPayload::MinSizeInBytes(); -} -namespace Constants {} // namespace Constants - -namespace Constants { -inline constexpr ::std::int32_t exact_quotient() { - return ::emboss::support::Maybe( - static_cast(20LL)) - .ValueOrDefault(); -} -} // namespace Constants - -template -inline constexpr ::std::int32_t -GenericConstantsView::EmbossReservedVirtualExactQuotientView::Read() { - return Constants::exact_quotient(); -} - -template -inline constexpr ::std::int32_t GenericConstantsView< - Storage>::EmbossReservedVirtualExactQuotientView::UncheckedRead() { - return Constants::exact_quotient(); -} - -namespace Constants { -inline constexpr ::std::int32_t truncating_quotient() { - return ::emboss::support::Maybe( - static_cast(14LL)) - .ValueOrDefault(); -} -} // namespace Constants - template -inline constexpr ::std::int32_t GenericConstantsView< - Storage>::EmbossReservedVirtualTruncatingQuotientView::Read() { - return Constants::truncating_quotient(); +inline typename GenericPayloadSizedByDivisionView< + Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView +GenericPayloadSizedByDivisionView::IntrinsicSizeInBytes() const { + return typename GenericPayloadSizedByDivisionView< + Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(*this); } template -inline constexpr ::std::int32_t GenericConstantsView< - Storage>::EmbossReservedVirtualTruncatingQuotientView::UncheckedRead() { - return Constants::truncating_quotient(); +inline ::emboss::support::Maybe +GenericPayloadSizedByDivisionView::has_IntrinsicSizeInBytes() const { + return ::emboss::support::Maybe(true); } -namespace Constants { -inline constexpr ::std::int32_t negative_quotient() { +namespace PayloadSizedByDivision { +inline constexpr ::std::int32_t MaxSizeInBytes() { return ::emboss::support::Maybe( - static_cast(-4LL)) + static_cast(17LL)) .ValueOrDefault(); } -} // namespace Constants +} // namespace PayloadSizedByDivision template -inline constexpr ::std::int32_t GenericConstantsView< - Storage>::EmbossReservedVirtualNegativeQuotientView::Read() { - return Constants::negative_quotient(); +inline constexpr ::std::int32_t GenericPayloadSizedByDivisionView< + Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() { + return PayloadSizedByDivision::MaxSizeInBytes(); } template -inline constexpr ::std::int32_t GenericConstantsView< - Storage>::EmbossReservedVirtualNegativeQuotientView::UncheckedRead() { - return Constants::negative_quotient(); +inline constexpr ::std::int32_t GenericPayloadSizedByDivisionView< + Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() { + return PayloadSizedByDivision::MaxSizeInBytes(); } -namespace Constants { -inline constexpr ::std::int32_t exact_modulus() { +namespace PayloadSizedByDivision { +inline constexpr ::std::int32_t MinSizeInBytes() { return ::emboss::support::Maybe( - static_cast(0LL)) + static_cast(1LL)) .ValueOrDefault(); } -} // namespace Constants +} // namespace PayloadSizedByDivision template -inline constexpr ::std::int32_t -GenericConstantsView::EmbossReservedVirtualExactModulusView::Read() { - return Constants::exact_modulus(); +inline constexpr ::std::int32_t GenericPayloadSizedByDivisionView< + Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() { + return PayloadSizedByDivision::MinSizeInBytes(); } template -inline constexpr ::std::int32_t GenericConstantsView< - Storage>::EmbossReservedVirtualExactModulusView::UncheckedRead() { - return Constants::exact_modulus(); +inline constexpr ::std::int32_t GenericPayloadSizedByDivisionView< + Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() { + return PayloadSizedByDivision::MinSizeInBytes(); } +namespace FieldGatedByDivision {} // namespace FieldGatedByDivision -namespace Constants { -inline constexpr ::std::int32_t truncating_modulus() { - return ::emboss::support::Maybe( - static_cast(2LL)) - .ValueOrDefault(); +template +inline typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + +GenericFieldGatedByDivisionView::divisor() const { + if (has_divisor().ValueOr(false)) { + auto emboss_reserved_local_size = + ::emboss::support::Maybe( + static_cast(1LL)); + auto emboss_reserved_local_offset = + ::emboss::support::Maybe( + static_cast(0LL)); + if (emboss_reserved_local_size.Known() && + emboss_reserved_local_size.ValueOr(0) >= 0 && + emboss_reserved_local_offset.Known() && + emboss_reserved_local_offset.ValueOr(0) >= 0) { + return ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + + (backing_.template GetOffsetStorage<0, 0>( + emboss_reserved_local_offset.ValueOrDefault(), + emboss_reserved_local_size.ValueOrDefault())); + } + } + return ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + + (); } -} // namespace Constants template -inline constexpr ::std::int32_t GenericConstantsView< - Storage>::EmbossReservedVirtualTruncatingModulusView::Read() { - return Constants::truncating_modulus(); +inline ::emboss::support::Maybe +GenericFieldGatedByDivisionView::has_divisor() const { + return ::emboss::support::Maybe(true); } template -inline constexpr ::std::int32_t GenericConstantsView< - Storage>::EmbossReservedVirtualTruncatingModulusView::UncheckedRead() { - return Constants::truncating_modulus(); +inline typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + +GenericFieldGatedByDivisionView::gated() const { + if (has_gated().ValueOr(false)) { + auto emboss_reserved_local_size = + ::emboss::support::Maybe( + static_cast(1LL)); + auto emboss_reserved_local_offset = + ::emboss::support::Maybe( + static_cast(1LL)); + if (emboss_reserved_local_size.Known() && + emboss_reserved_local_size.ValueOr(0) >= 0 && + emboss_reserved_local_offset.Known() && + emboss_reserved_local_offset.ValueOr(0) >= 0) { + return ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + + (backing_.template GetOffsetStorage<0, 1>( + emboss_reserved_local_offset.ValueOrDefault(), + emboss_reserved_local_size.ValueOrDefault())); + } + } + return ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + + (); } -namespace Constants { -inline constexpr ::std::int32_t negative_modulus() { - return ::emboss::support::Maybe( - static_cast(1LL)) - .ValueOrDefault(); +template +inline ::emboss::support::Maybe +GenericFieldGatedByDivisionView::has_gated() const { + return ::emboss::support::Equal( + ::emboss::support::FlooringQuotient( + ::emboss::support::Maybe( + static_cast(12LL)), + (divisor().Ok() ? ::emboss::support::Maybe( + static_cast( + divisor().UncheckedRead())) + : ::emboss::support::Maybe())), + ::emboss::support::Maybe( + static_cast(3LL))); } -} // namespace Constants template -inline constexpr ::std::int32_t GenericConstantsView< - Storage>::EmbossReservedVirtualNegativeModulusView::Read() { - return Constants::negative_modulus(); +inline typename GenericFieldGatedByDivisionView< + Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView +GenericFieldGatedByDivisionView::IntrinsicSizeInBytes() const { + return typename GenericFieldGatedByDivisionView< + Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(*this); } template -inline constexpr ::std::int32_t GenericConstantsView< - Storage>::EmbossReservedVirtualNegativeModulusView::UncheckedRead() { - return Constants::negative_modulus(); +inline ::emboss::support::Maybe +GenericFieldGatedByDivisionView::has_IntrinsicSizeInBytes() const { + return ::emboss::support::Maybe(true); } -namespace Constants { -inline constexpr ::std::int32_t chained_div() { +namespace FieldGatedByDivision { +inline constexpr ::std::int32_t MaxSizeInBytes() { return ::emboss::support::Maybe( - static_cast(10LL)) + static_cast(2LL)) .ValueOrDefault(); } -} // namespace Constants +} // namespace FieldGatedByDivision template -inline constexpr ::std::int32_t -GenericConstantsView::EmbossReservedVirtualChainedDivView::Read() { - return Constants::chained_div(); +inline constexpr ::std::int32_t GenericFieldGatedByDivisionView< + Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() { + return FieldGatedByDivision::MaxSizeInBytes(); } template -inline constexpr ::std::int32_t GenericConstantsView< - Storage>::EmbossReservedVirtualChainedDivView::UncheckedRead() { - return Constants::chained_div(); +inline constexpr ::std::int32_t GenericFieldGatedByDivisionView< + Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() { + return FieldGatedByDivision::MaxSizeInBytes(); } -namespace Constants { -inline constexpr ::std::int32_t chained_mod() { +namespace FieldGatedByDivision { +inline constexpr ::std::int32_t MinSizeInBytes() { return ::emboss::support::Maybe( - static_cast(3LL)) + static_cast(1LL)) .ValueOrDefault(); } -} // namespace Constants +} // namespace FieldGatedByDivision template -inline constexpr ::std::int32_t -GenericConstantsView::EmbossReservedVirtualChainedModView::Read() { - return Constants::chained_mod(); +inline constexpr ::std::int32_t GenericFieldGatedByDivisionView< + Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() { + return FieldGatedByDivision::MinSizeInBytes(); } template -inline constexpr ::std::int32_t GenericConstantsView< - Storage>::EmbossReservedVirtualChainedModView::UncheckedRead() { - return Constants::chained_mod(); +inline constexpr ::std::int32_t GenericFieldGatedByDivisionView< + Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() { + return FieldGatedByDivision::MinSizeInBytes(); } +namespace CollapsingQuotient {} // namespace CollapsingQuotient -namespace Constants { -inline constexpr ::std::int32_t mixed_divmod() { - return ::emboss::support::Maybe( - static_cast(1LL)) - .ValueOrDefault(); +template +inline typename ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + +GenericCollapsingQuotientView::divisor() const { + if (has_divisor().ValueOr(false)) { + auto emboss_reserved_local_size = + ::emboss::support::Maybe( + static_cast(1LL)); + auto emboss_reserved_local_offset = + ::emboss::support::Maybe( + static_cast(0LL)); + if (emboss_reserved_local_size.Known() && + emboss_reserved_local_size.ValueOr(0) >= 0 && + emboss_reserved_local_offset.Known() && + emboss_reserved_local_offset.ValueOr(0) >= 0) { + return ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + + (backing_.template GetOffsetStorage<0, 0>( + emboss_reserved_local_offset.ValueOrDefault(), + emboss_reserved_local_size.ValueOrDefault())); + } + } + return ::emboss::prelude::UIntView< + /**/ ::emboss::support::FixedSizeViewParameters< + 8, ::emboss::support::AllValuesAreOk>, + typename ::emboss::support::BitBlock< + /**/ ::emboss::support::LittleEndianByteOrderer< + typename Storage::template OffsetStorageType>, + 8>> + + (); } -} // namespace Constants template -inline constexpr ::std::int32_t -GenericConstantsView::EmbossReservedVirtualMixedDivmodView::Read() { - return Constants::mixed_divmod(); +inline ::emboss::support::Maybe +GenericCollapsingQuotientView::has_divisor() const { + return ::emboss::support::Maybe(true); } template -inline constexpr ::std::int32_t GenericConstantsView< - Storage>::EmbossReservedVirtualMixedDivmodView::UncheckedRead() { - return Constants::mixed_divmod(); +inline typename GenericCollapsingQuotientView< + Storage>::EmbossReservedVirtualZeroOrUndefinedView +GenericCollapsingQuotientView::zero_or_undefined() const { + return typename GenericCollapsingQuotientView< + Storage>::EmbossReservedVirtualZeroOrUndefinedView(*this); } -namespace Constants { +template +inline ::emboss::support::Maybe +GenericCollapsingQuotientView::has_zero_or_undefined() const { + return ::emboss::support::Maybe(true); +} + +namespace CollapsingQuotient { inline constexpr ::std::int32_t IntrinsicSizeInBytes() { return ::emboss::support::Maybe( - static_cast(0LL)) + static_cast(1LL)) .ValueOrDefault(); } -} // namespace Constants +} // namespace CollapsingQuotient template -inline constexpr ::std::int32_t GenericConstantsView< +inline constexpr ::std::int32_t GenericCollapsingQuotientView< Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() { - return Constants::IntrinsicSizeInBytes(); + return CollapsingQuotient::IntrinsicSizeInBytes(); } template -inline constexpr ::std::int32_t GenericConstantsView:: +inline constexpr ::std::int32_t GenericCollapsingQuotientView:: EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() { - return Constants::IntrinsicSizeInBytes(); + return CollapsingQuotient::IntrinsicSizeInBytes(); } -namespace Constants { +namespace CollapsingQuotient { inline constexpr ::std::int32_t MaxSizeInBytes() { return ::emboss::support::Maybe( - static_cast(0LL)) + static_cast(1LL)) .ValueOrDefault(); } -} // namespace Constants +} // namespace CollapsingQuotient template -inline constexpr ::std::int32_t GenericConstantsView< +inline constexpr ::std::int32_t GenericCollapsingQuotientView< Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() { - return Constants::MaxSizeInBytes(); + return CollapsingQuotient::MaxSizeInBytes(); } template -inline constexpr ::std::int32_t GenericConstantsView< +inline constexpr ::std::int32_t GenericCollapsingQuotientView< Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() { - return Constants::MaxSizeInBytes(); + return CollapsingQuotient::MaxSizeInBytes(); } -namespace Constants { +namespace CollapsingQuotient { inline constexpr ::std::int32_t MinSizeInBytes() { return ::emboss::support::Maybe( - static_cast(0LL)) + static_cast(1LL)) .ValueOrDefault(); } -} // namespace Constants +} // namespace CollapsingQuotient template -inline constexpr ::std::int32_t GenericConstantsView< +inline constexpr ::std::int32_t GenericCollapsingQuotientView< Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() { - return Constants::MinSizeInBytes(); + return CollapsingQuotient::MinSizeInBytes(); } template -inline constexpr ::std::int32_t GenericConstantsView< +inline constexpr ::std::int32_t GenericCollapsingQuotientView< Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() { - return Constants::MinSizeInBytes(); + return CollapsingQuotient::MinSizeInBytes(); } } // namespace test