1*b23bdf5aSs.makeev_local // The MIT License (MIT) 2*b23bdf5aSs.makeev_local // 3*b23bdf5aSs.makeev_local // Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev 4*b23bdf5aSs.makeev_local // 5*b23bdf5aSs.makeev_local // Permission is hereby granted, free of charge, to any person obtaining a copy 6*b23bdf5aSs.makeev_local // of this software and associated documentation files (the "Software"), to deal 7*b23bdf5aSs.makeev_local // in the Software without restriction, including without limitation the rights 8*b23bdf5aSs.makeev_local // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9*b23bdf5aSs.makeev_local // copies of the Software, and to permit persons to whom the Software is 10*b23bdf5aSs.makeev_local // furnished to do so, subject to the following conditions: 11*b23bdf5aSs.makeev_local // 12*b23bdf5aSs.makeev_local // The above copyright notice and this permission notice shall be included in 13*b23bdf5aSs.makeev_local // all copies or substantial portions of the Software. 14*b23bdf5aSs.makeev_local // 15*b23bdf5aSs.makeev_local // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16*b23bdf5aSs.makeev_local // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17*b23bdf5aSs.makeev_local // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18*b23bdf5aSs.makeev_local // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19*b23bdf5aSs.makeev_local // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20*b23bdf5aSs.makeev_local // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21*b23bdf5aSs.makeev_local // THE SOFTWARE. 22*b23bdf5aSs.makeev_local 23*b23bdf5aSs.makeev_local #pragma once 24*b23bdf5aSs.makeev_local 25*b23bdf5aSs.makeev_local 26*b23bdf5aSs.makeev_local namespace MT 27*b23bdf5aSs.makeev_local { 28*b23bdf5aSs.makeev_local 29*b23bdf5aSs.makeev_local /// \class Static vector 30*b23bdf5aSs.makeev_local /// \brief A variable-size array container with fixed capacity. 31*b23bdf5aSs.makeev_local template<class T, size_t CAPACITY> 32*b23bdf5aSs.makeev_local class StaticVector 33*b23bdf5aSs.makeev_local { 34*b23bdf5aSs.makeev_local static const int32 ALIGNMENT = 16; 35*b23bdf5aSs.makeev_local static const int32 ALIGNMENT_MASK = (ALIGNMENT-1); 36*b23bdf5aSs.makeev_local 37*b23bdf5aSs.makeev_local uint32 count; 38*b23bdf5aSs.makeev_local 39*b23bdf5aSs.makeev_local byte rawMemory_[sizeof(T) * CAPACITY + ALIGNMENT]; 40*b23bdf5aSs.makeev_local IndexToObject(int32 index)41*b23bdf5aSs.makeev_local inline T* IndexToObject(int32 index) 42*b23bdf5aSs.makeev_local { 43*b23bdf5aSs.makeev_local byte* alignedMemory = (byte*)( ( (uintptr_t)&rawMemory_[0] + ALIGNMENT_MASK ) & ~(uintptr_t)ALIGNMENT_MASK ); 44*b23bdf5aSs.makeev_local T* pObjectMemory = (T*)(alignedMemory + index * sizeof(T)); 45*b23bdf5aSs.makeev_local return pObjectMemory; 46*b23bdf5aSs.makeev_local } 47*b23bdf5aSs.makeev_local CopyCtor(T * element,const T & val)48*b23bdf5aSs.makeev_local inline void CopyCtor(T* element, const T & val) 49*b23bdf5aSs.makeev_local { 50*b23bdf5aSs.makeev_local new(element) T(val); 51*b23bdf5aSs.makeev_local } 52*b23bdf5aSs.makeev_local MoveCtor(T * element,T && val)53*b23bdf5aSs.makeev_local inline void MoveCtor(T* element, T && val) 54*b23bdf5aSs.makeev_local { 55*b23bdf5aSs.makeev_local new(element) T(std::move(val)); 56*b23bdf5aSs.makeev_local } 57*b23bdf5aSs.makeev_local Dtor(T * element)58*b23bdf5aSs.makeev_local inline void Dtor(T* element) 59*b23bdf5aSs.makeev_local { 60*b23bdf5aSs.makeev_local MT_UNUSED(element); 61*b23bdf5aSs.makeev_local element->~T(); 62*b23bdf5aSs.makeev_local } 63*b23bdf5aSs.makeev_local 64*b23bdf5aSs.makeev_local public: 65*b23bdf5aSs.makeev_local 66*b23bdf5aSs.makeev_local MT_NOCOPYABLE(StaticVector); 67*b23bdf5aSs.makeev_local StaticVector()68*b23bdf5aSs.makeev_local inline StaticVector() 69*b23bdf5aSs.makeev_local : count(0) 70*b23bdf5aSs.makeev_local { 71*b23bdf5aSs.makeev_local } 72*b23bdf5aSs.makeev_local 73*b23bdf5aSs.makeev_local inline StaticVector(uint32 _count, const T & defaultElement = T()) count(_count)74*b23bdf5aSs.makeev_local : count(_count) 75*b23bdf5aSs.makeev_local { 76*b23bdf5aSs.makeev_local MT_ASSERT(count <= CAPACITY, "Too big size"); 77*b23bdf5aSs.makeev_local for (uint32 i = 0; i < count; i++) 78*b23bdf5aSs.makeev_local { 79*b23bdf5aSs.makeev_local CopyCtor(Begin() + i, defaultElement); 80*b23bdf5aSs.makeev_local } 81*b23bdf5aSs.makeev_local } 82*b23bdf5aSs.makeev_local ~StaticVector()83*b23bdf5aSs.makeev_local inline ~StaticVector() 84*b23bdf5aSs.makeev_local { 85*b23bdf5aSs.makeev_local for (uint32 i = 0; i < count; i++) 86*b23bdf5aSs.makeev_local { 87*b23bdf5aSs.makeev_local Dtor(Begin() + i); 88*b23bdf5aSs.makeev_local } 89*b23bdf5aSs.makeev_local } 90*b23bdf5aSs.makeev_local 91*b23bdf5aSs.makeev_local inline const T &operator[]( uint32 i ) const 92*b23bdf5aSs.makeev_local { 93*b23bdf5aSs.makeev_local MT_ASSERT( i < Size(), "bad index" ); 94*b23bdf5aSs.makeev_local return *IndexToObject(i); 95*b23bdf5aSs.makeev_local } 96*b23bdf5aSs.makeev_local 97*b23bdf5aSs.makeev_local inline T &operator[]( uint32 i ) 98*b23bdf5aSs.makeev_local { 99*b23bdf5aSs.makeev_local MT_ASSERT( i < Size(), "bad index" ); 100*b23bdf5aSs.makeev_local return *IndexToObject(i); 101*b23bdf5aSs.makeev_local } 102*b23bdf5aSs.makeev_local PushBack(T && val)103*b23bdf5aSs.makeev_local inline void PushBack(T && val) 104*b23bdf5aSs.makeev_local { 105*b23bdf5aSs.makeev_local MT_ASSERT(count < CAPACITY, "Can't add element"); 106*b23bdf5aSs.makeev_local uint32 lastElementIndex = count; 107*b23bdf5aSs.makeev_local count++; 108*b23bdf5aSs.makeev_local MoveCtor( IndexToObject(lastElementIndex), std::move(val) ); 109*b23bdf5aSs.makeev_local } 110*b23bdf5aSs.makeev_local Size()111*b23bdf5aSs.makeev_local inline size_t Size() const 112*b23bdf5aSs.makeev_local { 113*b23bdf5aSs.makeev_local return count; 114*b23bdf5aSs.makeev_local } 115*b23bdf5aSs.makeev_local IsEmpty()116*b23bdf5aSs.makeev_local inline bool IsEmpty() const 117*b23bdf5aSs.makeev_local { 118*b23bdf5aSs.makeev_local return count == 0; 119*b23bdf5aSs.makeev_local } 120*b23bdf5aSs.makeev_local Begin()121*b23bdf5aSs.makeev_local inline T* Begin() 122*b23bdf5aSs.makeev_local { 123*b23bdf5aSs.makeev_local return IndexToObject(0); 124*b23bdf5aSs.makeev_local } 125*b23bdf5aSs.makeev_local }; 126*b23bdf5aSs.makeev_local 127*b23bdf5aSs.makeev_local 128*b23bdf5aSs.makeev_local 129*b23bdf5aSs.makeev_local } 130*b23bdf5aSs.makeev_local 131