Skip to content

Commit

Permalink
[cpp] Fix natural types build issues when used with GIDL
Browse files Browse the repository at this point in the history
This CL includes fixes to breakages found when building FIDL files used
by GIDL

MaxOrdinal currently fails if the number of members is zero -- the index
becomes -1 and std::get fails. This CL fixes the issue by wrapping the
entire body by an "if constexpr".

Clone of arrays currently fails and this CL includes a working
implementation of clone.

Change-Id: I8672fbf2be72871399e37d364df4458a11e8a7ca
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/636582
Fuchsia-Auto-Submit: Benjamin Prosnitz <bprosnitz@google.com>
Reviewed-by: Ian McKellar <ianloic@google.com>
Commit-Queue: Benjamin Prosnitz <bprosnitz@google.com>
  • Loading branch information
Benjamin Prosnitz authored and Commit Bot committed Jan 25, 2022
1 parent 2f59a62 commit 079c48d
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions src/lib/fidl/cpp/include/lib/fidl/cpp/internal/natural_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,15 @@ struct NaturalTableCodingTraits {
// Returns the largest ordinal of a present table member.
template <size_t I = std::tuple_size_v<decltype(T::kMembers)> - 1>
static size_t MaxOrdinal(T* value) {
auto T::Storage_::*member_ptr = std::get<I>(T::kMembers).member_ptr;
const auto& member = value->storage_.*member_ptr;
if (member.has_value()) {
return I + 1;
}
if constexpr (I > 0) {
return MaxOrdinal<I - 1>(value);
} else {
if constexpr (I == -1) {
return 0;
} else {
auto T::Storage_::*member_ptr = std::get<I>(T::kMembers).member_ptr;
const auto& member = value->storage_.*member_ptr;
if (member.has_value()) {
return I + 1;
}
return MaxOrdinal<I - 1>(value);
}
}

Expand Down Expand Up @@ -278,6 +278,18 @@ struct NaturalCloneHelper<std::vector<T>> {
}
};

template <typename T, size_t N, std::size_t... Indexes>
std::array<T, N> ArrayCloneHelper(const std::array<T, N>& value, std::index_sequence<Indexes...>) {
return std::array<T, N>{NaturalCloneHelper<T>::Clone(std::get<Indexes>(value))...};
}

template <typename T, size_t N>
struct NaturalCloneHelper<std::array<T, N>> {
static std::array<T, N> Clone(const std::array<T, N>& value) {
return ArrayCloneHelper(value, std::make_index_sequence<N>());
}
};

template <typename T>
T NaturalClone(const T& value) {
return NaturalCloneHelper<T>::Clone(value);
Expand Down

0 comments on commit 079c48d

Please sign in to comment.