tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FixedLengthVector.h (2720B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef ds_FixedLengthVector_h
      8 #define ds_FixedLengthVector_h
      9 
     10 #include "mozilla/Assertions.h"             // MOZ_ASSERT
     11 #include "mozilla/OperatorNewExtensions.h"  // mozilla::KnownNotNull
     12 
     13 #include <stddef.h>  // size_t
     14 
     15 #include "js/Utility.h"    // js_free
     16 #include "vm/JSContext.h"  // JSContext
     17 
     18 namespace js {
     19 
     20 // A dynamically-allocated fixed-length vector with bounds checking assertions.
     21 template <typename T>
     22 class FixedLengthVector {
     23  // The pointer to the storage.
     24  T* data_ = nullptr;
     25 
     26  // The size of the storage.
     27  size_t length_ = 0;
     28 
     29 public:
     30  FixedLengthVector() = default;
     31 
     32  FixedLengthVector(FixedLengthVector&) = delete;
     33  FixedLengthVector(FixedLengthVector&&) = default;
     34 
     35  ~FixedLengthVector() {
     36    if (initialized()) {
     37      js_free(data_);
     38    }
     39  }
     40 
     41  size_t length() const { return length_; }
     42 
     43  bool initialized() const { return !!data_; }
     44 
     45  // Allocate the storage with the given size, wihtout calling constructor.
     46  //
     47  // If the allocation fails, this returns false and sets the
     48  // pending exception on the given context.
     49  [[nodiscard]] bool allocateUninitialized(JSContext* cx, size_t length) {
     50    MOZ_ASSERT(!initialized());
     51 
     52    length_ = length;
     53    data_ = cx->pod_malloc<T>(length);
     54    if (MOZ_UNLIKELY(!data_)) {
     55      return false;
     56    }
     57 
     58    return true;
     59  }
     60 
     61  // Allocate the storage with the given size and call default constructor.
     62  //
     63  // If the allocation fails, this returns false and sets the
     64  // pending exception on the given context.
     65  [[nodiscard]] bool allocate(JSContext* cx, size_t length) {
     66    if (!allocateUninitialized(cx, length)) {
     67      return false;
     68    }
     69 
     70    for (size_t i = 0; i < length; i++) {
     71      new (mozilla::KnownNotNull, &data_[i]) T();
     72    }
     73    return true;
     74  }
     75 
     76  T* begin() {
     77    MOZ_ASSERT(initialized());
     78    return data_;
     79  }
     80 
     81  const T* begin() const {
     82    MOZ_ASSERT(initialized());
     83    return data_;
     84  }
     85 
     86  T* end() {
     87    MOZ_ASSERT(initialized());
     88    return data_ + length_;
     89  }
     90 
     91  const T* end() const {
     92    MOZ_ASSERT(initialized());
     93    return data_ + length_;
     94  }
     95 
     96  T& operator[](size_t index) {
     97    MOZ_ASSERT(initialized());
     98    MOZ_ASSERT(index < length_);
     99    return begin()[index];
    100  }
    101 
    102  const T& operator[](size_t index) const {
    103    MOZ_ASSERT(initialized());
    104    MOZ_ASSERT(index < length_);
    105    return begin()[index];
    106  }
    107 };
    108 
    109 }  // namespace js
    110 
    111 #endif  // ds_FixedLengthVector_h