Add a MaybeOneOf class

RESOLVED FIXED in mozilla33

Status

()

Core
MFBT
RESOLVED FIXED
4 years ago
4 years ago

People

(Reporter: jandem, Assigned: jandem)

Tracking

unspecified
mozilla33
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

Attachments

(1 attachment)

(Assignee)

Description

4 years ago
Created attachment 8439443 [details] [diff] [review]
Patch

For bug 1017107 we want a class like Maybe, but we have to be able to construct different types. This patch adds mozilla::MaybeOneOf<T1, T2>, so that you can do something like:

MaybeOneOf<Latin1CharBuffer, TwoByteCharBuffer> cb;
cb.construct<TwoByteCharBuffer>(cx);
cb.ref<TwoByteCharBuffer>();
cb.destroy();
cb.construct<Latin1CharBuffer>(cx);
Attachment #8439443 - Flags: review?(luke)

Comment 1

4 years ago
Comment on attachment 8439443 [details] [diff] [review]
Patch

Review of attachment 8439443 [details] [diff] [review]:
-----------------------------------------------------------------

::: mfbt/MaybeOneOf.h
@@ +29,5 @@
> +class MaybeOneOf
> +{
> +  union {
> +    AlignedStorage2<T1> storageT1;
> +    AlignedStorage2<T2> storageT2;

I think you can use:
  AlignedStorage<tl::Max<sizeof(T1)>::value, tl::Max<sizeof(T2)>::value> storage;
instead.

@@ +38,5 @@
> +  T1& asT1() { return *storageT1.addr(); }
> +  T2& asT2() { return *storageT2.addr(); }
> +
> +  const T1& asT1() const { return *storageT1.addr(); }
> +  const T2& asT2() const { return *storageT2.addr(); }

That will allow you to have:
  template <class T> T& as() { MOZ_ASSERT(state == Type2State<T>::result); return *(T*)storage.addr(); }
(with the construct() change mentioned below).

@@ +56,5 @@
> +    state = Type2State<T>::result;
> +    if (state == SomeT1)
> +      ::new (&asT1()) T();
> +    else
> +      ::new (&asT2()) T();

Here you could use:
  ::new (storage.addr()) T();
and similarly for the other construct()s.

@@ +92,5 @@
> +
> +  template <class T>
> +  T& ref() {
> +    MOZ_ASSERT(state == Type2State<T>::result);
> +    return (state == SomeT1) ? (T&)asT1() : (T&)asT2();

Here and for the next ref you could:
  return asT();
Attachment #8439443 - Flags: review?(luke) → review+
(Assignee)

Comment 2

4 years ago
https://hg.mozilla.org/integration/mozilla-inbound/rev/7244e4bee4a2

(In reply to Luke Wagner [:luke] from comment #1)
> I think you can use:
>   AlignedStorage<tl::Max<sizeof(T1)>::value, tl::Max<sizeof(T2)>::value>
> storage;
> instead.

Ah nice, that works and is cleaner :)

FWIW, to appease MSVC I also had to change:

  static const Enclosing::State result = Enclosing::SomeT1;

To:

  static const typename Enclosing::State result = Enclosing::SomeT1;
https://hg.mozilla.org/mozilla-central/rev/7244e4bee4a2
Status: ASSIGNED → RESOLVED
Last Resolved: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla33
You need to log in before you can comment on or make changes to this bug.