xref: /aosp_15_r20/external/emboss/doc/cpp-reference.md (revision 99e0aae7469b87d12f0ad23e61142c2d74c1ef70)
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