Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51bfc524 authored by Ytai Ben-Tsvi's avatar Ytai Ben-Tsvi
Browse files

Extract union utilities

Useful in other places.

Test: Compiles
Change-Id: I5e3fdd60348c3e47f2cf4582790b82583c0fafee
parent c54d504c
Loading
Loading
Loading
Loading
+0 −23
Original line number Diff line number Diff line
@@ -109,29 +109,6 @@ bool bitmaskIsSet(Mask mask, Enum index) {
    return (mask & enumToMask_index<Mask, Enum>(index)) != 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Utilities for working with AIDL unions.
// UNION_GET(obj, fieldname) returns a ConversionResult<T> containing either the strongly-typed
//   value of the respective field, or BAD_VALUE if the union is not set to the requested field.
// UNION_SET(obj, fieldname, value) sets the requested field to the given value.

template<typename T, typename T::Tag tag>
using UnionFieldType = std::decay_t<decltype(std::declval<T>().template get<tag>())>;

template<typename T, typename T::Tag tag>
ConversionResult<UnionFieldType<T, tag>> unionGetField(const T& u) {
    if (u.getTag() != tag) {
        return unexpected(BAD_VALUE);
    }
    return u.template get<tag>();
}

#define UNION_GET(u, field) \
    unionGetField<std::decay_t<decltype(u)>, std::decay_t<decltype(u)>::Tag::field>(u)

#define UNION_SET(u, field, value) \
    (u).set<std::decay_t<decltype(u)>::Tag::field>(value)

////////////////////////////////////////////////////////////////////////////////////////////////////

enum class Direction {
+23 −0
Original line number Diff line number Diff line
@@ -95,4 +95,27 @@ convertContainer(const InputContainer& input, const Func& itemConversion) {
    return output;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Utilities for working with AIDL unions.
// UNION_GET(obj, fieldname) returns a ConversionResult<T> containing either the strongly-typed
//   value of the respective field, or BAD_VALUE if the union is not set to the requested field.
// UNION_SET(obj, fieldname, value) sets the requested field to the given value.

template<typename T, typename T::Tag tag>
using UnionFieldType = std::decay_t<decltype(std::declval<T>().template get<tag>())>;

template<typename T, typename T::Tag tag>
ConversionResult<UnionFieldType<T, tag>> unionGetField(const T& u) {
    if (u.getTag() != tag) {
        return base::unexpected(BAD_VALUE);
    }
    return u.template get<tag>();
}

#define UNION_GET(u, field) \
    unionGetField<std::decay_t<decltype(u)>, std::decay_t<decltype(u)>::Tag::field>(u)

#define UNION_SET(u, field, value) \
    (u).set<std::decay_t<decltype(u)>::Tag::field>(value)

}  // namespace android