Skip to content

Commit

Permalink
Make it possible to call Encode/Decode on a subclass of a cluster-obj…
Browse files Browse the repository at this point in the history
…ect struct. (#11014)

Our enable_if machinery for Encode/Decode only worked for structs of
type T if there was a T::Encode method.  That made it impossible to
subclass a struct (e.g. with the subclass providing backing storage
for the struct's Spans) and call Encode on the subclass instance
without jumping through some sort of testing hoops.

This change changes our test from "T::Encode exists with the right
signature" to "an instance of T has a .Encode that when called with
the right arguments returns the right return type", which lets
subclassing work as desired.
  • Loading branch information
bzbarsky-apple authored and pull[bot] committed Jul 12, 2023
1 parent 91889f7 commit 291a63b
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 9 deletions.
9 changes: 5 additions & 4 deletions src/app/data-model/Decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,11 @@ inline CHIP_ERROR Decode(TLV::TLVReader & reader, Span<const char> & x)
* CHIP_ERROR <Object>::Decode(TLVReader &reader);
*
*/
template <
typename X,
typename std::enable_if_t<
std::is_class<X>::value && std::is_same<decltype(&X::Decode), CHIP_ERROR (X::*)(TLV::TLVReader &)>::value, X> * = nullptr>
template <typename X,
typename std::enable_if_t<
std::is_class<X>::value &&
std::is_same<decltype(std::declval<X>().Decode(std::declval<TLV::TLVReader &>())), CHIP_ERROR>::value,
X> * = nullptr>
CHIP_ERROR Decode(TLV::TLVReader & reader, X & x)
{
return x.Decode(reader);
Expand Down
11 changes: 6 additions & 5 deletions src/app/data-model/Encode.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@ inline CHIP_ERROR Encode(TLV::TLVWriter & writer, TLV::Tag tag, Span<const char>
*
*
*/
template <
typename X,
typename std::enable_if_t<std::is_class<X>::value &&
std::is_same<decltype(&X::Encode), CHIP_ERROR (X::*)(TLV::TLVWriter &, TLV::Tag) const>::value,
X> * = nullptr>
template <typename X,
typename std::enable_if_t<
std::is_class<X>::value &&
std::is_same<decltype(std::declval<X>().Encode(std::declval<TLV::TLVWriter &>(), std::declval<TLV::Tag>())),
CHIP_ERROR>::value,
X> * = nullptr>
CHIP_ERROR Encode(TLV::TLVWriter & writer, TLV::Tag tag, const X & x)
{
return x.Encode(writer, tag);
Expand Down

0 comments on commit 291a63b

Please sign in to comment.