AlignedTArray.h (3928B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */ 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 AlignedTArray_h__ 8 #define AlignedTArray_h__ 9 10 #include "nsTArray.h" 11 12 /** 13 * E: element type, must be a POD type. 14 * N: N bytes alignment for the first element, defaults to 32 15 * S: S bytes of inline storage 16 */ 17 template <typename E, int S, int N = 32> 18 class AlignedAutoTArray : private AutoTArray<E, S + N> { 19 static_assert((N & (N - 1)) == 0, "N must be power of 2"); 20 typedef AutoTArray<E, S + N> base_type; 21 22 public: 23 typedef E value_type; 24 typedef typename base_type::size_type size_type; 25 typedef typename base_type::index_type index_type; 26 27 AlignedAutoTArray() = default; 28 explicit AlignedAutoTArray(size_type capacity) 29 : base_type(capacity + sExtra) {} 30 value_type* Elements() { return getAligned(base_type::Elements()); } 31 const value_type* Elements() const { 32 return getAligned(base_type::Elements()); 33 } 34 value_type& operator[](index_type i) { return Elements()[i]; } 35 const value_type& operator[](index_type i) const { return Elements()[i]; } 36 37 void SetLength(size_type newLen) { base_type::SetLength(newLen + sExtra); } 38 39 [[nodiscard]] bool SetLength(size_type newLen, const mozilla::fallible_t&) { 40 return base_type::SetLength(newLen + sExtra, mozilla::fallible); 41 } 42 43 size_type Length() const { 44 return base_type::Length() <= sExtra ? 0 : base_type::Length() - sExtra; 45 } 46 47 using base_type::ShallowSizeOfExcludingThis; 48 using base_type::ShallowSizeOfIncludingThis; 49 50 private: 51 AlignedAutoTArray(const AlignedAutoTArray& other) = delete; 52 void operator=(const AlignedAutoTArray& other) = delete; 53 54 static const size_type sPadding = N <= alignof(E) ? 0 : N - alignof(E); 55 static const size_type sExtra = (sPadding + sizeof(E) - 1) / sizeof(E); 56 57 template <typename U> 58 static U* getAligned(U* p) { 59 return reinterpret_cast<U*>(((uintptr_t)p + N - 1) & ~(N - 1)); 60 } 61 }; 62 63 /** 64 * E: element type, must be a POD type. 65 * N: N bytes alignment for the first element, defaults to 32 66 */ 67 template <typename E, int N = 32> 68 class AlignedTArray : private nsTArray_Impl<E, nsTArrayInfallibleAllocator> { 69 static_assert((N & (N - 1)) == 0, "N must be power of 2"); 70 typedef nsTArray_Impl<E, nsTArrayInfallibleAllocator> base_type; 71 72 public: 73 typedef E value_type; 74 typedef typename base_type::size_type size_type; 75 typedef typename base_type::index_type index_type; 76 77 AlignedTArray() = default; 78 explicit AlignedTArray(size_type capacity) : base_type(capacity + sExtra) {} 79 value_type* Elements() { return getAligned(base_type::Elements()); } 80 const value_type* Elements() const { 81 return getAligned(base_type::Elements()); 82 } 83 value_type& operator[](index_type i) { return Elements()[i]; } 84 const value_type& operator[](index_type i) const { return Elements()[i]; } 85 86 void SetLength(size_type newLen) { base_type::SetLength(newLen + sExtra); } 87 88 [[nodiscard]] bool SetLength(size_type newLen, const mozilla::fallible_t&) { 89 return base_type::SetLength(newLen + sExtra, mozilla::fallible); 90 } 91 92 size_type Length() const { 93 return base_type::Length() <= sExtra ? 0 : base_type::Length() - sExtra; 94 } 95 96 using base_type::ShallowSizeOfExcludingThis; 97 using base_type::ShallowSizeOfIncludingThis; 98 99 private: 100 AlignedTArray(const AlignedTArray& other) = delete; 101 void operator=(const AlignedTArray& other) = delete; 102 103 static const size_type sPadding = N <= alignof(E) ? 0 : N - alignof(E); 104 static const size_type sExtra = (sPadding + sizeof(E) - 1) / sizeof(E); 105 106 template <typename U> 107 static U* getAligned(U* p) { 108 return reinterpret_cast<U*>(((uintptr_t)p + N - 1) & ~(N - 1)); 109 } 110 }; 111 112 #endif // AlignedTArray_h__