jArray.h (4158B)
1 /* 2 * Copyright (c) 2008-2015 Mozilla Foundation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 * DEALINGS IN THE SOFTWARE. 21 */ 22 23 #ifndef jArray_h 24 #define jArray_h 25 26 #include <array> 27 #include "mozilla/Attributes.h" 28 #include "mozilla/BinarySearch.h" 29 #include "mozilla/fallible.h" 30 31 template <class T, class L> 32 struct staticJArray { 33 const T* arr; 34 const L length; 35 operator T*() { return arr; } 36 T& operator[](L const index) { 37 MOZ_ASSERT(index >= 0, "Array access with negative index."); 38 MOZ_ASSERT(index < length, "Array index out of bounds."); 39 return ((T*)arr)[index]; 40 } 41 L binarySearch(T const elem) { 42 size_t idx; 43 bool found = mozilla::BinarySearch(arr, 0, length, elem, &idx); 44 return found ? idx : -1; 45 } 46 }; 47 48 template <class T, class L> 49 class autoJArray; 50 51 template <class T, class L> 52 class jArray { 53 friend class autoJArray<T, L>; 54 55 private: 56 T* arr; 57 58 public: 59 L length; 60 static jArray<T, L> newJArray(L const len) { 61 MOZ_ASSERT(len >= 0, "Negative length."); 62 jArray<T, L> newArray = {new T[size_t(len)], len}; 63 return newArray; 64 } 65 static jArray<T, L> newFallibleJArray(L const len) { 66 MOZ_ASSERT(len >= 0, "Negative length."); 67 T* a = new (mozilla::fallible) T[size_t(len)]; 68 jArray<T, L> newArray = {a, a ? len : 0}; 69 return newArray; 70 } 71 operator T*() { return arr; } 72 T& operator[](L const index) { 73 MOZ_ASSERT(index >= 0, "Array access with negative index."); 74 MOZ_ASSERT(index < length, "Array index out of bounds."); 75 return arr[index]; 76 } 77 void operator=(staticJArray<T, L>& other) { 78 arr = (T*)other.arr; 79 length = other.length; 80 } 81 MOZ_IMPLICIT jArray(decltype(nullptr)) : arr(nullptr), length(0) {} 82 jArray() : arr(nullptr), length(0) {} 83 84 private: 85 jArray(T* aArr, L aLength) : arr(aArr), length(aLength) {} 86 }; 87 88 template <class T, class L> 89 class autoJArray { 90 private: 91 T* arr; 92 93 public: 94 L length; 95 autoJArray() : arr(0), length(0) {} 96 MOZ_IMPLICIT autoJArray(const jArray<T, L>& other) 97 : arr(other.arr), length(other.length) {} 98 ~autoJArray() { delete[] arr; } 99 operator T*() { return arr; } 100 T& operator[](L const index) { 101 MOZ_ASSERT(index >= 0, "Array access with negative index."); 102 MOZ_ASSERT(index < length, "Array index out of bounds."); 103 return arr[index]; 104 } 105 operator jArray<T, L>() { 106 // WARNING! This makes it possible to goof with buffer ownership! 107 // This is needed for the getStack and getListOfActiveFormattingElements 108 // methods to work sensibly. 109 jArray<T, L> newArray = {arr, length}; 110 return newArray; 111 } 112 void operator=(const jArray<T, L>& other) { 113 delete[] arr; 114 arr = other.arr; 115 length = other.length; 116 } 117 void operator=(decltype(nullptr)) { 118 // Make assigning null to an array in Java delete the buffer in C++ 119 delete[] arr; 120 arr = nullptr; 121 length = 0; 122 } 123 }; 124 125 template <class T, size_t S> 126 class jInlineArray : public std::array<T, S> { 127 public: 128 using std::array<T, S>::array; 129 130 template <typename U> 131 explicit jInlineArray(U* aData) { 132 T* data = this->data(); 133 for (size_t i = 0; i < S; ++i) { 134 data[i] = aData[i]; 135 } 136 } 137 }; 138 139 #endif // jArray_h