summaryrefslogtreecommitdiffstats
path: root/contrib/restricted/wavm/Include/WAVM/Inline/InlineArray.h
blob: 24f56b383c0ab478849bfe1b2e448389dc96c58d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#pragma once

#include "Impl/OptionalStorage.h"
#include "WAVM/Inline/Assert.h"

namespace WAVM {
	template<typename Element, Uptr maxElements> struct InlineArray
	{
		InlineArray() : numElements(0) {}
		~InlineArray()
		{
			if(!std::is_trivially_destructible<Element>::value)
			{
				for(Uptr index = 0; index < numElements; ++index) { elements[index].destruct(); }
			}
		}

		template<typename... ElementArgs> void push_back(ElementArgs&&... elementArgs)
		{
			WAVM_ERROR_UNLESS(numElements < maxElements);
			elements[numElements++].construct(std::forward<ElementArgs>(elementArgs)...);
		}

		template<typename... ElementArgs>
		void resize(Uptr newNumElements, ElementArgs&&... elementArgs)
		{
			WAVM_ERROR_UNLESS(newNumElements < maxElements);
			if(newNumElements < numElements)
			{
				for(Uptr index = newNumElements; index < numElements; ++index)
				{ elements[index].destruct(); }
			}
			else if(newNumElements > numElements)
			{
				for(Uptr index = numElements; index < newNumElements; ++index)
				{ elements[index].construct(std::forward<ElementArgs>(elementArgs)...); }
			}
			numElements = newNumElements;
		}

		Uptr size() const { return numElements; }
		Uptr maxSize() const { return maxElements; }
		bool isFull() const { return numElements == maxElements; }

		const Element& operator[](Uptr index) const
		{
			WAVM_ASSERT(index < numElements);
			return elements[index].get();
		}
		Element& operator[](Uptr index)
		{
			WAVM_ASSERT(index < numElements);
			return elements[index].get();
		}

	private:
		Uptr numElements;
		WAVM::OptionalStorage<Element> elements[maxElements];
	};
}