1# Emboss C++ Generated Code Reference 2 3## `struct`s 4 5A `struct` will have a corresponding view class, and functions to create views. 6 7### <code>Make*Struct*View</code> free function 8 9```c++ 10template <typename T> 11auto MakeStructView(/* view parameters, */ T *data, size_t size); 12``` 13 14```c++ 15template <typename T> 16auto MakeStructView(/* view parameters, */ T *container); 17``` 18 19*`Struct`* will be replaced by the name of the specific `struct` whose view 20will be constructed; for example, to make a view for `struct Message`, call the 21`MakeMessageView` function. 22 23*View parameters* will be replaced by one argument for each parameter attached 24to the `struct`. E.g., for: 25 26``` 27struct Foo(x: UInt:8): 28 -- 29``` 30 31`MakeFooView` will be: 32 33```c++ 34template <typename T> 35auto MakeFooView(std::uint8_t x, T *data, size_t size); 36``` 37 38```c++ 39template <typename T> 40auto MakeFooView(std::uint8_t x, T *container); 41``` 42 43And for: 44 45``` 46struct Bar(x: UInt:8, y: Int:32): 47 -- 48``` 49 50`MakeBarView` will be: 51 52```c++ 53template <typename T> 54auto MakeBarView(std::uint8_t x, std::int32_t y, T *data, size_t size); 55``` 56 57```c++ 58template <typename T> 59auto MakeBarView(std::uint8_t x, std::int32_t y, T *container); 60``` 61 62The <code>Make*Struct*View</code> functions construct a view for *`Struct`* 63over the given bytes. For the data/size form, the type `T` must be a character 64type: `char`, `const char`, `unsigned char`, `const unsigned char`, `signed 65char`, or `const signed char`. For the container form, the container can be a 66`std::vector`, `std::array`, or `std::basic_string` of a character type, or any 67other type with a `data()` method that returns a possibly-`const` `char *`, 68`signed char *`, or `unsigned char *`, and a `size()` method that returns a size 69in bytes. Google's `absl::string_view` is one example of such a type. 70 71If given a pointer to a `const` character type or a `const` reference to a 72container, <code>Make*Struct*View</code> will return a read-only view; otherwise 73it will return a read-write view. 74 75The result of <code>Make*Struct*View</code> should be stored in an `auto` 76variable: 77 78```c++ 79auto view = MakeFooView(byte_buffer, available_byte_count); 80``` 81 82The specific type returned by <code>Make*Struct*View</code> is subject to 83change. 84 85 86### `CopyFrom` method 87 88```c++ 89template <typename OtherStorage> 90void CopyFrom(GenericStructView<OtherStorage> other) const; 91``` 92 93The `CopyFrom` method copies data from the view `other` into the current view. 94When complete, the current view's backing storage will contain the same bytes 95as `other`. This works even if the view's backing storage overlaps, in which 96case `other`'s backing storage is modified by the operation. 97 98### `UncheckedCopyFrom` method 99 100```c++ 101template <typename OtherStorage> 102void UncheckedCopyFrom(GenericStructView<OtherStorage> other) const; 103``` 104 105The `UncheckedCopyFrom` method performs the same operation as `CopyFrom` but 106without any checks on the integrity of or the compatibility of the two views. 107 108### `TryToCopyFrom` method 109 110```c++ 111template <typename OtherStorage> 112bool TryToCopyFrom(GenericStructView<OtherStorage> other) const; 113``` 114 115`TryToCopyFrom` copies data from `other` into the current view, if `other` is 116`Ok()` and the current backing storage is large enough to hold `other`'s data. 117 118### `Equals` method 119 120```c++ 121template <typename OtherStorage> 122bool Equals(GenericStructView<OtherStorage> other); 123``` 124 125The `Equals` method returns `true` if and only if itself and `other` contain the 126same fields yielding equivalent values (as measured by the `==` operator). 127`Equals()` should only be called if `Ok()` is true on both views. 128 129### `UncheckedEquals` method 130 131```c++ 132template <typename OtherStorage> 133bool UncheckedEquals(GenericStructView<OtherStorage> other); 134``` 135 136The `UncheckedEquals` method performs the same operation as `Equals`, but 137without any checks on the integrity of or the compatibility of the two views 138when reading values. `UncheckedEquals()` should only be called if `Ok()` is 139true on both views. 140 141### `Ok` method 142 143```c++ 144bool Ok() const; 145``` 146 147The `Ok` method returns `true` if and only if there are enough bytes in the 148backing store, and the `Ok` methods of all active fields return `true`. 149 150 151### `IsComplete` method 152 153```c++ 154bool IsComplete() const; 155``` 156 157The `IsComplete` method returns `true` if there are enough bytes in the backing 158store to fully contain the `struct`. If `IsComplete()` returns `true` but 159`Ok()` returns `false`, then the structure is broken in some way that cannot be 160fixed by adding more bytes. 161 162 163### `IntrinsicSizeInBytes` method 164 165```c++ 166auto IntrinsicSizeInBytes() const; 167``` 168 169or 170 171```c++ 172static constexpr auto IntrinsicSizeInBytes() const; 173``` 174 175The `IntrinsicSizeInBytes` method is the [field method](#struct-field-methods) 176for [`$size_in_bytes`](language-reference.md#size-in-bytes). The `Read` method 177of the result returns the size of the `struct`, and the `Ok` method returns 178`true` if the `struct`'s intrinsic size is known; i.e.: 179 180```c++ 181if (view.IntrinsicSizeInBytes().Ok()) { 182 // The exact return type of view.IntrinsicSizeInBytes().Read() may vary, but 183 // it will always be implicitly convertible to std::uint64_t. 184 std::uint64_t view_size = view.IntrinsicSizeInBytes().Read(); 185} 186``` 187 188Alternately, if you are sure the size is known: 189 190```c++ 191std::uint64_t view_size = view.IntrinsicSizeInBytes().UncheckedRead(); 192``` 193 194Or, if the size is a compile-time constant: 195 196```c++ 197constexpr std::uint64_t view_size = StructView::IntrinsicSizeInBytes().Read(); 198constexpr std::uint64_t view_size2 = Struct::IntrinsicSizeInBytes(); 199``` 200 201 202### `MaxSizeInBytes` method 203 204```c++ 205auto MaxSizeInBytes() const; 206``` 207 208or 209 210```c++ 211static constexpr auto MaxSizeInBytes() const; 212``` 213 214The `MaxSizeInBytes` method is the [field method](#struct-field-methods) 215for [`$max_size_in_bytes`](language-reference.md#max-size-in-bytes). The `Read` 216method of the result returns the maximum size of the `struct`, and the `Ok` 217always method returns `true`. 218 219```c++ 220assert(view.MaxSizeInBytes().Ok()); 221// The exact return type of view.MaxSizeInBytes().Read() may vary, but it will 222// always be implicitly convertible to std::uint64_t. 223std::uint64_t view_size = view.MaxSizeInBytes().Read(); 224``` 225 226Alternately: 227 228```c++ 229std::uint64_t view_size = view.MaxSizeInBytes().UncheckedRead(); 230``` 231 232Or: 233 234```c++ 235constexpr std::uint64_t view_size = StructView::MaxSizeInBytes().Read(); 236constexpr std::uint64_t view_size2 = Struct::MaxSizeInBytes(); 237``` 238 239 240### `MinSizeInBytes` method 241 242```c++ 243auto MinSizeInBytes() const; 244``` 245 246or 247 248```c++ 249static constexpr auto MinSizeInBytes() const; 250``` 251 252The `MinSizeInBytes` method is the [field method](#struct-field-methods) 253for [`$min_size_in_bytes`](language-reference.md#max-size-in-bytes). The `Read` 254method of the result returns the minimum size of the `struct`, and the `Ok` 255always method returns `true`. 256 257```c++ 258assert(view.MinSizeInBytes().Ok()); 259// The exact return type of view.MinSizeInBytes().Read() may vary, but it will 260// always be implicitly convertible to std::uint64_t. 261std::uint64_t view_size = view.MinSizeInBytes().Read(); 262``` 263 264Alternately: 265 266```c++ 267std::uint64_t view_size = view.MinSizeInBytes().UncheckedRead(); 268``` 269 270Or: 271 272```c++ 273constexpr std::uint64_t view_size = StructView::MinSizeInBytes().Read(); 274constexpr std::uint64_t view_size2 = Struct::MinSizeInBytes(); 275``` 276 277 278### `SizeIsKnown` method 279 280```c++ 281bool SizeIsKnown() const; 282``` 283 284or 285 286```c++ 287static constexpr bool SizeIsKnown() const; 288``` 289 290The `SizeIsKnown` method is an alias of `IntrinsicSizeInBytes().Ok()`. 291 292The `SizeIsKnown` method returns `true` if the size of the `struct` can be 293determined from the bytes that are available. For example, consider a `struct` 294like: 295 296``` 297struct Message: 298 0 [+4] UInt payload_length (pl) 299 4 [+pl] UInt:8[pl] payload 300``` 301 302The `Message`'s view's `SizeIsKnown` method will return `true` if at least four 303bytes are available in the backing store, because it can determine the actual 304size of the message if at least four bytes can be read. If the backing store 305contains three or fewer bytes, then `SizeIsKnown` will be false. 306 307Note that if the `struct` contains no dynamically-sized or dynamically-located 308fields, then `SizeIsKnown` will be a `static constexpr` method that always 309return `true`. 310 311 312### `SizeInBytes` method 313 314```c++ 315std::size_t SizeInBytes() const; 316``` 317 318or 319 320```c++ 321static constexpr std::size_t SizeInBytes() const; 322``` 323 324The `SizeInBytes` method returns 325`static_cast<std::size_t>(IntrinsicSizeInBytes().Read())`. 326 327The `SizeInBytes` method returns the size of the `struct` in bytes. 328`SizeInBytes` asserts that `SizeIsKnown()`, so applications should ensure that 329`SizeIsKnown()` before calling `SizeInBytes`. 330 331If the `struct` contains no dynamically-sized or dynamically-located fields, 332then `SizeInBytes` will be a `static constexpr` method, and can always be called 333safely. 334 335 336### `UpdateFromTextStream` method 337 338```c++ 339template <class Stream> 340bool UpdateFromTextStream(Stream *stream) const; 341``` 342 343`UpdateFromTextStream` will read a text-format representation of the structure 344from the given `stream` and update fields. Generally, applications would not 345call this directly; instead, use the global `UpdateFromText` method, which 346handles setting up a stream from a `std::string`. 347 348### `WriteToTextStream` method 349 350```c++ 351template <class Stream> 352bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const; 353``` 354 355`WriteToTextStream` will write a text representation of the current value in a 356form that can be decoded by `UpdateFromTextStream`. Generally, applications 357would not call this directly; instead, use the global `WriteToString` method, 358which handles setting up the stream and returning the resulting string. 359 360### `BackingStorage` method 361 362```c++ 363Storage BackingStorage() const; 364``` 365 366Returns the backing storage for the view. The return type of `BackingStorage()` 367is a template parameter on the view. 368 369 370### Field methods {#struct-field-methods} 371 372Each physical field and virtual field in the `struct` will have a corresponding 373method in the generated view for that `struct`, which returns a subview of that 374field. For example, take the `struct` definition: 375 376``` 377struct Foo: 378 0 [+4] UInt bar 379 4 [+4] Int baz 380 let qux = 2 * bar 381 let bar_alias = bar 382``` 383 384In this case, the generated code will have methods 385 386```c++ 387auto bar() const; 388auto baz() const; 389auto qux() const; 390auto bar_alias() const; 391``` 392 393The `bar` method will return a `UInt` view, and `baz()` will return an `Int` 394view. The `qux` method will return a pseudo-`UInt` view which can only be read. 395The `bar_alias` method actually forwards to `bar`, and can be both read and 396written: 397 398```c++ 399auto foo_view = MakeFooView(&vector_of_foo_bytes); 400uint32_t bar_value = foo_view.bar().Read(); 401int32_t baz_value = foo_view.baz().Read(); 402int64_t qux_value = foo_view.qux().Read(); 403uint32_t bar_alias_value = foo_view.bar_alias().Read(); 404foo_view.bar_alias().Write(100); 405assert(foo_view.bar().Read() == 100); 406``` 407 408As with <code>Make*Struct*View</code>, the exact return type of field methods is 409subject to change; if a field's view must be stored, use an `auto` variable. 410 411Fields in anonymous `bits` are treated as if they were fields of the enclosing 412`struct` in the generated code. Take this `struct`: 413 414``` 415struct Foo: 416 0 [+4] bits: 417 5 [+5] UInt bar 418``` 419 420In C++, `bar` would be read like so: 421 422```c++ 423auto foo_view = MakeFooView(&vector_of_foo_bytes); 424uint8_t bar_value = foo_view.bar().Read(); 425``` 426 427For each field, there is a <code>has_*field*()</code> method, which returns an 428object. `has_` methods are typically used for conditional fields. Suppose you 429have a `struct` like: 430 431``` 432struct Foo: 433 0 [+1] enum message_type: 434 BAR = 1 435 if message_type == MessageType.BAR: 436 1 [+25] Bar bar 437``` 438 439When you have a view of a `Foo`, you can call `foo_view.has_bar().Known()` to 440find out whether `foo_view` has enough information to determine if the field 441`bar` should exist. If it does `.Known()` returns `true`, you may call 442`foo_view.has_bar().Value()` to find out if `bar` should exist. You can also 443call `foo_view.has_bar().ValueOr(false)`, which will return `true` if `bar`'s 444status is known, and `bar` exists. 445 446Every field will have a corresponding `has_` method. In the example above, 447`foo_view.has_message_type().Known()` and `foo_view.has_message_type().Value()` 448are both supported calls; both will always return `true`. 449 450Note that just because a field "exists," that does not mean that it can be read 451from or written to the current message: the field's bytes might be missing, or 452present but contain a non-`Ok()` value. You can use `view.field().Ok()` to 453determine if the field can be *read*, and `view.field().IsComplete()` to 454determine if the field can be *written*. 455 456 457### Constant Virtual Fields 458 459Virtual fields whose values are compile-time constants can be read without 460instantiating a view: 461 462``` 463struct Foo: 464 let register_number = 0xf8 465 0 [+4] UInt foo 466``` 467 468``` 469// Foo::register_number() is a constexpr function. 470static_assert(Foo::register_number() == 0xf8); 471``` 472 473 474### <code>*field*().Ok()</code> vs <code>*field*().IsComplete()</code> vs <code>has_*field*()</code> 475 476Emboss provides a number of methods to query different kinds of validity. 477 478<code>has_*field*()</code> is used for checking the existence condition 479specified in the `.emb` file: 480 481``` 482struct Foo: 483 0 [+1] UInt x 484 if x < 10: 485 1 [+1] UInt y 486``` 487 488In the .cc file: 489 490```c++ 491::std::array<char, 2> bytes = { 5, 7 }; 492auto foo = MakeFooView(&bytes); 493assert(foo.x().Read() == 5); 494 495// foo.x() is readable, so the existence condition on y is known. 496assert(foo.has_y().Known()); 497 498// foo.x().Read() < 10, so y exists in foo. 499assert(foo.has_y().Value()); 500 501foo.x().Write(15); 502 503// foo.x().Read() >= 10, so y no longer exists in foo. 504assert(foo.has_y().Known()); 505assert(!foo.has_y().Value()); 506 507// foo.has_x() is always true, since x's existence condition is just "true". 508assert(foo.has_x().Known()); 509assert(foo.has_x().Value()); 510 511// incomplete_foo has 0 bytes of backing storage, so x is unreadable. 512auto incomplete_foo = MakeFooView(&bytes[0], 0); 513 514// incomplete_foo.has_x() is known, since it does not depend on anything. 515assert(incomplete_foo.has_x().Known()); 516assert(incomplete_foo.has_x().Value()); 517 518// incomplete_foo.x().Ok() is false, since x cannot be read. 519assert(!incomplete_foo.x().Ok()); 520 521// Since x cannot be read, incomplete_foo.has_y().Known() is false. 522assert(!incomplete_foo.has_y().Known()); 523 524// Since has_y() is not Known(), calling has_y().Value() will crash if Emboss 525// assertions are enabled. 526// incomplete_foo.has_y().Value() // Would crash 527 528// It is safe to call has_y().ValueOr(false). 529assert(!incomplete_foo.has_y().ValueOr(false)); 530``` 531 532<code>has_*field*()</code> is notional: it queries whether *`field`* *should* be 533present in the view. Even if <code>has_*field*().Value()</code> is `true`, 534<code>*field*().IsComplete()</code> and *field*().Ok() might return `false`. 535 536<code>*field*().IsComplete()</code> tests if there are enough bytes in the 537backing storage to hold *`field`*. If <code>*field*().IsComplete()</code>, it 538is safe to call `Write()` on the field with a valid value for that field. 539<code>*field*().Ok()</code> tests if there are enough bytes in the backing 540storage to hold *`field`*, *and* that those bytes contain a valid value for 541*`field`*: 542 543``` 544struct Bar: 545 0 [+1] Bcd x 546 1 [+1] Bcd y 547``` 548 549```c++ 550::std::array<char, 1> bytes = { 0xbb }; // Not a valid BCD number. 551auto bar = MakeBarView(&bytes); 552 553// There are enough bytes to read and write x. 554assert(bar.x().IsComplete()); 555 556// The value in x is not correct. 557assert(!bar.x().Ok()); 558 559// Read() would crash if assertions are enabled. 560// bar.x().Read(); 561 562// Writing a valid value is safe. 563bar.x().Write(99); 564assert(bar.x().Ok()); 565 566// Notionally, bar should have y, even though y's byte is not available: 567assert(bar.has_y().Value()); 568 569// Since there is no byte to read y from, y is not complete: 570assert(!bar.y().IsComplete()); 571``` 572 573Note that all views have `Ok()` and `IsComplete()` methods. A view of a 574structure is `Ok()` if all of its fields are either `Ok()` or not present, and 575<code>has_*field*().Known()</code> is `true` for all fields. 576 577A structure view `IsComplete()` if its `SizeIsKnown()` and its backing storage 578contains at least `SizeInBits()` or `SizeInBytes()` bits or bytes. In other 579words: `IsComplete()` is true if Emboss can determine that (just) adding more 580bytes to the view's backing storage won't help. Note that just because 581`IsComplete()` is false, that does not mean that adding more bytes *will* help. 582It is possible to define incoherent structures that will confuse Emboss, such 583as: 584 585``` 586struct SizeNeverKnown: 587 if false: 588 0 [+1] UInt x_loc 589 x_loc [+1] UInt x 590``` 591 592<!-- TODO(bolms): Rename "existence condition" to "presence condition." --> 593 594 595## `bits` Views 596 597The code generated for a `bits` construct is very similar to the code generated 598for a `struct`. The primary differences are that there is no 599<code>Make*Bits*View</code> function and that `SizeInBytes` is replaced by 600`SizeInBits`. 601 602 603### `Ok` method 604 605```c++ 606bool Ok() const; 607``` 608 609The `Ok` method returns `true` if and only if there are enough bytes in the 610backing store, and the `Ok` methods of all active fields return `true`. 611 612 613### `IsComplete` method 614 615```c++ 616bool IsComplete() const; 617``` 618 619The `IsComplete` method returns `true` if there are enough bytes in the backing 620store to fully contain the `bits`. If `IsComplete()` returns `true` but 621`Ok()` returns `false`, then the structure is broken in some way that cannot be 622fixed by adding more bytes. 623 624 625### `IntrinsicSizeInBits` method 626 627```c++ 628auto IntrinsicSizeInBits() const; 629``` 630 631or 632 633```c++ 634static constexpr auto IntrinsicSizeInBits() const; 635``` 636 637The `IntrinsicSizeInBits` method is the [field method](#bits-field-methods) for 638[`$size_in_bits`](language-reference.md#size-in-bits). The `Read` method of 639the result returns the size of the `struct`, and the `Ok` method returns `true` 640if the `struct`'s intrinsic size is known; i.e.: 641 642```c++ 643if (view.IntrinsicSizeInBits().Ok()) { 644 std::uint64_t view_size = view.IntrinsicSizeInBits().Read(); 645} 646``` 647 648Since the intrinsic size of a `bits` is always a compile-time constant: 649 650```c++ 651constexpr std::uint64_t view_size = BitsView::IntrinsicSizeInBits().Read(); 652constexpr std::uint64_t view_size2 = Bits::IntrinsicSizeInBits(); 653``` 654 655 656### `MaxSizeInBits` method 657 658```c++ 659auto MaxSizeInBits() const; 660``` 661 662or 663 664```c++ 665static constexpr auto MaxSizeInBits() const; 666``` 667 668The `MaxSizeInBits` method is the [field method](#struct-field-methods) 669for [`$max_size_in_bits`](language-reference.md#max-size-in-bits). The `Read` 670method of the result returns the maximum size of the `bits`, and the `Ok` 671always method returns `true`. 672 673```c++ 674assert(view.MaxSizeInBits().Ok()); 675// The exact return type of view.MaxSizeInBits().Read() may vary, but it will 676// always be implicitly convertible to std::uint64_t. 677std::uint64_t view_size = view.MaxSizeInBits().Read(); 678``` 679 680Alternately: 681 682```c++ 683std::uint64_t view_size = view.MaxSizeInBits().UncheckedRead(); 684``` 685 686Or: 687 688```c++ 689constexpr std::uint64_t view_size = StructView::MaxSizeInBits().Read(); 690constexpr std::uint64_t view_size2 = Struct::MaxSizeInBits(); 691``` 692 693 694### `MinSizeInBits` method 695 696```c++ 697auto MinSizeInBits() const; 698``` 699 700or 701 702```c++ 703static constexpr auto MinSizeInBits() const; 704``` 705 706The `MinSizeInBits` method is the [field method](#struct-field-methods) 707for [`$min_size_in_bits`](language-reference.md#min-size-in-bits). The `Read` 708method of the result returns the minimum size of the `bits`, and the `Ok` 709always method returns `true`. 710 711```c++ 712assert(view.MinSizeInBits().Ok()); 713// The exact return type of view.MinSizeInBits().Read() may vary, but it will 714// always be implicitly convertible to std::uint64_t. 715std::uint64_t view_size = view.MinSizeInBits().Read(); 716``` 717 718Alternately: 719 720```c++ 721std::uint64_t view_size = view.MinSizeInBits().UncheckedRead(); 722``` 723 724Or: 725 726```c++ 727constexpr std::uint64_t view_size = StructView::MinSizeInBits().Read(); 728constexpr std::uint64_t view_size2 = Struct::MinSizeInBits(); 729``` 730 731 732### `SizeIsKnown` method 733 734```c++ 735static constexpr bool SizeIsKnown() const; 736``` 737 738For a `bits` construct, `SizeIsKnown()` always returns `true`, because the size 739of a `bits` construct is always statically known at compilation time. 740 741 742### `SizeInBits` method 743 744```c++ 745static constexpr std::size_t SizeInBits() const; 746``` 747 748The `SizeInBits` method returns the size of the `bits` in bits. It is 749equivalent to `static_cast<std::size_t>(IntrinsicSizeInBits().Read())`. 750 751 752### `UpdateFromTextStream` method 753 754```c++ 755template <class Stream> 756bool UpdateFromTextStream(Stream *stream) const; 757``` 758 759`UpdateFromTextStream` will read a text-format representation of the structure 760from the given `stream` and update fields. Generally, applications would not 761call this directly; instead, use the global `UpdateFromText` method, which 762handles setting up a stream from a `std::string`. 763 764### `WriteToTextStream` method 765 766```c++ 767template <class Stream> 768bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const; 769``` 770 771`WriteToTextStream` will write a text representation of the current value in a 772form that can be decoded by `UpdateFromTextStream`. Generally, applications 773would not call this directly; instead, use the global `WriteToString` method, 774which handles setting up the stream and returning the resulting string. 775 776### Field methods {#bits-field-methods} 777 778As with `struct`, each field in a `bits` will have a corresponding method of the 779same name generated, and each such method will return a view of the given field. 780Take the module: 781 782``` 783bits Bar: 784 0 [+12] UInt baz 785 31 [+1] Flag qux 786 let two_baz = baz * 2 787 788struct Foo: 789 0 [+4] Bar bar 790``` 791 792In this case, the generated code in the `Bar` view will have methods 793 794```c++ 795auto baz() const; 796auto qux() const; 797auto two_baz() const; 798``` 799 800The `baz` method will return a `UInt` view, and `qux()` will return a `Flag` 801view: 802 803```c++ 804auto foo_view = MakeFooView(&vector_of_foo_bytes); 805uint16_t baz_value = foo_view.bar().baz().Read(); 806bool qux_value = foo_view.bar().qux().Read(); 807uint32_t two_baz_value = foo_view.bar().two_baz().Read(); 808``` 809 810The exact return type of field methods is subject to change; if a field's view 811must be stored, use an `auto` variable. 812 813 814## `enum`s 815 816For each `enum` in an `.emb`, the Emboss compiler will generate a corresponding 817C++11-style `enum class`. Take the following Emboss `enum`: 818 819``` 820enum Foo: 821 BAR = 1 822 BAZ = 1000 823``` 824 825Emboss will generate something equivalent to the following C++: 826 827```c++ 828enum class Foo : uint64_t { 829 BAR = 1, 830 BAZ = 1000, 831}; 832``` 833 834Additionally, like other Emboss entities, `enum`s have corresponding view 835classes. 836 837 838### `TryToGetEnumFromName` free function 839 840```c++ 841static inline bool TryToGetEnumFromName(const char *name, EnumType *result); 842``` 843 844The `TryToGetEnumFromName` function will try to match `name` against the names 845in the Emboss `enum` definition. If it finds an exact match, it will return 846`true` and update `result` with the corresponding enum value. If it does not 847find a match, it will return `false` and leave `result` unchanged. 848 849Note that `TryToGetNameFromEnum` will not match the text of the numeric value of 850an enum; given the `Foo` enum above, `TryToGetEnumFromName("1000", &my_foo)` 851would return `false`. 852 853 854### `TryToGetNameFromEnum` free function 855 856```c++ 857static inline const char *TryToGetNameFromEnum(EnumType value); 858``` 859 860`TryToGetNameFromEnum` will attempt to find the textual name for the 861corresponding enum value. If a name is found, it will be returned; otherwise 862`TryToGetEnumFromName` will return `nullptr`. (Note that C++ enums are allowed 863to contain numeric values that are not explicitly listed in the enum definition, 864as long as they are in range for the underlying integral type.) If the given 865value has more than one name, the first name that appears in the Emboss 866definition will be returned. 867 868 869### `Read` method 870 871```c++ 872EnumType Read() const; 873``` 874 875The `Read` method reads the enum from the underlying bytes and returns its 876value as a C++ enum. `Read` will assert that there are enough bytes to read. 877If the application cannot tolerate a failed assertion, it should first call 878`Ok()` to ensure that it can safely read the enum. If performance is critical 879and the application can assure that there will always be enough bytes to read 880the enum, it can call `UncheckedRead` instead. 881 882 883### `UncheckedRead` method 884 885```c++ 886EnumType UncheckedRead() const; 887``` 888 889Like `Read`, `UncheckedRead` reads the enum from the underlying bytes and 890returns it value as a C++ enum. Unlike `Read`, `UncheckedRead` does not attempt 891to validate that there are enough bytes in the backing store to actually perform 892the read. In performance-critical situations, if the application is otherwise 893able to ensure that there are sufficient bytes in the backing store to read the 894enum, `UncheckedRead` may be used. 895 896 897### `Write` method 898 899```c++ 900void Write(EnumType value) const; 901``` 902 903`Write` writes the `value` into the backing store. Like `Read`, `Write` asserts 904that there are enough bytes in the backing store to safely write the enum. If 905the application cannot tolerate an assertion failure, it can use `TryToWrite` or 906the combination of `IsComplete` and `CouldWriteValue`. 907 908 909### `TryToWrite` method 910 911```c++ 912bool TryToWrite(EnumType value) const; 913``` 914 915`TryToWrite` attempts to write the `value` into the backing store. If the 916backing store does not have enough bytes to hold the enum field, or `value` is 917too large for the specific enum field, then `TryToWrite` will return `false` and 918not update anything. 919 920 921### `CouldWriteValue` method 922 923```c++ 924static constexpr bool CouldWriteValue(EnumType value); 925``` 926 927`CouldWriteValue` returns `true` if the given `value` could be written into the 928enum field, assuming that there were enough bytes in the backing store to cover 929the field. 930 931Although `CouldWriteValue` is `static constexpr`, it is tricky to call 932statically; client code that wishes to call it statically must use `decltype` 933and `declval` to get the specific type for the specific enum *field* in 934question. 935 936 937### `UncheckedWrite` method 938 939```c++ 940void UncheckedWrite(EnumType value) const; 941``` 942 943Like `Write`, `UncheckedWrite` writes the given value to the backing store. 944Unlike `Write`, `UncheckedWrite` does not check that there are actually enough 945bytes in the backing store to safely write; it should only be used if the 946application has ensured that there are sufficient bytes in the backing store in 947some other way, and performance is a concern. 948 949 950### `Ok` method 951 952```c++ 953bool Ok() const; 954``` 955 956`Ok` returns `true` if there are enough bytes in the backing store for the enum 957field to be read or written. 958 959In the future, Emboss may add a "known values only" annotation to enum fields, 960in which case `Ok` would also check that the given field contains a known value. 961 962 963### `IsComplete` method 964 965```c++ 966bool IsComplete() const; 967``` 968 969`IsComplete` returns `true` if there are enough bytes in the backing store for 970the enum field to be read or written. 971 972 973### `UpdateFromTextStream` method 974 975```c++ 976template <class Stream> 977bool UpdateFromTextStream(Stream *stream) const; 978``` 979 980`UpdateFromTextStream` will read a text-format representation of the enum from 981the given `stream` and write it into the backing store. Generally, applications 982would not call this directly; instead, use the global `UpdateFromText` method, 983which handles setting up a stream from a `std::string`. 984 985### `WriteToTextStream` method 986 987```c++ 988template <class Stream> 989bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const; 990``` 991 992`WriteToTextStream` will write a text representation of the current value in a 993form that can be decoded by `UpdateFromTextStream`. Generally, applications 994would not call this directly; instead, use the global `WriteToString` method, 995which handles setting up the stream and returning the resulting string. 996 997## Arrays 998 999### `operator[]` method 1000 1001```c++ 1002ElementView operator[](size_t index) const; 1003``` 1004 1005The `operator[]` method of an array view returns a view of the array element at 1006`index`. 1007 1008### `begin()`/`rbegin()` and `end()`/`rend()` methods 1009 1010```c++ 1011ElementViewIterator<> begin(); 1012ElementViewIterator<> end(); 1013ElementViewIterator<> rbegin(); 1014ElementViewIterator<> rend(); 1015``` 1016 1017The `begin()` and `end()` methods of an array view returns view iterators to the 1018beginning and past-the-end of the array, respectively. They may be used with 1019arrays in range-based for loops, for example: 1020 1021```c++ 1022 auto view = MakeArrayView(...); 1023 for(auto element : view){ 1024 int a = view.member().Read(); 1025 ... 1026 } 1027``` 1028 1029The `rbegin()` and `rend()` methods of an array view returns reverse view 1030iterators to the end and element preceding the first, respectively. 1031 1032### `SizeInBytes` or `SizeInBits` method 1033 1034```c++ 1035size_t SizeInBytes() const; 1036``` 1037 1038or 1039 1040```c++ 1041size_t SizeInBits() const; 1042``` 1043 1044Arrays in `struct`s have the `SizeInBytes` method; arrays in `bits` have the 1045`SizeInBits` method. `SizeInBytes` returns the size of the array in bytes; 1046`SizeInBits` returns the size of the array in bits. 1047 1048 1049### `ElementCount` method 1050 1051```c++ 1052size_t ElementCount() const; 1053``` 1054 1055`ElementCount` returns the number of elements in the array. 1056 1057 1058### `Ok` method 1059 1060```c++ 1061bool Ok() const; 1062``` 1063 1064`Ok` returns `true` if there are enough bytes in the backing store to hold the 1065entire array, and every element's `Ok` method returns `true`. 1066 1067 1068### `IsComplete` method 1069 1070```c++ 1071bool IsComplete() const; 1072``` 1073 1074`IsComplete` returns `true` if there are sufficient bytes in the backing store 1075to hold the entire array. 1076 1077 1078### `ToString` method 1079 1080```c++ 1081template <class String> 1082String ToString() const; 1083``` 1084 1085Intended usage: 1086 1087```c++ 1088// Makes a copy of view's backing storage. 1089auto str = view.ToString<std::string>(); 1090 1091// Points to view's backing storage. 1092auto str_view = view.ToString<std::string_view>(); 1093``` 1094 1095`ToString()` returns a string type constructed from the backing storage of the 1096array. Note that `ToString()` is only enabled for arrays of 1-byte values, 1097such as `UInt:8[]`, and only when the array view's underlying storage is 1098contiguous. 1099 1100Although it is intended for use with `std::string` and `std::string_view`, 1101`ToString()` can work with any C++ type that: 1102 11031. Has a `data()` method that returns a pointer to the string's underlying 1104 data as a `char` type. 11052. Has a constructor that accepts a `const declval(data())` pointer and a 1106 `size_t` length. 1107 1108 1109### `UpdateFromTextStream` method 1110 1111```c++ 1112template <class Stream> 1113bool UpdateFromTextStream(Stream *stream) const; 1114``` 1115 1116`UpdateFromTextStream` will read a text-format representation of the structure 1117from the given `stream` and update array elements. Generally, applications 1118would not call this directly; instead, use the global `UpdateFromText` method, 1119which handles setting up a stream from a `std::string`. 1120 1121### `WriteToTextStream` method 1122 1123```c++ 1124template <class Stream> 1125bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const; 1126``` 1127 1128`WriteToTextStream` will write a text representation of the current value in a 1129form that can be decoded by `UpdateFromTextStream`. Generally, applications 1130would not call this directly; instead, use the global `WriteToString` method, 1131which handles setting up the stream and returning the resulting string. 1132 1133### `BackingStorage` method 1134 1135```c++ 1136Storage BackingStorage() const; 1137``` 1138 1139Returns the backing storage for the view. The return type of `BackingStorage()` 1140is a template parameter on the view. 1141 1142## `UInt` 1143 1144### Type `ValueType` 1145 1146```c++ 1147using ValueType = ...; 1148``` 1149 1150The `ValueType` type alias maps to the least-width C++ unsigned integer type 1151that contains enough bits to hold any value of the given `UInt`. For example: 1152 1153* a `UInt:32`'s `ValueType` would be `uint32_t` 1154* a `UInt:64`'s `ValueType` would be `uint64_t` 1155* a `UInt:12`'s `ValueType` would be `uint16_t` 1156* a `UInt:2`'s `ValueType` would be `uint8_t` 1157 1158The `Read` and `Write` families of methods use `ValueType` to return or accept 1159values, respectively. 1160 1161 1162### `Read` method 1163 1164```c++ 1165ValueType Read() const; 1166``` 1167 1168The `Read` method reads the `UInt` from the underlying bytes and returns its 1169value as a C++ unsigned integer type. `Read` will assert that there are enough 1170bytes to read. If the application cannot tolerate a failed assertion, it should 1171first call `Ok()` to ensure that it can safely read the `UInt`. If performance 1172is critical and the application can assure that there will always be enough 1173bytes to read the `UInt`, it can call `UncheckedRead` instead. 1174 1175 1176### `UncheckedRead` method 1177 1178```c++ 1179ValueType UncheckedRead(); 1180``` 1181 1182Like `Read`, `UncheckedRead` reads the `UInt` from the underlying bytes and 1183returns it value as a C++ unsigned integer type. Unlike `Read`, `UncheckedRead` 1184does not attempt to validate that there are enough bytes in the backing store to 1185actually perform the read. In performance-critical situations, if the 1186application is otherwise able to ensure that there are sufficient bytes in the 1187backing store to read the `UInt`, `UncheckedRead` may be used. 1188 1189 1190### `Write` method 1191 1192```c++ 1193void Write(ValueType value); 1194``` 1195 1196`Write` writes the `value` into the backing store. Like `Read`, `Write` asserts 1197that there are enough bytes in the backing store to safely write the `UInt`. If 1198the application cannot tolerate an assertion failure, it can use `TryToWrite` or 1199the combination of `IsComplete` and `CouldWriteValue`. 1200 1201 1202### `TryToWrite` method 1203 1204```c++ 1205bool TryToWrite(ValueType value); 1206``` 1207 1208`TryToWrite` attempts to write the `value` into the backing store. If the 1209backing store does not have enough bytes to hold the `UInt` field, or `value` is 1210too large for the `UInt` field, then `TryToWrite` will return `false` and not 1211update anything. 1212 1213 1214### `CouldWriteValue` method 1215 1216```c++ 1217static constexpr bool CouldWriteValue(ValueType value); 1218``` 1219 1220`CouldWriteValue` returns `true` if the given `value` could be written into the 1221`UInt` field, assuming that there were enough bytes in the backing store to 1222cover the field. 1223 1224Although `CouldWriteValue` is `static constexpr`, it is tricky to call 1225statically; client code that wishes to call it statically must use `decltype` 1226and `declval` to get the specific type for the specific `UInt` field in 1227question. 1228 1229 1230### `UncheckedWrite` method 1231 1232```c++ 1233void UncheckedWrite(ValueType value); 1234``` 1235 1236Like `Write`, `UncheckedWrite` writes the given value to the backing store. 1237Unlike `Write`, `UncheckedWrite` does not check that there are actually enough 1238bytes in the backing store to safely write; it should only be used if the 1239application has ensured that there are sufficient bytes in the backing store in 1240some other way, and performance is a concern. 1241 1242 1243### `Ok` method 1244 1245```c++ 1246bool Ok() const; 1247``` 1248 1249The `Ok` method returns `true` if there are enough bytes in the backing store to 1250hold the given `UInt` field. 1251 1252 1253### `IsComplete` method 1254 1255```c++ 1256bool IsComplete(); 1257``` 1258 1259The `IsComplete` method returns `true` if there are enough bytes in the backing 1260store to hold the given `UInt` field. 1261 1262 1263### `UpdateFromTextStream` method 1264 1265```c++ 1266template <class Stream> 1267bool UpdateFromTextStream(Stream *stream) const; 1268``` 1269 1270`UpdateFromTextStream` will read a text-format representation of the `UInt` from 1271the given `stream` and update fields. Generally, applications would not call 1272this directly; instead, use the global `UpdateFromText` method, which handles 1273setting up a stream from a `std::string`. 1274 1275### `WriteToTextStream` method 1276 1277```c++ 1278template <class Stream> 1279bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const; 1280``` 1281 1282`WriteToTextStream` will write a text representation of the current value in a 1283form that can be decoded by `UpdateFromTextStream`. Generally, applications 1284would not call this directly; instead, use the global `WriteToString` method, 1285which handles setting up the stream and returning the resulting string. 1286 1287### `SizeInBits` method 1288 1289```c++ 1290static constexpr int SizeInBits(); 1291``` 1292 1293The `SizeInBits` method returns the size of this specific `UInt` field, in bits. 1294 1295 1296## `Int` 1297 1298### Type `ValueType` 1299 1300```c++ 1301using ValueType = ...; 1302``` 1303 1304The `ValueType` type alias maps to the least-width C++ signed integer type 1305that contains enough bits to hold any value of the given `Int`. For example: 1306 1307* a `Int:32`'s `ValueType` would be `int32_t` 1308* a `Int:64`'s `ValueType` would be `int64_t` 1309* a `Int:12`'s `ValueType` would be `int16_t` 1310* a `Int:2`'s `ValueType` would be `int8_t` 1311 1312The `Read` and `Write` families of methods use `ValueType` to return or accept 1313values, respectively. 1314 1315 1316### `Read` method 1317 1318```c++ 1319ValueType Read() const; 1320``` 1321 1322The `Read` method reads the `Int` from the underlying bytes and returns its 1323value as a C++ signed integer type. `Read` will assert that there are enough 1324bytes to read. If the application cannot tolerate a failed assertion, it should 1325first call `Ok()` to ensure that it can safely read the `Int`. If performance 1326is critical and the application can assure that there will always be enough 1327bytes to read the `Int`, it can call `UncheckedRead` instead. 1328 1329 1330### `UncheckedRead` method 1331 1332```c++ 1333ValueType UncheckedRead(); 1334``` 1335 1336Like `Read`, `UncheckedRead` reads the `Int` from the underlying bytes and 1337returns it value as a C++ signed integer type. Unlike `Read`, `UncheckedRead` 1338does not attempt to validate that there are enough bytes in the backing store to 1339actually perform the read. In performance-critical situations, if the 1340application is otherwise able to ensure that there are sufficient bytes in the 1341backing store to read the `Int`, `UncheckedRead` may be used. 1342 1343 1344### `Write` method 1345 1346```c++ 1347void Write(ValueType value); 1348``` 1349 1350`Write` writes the `value` into the backing store. Like `Read`, `Write` asserts 1351that there are enough bytes in the backing store to safely write the `Int`. If 1352the application cannot tolerate an assertion failure, it can use `TryToWrite` or 1353the combination of `IsComplete` and `CouldWriteValue`. 1354 1355 1356### `TryToWrite` method 1357 1358```c++ 1359bool TryToWrite(ValueType value); 1360``` 1361 1362`TryToWrite` attempts to write the `value` into the backing store. If the 1363backing store does not have enough bytes to hold the `Int` field, or `value` is 1364too large for the `Int` field, then `TryToWrite` will return `false` and not 1365update anything. 1366 1367 1368### `CouldWriteValue` method 1369 1370```c++ 1371static constexpr bool CouldWriteValue(ValueType value); 1372``` 1373 1374`CouldWriteValue` returns `true` if the given `value` could be written into the 1375`Int` field, assuming that there were enough bytes in the backing store to cover 1376the field. 1377 1378Although `CouldWriteValue` is `static constexpr`, it is tricky to call 1379statically; client code that wishes to call it statically must use `decltype` 1380and `declval` to get the specific type for the specific `Int` field in question. 1381 1382 1383### `UncheckedWrite` method 1384 1385```c++ 1386void UncheckedWrite(ValueType value); 1387``` 1388 1389Like `Write`, `UncheckedWrite` writes the given value to the backing store. 1390Unlike `Write`, `UncheckedWrite` does not check that there are actually enough 1391bytes in the backing store to safely write; it should only be used if the 1392application has ensured that there are sufficient bytes in the backing store in 1393some other way, and performance is a concern. 1394 1395 1396### `Ok` method 1397 1398```c++ 1399bool Ok() const; 1400``` 1401 1402The `Ok` method returns `true` if there are enough bytes in the backing store to 1403hold the given `Int` field. 1404 1405 1406### `IsComplete` method 1407 1408```c++ 1409bool IsComplete(); 1410``` 1411 1412The `IsComplete` method returns `true` if there are enough bytes in the backing 1413store to hold the given `Int` field. 1414 1415 1416### `UpdateFromTextStream` method 1417 1418```c++ 1419template <class Stream> 1420bool UpdateFromTextStream(Stream *stream) const; 1421``` 1422 1423`UpdateFromTextStream` will read a text-format representation of the `Int` from 1424the given `stream` and update fields. Generally, applications would not call 1425this directly; instead, use the global `UpdateFromText` method, which handles 1426setting up a stream from a `std::string`. 1427 1428### `WriteToTextStream` method 1429 1430```c++ 1431template <class Stream> 1432bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const; 1433``` 1434 1435`WriteToTextStream` will write a text representation of the current value in a 1436form that can be decoded by `UpdateFromTextStream`. Generally, applications 1437would not call this directly; instead, use the global `WriteToString` method, 1438which handles setting up the stream and returning the resulting string. 1439 1440### `SizeInBits` method 1441 1442```c++ 1443static constexpr int SizeInBits(); 1444``` 1445 1446The `SizeInBits` method returns the size of this specific `Int` field, in bits. 1447 1448 1449## `Bcd` 1450 1451### Type `ValueType` 1452 1453```c++ 1454using ValueType = ...; 1455``` 1456 1457The `ValueType` type alias maps to a C++ unsigned integer type that contains 1458at least enough bits to hold any value of the given `Bcd`. For example: 1459 1460* a `Bcd:32`'s `ValueType` would be `uint32_t` 1461* a `Bcd:64`'s `ValueType` would be `uint64_t` 1462* a `Bcd:12`'s `ValueType` would be `uint16_t` 1463* a `Bcd:2`'s `ValueType` would be `uint8_t` 1464 1465The `Read` and `Write` families of methods use `ValueType` to return or accept 1466values, respectively. 1467 1468 1469### `Read` method 1470 1471```c++ 1472ValueType Read() const; 1473``` 1474 1475The `Read` method reads the `Bcd` from the underlying bytes and returns its 1476value as a C++ unsigned integer type. `Read` will assert that there are enough 1477bytes to read, and that the binary representation is a valid BCD integer. If 1478the application cannot tolerate a failed assertion, it should first call `Ok()` 1479to ensure that it can safely read the `Bcd`. If performance is critical and the 1480application can assure that there will always be enough bytes to read the `Bcd`, 1481and that the bytes will be a valid BCD value, it can call `UncheckedRead` 1482instead. 1483 1484 1485### `UncheckedRead` method 1486 1487```c++ 1488ValueType UncheckedRead(); 1489``` 1490 1491Like `Read`, `UncheckedRead` reads the `Bcd` from the underlying bytes and 1492returns it value as a C++ unsigned integer type. Unlike `Read`, `UncheckedRead` 1493does not attempt to validate that there are enough bytes in the backing store to 1494actually perform the read, nor that the bytes contain an actual BCD number. In 1495performance-critical situations, if the application is otherwise able to ensure 1496that there are sufficient bytes in the backing store to read the `Bcd`, 1497`UncheckedRead` may be used. 1498 1499 1500### `Write` method 1501 1502```c++ 1503void Write(ValueType value); 1504``` 1505 1506`Write` writes the `value` into the backing store. Like `Read`, `Write` asserts 1507that there are enough bytes in the backing store to safely write the `Bcd`. If 1508the application cannot tolerate an assertion failure, it can use `TryToWrite` or 1509the combination of `IsComplete` and `CouldWriteValue`. 1510 1511 1512### `TryToWrite` method 1513 1514```c++ 1515bool TryToWrite(ValueType value); 1516``` 1517 1518`TryToWrite` attempts to write the `value` into the backing store. If the 1519backing store does not have enough bytes to hold the `Bcd` field, or `value` is 1520too large for the `Bcd` field, then `TryToWrite` will return `false` and not 1521update anything. 1522 1523 1524### `CouldWriteValue` method 1525 1526```c++ 1527static constexpr bool CouldWriteValue(ValueType value); 1528``` 1529 1530`CouldWriteValue` returns `true` if the given `value` could be written into the 1531`Bcd` field, assuming that there were enough bytes in the backing store to cover 1532the field. 1533 1534Although `CouldWriteValue` is `static constexpr`, it is tricky to call 1535statically; client code that wishes to call it statically must use `decltype` 1536and `declval` to get the specific type for the specific `Bcd` field in question. 1537 1538 1539### `UncheckedWrite` method 1540 1541```c++ 1542void UncheckedWrite(ValueType value); 1543``` 1544 1545Like `Write`, `UncheckedWrite` writes the given value to the backing store. 1546Unlike `Write`, `UncheckedWrite` does not check that there are actually enough 1547bytes in the backing store to safely write; it should only be used if the 1548application has ensured that there are sufficient bytes in the backing store in 1549some other way, and performance is a concern. 1550 1551 1552### `Ok` method 1553 1554```c++ 1555bool Ok() const; 1556``` 1557 1558The `Ok` method returns `true` if there are enough bytes in the backing store to 1559hold the given `Bcd` field, and the bytes contain a valid BCD number: that is, 1560that every nibble in the backing store contains a value between 0 and 9, 1561inclusive. 1562 1563 1564### `IsComplete` method 1565 1566```c++ 1567bool IsComplete(); 1568``` 1569 1570The `IsComplete` method returns `true` if there are enough bytes in the backing 1571store to hold the given `Bcd` field. 1572 1573 1574### `UpdateFromTextStream` method 1575 1576```c++ 1577template <class Stream> 1578bool UpdateFromTextStream(Stream *stream) const; 1579``` 1580 1581`UpdateFromTextStream` will read a text-format representation of the `Bcd` from 1582the given `stream` and update fields. Generally, applications would not call 1583this directly; instead, use the global `UpdateFromText` method, which handles 1584setting up a stream from a `std::string`. 1585 1586### `WriteToTextStream` method 1587 1588```c++ 1589template <class Stream> 1590bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const; 1591``` 1592 1593`WriteToTextStream` will write a text representation of the current value in a 1594form that can be decoded by `UpdateFromTextStream`. Generally, applications 1595would not call this directly; instead, use the global `WriteToString` method, 1596which handles setting up the stream and returning the resulting string. 1597 1598### `SizeInBits` method 1599 1600```c++ 1601static constexpr int SizeInBits(); 1602``` 1603 1604The `SizeInBits` method returns the size of this specific `Bcd` field, in bits. 1605 1606 1607## `Flag` 1608 1609### `Read` method 1610 1611```c++ 1612bool Read() const; 1613``` 1614 1615The `Read` method reads the `Flag` from the underlying bit and returns its 1616value as a C++ `bool`. `Read` will assert that the underlying bit is in the 1617backing store. If the application cannot tolerate a failed assertion, it should 1618first call `Ok()` to ensure that it can safely read the `Flag`. If performance 1619is critical and the application can assure that there will always be enough 1620bytes to read the `Flag`, it can call `UncheckedRead` instead. 1621 1622 1623### `UncheckedRead` method 1624 1625```c++ 1626bool UncheckedRead(); 1627``` 1628 1629Like `Read`, `UncheckedRead` reads the `Flag` from the underlying bit and 1630returns it value as a C++ bool. Unlike `Read`, `UncheckedRead` does not attempt 1631to validate that the backing bit is actually in the backing store. In 1632performance-critical situations, if the application is otherwise able to ensure 1633that there are sufficient bytes in the backing store to read the `Flag`, 1634`UncheckedRead` may be used. 1635 1636 1637### `Write` method 1638 1639```c++ 1640void Write(bool value); 1641``` 1642 1643`Write` writes the `value` into the backing store. Like `Read`, `Write` asserts 1644that there are enough bytes in the backing store to safely write the `Flag`. If 1645the application cannot tolerate an assertion failure, it can use `TryToWrite` or 1646the combination of `IsComplete` and `CouldWriteValue`. 1647 1648 1649### `TryToWrite` method 1650 1651```c++ 1652bool TryToWrite(bool value); 1653``` 1654 1655`TryToWrite` attempts to write the `value` into the backing store. If the 1656backing store does not contain the `Flag`'s bit, then `TryToWrite` will return 1657`false` and not update anything. 1658 1659 1660### `CouldWriteValue` method 1661 1662```c++ 1663static constexpr bool CouldWriteValue(bool value); 1664``` 1665 1666`CouldWriteValue` returns `true`, as both C++ `bool` values can be written to 1667any `Flag`. 1668 1669 1670### `UncheckedWrite` method 1671 1672```c++ 1673void UncheckedWrite(ValueType value); 1674``` 1675 1676Like `Write`, `UncheckedWrite` writes the given value to the backing store. 1677Unlike `Write`, `UncheckedWrite` does not check that there are actually enough 1678bytes in the backing store to safely write; it should only be used if the 1679application has ensured that there are sufficient bytes in the backing store in 1680some other way, and performance is a concern. 1681 1682 1683### `Ok` method 1684 1685```c++ 1686bool Ok() const; 1687``` 1688 1689The `Ok` method returns `true` if the backing store contains the `Flag`'s bit. 1690 1691 1692### `IsComplete` method 1693 1694```c++ 1695bool IsComplete(); 1696``` 1697 1698The `IsComplete` method returns `true` if the backing store contains the 1699`Flag`'s bit. 1700 1701 1702### `UpdateFromTextStream` method 1703 1704```c++ 1705template <class Stream> 1706bool UpdateFromTextStream(Stream *stream) const; 1707``` 1708 1709`UpdateFromTextStream` will read a text-format representation of the `Flag` from 1710the given `stream` and update fields. Generally, applications would not call 1711this directly; instead, use the global `UpdateFromText` method, which handles 1712setting up a stream from a `std::string`. 1713 1714### `WriteToTextStream` method 1715 1716```c++ 1717template <class Stream> 1718bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const; 1719``` 1720 1721`WriteToTextStream` will write a text representation of the current value in a 1722form that can be decoded by `UpdateFromTextStream`. Generally, applications 1723would not call this directly; instead, use the global `WriteToString` method, 1724which handles setting up the stream and returning the resulting string. 1725 1726## `Float` 1727 1728### Type `ValueType` 1729 1730```c++ 1731using ValueType = ...; 1732``` 1733 1734The `ValueType` type alias maps to the C++ floating-point type that matches the 1735`Float` field's type; generally `float` for 32-bit `Float`s and `double` for 173664-bit `Float`s. 1737 1738The `Read` and `Write` families of methods use `ValueType` to return or accept 1739values, respectively. 1740 1741 1742### `Read` method 1743 1744```c++ 1745ValueType Read() const; 1746``` 1747 1748The `Read` method reads the `Float` from the underlying bytes and returns its 1749value as a C++ floating point type. `Read` will assert that there are enough 1750bytes to read. If the application cannot tolerate a failed assertion, it should 1751first call `Ok()` to ensure that it can safely read the `Float`. If performance 1752is critical and the application can assure that there will always be enough 1753bytes to read the `Float`, it can call `UncheckedRead` instead. 1754 1755 1756### `UncheckedRead` method 1757 1758```c++ 1759ValueType UncheckedRead(); 1760``` 1761 1762Like `Read`, `UncheckedRead` reads the `Float` from the underlying bytes and 1763returns it value as a C++ floating point type. Unlike `Read`, `UncheckedRead` 1764does not attempt to validate that there are enough bytes in the backing store to 1765actually perform the read. In performance-critical situations, if the 1766application is otherwise able to ensure that there are sufficient bytes in the 1767backing store to read the `Float`, `UncheckedRead` may be used. 1768 1769 1770### `Write` method 1771 1772```c++ 1773void Write(ValueType value); 1774``` 1775 1776`Write` writes the `value` into the backing store. Like `Read`, `Write` asserts 1777that there are enough bytes in the backing store to safely write the `Float`. 1778If the application cannot tolerate an assertion failure, it can use `TryToWrite` 1779or the combination of `IsComplete` and `CouldWriteValue`. 1780 1781 1782### `TryToWrite` method 1783 1784```c++ 1785bool TryToWrite(ValueType value); 1786``` 1787 1788`TryToWrite` attempts to write the `value` into the backing store. If the 1789backing store does not have enough bytes to hold the `Float` field, then 1790`TryToWrite` will return `false` and not update anything. 1791 1792 1793### `CouldWriteValue` method 1794 1795```c++ 1796static constexpr bool CouldWriteValue(ValueType value); 1797``` 1798 1799`CouldWriteValue` returns `true`. 1800 1801 1802### `UncheckedWrite` method 1803 1804```c++ 1805void UncheckedWrite(ValueType value); 1806``` 1807 1808Like `Write`, `UncheckedWrite` writes the given value to the backing store. 1809Unlike `Write`, `UncheckedWrite` does not check that there are actually enough 1810bytes in the backing store to safely write; it should only be used if the 1811application has ensured that there are sufficient bytes in the backing store in 1812some other way, and performance is a concern. 1813 1814 1815### `Ok` method 1816 1817```c++ 1818bool Ok() const; 1819``` 1820 1821The `Ok` method returns `true` if there are enough bytes in the backing store to 1822hold the given `Float` field. 1823 1824 1825### `IsComplete` method 1826 1827```c++ 1828bool IsComplete(); 1829``` 1830 1831The `IsComplete` method returns `true` if there are enough bytes in the backing 1832store to hold the given `Float` field. 1833 1834 1835### `UpdateFromTextStream` method 1836 1837```c++ 1838template <class Stream> 1839bool UpdateFromTextStream(Stream *stream) const; 1840``` 1841 1842`UpdateFromTextStream` will read a text-format representation of the `Float` 1843from the given `stream` and update fields. Generally, applications would not 1844call this directly; instead, use the global `UpdateFromText` method, which 1845handles setting up a stream from a `std::string`. 1846 1847*Note: this method is not yet implemented.* 1848 1849### `WriteToTextStream` method 1850 1851```c++ 1852template <class Stream> 1853bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const; 1854``` 1855 1856`WriteToTextStream` will write a text representation of the current value in a 1857form that can be decoded by `UpdateFromTextStream`. Generally, applications 1858would not call this directly; instead, use the global `WriteToString` method, 1859which handles setting up the stream and returning the resulting string. 1860 1861*Note: this method is not yet implemented.* 1862 1863 1864## `::emboss::UpdateFromText` function 1865 1866```c++ 1867template <typename EmbossViewType> 1868bool UpdateFromText(EmbossViewType view, const ::std::string &text) const; 1869``` 1870 1871The `::emboss::UpdateFromText` function constructs an appropriate text strem 1872object from the given `text` and calls `view`'s `UpdateFromTextStream` method. 1873This is the preferred way to read Emboss text format in C++. 1874 1875## `::emboss::WriteToString` function 1876 1877```c++ 1878template <typename EmbossViewType> 1879::std::string WriteToString(EmbossViewType view); 1880template <typename EmbossViewType> 1881::std::string WriteToString(EmbossViewType view, TextOutputOptions options); 1882``` 1883 1884The `::emboss::WriteToString` function constructs a string stream, passes it 1885into the `view`'s `WriteToTextStream` method, and finally returns the text 1886format of the `view`. 1887 1888The single-argument form `WriteToString(view)` will return a single line of 1889text. For more readable output, `WriteToString(view, ::emboss::MultilineText())` 1890should help. 1891 1892## `::emboss::TextOutputOptions` class 1893 1894The `TextOutputOptions` is used to set options for text output, such as numeric 1895base, whether or not to use multiple lines, etc. 1896 1897### `PlusOneIndent` method 1898 1899```c++ 1900TextOutputOptions PlusOneIndent() const; 1901``` 1902 1903`PlusOneIndent` returns a new `TextOutputOptions` with one more level of 1904indentation than the current `TextOutputOptions`. This is primarily intended for 1905use inside of `WriteToTextStream` methods, as a way to get an indented 1906`TextOutputOptions` to pass to the `WriteToTextStream` methods of child 1907objects. However, application callers may use `PlusOneIndent()`, possibly 1908multiple times, to indent the entire output. 1909 1910### `Multiline` method 1911 1912```c++ 1913TextOutputOptions Multiline(bool new_value) const; 1914``` 1915 1916Returns a new `TextOutputOptions` with the same options as the current 1917`TextOutputOptions`, except for a new value for `multiline()`. 1918 1919### `WithIndent` method 1920 1921```c++ 1922TextOutputOptions WithIndent(::std::string new_value) const; 1923``` 1924 1925Returns a new `TextOutputOptions` with the same options as the current 1926`TextOutputOptions`, except for a new value for `indent()`. 1927 1928### `WithComments` method 1929 1930```c++ 1931TextOutputOptions WithComments(bool new_value) const; 1932``` 1933 1934Returns a new `TextOutputOptions` with the same options as the current 1935`TextOutputOptions`, except for a new value for `comments()`. 1936 1937### `WithDigitGrouping` method 1938 1939```c++ 1940TextOutputOptions WithDigitGrouping(bool new_value) const; 1941``` 1942 1943Returns a new `TextOutputOptions` with the same options as the current 1944`TextOutputOptions`, except for a new value for `digit_grouping()`. 1945 1946### `WithNumericBase` method 1947 1948```c++ 1949TextOutputOptions WithNumericBase(int new_value) const; 1950``` 1951 1952Returns a new `TextOutputOptions` with the same options as the current 1953`TextOutputOptions`, except for a new value for `digit_grouping()`. The new 1954numeric base should be 2, 10, or 16. 1955 1956### `WithAllowPartialOutput` method 1957 1958```c++ 1959TextOutputOptions WithAllowPartialOutput(bool new_value) const; 1960``` 1961 1962Returns a new `TextOutputOptions` with the same options as the current 1963`TextOutputOptions`, except for a new value for `allow_partial_output()`. 1964 1965### `current_indent` method 1966 1967```c++ 1968::std::string current_indent() const; // Default "". 1969``` 1970 1971Returns the current indent string. 1972 1973### `indent` method 1974 1975```c++ 1976::std::string indent() const; // Default " ". 1977``` 1978 1979Returns the indent string. The indent string is the string used for a *single* 1980level of indentation. 1981 1982### `multiline` method 1983 1984```c++ 1985bool multiline() const; // Default false. 1986``` 1987 1988Returns `true` if text output should use multiple lines, or `false` if text 1989output should be single-line only. 1990 1991### `digit_grouping` method 1992 1993```c++ 1994bool digit_grouping() const; // Default false. 1995``` 1996 1997Returns `true` if text output should include digit separators on numbers; i.e. 1998`1_000_000` instead of `1000000`. 1999 2000### `comments` method 2001 2002```c++ 2003bool comments() const; // Default false. 2004``` 2005 2006Returns `true` if text output should include comments, e.g., to show numbers in 2007multiple bases. 2008 2009### `numeric_base` method 2010 2011```c++ 2012uint8_t numeric_base() const; // Default 10. 2013``` 2014 2015Returns the numeric base that should be used for formatting numbers. This should 2016always be 2, 10, or 16. 2017 2018### `allow_partial_output` method 2019 2020```c++ 2021bool allow_partial_output() const; // Default false. 2022``` 2023 2024Returns `true` if text output should attempt to extract fields from a view that 2025is not `Ok()`. If so: 2026 2027* `WriteToString()` or `WriteToTextStream()` should never `CHECK`-fail. 2028* Atomic fields (e.g., `Int`, `UInt`, `enum`, `Flag`, etc. types) will not be 2029 written to the text stream if they cannot be read. 2030* If `comments()` is also `true`, unreadable atomic fields will be commented 2031 in the text stream. 2032* Aggregate fields (`struct`, `bits`, or arrays) will be written, but may be 2033 missing fields or entirely empty if they have non-`Ok()` members. 2034