# 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.


### `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.

### `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.

### `current_indent` method

```c++
::std::string current_indent() const;
```

Returns the current indent string.

### `indent` method

```c++
::std::string indent() const;
```

Returns the indent string. The indent string is the string used for a single
level of indentation; most callers will prefer `current_indent`.

### `multiline` method

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

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;
```

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;
```

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;
```

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