<commit_before>#pragma once


#include "core/lux.h"
#include <cstdlib>
#include <new>


namespace Lux
{


template <class T>
class vector
{
	public:
		vector()
		{
			m_data = 0;
			m_capacity = 0;
			m_size = 0;
		}

		vector(const vector<T>& rhs)
		{
			m_capacity = 0;
			m_size = 0;
			m_data = 0;
			reserve(rhs.m_capacity);
			memcpy(m_data, rhs.m_data, sizeof(T) * rhs.m_size);
			m_size = rhs.m_size;
		}

		~vector()
		{
			for(int i = 0; i < m_size; ++i)
			{
				m_data[i].~T();
			}
			delete[] (char*)m_data;
		}

		void eraseFast(int index)
		{
			if(index >= 0 && index < m_size)
			{
				m_data[index].~T();
				if(index != m_size - 1)
				{
					memmove(m_data + index, m_data + m_size - 1, sizeof(T));
				}
				--m_size;
			}
		}

		void erase(int index)
		{
			if(index >= 0 && index < m_size)
			{
				m_data[index].~T();
				memmove(m_data + index, m_data + index + 1, sizeof(T) * (m_size - index - 1));
				--m_size;
			}
		}

		void push_back(const T& value)
		{
			if(m_size == m_capacity)
			{
				grow();
			}
			new ((char*)(m_data+m_size)) T(value);
			++m_size;
		}

		bool empty() const { return m_size == 0; }

		void clear()
		{
			for(int i = 0; i < m_size; ++i)
			{
				m_data[i].~T();
			}
			m_size = 0;
		}

		T& push_back_empty()
		{
			if(m_size == m_capacity)
			{
				grow();
			}
			new ((char*)(m_data+m_size)) T();
			++m_size;
			return m_data[m_size-1];
		}


		const T& back() const
		{
			return m_data[m_size-1];
		}


		T& back()
		{
			return m_data[m_size-1];
		}


		void pop_back()
		{
			if(m_size > 0)
			{
				m_data[m_size-1].~T();
				--m_size;
			}
		}

		void set_size(int size)
		{
			if(size <= m_capacity)
			{
				m_size = size;
			}
		}

		void resize(int size)
		{
			if(size > m_capacity)
			{
				reserve(size);
			}
			for(int i = m_size; i < size; ++i)
			{
				new ((char*)(m_data+i)) T();
			}
			for(int i = size; i < m_size; ++i)
			{
				m_data[i].~T();
			}
			m_size = size;
		}

		void reserve(int capacity)
		{
			if(capacity > m_capacity)
			{
				T* newData = (T*)new char[capacity * sizeof(T)];
				memcpy(newData, m_data, m_size * sizeof(T));
				delete[] ((char*)m_data);
				m_data = newData;
				m_capacity = capacity;			
			}
		}

		const T& operator[] (int index) const { ASSERT(index < m_size); return m_data[index]; }
		T& operator[](int index) { return m_data[index]; }
 		int size() const { return m_size; }
		int capacity() const { return m_capacity; }

		void operator =(const vector<T>& rhs) 
		{
			if(m_capacity < rhs.m_size)
			{
				delete[] m_data;
				m_data = (T*)new char[rhs.m_size * sizeof(T)];
				m_capacity = rhs.m_size;
			}
			m_size = rhs.m_size;
			if(m_size > 0)
			{
				memcpy(m_data, rhs.m_data, sizeof(T) * rhs.m_size);
			}
		}
	private:
		void* operator &() { return 0; }

		void grow()
		{
			int newCapacity = m_capacity == 0 ? 4 : m_capacity * 2;
			T* newData = (T*)new char[newCapacity * sizeof(T)];
			memcpy(newData, m_data, m_size * sizeof(T));
			delete[] ((char*)m_data);
			m_data = newData;
			m_capacity = newCapacity;
		}

	private:
		int m_capacity;
		int m_size;
		T* m_data;
};


} // ~namespace Lux<commit_msg>fixed vector - call destructors when necessary<commit_after>#pragma once


#include "core/lux.h"
#include <cstdlib>
#include <new>


namespace Lux
{


template <typename T>
class vector
{
	public:
		vector()
		{
			m_data = 0;
			m_capacity = 0;
			m_size = 0;
		}

