# Emboss C++ Generated Code Reference

[TOC]

## `struct`s

A `struct` will have a corresponding view class, and functions to create views.

### `Make`*`Struct`*`View` free function

```c++
template <typename T>
auto MakeStructView(/* view parameters, */ T *data, size_t size);
```

```c++
template <typename T>
auto MakeStructView(/* view parameters, */ T *container);
```

*`Struct`* will be replaced by the name of the specific `struct` whose view
will be constructed; for example, to make a view for `struct Message`, call the
`MakeMessageView` function.

*View parameters* will be replaced by one argument for each parameter attached
to the `struct`.  E.g., for:

```
struct Foo(x: UInt:8):
   --
```

`MakeFooView` will be:

```c++
template <typename T>
auto MakeFooView(std::uint8_t x, T *data, size_t size);
```

```c++
template <typename T>
auto MakeFooView(std::uint8_t x, T *container);
```

And for:

```
struct Bar(x: UInt:8, y: Int:32):
  --
```

`MakeBarView` will be:

```c++
template <typename T>
auto MakeBarView(std::uint8_t x, std::int32_t y, T *data, size_t size);
```

```c++
template <typename T>
auto MakeBarView(std::uint8_t x, std::int32_t y, T *container);
```

The `Make`*`Struct`*`View` functions construct a view for *`Struct`* over the
given bytes.  For the data/size form, the type `T` must be a character type:
`char`, `const char`, `unsigned char`, `const unsigned char`, `signed char`, or
`const signed char`.  For the container form, the container can be a
`std::vector`, `std::array`, or `std::basic_string` of a character type, or any
other type with a `data()` method that returns a possibly-`const` `char *`,
`signed char *`, or `unsigned char *`, and a `size()` method that returns a size
in bytes.  Google's `absl::string_view` is one example of such a type.

If given a pointer to a `const` character type or a `const` reference to a
container, `Make`*`Struct`*`View` will return a read-only view; otherwise
it will return a read-write view.

The result of `Make`*`Struct`*`View` should be stored in an `auto` variable:

```c++
auto view = MakeFooView(byte_buffer, available_byte_count);
```

The specific type returned by `Make`*`Struct`*`View` is subject to change.


### `CopyFrom` method

```c++
template <typename OtherStorage>
void CopyFrom(GenericStructView<OtherStorage> other) const;
```

The `CopyFrom` method copies data from the view `other` into the current view.
When complete, the current view's backing storage will contain the same bytes
as `other`.  This works even if the view's backing storage overlaps, in which
case `other`'s backing storage is modified by the operation.

### `UncheckedCopyFrom` method

```c++
template <typename OtherStorage>
void UncheckedCopyFrom(GenericStructView<OtherStorage> other) const;
```

The `UncheckedCopyFrom` method performs the same operation as `CopyFrom` but
without any checks on the integrity of or the compatibility of the two views.

### `TryToCopyFrom` method

```c++
template <typename OtherStorage>
bool TryToCopyFrom(GenericStructView<OtherStorage> other) const;
```

`TryToCopyFrom` copies data from `other` into the current view, if `other` is
`Ok()` and the current backing storage is large enough to hold `other`'s data.

### `Equals` method

```c++
template <typename OtherStorage>
bool Equals(GenericStructView<OtherStorage> other);
```

The `Equals` method returns `true` if and only if itself and `other` contain the
same fields yielding equivalent values (as measured by the `==` operator).
`Equals()` should only be called if `Ok()` is true on both views.

### `UncheckedEquals` method

```c++
template <typename OtherStorage>
bool UncheckedEquals(GenericStructView<OtherStorage> other);
```

The `UncheckedEquals` method performs the same operation as `Equals`, but
without any checks on the integrity of or the compatibility of the two views
when reading values.  `UncheckedEquals()` should only be called if `Ok()` is
true on both views.

### `Ok` method

```c++
bool Ok() const;
```

The `Ok` method returns `true` if and only if there are enough bytes in the
backing store, and the `Ok` methods of all active fields return `true`.


### `IsComplete` method

```c++
bool IsComplete() const;
```

The `IsComplete` method returns `true` if there are enough bytes in the backing
store to fully contain the `struct`.  If `IsComplete()` returns `true` but
`Ok()` returns `false`, then the structure is broken in some way that cannot be
fixed by adding more bytes.


### `IntrinsicSizeInBytes` method

```c++
auto IntrinsicSizeInBytes() const;
```

or

```c++
static constexpr auto IntrinsicSizeInBytes() const;
```

