1 /* 2 * Array.h 3 * Apto 4 * 5 * Created by David on 2/4/11. 6 * Copyright 2011 David Michael Bryson. All rights reserved. 7 * http://programerror.com/software/apto 8 * 9 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 10 * following conditions are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the 13 * following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the 15 * following disclaimer in the documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of David Michael Bryson, nor the names of contributors may be used to endorse or promote 17 * products derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY DAVID MICHAEL BRYSON AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL DAVID MICHAEL BRYSON OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 25 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * Authors: David M. Bryson <david@programerror.com> 28 * 29 */ 30 31 #ifndef AptoCoreArray_h 32 #define AptoCoreArray_h 33 34 #include "apto/core/Definitions.h" 35 #include "apto/core/ArrayStorage.h" 36 37 #include <cassert> 38 39 40 namespace Apto { 41 42 // Array 43 // -------------------------------------------------------------------------------------------------------------- 44 45 template <class T, template <class> class StoragePolicy = Basic> 46 class Array : public StoragePolicy<T> 47 { 48 typedef StoragePolicy<T> SP; 49 50 public: 51 typedef T ValueType; 52 class Iterator; 53 class ConstIterator; 54 55 public: SP(size)56 inline explicit Array(int size = 0) : SP(size) { ; } 57 58 template <typename T1, template <class> class SP1> Array(const Array<T1,SP1> & rhs)59 inline explicit Array(const Array<T1, SP1>& rhs) : SP(rhs.GetSize()) { this->operator=(rhs); } 60 ~Array()61 ~Array() { ; } 62 63 template <typename T1, template <class> class SP1> 64 Array& operator=(const Array<T1, SP1>& rhs) 65 { 66 if (SP::GetSize() != rhs.GetSize()) SP::Resize(rhs.GetSize()); 67 for (int i = 0; i < GetSize(); i++) SP::operator[](i) = rhs[i]; 68 return *this; 69 } 70 71 template <typename T1, template <class> class SP1> 72 Array& operator+=(const Array<T1, SP1>& rhs) 73 { 74 int old_size = SP::GetSize(); 75 int rhs_size = rhs.GetSize(); 76 SP::Resize(old_size + rhs_size); 77 for (int i = 0; i < rhs_size; i++) SP::operator[](i + old_size) = rhs[i]; 78 return *this; 79 } 80 81 template <typename T1, template <class> class SP1> 82 Array operator+(const Array<T1, SP1>& rhs) const 83 { 84 Array new_arr(SP::GetSize() + rhs.GetSize()); 85 for (int i = 0; i < SP::GetSize(); i++) new_arr[i] = SP::operator[](i); 86 for (int i = 0; i < rhs.GetSize(); i++) new_arr[SP::GetSize() + i] = rhs[i]; 87 return new_arr; 88 } 89 90 template <typename T1, template <class> class SP1> 91 bool operator==(const Array<T1, SP1>& rhs) 92 { 93 if (SP::GetSize() != rhs.GetSize()) return false; 94 for (int i = 0; i < SP::GetSize(); i++) if (SP::operator[](i) != rhs[i]) return false; 95 return true; 96 } 97 98 template <typename T1, template <class> class SP1> 99 bool operator!=(const Array<T1, SP1>& rhs) { return !operator==(rhs); } 100 GetSize()101 inline int GetSize() const { return SP::GetSize(); } 102 ResizeClear(const int in_size)103 inline void ResizeClear(const int in_size) 104 { 105 assert(in_size >= 0); 106 SP::ResizeClear(in_size); 107 } 108 Resize(int new_size)109 inline void Resize(int new_size) 110 { 111 assert(new_size >= 0); 112 SP::Resize(new_size); 113 } 114 Resize(int new_size,const T & empty_value)115 void Resize(int new_size, const T& empty_value) 116 { 117 int old_size = SP::GetSize(); 118 SP::Resize(new_size); 119 for (int i = old_size; i < new_size; i++) SP::operator[](i) = empty_value; 120 } 121 122 T& operator[](const int index) 123 { 124 assert(index >= 0); // Lower Bounds Error 125 assert(index < SP::GetSize()); // Upper Bounds Error 126 return SP::operator[](index); 127 } 128 const T& operator[](const int index) const 129 { 130 assert(index >= 0); // Lower Bounds Error 131 assert(index < SP::GetSize()); // Upper Bounds Error 132 return SP::operator[](index); 133 } 134 Get(const int index)135 inline T& Get(const int index) { return operator[](index); } Get(const int index)136 inline const T& Get(const int index) const { return operator[](index); } 137 138 // Stack-like Methods... Push(const T & value)139 void Push(const T& value) 140 { 141 SP::Resize(SP::GetSize() + 1); 142 SP::operator[](SP::GetSize() - 1) = value; 143 } 144 Pop()145 T Pop() 146 { 147 T value = SP::operator[](SP::GetSize() - 1); 148 SP::Resize(SP::GetSize() - 1); 149 return value; 150 } 151 152 Swap(int idx1,int idx2)153 void Swap(int idx1, int idx2) 154 { 155 assert(idx1 >= 0); // Lower Bounds Error 156 assert(idx1 < SP::GetSize()); // Upper Bounds Error 157 assert(idx2 >= 0); // Lower Bounds Error 158 assert(idx2 < SP::GetSize()); // Upper Bounds Error 159 160 SP::Swap(idx1, idx2); 161 } 162 163 SetAll(const T & value)164 void SetAll(const T& value) 165 { 166 for (int i = 0; i < SP::GetSize(); i++) SP::operator[](i) = value; 167 } 168 Begin()169 Iterator Begin() { return Iterator(*this); } Begin()170 ConstIterator Begin() const { return ConstIterator(*this); } 171 172 173 public: 174 class Iterator 175 { 176 friend class Array; 177 178 private: 179 Array& m_arr; 180 int m_index; 181 182 Iterator(); // @not_implemented Iterator(Array & arr)183 Iterator(Array& arr) : m_arr(arr), m_index(-1) { ; } 184 185 public: Get()186 T* Get() { return (m_index < m_arr.GetSize()) ? &(m_arr.SP::operator[](m_index)) : NULL; } Next()187 T* Next() { return (++m_index < m_arr.GetSize()) ? &(m_arr.SP::operator[](m_index)) : NULL; } 188 }; 189 190 class ConstIterator 191 { 192 friend class Array; 193 private: 194 const Array& m_arr; 195 int m_index; 196 197 ConstIterator(); // @not_implemented ConstIterator(const Array & arr)198 ConstIterator(const Array& arr) : m_arr(arr), m_index(-1) { ; } 199 200 public: Get()201 const T* Get() { return (m_index < m_arr.GetSize()) ? &(m_arr.SP::operator[](m_index)) : NULL; } Next()202 const T* Next() { return (++m_index < m_arr.GetSize()) ? &(m_arr.SP::operator[](m_index)) : NULL; } 203 }; 204 }; 205 }; 206 207 #endif 208