Skip to content

Commit

Permalink
Use List<const Whatever> for encodable lists. (#11006)
Browse files Browse the repository at this point in the history
We should not be requiring creation of non-const data to encode a list
if it can be backed by const data instead.

Another option would be to make List<T> inherit from Span<const T>,
but that makes some assumptions about whether people will want to
write to a buffer via its List representation.

The change to the List::operator= is because importing _all_ operator=
from the super-class, including the implicitly-defined ones, causes
assignments from List<T> to List<const T> to be ambiguous.  Forwarding
just the one operator= we want to forward fixes that.
  • Loading branch information
bzbarsky-apple authored and pull[bot] committed Feb 7, 2022
1 parent d9857ce commit 1669826
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 92 deletions.
8 changes: 7 additions & 1 deletion src/app/data-model/List.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,13 @@ struct List : public Span<T>
// List<T> instances as though they were just Spans.
//
using Span<T>::Span;
using Span<T>::operator=;

template <size_t N>
constexpr List & operator=(T (&databuf)[N])
{
Span<T>::operator=(databuf);
return (*this);
}
};

template <typename X>
Expand Down
12 changes: 10 additions & 2 deletions src/app/zap-templates/templates/app/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -375,11 +375,19 @@ async function zapTypeToClusterObjectType(type, isDecodable, options)
let promise = templateUtil.ensureZclPackageId(this).then(fn.bind(this));
if ((this.isList || this.isArray || this.entryType) && !options.hash.forceNotList) {
passByReference = true;
let listType = isDecodable ? "DecodableList" : "List";
// If we did not have a namespace provided, we can assume we're inside
// chip::app.
let listNamespace = options.hash.ns ? "chip::app::" : ""
promise = promise.then(typeStr => `${listNamespace}DataModel::${listType}<${typeStr}>`);
if (isDecodable)
{
promise = promise.then(typeStr => `${listNamespace}DataModel::DecodableList<${typeStr}>`);
}
else
{
// Use const ${typeStr} so that consumers don't have to create non-const
// data to encode.
promise = promise.then(typeStr => `${listNamespace}DataModel::List<const ${typeStr}>`);
}
}
if (this.isNullable && !options.hash.forceNotNullable) {
passByReference = true;
Expand Down
Loading

0 comments on commit 1669826

Please sign in to comment.