		vector(const vector<T>& rhs)
		{
			m_capacity = 0;
			m_size = 0;
			m_data = 0;
			reserve(rhs.m_capacity);
			for(int i = 0; i < rhs.m_size; ++i)
			{
				new ((char*)(m_data+i)) T(rhs.m_data[i]);
			}
			m_size = rhs.m_size;
		}

		~vector()
		{
			callDestructors(m_data, m_data + m_size);
			delete[] (char*)m_data;
		}

		void eraseFast(int index)
		{
			if(index >= 0 && index < m_size)
			{
				m_data[index].~T();
				if(index != m_size - 1)
				{
					new ((char*)(m_data+index)) T(m_data[m_size - 1]);
				}
				--m_size;
			}
		}

		void erase(int index)
		{
			if(index >= 0 && index < m_size)
			{
				m_data[index].~T();
				for(int i = index + 1; i < m_size; ++i)
				{
					new ((char*)(m_data+i-1)) T(m_data[i]);
					m_data[i].~T();
				}
				--m_size;
			}
		}

		void push_back(const T& value)
		{
			if(m_size == m_capacity)
			{
				grow();
			}
			new ((char*)(m_data+m_size)) T(value);
			++m_size;
		}

		bool empty() const { return m_size == 0; }

		void clear()
		{
			callDestructors(m_data, m_data + m_size);
			m_size = 0;
		}

		T& push_back_empty()
		{
			if(m_size == m_capacity)
			{
				grow();
			}
			new ((char*)(m_data+m_size)) T();
			++m_size;
			return m_data[m_size-1];
		}


		const T& back() const
		{
			return m_data[m_size-1];
		}


		T& back()
		{
			return m_data[m_size-1];
		}


		void pop_back()
		{
			if(m_size > 0)
			{
				m_data[m_size-1].~T();
				--m_size;
			}
		}

		/// TODO remove this when we have PODArray
		void set_size(int size)
		{
			if(size <= m_capacity)
			{
				m_size = size;
			}
		}

		void resize(int size)
		{
			if(size > m_capacity)
			{
				reserve(size);
			}
			for(int i = m_size; i < size; ++i)
			{
				new ((char*)(m_data+i)) T();
			}
			callDestructors(m_data + size, m_data + m_size);
			m_size = size;
		}

		void reserve(int capacity)
		{
			if(capacity > m_capacity)
			{
				T* newData = (T*)new char[capacity * sizeof(T)];
				for(int i = 0; i < m_size; ++i)
				{
					new ((char*)(newData+i)) T(m_data[i]);
				}
				callDestructors(m_data, m_data + m_size);
				delete[] ((char*)m_data);
				m_data = newData;
				m_capacity = capacity;			
			}
		}

		const T& operator[] (int index) const { ASSERT(index < m_size); return m_data[index]; }
		T& operator[](int index) { return m_data[index]; }
 		int size() const { return m_size; }
		int capacity() const { return m_capacity; }

		void operator =(const vector<T>& rhs) 
		{
			callDestructors(m_data, m_data + m_size);
			if(m_capacity < rhs.m_size)
			{
				delete[] m_data;
				m_data = (T*)new char[rhs.m_size * sizeof(T)];
				m_capacity = rhs.m_size;
			}
			m_size = rhs.m_size;
			if(m_size > 0)
			{
				for(int i = 0; i < rhs.m_size; ++i)
				{
					new ((char*)(m_data + i)) T(rhs.m_data[i]);
				}
			}
		}
	private:
		void* operator &() { return 0; }

		void grow()
		{
			int newCapacity = m_capacity == 0 ? 4 : m_capacity * 2;
			T* newData = (T*)new char[newCapacity * sizeof(T)];
			for(int i = 0; i < m_size; ++i)
			{
				new ((char*)(newData + i)) T(m_data[i]);
			}
			callDestructors(m_data, m_data + m_size);
			delete[] ((char*)m_data);
			m_data = newData;
			m_capacity = newCapacity;
		}

		void callDestructors(T* begin, T* end)
		{
			for(; begin < end; ++begin)
			{
				begin->~T();
			}
		}

	private:
		int m_capacity;
		int m_size;
		T* m_data;
};


} // ~namespace Lux
{'fraction_non_alphanumeric': 0.17291789722386297, 'fraction_numerical': 0.007974010632014175, 'mean_word_length': 2.434584178498986, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4180765', 'n_tokens_mistral': 3616, 'n_tokens_neox': 2906, 'n_words': 595}