The `IntrinsicSizeInBytes` method is the [field method](#struct-field-methods)
for [`$size_in_bytes`](language-reference.md#size-in-bytes).  The `Read` method
of the result returns the size of the `struct`, and the `Ok` method returns
`true` if the `struct`'s intrinsic size is known; i.e.:

```c++
if (view.IntrinsicSizeInBytes().Ok()) {
  // The exact return type of view.IntrinsicSizeInBytes().Read() may vary, but
  // it will always be implicitly convertible to std::uint64_t.
  std::uint64_t view_size = view.IntrinsicSizeInBytes().Read();
}
```

Alternately, if you are sure the size is known:

```c++
std::uint64_t view_size = view.IntrinsicSizeInBytes().UncheckedRead();
```

Or, if the size is a compile-time constant:

```c++
constexpr std::uint64_t view_size = StructView::IntrinsicSizeInBytes().Read();
constexpr std::uint64_t view_size2 = Struct::IntrinsicSizeInBytes();
```


### `MaxSizeInBytes` method

```c++
auto MaxSizeInBytes() const;
```

or

```c++
static constexpr auto MaxSizeInBytes() const;
```

The `MaxSizeInBytes` method is the [field method](#struct-field-methods)
for [`$max_size_in_bytes`](language-reference.md#max-size-in-bytes).  The `Read`
method of the result returns the maximum size of the `struct`, and the `Ok`
always method returns `true`.

```c++
assert(view.MaxSizeInBytes().Ok());
// The exact return type of view.MaxSizeInBytes().Read() may vary, but it will
// always be implicitly convertible to std::uint64_t.
std::uint64_t view_size = view.MaxSizeInBytes().Read();
```

Alternately:

```c++
std::uint64_t view_size = view.MaxSizeInBytes().UncheckedRead();
```

Or:

```c++
constexpr std::uint64_t view_size = StructView::MaxSizeInBytes().Read();
constexpr std::uint64_t view_size2 = Struct::MaxSizeInBytes();
```


### `MinSizeInBytes` method

```c++
auto MinSizeInBytes() const;
```

or

```c++
static constexpr auto MinSizeInBytes() const;
```

The `MinSizeInBytes` method is the [field method](#struct-field-methods)
for [`$min_size_in_bytes`](language-reference.md#max-size-in-bytes).  The `Read`
method of the result returns the minimum size of the `struct`, and the `Ok`
always method returns `true`.

```c++
assert(view.MinSizeInBytes().Ok());
// The exact return type of view.MinSizeInBytes().Read() may vary, but it will
// always be implicitly convertible to std::uint64_t.
std::uint64_t view_size = view.MinSizeInBytes().Read();
```

Alternately:

```c++
std::uint64_t view_size = view.MinSizeInBytes().UncheckedRead();
```

Or:

```c++
constexpr std::uint64_t view_size = StructView::MinSizeInBytes().Read();
constexpr std::uint64_t view_size2 = Struct::MinSizeInBytes();
```


### `SizeIsKnown` method

```c++
bool SizeIsKnown() const;
```

or

```c++
static constexpr bool SizeIsKnown() const;
```

The `SizeIsKnown` method is an alias of `IntrinsicSizeInBytes().Ok()`.

The `SizeIsKnown` method returns `true` if the size of the `struct` can be
determined from the bytes that are available.  For example, consider a `struct`
like:

```
struct Message:
  0 [+4]   UInt        payload_length (pl)
  4 [+pl]  UInt:8[pl]  payload
```

The `Message`'s view's `SizeIsKnown` method will return `true` if at least four
bytes are available in the backing store, because it can determine the actual
size of the message if at least four bytes can be read.  If the backing store
contains three or fewer bytes, then `SizeIsKnown` will be false.

Note that if the `struct` contains no dynamically-sized or dynamically-located
fields, then `SizeIsKnown` will be a `static constexpr` method that always
return `true`.


### `SizeInBytes` method

```c++
std::size_t SizeInBytes() const;
```

or

```c++
static constexpr std::size_t SizeInBytes() const;
```

The `SizeInBytes` method returns
`static_cast<std::size_t>(IntrinsicSizeInBytes().Read())`.

The `SizeInBytes` method returns the size of the `struct` in bytes.
`SizeInBytes` asserts that `SizeIsKnown()`, so applications should ensure that
`SizeIsKnown()` before calling `SizeInBytes`.

If the `struct` contains no dynamically-sized or dynamically-located fields,
then `SizeInBytes` will be a `static constexpr` method, and can always be called
safely.


### `UpdateFromTextStream` method

```c++
template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;
```

`UpdateFromTextStream` will read a text-format representation of the structure
from the given `stream` and update fields.  Generally, applications would not
call this directly; instead, use the global `UpdateFromText` method, which
handles setting up a stream from a `std::string`.

### `WriteToTextStream` method

```c++
template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;
```

`WriteToTextStream` will write a text representation of the current value in a
form that can be decoded by `UpdateFromTextStream`. Generally, applications
would not call this directly; instead, use the global `WriteToString` method,
which handles setting up the stream and returning the resulting string.

### `BackingStorage` method

```c++
Storage BackingStorage() const;
```

Returns the backing storage for the view.  The return type of `BackingStorage()`
is a template parameter on the view.


### Field methods {#struct-field-methods}

Each physical field and virtual field in the `struct` will have a corresponding
method in the generated view for that `struct`, which returns a subview of that
field.  For example, take the `struct` definition:

```
struct Foo:
  0 [+4]  UInt  bar
  4 [+4]  Int   baz
  let qux = 2 * bar
  let bar_alias = bar
```

In this case, the generated code will have methods

```c++
auto bar() const;
auto baz() const;
auto qux() const;
auto bar_alias() const;
```

The `bar` method will return a `UInt` view, and `baz()` will return an `Int`
view.  The `qux` method will return a pseudo-`UInt` view which can only be read.
The `bar_alias` method actually forwards to `bar`, and can be both read and
written:

```c++
auto foo_view = MakeFooView(&vector_of_foo_bytes);
uint32_t bar_value = foo_view.bar().Read();
int32_t baz_value = foo_view.baz().Read();
int64_t qux_value = foo_view.qux().Read();
uint32_t bar_alias_value = foo_view.bar_alias().Read();
foo_view.bar_alias().Write(100);
assert(foo_view.bar().Read() == 100);
```

As with `Make`*`Struct`*`View`, the exact return type of field methods is
subject to change; if a field's view must be stored, use an `auto` variable.

Fields in anonymous `bits` are treated as if they were fields of the enclosing
`struct` in the generated code.  Take this `struct`:

```
struct Foo:
  0 [+4]  bits:
    5 [+5]  UInt  bar
```

In C++, `bar` would be read like so:

```c++
auto foo_view = MakeFooView(&vector_of_foo_bytes);
uint8_t bar_value = foo_view.bar().Read();
```

For each field, there is a `has_`*`field`*`()` method, which returns an object.
`has_` methods are typically used for conditional fields.  Suppose you have a
`struct` like:

```
struct Foo:
  0 [+1]  enum  message_type:
    BAR = 1
  if message_type == MessageType.BAR:
    1 [+25]  Bar  bar
```

When you have a view of a `Foo`, you can call `foo_view.has_bar().Known()` to
find out whether `foo_view` has enough information to determine if the field
`bar` should exist.  If it does `.Known()` returns `true`, you may call
`foo_view.has_bar().Value()` to find out if `bar` should exist.  You can also
call `foo_view.has_bar().ValueOr(false)`, which will return `true` if `bar`'s
status is known, and `bar` exists.

Every field will have a corresponding `has_` method.  In the example above,
`foo_view.has_message_type().Known()` and `foo_view.has_message_type().Value()`
are both supported calls; both will always return `true`.

Note that just because a field "exists," that does not mean that it can be read
from or written to the current message: the field's bytes might be missing, or
present but contain a non-`Ok()` value.  You can use `view.field().Ok()` to
determine if the field can be *read*, and `view.field().IsComplete()` to
determine if the field can be *written*.


### Constant Virtual Fields

Virtual fields whose values are compile-time constants can be read without
instantiating a view:

```
struct Foo:
  let register_number = 0xf8
  0 [+4]  UInt  foo
```

```
// Foo::register_number() is a constexpr function.
static_assert(Foo::register_number() == 0xf8);
```


### *`field`*`().Ok()` vs *`field`*`().IsComplete()` vs `has_`*`field`*`()`

Emboss provides a number of methods to query different kinds of validity.

`has_`*`field`*`()` is used for checking the existence condition specified in
the `.emb` file:

```
struct Foo:
  0 [+1]    UInt  x
  if x < 10:
    1 [+1]  UInt  y
```

In the .cc file:

```c++
::std::array<char, 2> bytes = { 5, 7 };
auto foo = MakeFooView(&bytes);
assert(foo.x().Read() == 5);

// foo.x() is readable, so the existence condition on y is known.
assert(foo.has_y().Known());

// foo.x().Read() < 10, so y exists in foo.
assert(foo.has_y().Value());

foo.x().Write(15);

// foo.x().Read() >= 10, so y no longer exists in foo.
assert(foo.has_y().Known());
assert(!foo.has_y().Value());

// foo.has_x() is always true, since x's existence condition is just "true".
assert(foo.has_x().Known());
assert(foo.has_x().Value());

// incomplete_foo has 0 bytes of backing storage, so x is unreadable.
auto incomplete_foo = MakeFooView(&bytes[0], 0);

// incomplete_foo.has_x() is known, since it does not depend on anything.
assert(incomplete_foo.has_x().Known());
assert(incomplete_foo.has_x().Value());

// incomplete_foo.x().Ok() is false, since x cannot be read.
assert(!incomplete_foo.x().Ok());

// Since x cannot be read, incomplete_foo.has_y().Known() is false.
assert(!incomplete_foo.has_y().Known());

// Since has_y() is not Known(), calling has_y().Value() will crash if Emboss
// assertions are enabled.
// incomplete_foo.has_y().Value()  // Would crash

// It is safe to call has_y().ValueOr(false).
assert(!incomplete_foo.has_y().ValueOr(false));
```

`has_`*`field`*`()` is notional: it queries whether *`field`* *should* be
present in the view.  Even if `has_`*`field`*`().Value()` is `true`,
*`field`*`().IsComplete()` and *`field`*`().Ok()` might return `false`.

*`field`*`().IsComplete()` tests if there are enough bytes in the backing
storage to hold *`field`*.  If *`field`*`().IsComplete()`, it is safe to call
`Write()` on the field with a valid value for that field.  *`field`*`().Ok()`
tests if there are enough bytes in the backing storage to hold *`field`*, *and*
that those bytes contain a valid value for *`field`*:

```
struct Bar:
  0 [+1]  Bcd  x
  1 [+1]  Bcd  y
```

```c++
::std::array<char, 1> bytes = { 0xbb };  // Not a valid BCD number.
auto bar = MakeBarView(&bytes);

// There are enough bytes to read and write x.
assert(bar.x().IsComplete());

// The value in x is not correct.
assert(!bar.x().Ok());

// Read() would crash if assertions are enabled.
// bar.x().Read();

// Writing a valid value is safe.
bar.x().Write(99);
assert(bar.x().Ok());

// Notionally, bar should have y, even though y's byte is not available:
assert(bar.has_y().Value());

// Since there is no byte to read y from, y is not complete:
assert(!bar.y().IsComplete());
```

Note that all views have `Ok()` and `IsComplete()` methods.  A view of a
structure is `Ok()` if all of its fields are either `Ok()` or not present, and
`has_`*`field`*`().Known()` is `true` for all fields.

A structure view `IsComplete()` if its `SizeIsKnown()` and its backing storage
contains at least `SizeInBits()` or `SizeInBytes()` bits or bytes.  In other
words: `IsComplete()` is true if Emboss can determine that (just) adding more
bytes to the view's backing storage won't help.  Note that just because
`IsComplete()` is false, that does not mean that adding more bytes *will* help.
It is possible to define incoherent structures that will confuse Emboss, such
as:

```
struct SizeNeverKnown:
  if false:
    0   [+1]  UInt  x_loc
  x_loc [+1]  UInt  x
```

<!-- TODO(bolms): Rename "existence condition" to "presence condition." -->


## `bits` Views

The code generated for a `bits` construct is very similar to the code generated
for a `struct`.  The primary differences are that there is no
`Make`*`Bits`*`View` function and that `SizeInBytes` is replaced by
`SizeInBits`.


### `Ok` method

```c++
bool Ok() const;
```

The `Ok` method returns `true` if and only if there are enough bytes in the
backing store, and the `Ok` methods of all active fields return `true`.


### `IsComplete` method

```c++
bool IsComplete() const;
```

The `IsComplete` method returns `true` if there are enough bytes in the backing
store to fully contain the `bits`.  If `IsComplete()` returns `true` but
`Ok()` returns `false`, then the structure is broken in some way that cannot be
fixed by adding more bytes.


### `IntrinsicSizeInBits` method

```c++
auto IntrinsicSizeInBits() const;
```

or

```c++
static constexpr auto IntrinsicSizeInBits() const;
```

The `IntrinsicSizeInBits` method is the [field method](#bits-field-methods) for
[`$size_in_bits`](language-reference.md#size-in-bits).  The `Read` method of
the result returns the size of the `struct`, and the `Ok` method returns `true`
if the `struct`'s intrinsic size is known; i.e.:

```c++
if (view.IntrinsicSizeInBits().Ok()) {
  std::uint64_t view_size = view.IntrinsicSizeInBits().Read();
}
```

Since the intrinsic size of a `bits` is always a compile-time constant:

```c++
constexpr std::uint64_t view_size = BitsView::IntrinsicSizeInBits().Read();
constexpr std::uint64_t view_size2 = Bits::IntrinsicSizeInBits();
```


### `MaxSizeInBits` method

```c++
auto MaxSizeInBits() const;
```

or

```c++
static constexpr auto MaxSizeInBits() const;
```

The `MaxSizeInBits` method is the [field method](#struct-field-methods)
for [`$max_size_in_bits`](language-reference.md#max-size-in-bits).  The `Read`
method of the result returns the maximum size of the `bits`, and the `Ok`
always method returns `true`.

```c++
assert(view.MaxSizeInBits().Ok());
// The exact return type of view.MaxSizeInBits().Read() may vary, but it will
// always be implicitly convertible to std::uint64_t.
std::uint64_t view_size = view.MaxSizeInBits().Read();
```

Alternately:

```c++
std::uint64_t view_size = view.MaxSizeInBits().UncheckedRead();
```

Or:

```c++
constexpr std::uint64_t view_size = StructView::MaxSizeInBits().Read();
constexpr std::uint64_t view_size2 = Struct::MaxSizeInBits();
```


### `MinSizeInBits` method

```c++
auto MinSizeInBits() const;
```

or

```c++
static constexpr auto MinSizeInBits() const;
```

The `MinSizeInBits` method is the [field method](#struct-field-methods)
for [`$min_size_in_bits`](language-reference.md#min-size-in-bits).  The `Read`
method of the result returns the minimum size of the `bits`, and the `Ok`
always method returns `true`.

```c++
assert(view.MinSizeInBits().Ok());
// The exact return type of view.MinSizeInBits().Read() may vary, but it will
// always be implicitly convertible to std::uint64_t.
std::uint64_t view_size = view.MinSizeInBits().Read();
```

Alternately:

```c++
std::uint64_t view_size = view.MinSizeInBits().UncheckedRead();
```

Or:

```c++
constexpr std::uint64_t view_size = StructView::MinSizeInBits().Read();
constexpr std::uint64_t view_size2 = Struct::MinSizeInBits();
```


### `SizeIsKnown` method

```c++
static constexpr bool SizeIsKnown() const;
```

For a `bits` construct, `SizeIsKnown()` always returns `true`, because the size
of a `bits` construct is always statically known at compilation time.


### `SizeInBits` method

```c++
static constexpr std::size_t SizeInBits() const;
```

The `SizeInBits` method returns the size of the `bits` in bits.  It is
equivalent to `static_cast<std::size_t>(IntrinsicSizeInBits().Read())`.


### `UpdateFromTextStream` method

```c++
template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;
```

`UpdateFromTextStream` will read a text-format representation of the structure
from the given `stream` and update fields.  Generally, applications would not
call this directly; instead, use the global `UpdateFromText` method, which
handles setting up a stream from a `std::string`.

### `WriteToTextStream` method

```c++
template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;
```

`WriteToTextStream` will write a text representation of the current value in a
form that can be decoded by `UpdateFromTextStream`. Generally, applications
would not call this directly; instead, use the global `WriteToString` method,
which handles setting up the stream and returning the resulting string.

### Field methods {#bits-field-methods}

As with `struct`, each field in a `bits` will have a corresponding method of the
same name generated, and each such method will return a view of the given field.
Take the module:

```
bits Bar:
  0 [+12]  UInt  baz
  31 [+1]  Flag  qux
  let two_baz = baz * 2

struct Foo:
  0 [+4]  Bar  bar
```

In this case, the generated code in the `Bar` view will have methods

```c++
auto baz() const;
auto qux() const;
auto two_baz() const;
```

The `baz` method will return a `UInt` view, and `qux()` will return a `Flag`
view:

```c++
auto foo_view = MakeFooView(&vector_of_foo_bytes);
uint16_t baz_value = foo_view.bar().baz().Read();
bool qux_value = foo_view.bar().qux().Read();
uint32_t two_baz_value = foo_view.bar().two_baz().Read();
```

The exact return type of field methods is subject to change; if a field's view
must be stored, use an `auto` variable.


## `enum`s

For each `enum` in an `.emb`, the Emboss compiler will generate a corresponding
C++11-style `enum class`.  Take the following Emboss `enum`:

```
enum Foo:
  BAR = 1
  BAZ = 1000
```

Emboss will generate something equivalent to the following C++:

```c++
enum class Foo : uint64_t {
  BAR = 1,
  BAZ = 1000,
};
```

Additionally, like other Emboss entities, `enum`s have corresponding view
classes.


### `TryToGetEnumFromName` free function

```c++
static inline bool TryToGetEnumFromName(const char *name, EnumType *result);
```

The `TryToGetEnumFromName` function will try to match `name` against the names
in the Emboss `enum` definition.  If it finds an exact match, it will return
`true` and update `result` with the corresponding enum value.  If it does not
find a match, it will return `false` and leave `result` unchanged.

Note that `TryToGetNameFromEnum` will not match the text of the numeric value of
an enum; given the `Foo` enum above, `TryToGetEnumFromName("1000", &my_foo)`
would return `false`.


### `TryToGetNameFromEnum` free function

```c++
static inline const char *TryToGetNameFromEnum(EnumType value);
```

`TryToGetNameFromEnum` will attempt to find the textual name for the
corresponding enum value.  If a name is found, it will be returned; otherwise
`TryToGetEnumFromName` will return `nullptr`.  (Note that C++ enums are allowed
to contain numeric values that are not explicitly listed in the enum definition,
as long as they are in range for the underlying integral type.)  If the given
value has more than one name, the first name that appears in the Emboss
definition will be returned.


### `Read` method

```c++
EnumType Read() const;
```

The `Read` method reads the enum from the underlying bytes and returns its
value as a C++ enum.  `Read` will assert that there are enough bytes to read.
If the application cannot tolerate a failed assertion, it should first call
`Ok()` to ensure that it can safely read the enum.  If performance is critical
and the application can assure that there will always be enough bytes to read
the enum, it can call `UncheckedRead` instead.


### `UncheckedRead` method

```c++
EnumType UncheckedRead() const;
```

Like `Read`, `UncheckedRead` reads the enum from the underlying bytes and
returns it value as a C++ enum.  Unlike `Read`, `UncheckedRead` does not attempt
to validate that there are enough bytes in the backing store to actually perform
the read.  In performance-critical situations, if the application is otherwise
able to ensure that there are sufficient bytes in the backing store to read the
enum, `UncheckedRead` may be used.


### `Write` method

```c++
void Write(EnumType value) const;
```

`Write` writes the `value` into the backing store.  Like `Read`, `Write` asserts
that there are enough bytes in the backing store to safely write the enum.  If
the application cannot tolerate an assertion failure, it can use `TryToWrite` or
the combination of `IsComplete` and `CouldWriteValue`.


### `TryToWrite` method

```c++
bool TryToWrite(EnumType value) const;
```

`TryToWrite` attempts to write the `value` into the backing store.  If the
backing store does not have enough bytes to hold the enum field, or `value` is
too large for the specific enum field, then `TryToWrite` will return `false` and
not update anything.


### `CouldWriteValue` method

```c++
static constexpr bool CouldWriteValue(EnumType value);
```

`CouldWriteValue` returns `true` if the given `value` could be written into the
enum field, assuming that there were enough bytes in the backing store to cover
the field.

Although `CouldWriteValue` is `static constexpr`, it is tricky to call
statically; client code that wishes to call it statically must use `decltype`
and `declval` to get the specific type for the specific enum *field* in
question.


### `UncheckedWrite` method

```c++
void UncheckedWrite(EnumType value) const;
```

Like `Write`, `UncheckedWrite` writes the given value to the backing store.
Unlike `Write`, `UncheckedWrite` does not check that there are actually enough
bytes in the backing store to safely write; it should only be used if the
application has ensured that there are sufficient bytes in the backing store in
some other way, and performance is a concern.


### `Ok` method

```c++
bool Ok() const;
```

`Ok` returns `true` if there are enough bytes in the backing store for the enum
field to be read or written.

In the future, Emboss may add a "known values only" annotation to enum fields,
in which case `Ok` would also check that the given field contains a known value.


### `IsComplete` method

```c++
bool IsComplete() const;
```

`IsComplete` returns `true` if there are enough bytes in the backing store for
the enum field to be read or written.


### `UpdateFromTextStream` method

```c++
template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;
```

`UpdateFromTextStream` will read a text-format representation of the enum from
the given `stream` and write it into the backing store.  Generally, applications
would not call this directly; instead, use the global `UpdateFromText` method,
which handles setting up a stream from a `std::string`.

### `WriteToTextStream` method

```c++
template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;
```

`WriteToTextStream` will write a text representation of the current value in a
form that can be decoded by `UpdateFromTextStream`. Generally, applications
would not call this directly; instead, use the global `WriteToString` method,
which handles setting up the stream and returning the resulting string.

## Arrays

### `operator[]` method

```c++
ElementView operator[](size_t index) const;
```

The `operator[]` method of an array view returns a view of the array element at
`index`.

### `begin()`/`rbegin()` and `end()`/`rend()` methods

```c++
ElementViewIterator<> begin();
ElementViewIterator<> end();
ElementViewIterator<> rbegin();
ElementViewIterator<> rend();
```

The `begin()` and `end()` methods of an array view returns view iterators to the
beginning and past-the-end of the array, respectively. They may be used with
arrays in range-based for loops, for example:

```c++
  auto view = MakeArrayView(...);
  for(auto element : view){
    int a = view.member().Read();
    ...
  }
```

The `rbegin()` and `rend()` methods of an array view returns reverse view
iterators to the end and element preceding the first, respectively.

### `SizeInBytes` or `SizeInBits` method

```c++
size_t SizeInBytes() const;
```

or

```c++
size_t SizeInBits() const;
```

Arrays in `struct`s have the `SizeInBytes` method; arrays in `bits` have the
`SizeInBits` method.  `SizeInBytes` returns the size of the array in bytes;
`SizeInBits` returns the size of the array in bits.


### `ElementCount` method

```c++
size_t ElementCount() const;
```

`ElementCount` returns the number of elements in the array.


### `Ok` method

```c++
bool Ok() const;
```

`Ok` returns `true` if there are enough bytes in the backing store to hold the
entire array, and every element's `Ok` method returns `true`.


### `IsComplete` method

```c++
bool IsComplete() const;
```

`IsComplete` returns `true` if there are sufficient bytes in the backing store
to hold the entire array.


### `ToString` method

```c++
template <class String>
String ToString() const;
```

Intended usage:

```c++
// Makes a copy of view's backing storage.
auto str = view.ToString<std::string>();

// Points to view's backing storage.
auto str_view = view.ToString<std::string_view>();
```

`ToString()` returns a string type constructed from the backing storage of the
array.  Note that `ToString()` is only enabled for arrays of 1-byte values,
such as `UInt:8[]`, and only when the array view's underlying storage is
contiguous.

Although it is intended for use with `std::string` and `std::string_view`,
`ToString()` can work with any C++ type that:

1.  Has a `data()` method that returns a pointer to the string's underlying
    data as a `char` type.
2.  Has a constructor that accepts a `const declval(data())` pointer and a
    `size_t` length.


### `UpdateFromTextStream` method

```c++
template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;
```

`UpdateFromTextStream` will read a text-format representation of the structure
from the given `stream` and update array elements.  Generally, applications
would not call this directly; instead, use the global `UpdateFromText` method,
which handles setting up a stream from a `std::string`.

### `WriteToTextStream` method

```c++
template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;
```

`WriteToTextStream` will write a text representation of the current value in a
form that can be decoded by `UpdateFromTextStream`. Generally, applications
would not call this directly; instead, use the global `WriteToString` method,
which handles setting up the stream and returning the resulting string.

### `BackingStorage` method

```c++
Storage BackingStorage() const;
```

Returns the backing storage for the view.  The return type of `BackingStorage()`
is a template parameter on the view.

## `UInt`

### Type `ValueType`

```c++
using ValueType = ...;
```

The `ValueType` type alias maps to the least-width C++ unsigned integer type
that contains enough bits to hold any value of the given `UInt`.  For example:

*   a `UInt:32`'s `ValueType` would be `uint32_t`
*   a `UInt:64`'s `ValueType` would be `uint64_t`
*   a `UInt:12`'s `ValueType` would be `uint16_t`
*   a `UInt:2`'s `ValueType` would be `uint8_t`

The `Read` and `Write` families of methods use `ValueType` to return or accept
values, respectively.


### `Read` method

```c++
ValueType Read() const;
```

The `Read` method reads the `UInt` from the underlying bytes and returns its
value as a C++ unsigned integer type.  `Read` will assert that there are enough
bytes to read.  If the application cannot tolerate a failed assertion, it should
first call `Ok()` to ensure that it can safely read the `UInt`.  If performance
is critical and the application can assure that there will always be enough
bytes to read the `UInt`, it can call `UncheckedRead` instead.


### `UncheckedRead` method

```c++
ValueType UncheckedRead();
```

Like `Read`, `UncheckedRead` reads the `UInt` from the underlying bytes and
returns it value as a C++ unsigned integer type.  Unlike `Read`, `UncheckedRead`
does not attempt to validate that there are enough bytes in the backing store to
actually perform the read.  In performance-critical situations, if the
application is otherwise able to ensure that there are sufficient bytes in the
backing store to read the `UInt`, `UncheckedRead` may be used.


### `Write` method

```c++
void Write(ValueType value);
```

`Write` writes the `value` into the backing store.  Like `Read`, `Write` asserts
that there are enough bytes in the backing store to safely write the `UInt`.  If
the application cannot tolerate an assertion failure, it can use `TryToWrite` or
the combination of `IsComplete` and `CouldWriteValue`.


### `TryToWrite` method

```c++
bool TryToWrite(ValueType value);
```

`TryToWrite` attempts to write the `value` into the backing store.  If the
backing store does not have enough bytes to hold the `UInt` field, or `value` is
too large for the `UInt` field, then `TryToWrite` will return `false` and not
update anything.


### `CouldWriteValue` method

```c++
static constexpr bool CouldWriteValue(ValueType value);
```

`CouldWriteValue` returns `true` if the given `value` could be written into the
`UInt` field, assuming that there were enough bytes in the backing store to
cover the field.

Although `CouldWriteValue` is `static constexpr`, it is tricky to call
statically; client code that wishes to call it statically must use `decltype`
and `declval` to get the specific type for the specific `UInt` field in
question.


### `UncheckedWrite` method

```c++
void UncheckedWrite(ValueType value);
```

Like `Write`, `UncheckedWrite` writes the given value to the backing store.
Unlike `Write`, `UncheckedWrite` does not check that there are actually enough
bytes in the backing store to safely write; it should only be used if the
application has ensured that there are sufficient bytes in the backing store in
some other way, and performance is a concern.


### `Ok` method

```c++
bool Ok() const;
```

The `Ok` method returns `true` if there are enough bytes in the backing store to
hold the given `UInt` field.


### `IsComplete` method

```c++
bool IsComplete();
```

The `IsComplete` method returns `true` if there are enough bytes in the backing
store to hold the given `UInt` field.


### `UpdateFromTextStream` method

```c++
template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;
```

`UpdateFromTextStream` will read a text-format representation of the `UInt` from
the given `stream` and update fields.  Generally, applications would not call
this directly; instead, use the global `UpdateFromText` method, which handles
setting up a stream from a `std::string`.

### `WriteToTextStream` method

```c++
template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;
```

`WriteToTextStream` will write a text representation of the current value in a
form that can be decoded by `UpdateFromTextStream`. Generally, applications
would not call this directly; instead, use the global `WriteToString` method,
which handles setting up the stream and returning the resulting string.

### `SizeInBits` method

```c++
static constexpr int SizeInBits();
```

The `SizeInBits` method returns the size of this specific `UInt` field, in bits.


## `Int`

### Type `ValueType`

```c++
using ValueType = ...;
```

The `ValueType` type alias maps to the least-width C++ signed integer type
that contains enough bits to hold any value of the given `Int`.  For example:

*   a `Int:32`'s `ValueType` would be `int32_t`
*   a `Int:64`'s `ValueType` would be `int64_t`
*   a `Int:12`'s `ValueType` would be `int16_t`
*   a `Int:2`'s `ValueType` would be `int8_t`

The `Read` and `Write` families of methods use `ValueType` to return or accept
values, respectively.


### `Read` method

```c++
ValueType Read() const;
```

The `Read` method reads the `Int` from the underlying bytes and returns its
value as a C++ signed integer type.  `Read` will assert that there are enough
bytes to read.  If the application cannot tolerate a failed assertion, it should
first call `Ok()` to ensure that it can safely read the `Int`.  If performance
is critical and the application can assure that there will always be enough
bytes to read the `Int`, it can call `UncheckedRead` instead.


### `UncheckedRead` method

```c++
ValueType UncheckedRead();
```

Like `Read`, `UncheckedRead` reads the `Int` from the underlying bytes and
returns it value as a C++ signed integer type.  Unlike `Read`, `UncheckedRead`
does not attempt to validate that there are enough bytes in the backing store to
actually perform the read.  In performance-critical situations, if the
application is otherwise able to ensure that there are sufficient bytes in the
backing store to read the `Int`, `UncheckedRead` may be used.


### `Write` method

```c++
void Write(ValueType value);
```

`Write` writes the `value` into the backing store.  Like `Read`, `Write` asserts
that there are enough bytes in the backing store to safely write the `Int`.  If
the application cannot tolerate an assertion failure, it can use `TryToWrite` or
the combination of `IsComplete` and `CouldWriteValue`.


### `TryToWrite` method

```c++
bool TryToWrite(ValueType value);
```

`TryToWrite` attempts to write the `value` into the backing store.  If the
backing store does not have enough bytes to hold the `Int` field, or `value` is
too large for the `Int` field, then `TryToWrite` will return `false` and not
update anything.


### `CouldWriteValue` method

```c++
static constexpr bool CouldWriteValue(ValueType value);
```

`CouldWriteValue` returns `true` if the given `value` could be written into the
`Int` field, assuming that there were enough bytes in the backing store to cover
the field.

Although `CouldWriteValue` is `static constexpr`, it is tricky to call
statically; client code that wishes to call it statically must use `decltype`
and `declval` to get the specific type for the specific `Int` field in question.


### `UncheckedWrite` method

```c++
void UncheckedWrite(ValueType value);
```

Like `Write`, `UncheckedWrite` writes the given value to the backing store.
Unlike `Write`, `UncheckedWrite` does not check that there are actually enough
bytes in the backing store to safely write; it should only be used if the
application has ensured that there are sufficient bytes in the backing store in
some other way, and performance is a concern.


### `Ok` method

```c++
bool Ok() const;
```

The `Ok` method returns `true` if there are enough bytes in the backing store to
hold the given `Int` field.


### `IsComplete` method

```c++
bool IsComplete();
```

The `IsComplete` method returns `true` if there are enough bytes in the backing
store to hold the given `Int` field.


### `UpdateFromTextStream` method

```c++
template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;
```

`UpdateFromTextStream` will read a text-format representation of the `Int` from
the given `stream` and update fields.  Generally, applications would not call
this directly; instead, use the global `UpdateFromText` method, which handles
setting up a stream from a `std::string`.

### `WriteToTextStream` method

```c++
template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;
```

`WriteToTextStream` will write a text representation of the current value in a
form that can be decoded by `UpdateFromTextStream`. Generally, applications
would not call this directly; instead, use the global `WriteToString` method,
which handles setting up the stream and returning the resulting string.

### `SizeInBits` method

```c++
static constexpr int SizeInBits();
```

The `SizeInBits` method returns the size of this specific `Int` field, in bits.


## `Bcd`

### Type `ValueType`

```c++
using ValueType = ...;
```

The `ValueType` type alias maps to a C++ unsigned integer type that contains
at least enough bits to hold any value of the given `Bcd`.  For example:

*   a `Bcd:32`'s `ValueType` would be `uint32_t`
*   a `Bcd:64`'s `ValueType` would be `uint64_t`
*   a `Bcd:12`'s `ValueType` would be `uint16_t`
*   a `Bcd:2`'s `ValueType` would be `uint8_t`

The `Read` and `Write` families of methods use `ValueType` to return or accept
values, respectively.


### `Read` method

```c++
ValueType Read() const;
```

The `Read` method reads the `Bcd` from the underlying bytes and returns its
value as a C++ unsigned integer type.  `Read` will assert that there are enough
bytes to read, and that the binary representation is a valid BCD integer.  If
the application cannot tolerate a failed assertion, it should first call `Ok()`
to ensure that it can safely read the `Bcd`.  If performance is critical and the
application can assure that there will always be enough bytes to read the `Bcd`,
and that the bytes will be a valid BCD value, it can call `UncheckedRead`
instead.


### `UncheckedRead` method

```c++
ValueType UncheckedRead();
```

Like `Read`, `UncheckedRead` reads the `Bcd` from the underlying bytes and
returns it value as a C++ unsigned integer type.  Unlike `Read`, `UncheckedRead`
does not attempt to validate that there are enough bytes in the backing store to
actually perform the read, nor that the bytes contain an actual BCD number.  In
performance-critical situations, if the application is otherwise able to ensure
that there are sufficient bytes in the backing store to read the `Bcd`,
`UncheckedRead` may be used.


### `Write` method

```c++
void Write(ValueType value);
```

`Write` writes the `value` into the backing store.  Like `Read`, `Write` asserts
that there are enough bytes in the backing store to safely write the `Bcd`.  If
the application cannot tolerate an assertion failure, it can use `TryToWrite` or
the combination of `IsComplete` and `CouldWriteValue`.


### `TryToWrite` method

```c++
bool TryToWrite(ValueType value);
```

`TryToWrite` attempts to write the `value` into the backing store.  If the
backing store does not have enough bytes to hold the `Bcd` field, or `value` is
too large for the `Bcd` field, then `TryToWrite` will return `false` and not
update anything.


### `CouldWriteValue` method

```c++
static constexpr bool CouldWriteValue(ValueType value);
```

`CouldWriteValue` returns `true` if the given `value` could be written into the
`Bcd` field, assuming that there were enough bytes in the backing store to cover
the field.

Although `CouldWriteValue` is `static constexpr`, it is tricky to call
statically; client code that wishes to call it statically must use `decltype`
and `declval` to get the specific type for the specific `Bcd` field in question.


### `UncheckedWrite` method

```c++
void UncheckedWrite(ValueType value);
```

Like `Write`, `UncheckedWrite` writes the given value to the backing store.
Unlike `Write`, `UncheckedWrite` does not check that there are actually enough
bytes in the backing store to safely write; it should only be used if the
application has ensured that there are sufficient bytes in the backing store in
some other way, and performance is a concern.


### `Ok` method

```c++
bool Ok() const;
```

The `Ok` method returns `true` if there are enough bytes in the backing store to
hold the given `Bcd` field, and the bytes contain a valid BCD number: that is,
that every nibble in the backing store contains a value between 0 and 9,
inclusive.


### `IsComplete` method

```c++
bool IsComplete();
```

The `IsComplete` method returns `true` if there are enough bytes in the backing
store to hold the given `Bcd` field.


### `UpdateFromTextStream` method

```c++
template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;
```

`UpdateFromTextStream` will read a text-format representation of the `Bcd` from
the given `stream` and update fields.  Generally, applications would not call
this directly; instead, use the global `UpdateFromText` method, which handles
setting up a stream from a `std::string`.

### `WriteToTextStream` method

```c++
template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;
```

`WriteToTextStream` will write a text representation of the current value in a
form that can be decoded by `UpdateFromTextStream`. Generally, applications
would not call this directly; instead, use the global `WriteToString` method,
which handles setting up the stream and returning the resulting string.

### `SizeInBits` method

```c++
static constexpr int SizeInBits();
```

The `SizeInBits` method returns the size of this specific `Bcd` field, in bits.


## `Flag`

### `Read` method

```c++
bool Read() const;
```

The `Read` method reads the `Flag` from the underlying bit and returns its
value as a C++ `bool`.  `Read` will assert that the underlying bit is in the
backing store.  If the application cannot tolerate a failed assertion, it should
first call `Ok()` to ensure that it can safely read the `Flag`.  If performance
is critical and the application can assure that there will always be enough
bytes to read the `Flag`, it can call `UncheckedRead` instead.


### `UncheckedRead` method

```c++
bool UncheckedRead();
```

Like `Read`, `UncheckedRead` reads the `Flag` from the underlying bit and
returns it value as a C++ bool.  Unlike `Read`, `UncheckedRead` does not attempt
to validate that the backing bit is actually in the backing store.  In
performance-critical situations, if the application is otherwise able to ensure
that there are sufficient bytes in the backing store to read the `Flag`,
`UncheckedRead` may be used.


### `Write` method

```c++
void Write(bool value);
```

`Write` writes the `value` into the backing store.  Like `Read`, `Write` asserts
that there are enough bytes in the backing store to safely write the `Flag`.  If
the application cannot tolerate an assertion failure, it can use `TryToWrite` or
the combination of `IsComplete` and `CouldWriteValue`.


### `TryToWrite` method

```c++
bool TryToWrite(bool value);
```

`TryToWrite` attempts to write the `value` into the backing store.  If the
backing store does not contain the `Flag`'s bit, then `TryToWrite` will return
`false` and not update anything.


### `CouldWriteValue` method

```c++
static constexpr bool CouldWriteValue(bool value);
```

`CouldWriteValue` returns `true`, as both C++ `bool` values can be written to
any `Flag`.


### `UncheckedWrite` method

```c++
void UncheckedWrite(ValueType value);
```

Like `Write`, `UncheckedWrite` writes the given value to the backing store.
Unlike `Write`, `UncheckedWrite` does not check that there are actually enough
bytes in the backing store to safely write; it should only be used if the
application has ensured that there are sufficient bytes in the backing store in
some other way, and performance is a concern.


### `Ok` method

```c++
bool Ok() const;
```

The `Ok` method returns `true` if the backing store contains the `Flag`'s bit.


### `IsComplete` method

```c++
bool IsComplete();
```

The `IsComplete` method returns `true` if the backing store contains the
`Flag`'s bit.


### `UpdateFromTextStream` method

```c++
template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;
```

`UpdateFromTextStream` will read a text-format representation of the `Flag` from
the given `stream` and update fields.  Generally, applications would not call
this directly; instead, use the global `UpdateFromText` method, which handles
setting up a stream from a `std::string`.

### `WriteToTextStream` method

```c++
template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;
```

`WriteToTextStream` will write a text representation of the current value in a
form that can be decoded by `UpdateFromTextStream`. Generally, applications
would not call this directly; instead, use the global `WriteToString` method,
which handles setting up the stream and returning the resulting string.

## `Float`

### Type `ValueType`

```c++
using ValueType = ...;
```

The `ValueType` type alias maps to the C++ floating-point type that matches the
`Float` field's type; generally `float` for 32-bit `Float`s and `double` for
64-bit `Float`s.

The `Read` and `Write` families of methods use `ValueType` to return or accept
values, respectively.


### `Read` method

```c++
ValueType Read() const;
```

The `Read` method reads the `Float` from the underlying bytes and returns its
value as a C++ floating point type.  `Read` will assert that there are enough
bytes to read.  If the application cannot tolerate a failed assertion, it should
first call `Ok()` to ensure that it can safely read the `Float`.  If performance
is critical and the application can assure that there will always be enough
bytes to read the `Float`, it can call `UncheckedRead` instead.


### `UncheckedRead` method

```c++
ValueType UncheckedRead();
```

Like `Read`, `UncheckedRead` reads the `Float` from the underlying bytes and
returns it value as a C++ floating point type.  Unlike `Read`, `UncheckedRead`
does not attempt to validate that there are enough bytes in the backing store to
actually perform the read.  In performance-critical situations, if the
application is otherwise able to ensure that there are sufficient bytes in the
backing store to read the `Float`, `UncheckedRead` may be used.


### `Write` method

```c++
void Write(ValueType value);
```

`Write` writes the `value` into the backing store.  Like `Read`, `Write` asserts
that there are enough bytes in the backing store to safely write the `Float`.
If the application cannot tolerate an assertion failure, it can use `TryToWrite`
or the combination of `IsComplete` and `CouldWriteValue`.


### `TryToWrite` method

```c++
bool TryToWrite(ValueType value);
```

`TryToWrite` attempts to write the `value` into the backing store.  If the
backing store does not have enough bytes to hold the `Float` field, then
`TryToWrite` will return `false` and not update anything.


### `CouldWriteValue` method

```c++
static constexpr bool CouldWriteValue(ValueType value);
```

`CouldWriteValue` returns `true`.


### `UncheckedWrite` method

```c++
void UncheckedWrite(ValueType value);
```

Like `Write`, `UncheckedWrite` writes the given value to the backing store.
Unlike `Write`, `UncheckedWrite` does not check that there are actually enough
bytes in the backing store to safely write; it should only be used if the
application has ensured that there are sufficient bytes in the backing store in
some other way, and performance is a concern.


### `Ok` method

```c++
bool Ok() const;
```

The `Ok` method returns `true` if there are enough bytes in the backing store to
hold the given `Float` field.


### `IsComplete` method

```c++
bool IsComplete();
```

The `IsComplete` method returns `true` if there are enough bytes in the backing
store to hold the given `Float` field.


### `UpdateFromTextStream` method

```c++
template <class Stream>
bool UpdateFromTextStream(Stream *stream) const;
```

`UpdateFromTextStream` will read a text-format representation of the `Float`
from the given `stream` and update fields.  Generally, applications would not
call this directly; instead, use the global `UpdateFromText` method, which
handles setting up a stream from a `std::string`.

*Note: this method is not yet implemented.*

### `WriteToTextStream` method

```c++
template <class Stream>
bool WriteToTextStream(Stream *stream, const TextOutputOptions &options) const;
```

`WriteToTextStream` will write a text representation of the current value in a
form that can be decoded by `UpdateFromTextStream`. Generally, applications
would not call this directly; instead, use the global `WriteToString` method,
which handles setting up the stream and returning the resulting string.

*Note: this method is not yet implemented.*


## `::emboss::UpdateFromText` function

```c++
template <typename EmbossViewType>
bool UpdateFromText(EmbossViewType view, const ::std::string &text) const;
```

The `::emboss::UpdateFromText` function constructs an appropriate text strem
object from the given `text` and calls `view`'s `UpdateFromTextStream` method.
This is the preferred way to read Emboss text format in C++.

## `::emboss::WriteToString` function

```c++
template <typename EmbossViewType>
::std::string WriteToString(EmbossViewType view);
template <typename EmbossViewType>
::std::string WriteToString(EmbossViewType view, TextOutputOptions options);
```

The `::emboss::WriteToString` function constructs a string stream, passes it
into the `view`'s `WriteToTextStream` method, and finally returns the text
format of the `view`.

The single-argument form `WriteToString(view)` will return a single line of
text. For more readable output, `WriteToString(view, ::emboss::MultilineText())`
should help.

## `::emboss::TextOutputOptions` class

The `TextOutputOptions` is used to set options for text output, such as numeric
base, whether or not to use multiple lines, etc.

### `PlusOneIndent` method

```c++
TextOutputOptions PlusOneIndent() const;
```

`PlusOneIndent` returns a new `TextOutputOptions` with one more level of
indentation than the current `TextOutputOptions`. This is primarily intended for
use inside of `WriteToTextStream` methods, as a way to get an indented
`TextOutputOptions` to pass to the `WriteToTextStream` methods of child
objects.  However, application callers may use `PlusOneIndent()`, possibly
multiple times, to indent the entire output.

### `Multiline` method

```c++
TextOutputOptions Multiline(bool new_value) const;
```

Returns a new `TextOutputOptions` with the same options as the current
`TextOutputOptions`, except for a new value for `multiline()`.

### `WithIndent` method

```c++
TextOutputOptions WithIndent(::std::string new_value) const;
```

Returns a new `TextOutputOptions` with the same options as the current
`TextOutputOptions`, except for a new value for `indent()`.

### `WithComments` method

```c++
TextOutputOptions WithComments(bool new_value) const;
```

Returns a new `TextOutputOptions` with the same options as the current
`TextOutputOptions`, except for a new value for `comments()`.

### `WithDigitGrouping` method

```c++
TextOutputOptions WithDigitGrouping(bool new_value) const;
```

Returns a new `TextOutputOptions` with the same options as the current
`TextOutputOptions`, except for a new value for `digit_grouping()`.

### `WithNumericBase` method

```c++
TextOutputOptions WithNumericBase(int new_value) const;
```

Returns a new `TextOutputOptions` with the same options as the current
`TextOutputOptions`, except for a new value for `digit_grouping()`. The new
numeric base should be 2, 10, or 16.

### `WithAllowPartialOutput` method

```c++
TextOutputOptions WithAllowPartialOutput(bool new_value) const;
```

Returns a new `TextOutputOptions` with the same options as the current
`TextOutputOptions`, except for a new value for `allow_partial_output()`.

### `current_indent` method

```c++
::std::string current_indent() const;  // Default "".
```

Returns the current indent string.

### `indent` method

```c++
::std::string indent() const;  // Default "  ".
```

Returns the indent string.  The indent string is the string used for a *single*
level of indentation.

### `multiline` method

```c++
bool multiline() const;  // Default false.
```

Returns `true` if text output should use multiple lines, or `false` if text
output should be single-line only.

### `digit_grouping` method

```c++
bool digit_grouping() const;  // Default false.
```

Returns `true` if text output should include digit separators on numbers; i.e.
`1_000_000` instead of `1000000`.

### `comments` method

```c++
bool comments() const;  // Default false.
```

Returns `true` if text output should include comments, e.g., to show numbers in
multiple bases.

### `numeric_base` method

```c++
uint8_t numeric_base() const;  // Default 10.
```

Returns the numeric base that should be used for formatting numbers. This should
always be 2, 10, or 16.

### `allow_partial_output` method

```c++
bool allow_partial_output() const;  // Default false.
```

Returns `true` if text output should attempt to extract fields from a view that
is not `Ok()`.  If so:

*   `WriteToString()` or `WriteToTextStream()` should never `CHECK`-fail.
*   Atomic fields (e.g., `Int`, `UInt`, `enum`, `Flag`, etc. types) will not be
    written to the text stream if they cannot be read.
*   If `comments()` is also `true`, unreadable atomic fields will be commented
    in the text stream.
*   Aggregate fields (`struct`, `bits`, or arrays) will be written, but may be
    missing fields or entirely empty if they have non-`Ok()` members.
