Serenity Operating System
at portability 148 lines 4.2 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#pragma once 28 29#include <AK/Vector.h> 30 31namespace AK { 32 33template<typename T> 34class FixedArray { 35public: 36 FixedArray() {} 37 explicit FixedArray(size_t size) 38 : m_size(size) 39 { 40 m_elements = (T*)kmalloc(sizeof(T) * m_size); 41 for (size_t i = 0; i < m_size; ++i) 42 new (&m_elements[i]) T(); 43 } 44 ~FixedArray() 45 { 46 clear(); 47 } 48 49 FixedArray(const FixedArray& other) 50 : m_size(other.m_size) 51 { 52 m_elements = (T*)kmalloc(sizeof(T) * m_size); 53 for (size_t i = 0; i < m_size; ++i) 54 new (&m_elements[i]) T(other[i]); 55 } 56 57 FixedArray& operator=(const FixedArray& other) 58 { 59 FixedArray array(other); 60 swap(array); 61 return *this; 62 } 63 64 FixedArray(FixedArray&&) = delete; 65 FixedArray& operator=(FixedArray&&) = delete; 66 67 void clear() 68 { 69 if (!m_elements) 70 return; 71 for (size_t i = 0; i < m_size; ++i) 72 m_elements[i].~T(); 73 kfree(m_elements); 74 m_elements = nullptr; 75 m_size = 0; 76 } 77 78 size_t size() const { return m_size; } 79 80 T* data() 81 { 82 return m_elements; 83 } 84 const T* data() const 85 { 86 return m_elements; 87 } 88 89 T& operator[](size_t index) 90 { 91 ASSERT(index < m_size); 92 return m_elements[index]; 93 } 94 95 const T& operator[](size_t index) const 96 { 97 ASSERT(index < m_size); 98 return m_elements[index]; 99 } 100 101 void resize(size_t new_size) 102 { 103 if (new_size == m_size) 104 return; 105 auto* new_elements = (T*)kmalloc(new_size * sizeof(T)); 106 for (size_t i = 0; i < min(new_size, m_size); ++i) 107 new (&new_elements[i]) T(move(m_elements[i])); 108 for (size_t i = min(new_size, m_size); i < new_size; ++i) 109 new (&new_elements[i]) T(); 110 for (size_t i = 0; i < m_size; ++i) 111 m_elements[i].~T(); 112 if (m_elements) 113 kfree(m_elements); 114 m_elements = new_elements; 115 m_size = new_size; 116 } 117 118 bool contains(const T& value) const 119 { 120 for (size_t i = 0; i < m_size; ++i) { 121 if (m_elements[i] == value) 122 return true; 123 } 124 return false; 125 } 126 127 void swap(FixedArray& other) 128 { 129 ::swap(m_elements, other.m_elements); 130 ::swap(m_size, other.m_size); 131 } 132 133 using Iterator = VectorIterator<FixedArray, T>; 134 Iterator begin() { return Iterator(*this, 0); } 135 Iterator end() { return Iterator(*this, size()); } 136 137 using ConstIterator = VectorIterator<const FixedArray, const T>; 138 ConstIterator begin() const { return ConstIterator(*this, 0); } 139 ConstIterator end() const { return ConstIterator(*this, size()); } 140 141private: 142 size_t m_size { 0 }; 143 T* m_elements { nullptr }; 144}; 145 146} 147 148using AK::FixedArray;