DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (a093b204c573)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_recordreplay_InfallibleVector_h
#define mozilla_recordreplay_InfallibleVector_h

#include "mozilla/Vector.h"

namespace mozilla {
namespace recordreplay {

// This file declares two classes, InfallibleVector and StaticInfallibleVector,
// which behave like normal vectors except that all their operations are
// infallible: we will immediately crash if any operation on the underlying
// vector fails.
//
// StaticInfallibleVector is designed for use in static storage, and does not
// have a static constructor or destructor in release builds.

template <typename Outer, typename T, size_t MinInlineCapacity,
          class AllocPolicy>
class InfallibleVectorOperations {
  typedef Vector<T, MinInlineCapacity, AllocPolicy> InnerVector;
  InnerVector& Vector() { return static_cast<Outer*>(this)->Vector(); }
  const InnerVector& Vector() const {
    return static_cast<const Outer*>(this)->Vector();
  }

 public:
  size_t length() const { return Vector().length(); }
  bool empty() const { return Vector().empty(); }
  T* begin() { return Vector().begin(); }
  const T* begin() const { return Vector().begin(); }
  T* end() { return Vector().end(); }
  const T* end() const { return Vector().end(); }
  T& operator[](size_t aIndex) { return Vector()[aIndex]; }
  const T& operator[](size_t aIndex) const { return Vector()[aIndex]; }
  T& back() { return Vector().back(); }
  const T& back() const { return Vector().back(); }
  void popBack() { Vector().popBack(); }
  T popCopy() { return Vector().popCopy(); }
  void erase(T* aT) { Vector().erase(aT); }
  void clear() { Vector().clear(); }

  void reserve(size_t aRequest) {
    if (!Vector().reserve(aRequest)) {
      MOZ_CRASH();
    }
  }

  void resize(size_t aNewLength) {
    if (!Vector().resize(aNewLength)) {
      MOZ_CRASH();
    }
  }

  template <typename U>
  void append(U&& aU) {
    if (!Vector().append(std::forward<U>(aU))) {
      MOZ_CRASH();
    }
  }

  template <typename U>
  void append(const U* aBegin, size_t aLength) {
    if (!Vector().append(aBegin, aLength)) {
      MOZ_CRASH();
    }
  }

  void appendN(const T& aT, size_t aN) {
    if (!Vector().appendN(aT, aN)) {
      MOZ_CRASH();
    }
  }

  template <typename... Args>
  void emplaceBack(Args&&... aArgs) {
    if (!Vector().emplaceBack(std::forward<Args>(aArgs)...)) {
      MOZ_CRASH();
    }
  }

  template <typename... Args>
  void infallibleEmplaceBack(Args&&... aArgs) {
    Vector().infallibleEmplaceBack(std::forward<Args>(aArgs)...);
  }

  template <typename U>
  void insert(T* aP, U&& aVal) {
    if (!Vector().insert(aP, std::forward<U>(aVal))) {
      MOZ_CRASH();
    }
  }
};

template <typename T, size_t MinInlineCapacity = 0,
          class AllocPolicy = MallocAllocPolicy>
class InfallibleVector
    : public InfallibleVectorOperations<
          InfallibleVector<T, MinInlineCapacity, AllocPolicy>, T,
          MinInlineCapacity, AllocPolicy> {
  typedef Vector<T, MinInlineCapacity, AllocPolicy> InnerVector;
  InnerVector mVector;

 public:
  InnerVector& Vector() { return mVector; }
  const InnerVector& Vector() const { return mVector; }
};

template <typename T, size_t MinInlineCapacity = 0,
          class AllocPolicy = MallocAllocPolicy>
class StaticInfallibleVector
    : public InfallibleVectorOperations<
          StaticInfallibleVector<T, MinInlineCapacity, AllocPolicy>, T,
          MinInlineCapacity, AllocPolicy> {
  typedef Vector<T, MinInlineCapacity, AllocPolicy> InnerVector;
  mutable InnerVector* mVector;

  void EnsureVector() const {
    if (!mVector) {
      // N.B. This class can only be used with alloc policies that have a
      // default constructor.
      AllocPolicy policy;
      void* memory = policy.template pod_malloc<InnerVector>(1);
      MOZ_RELEASE_ASSERT(memory);
      mVector = new (memory) InnerVector();
    }
  }

 public:
  // InfallibleVectors are allocated in static storage and should not have
  // constructors. Their memory will be initially zero.

  InnerVector& Vector() {
    EnsureVector();
    return *mVector;
  }
  const InnerVector& Vector() const {
    EnsureVector();
    return *mVector;
  }
};

}  // namespace recordreplay
}  // namespace mozilla

#endif  // mozilla_recordreplay_InfallibleVector_h