summaryrefslogtreecommitdiffstats
path: root/source/core/array.h
blob: 2a5fa0aa7347ed1761ba2d3c92e87dd653a98522 (plain)
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#ifndef CORE_LIB_ARRAY_H
#define CORE_LIB_ARRAY_H

#include "exception.h"
#include "array-view.h"

namespace Slang
{
	template<typename T, int COUNT>
	class Array
	{
	private:
		T m_buffer[COUNT];
		int m_count = 0;
	public:
        T* begin() { return m_buffer; }
        const T* begin() const { return m_buffer; }

        const T* end() const { return m_buffer + m_count; }
        T* end() { return m_buffer + m_count; }

	public:
		inline int getCapacity() const { return COUNT; }
		inline int getCount() const { return m_count; }
		inline const T& getFirst() const
		{
            SLANG_ASSERT(m_count > 0);
			return m_buffer[0];
		}
        inline T& getFirst()
        {
            SLANG_ASSERT(m_count > 0);
            return m_buffer[0];
        }
		inline const T& getLast() const
		{
            SLANG_ASSERT(m_count > 0);
			return m_buffer[m_count - 1];
		}
        inline T& getLast()
        {
            SLANG_ASSERT(m_count > 0);
            return m_buffer[m_count - 1];
        }
		inline void setCount(int newCount)
		{
            SLANG_ASSERT(newCount >= 0 && newCount <= COUNT);
			m_count = newCount;
		}
		inline void add(const T & item)
		{
            SLANG_ASSERT(m_count < COUNT);
			m_buffer[m_count++] = item;
		}
		inline void add(T && item)
		{
            SLANG_ASSERT(m_count < COUNT);
			m_buffer[m_count++] = _Move(item);
		}

		inline const T& operator [](int idx) const
		{
            SLANG_ASSERT(idx >= 0 && idx < m_count);
			return m_buffer[idx];
		}
        inline T& operator [](int idx)
        {
            SLANG_ASSERT(idx >= 0 && idx < m_count);
            return m_buffer[idx];
        }

		inline const T* getBuffer() const { return m_buffer; }
        inline T* getBuffer() { return m_buffer; }

		inline void clear() { m_count = 0; }

		template<typename T2>
		int indexOf(const T2& val) const
		{
			for (int i = 0; i < m_count; i++)
			{
				if (m_buffer[i] == val)
					return i;
			}
			return -1;
		}

		template<typename T2>
		int lastIndexOf(const T2& val) const
		{
			for (int i = m_count - 1; i >= 0; i--)
			{
				if (m_buffer[i] == val)
					return i;
			}
			return -1;
		}

		inline ArrayView<T> getArrayView() const
		{
			return ArrayView<T>((T*)m_buffer, m_count);
		}
		inline ArrayView<T> getArrayView(int start, int count) const
		{
			return ArrayView<T>((T*)m_buffer + start, count);
		}
	};

	template<typename T, typename ...TArgs>
	struct FirstType
	{
		typedef T Type;
	};


	template<typename T, int SIZE>
	void insertArray(Array<T, SIZE>&) {}

	template<typename T, typename ...TArgs, int SIZE>
	void insertArray(Array<T, SIZE>& arr, const T& val, TArgs... args)
	{
		arr.add(val);
		insertArray(arr, args...);
	}

	template<typename ...TArgs>
	auto makeArray(TArgs ...args) -> Array<typename FirstType<TArgs...>::Type, sizeof...(args)>
	{
		Array<typename FirstType<TArgs...>::Type, sizeof...(args)> rs;
		insertArray(rs, args...);
		return rs;
	}
}

#endif