Blame dom/bindings/Nullable.h

Packit f0b94e
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
Packit f0b94e
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
Packit f0b94e
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
Packit f0b94e
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
Packit f0b94e
#ifndef mozilla_dom_Nullable_h
Packit f0b94e
#define mozilla_dom_Nullable_h
Packit f0b94e
Packit f0b94e
#include "mozilla/Assertions.h"
Packit f0b94e
#include "nsTArrayForwardDeclare.h"
Packit f0b94e
#include "mozilla/Move.h"
Packit f0b94e
#include "mozilla/Maybe.h"
Packit f0b94e
Packit f0b94e
#include <ostream>
Packit f0b94e
Packit f0b94e
class nsCycleCollectionTraversalCallback;
Packit f0b94e
Packit f0b94e
namespace mozilla {
Packit f0b94e
namespace dom {
Packit f0b94e
Packit f0b94e
// Support for nullable types
Packit f0b94e
template <typename T>
Packit f0b94e
struct Nullable {
Packit f0b94e
 private:
Packit f0b94e
  Maybe<T> mValue;
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  Nullable() : mValue() {}
Packit f0b94e
Packit f0b94e
  MOZ_IMPLICIT Nullable(const decltype(nullptr) &) : mValue() {}
Packit f0b94e
Packit f0b94e
  explicit Nullable(const T& aValue) : mValue() { mValue.emplace(aValue); }
Packit f0b94e
Packit f0b94e
  MOZ_IMPLICIT Nullable(T&& aValue) : mValue() {
Packit f0b94e
    mValue.emplace(mozilla::Move(aValue));
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  Nullable(Nullable<T>&& aOther) : mValue(mozilla::Move(aOther.mValue)) {}
Packit f0b94e
Packit f0b94e
  Nullable(const Nullable<T>& aOther) : mValue(aOther.mValue) {}
Packit f0b94e
Packit f0b94e
  void operator=(const Nullable<T>& aOther) { mValue = aOther.mValue; }
Packit f0b94e
Packit f0b94e
  void SetValue(const T& aArgs) {
Packit f0b94e
    mValue.reset();
Packit f0b94e
    mValue.emplace(aArgs);
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  void SetValue(T&& aArgs) {
Packit f0b94e
    mValue.reset();
Packit f0b94e
    mValue.emplace(mozilla::Move(aArgs));
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  // For cases when |T| is some type with nontrivial copy behavior, we may want
Packit f0b94e
  // to get a reference to our internal copy of T and work with it directly
Packit f0b94e
  // instead of relying on the copying version of SetValue().
Packit f0b94e
  T& SetValue() {
Packit f0b94e
    if (mValue.isNothing()) {
Packit f0b94e
      mValue.emplace();
Packit f0b94e
    }
Packit f0b94e
    return mValue.ref();
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  void SetNull() { mValue.reset(); }
Packit f0b94e
Packit f0b94e
  const T& Value() const { return mValue.ref(); }
Packit f0b94e
Packit f0b94e
  T& Value() { return mValue.ref(); }
Packit f0b94e
Packit f0b94e
  bool IsNull() const { return mValue.isNothing(); }
Packit f0b94e
Packit f0b94e
  bool Equals(const Nullable<T>& aOtherNullable) const {
Packit f0b94e
    return mValue == aOtherNullable.mValue;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  bool operator==(const Nullable<T>& aOtherNullable) const {
Packit f0b94e
    return Equals(aOtherNullable);
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  bool operator!=(const Nullable<T>& aOtherNullable) const {
Packit f0b94e
    return !Equals(aOtherNullable);
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  friend std::ostream& operator<<(std::ostream& aStream,
Packit f0b94e
                                  const Nullable& aNullable) {
Packit f0b94e
    return aStream << aNullable.mValue;
Packit f0b94e
  }
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
template <typename T>
Packit f0b94e
void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
Packit f0b94e
                                 Nullable<T>& aNullable, const char* aName,
Packit f0b94e
                                 uint32_t aFlags = 0) {
Packit f0b94e
  if (!aNullable.IsNull()) {
Packit f0b94e
    ImplCycleCollectionTraverse(aCallback, aNullable.Value(), aName, aFlags);
Packit f0b94e
  }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <typename T>
Packit f0b94e
void ImplCycleCollectionUnlink(Nullable<T>& aNullable) {
Packit f0b94e
  if (!aNullable.IsNull()) {
Packit f0b94e
    ImplCycleCollectionUnlink(aNullable.Value());
Packit f0b94e
  }
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
}  // namespace dom
Packit f0b94e
}  // namespace mozilla
Packit f0b94e
Packit f0b94e
#endif /* mozilla_dom_Nullable_h */