Skip to content

Instantly share code, notes, and snippets.

@jeremyroman
Last active April 25, 2017 01:01
Show Gist options
  • Save jeremyroman/73500b3fa91030451b9f5164035ed534 to your computer and use it in GitHub Desktop.
Save jeremyroman/73500b3fa91030451b9f5164035ed534 to your computer and use it in GitHub Desktop.
union template sketch
// template definition
template <int index, typename... UnionMemberTraits>
class IDLUnionImpl {
public:
bool IsNull() const { return type_ == 0; }
protected:
int type_ = 0;
};
template <int index, typename UnionMemberTraits, typename... Rest>
class IDLUnionImpl : public IDLUnionImpl<index + 1, Rest> {
protected:
bool IsImpl(UnionMemberTraits*) const { return type_ == index; }
UnionMemberTraits::AccessorType GetImpl(UnionMemberTraits* helper) {
DCHECK(IsImpl(helper));
return storage_;
}
void SetImpl(UnionMemberTraits* helper, UnionMemberTraits::AccessorType value) {
DCHECK(IsNull());
storage_ = std::move(value);
type_ = index;
DCHECK(IsImpl(helper));
}
UnionMemberTraits::StorageType storage_;
};
template <typename... UnionMemberTraits>
class IDLUnion : public IDLUnionImpl<1, UnionMemberTraits...> {
public:
template <typename T>
bool Is() const { return IsImpl(static_cast<T*>(nullptr)); }
template <typename T>
T::AccessorType Get() const { return GetImpl(static_cast<T*>(nullptr)); }
template <typename T>
void Set(T::AccessorType value) { SetImpl(static_cast<T*>(nullptr), std::move(value)); }
};
// union membership traits (these could be abstracted somewhat, if desired)
// additional stuff would be needed for tracing, conversion to/from V8, etc.
struct UnionTypeRequest {
using StorageType = Member<Request>;
using AccessType = Request*;
}
struct UnionTypeUSVString {
using StorageType = String;
using AccessType = String;
}
// type alias (can have multiple aliases for the same type)
using RequestOrUSVString = IDLUnion<UnionTypeRequest, UnionTypeUSVString>;
using SomeSpecificName = IDLUnion<UnionTypeRequest, UnionTypeUSVString>;
// usage (maybe it can be made slightly nicer?)
if (union.Is<UnionTypeRequest>()) {
doSomething(union.Get<UnionTypeRequest>());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment