bitsquid avatar bitsquid committed a69aedf

Changed name to foundation and introduced namespace.

Comments (0)

Files changed (13)

 syntax: glob
 *.o
 unit_test
-mini_foundation
+foundation
-# mini\_foundation
+# foundation
 
-*mini\_foundation* is a minimalistic foundation library with functions for memory allocation, data manipulation, etc.
+*foundation* is a minimalistic foundation library with functions for memory allocation, data manipulation, etc.
 
 ## Library Design
 
-*mini\_foundation* has been written with data-oriented programming in mind (POD data is preferred over complicated classes, flat arrays are the preferred data structure, etc).
+*foundation* has been written with data-oriented programming in mind (POD data is preferred over complicated classes, flat arrays are the preferred data structure, etc).
 
 mini_foundation is written in a "back-to-C" style of C++ programming. This means that there is a clear separation between data and code. Data defitions are found in \_types.h header files. Function definitions are found in .h header files.
 
-When you are writing a system using mini\_foundation, your header files typically only need to include the \_types.h files. These are designed to be as compact as possible, meaning your compile times will be short. In the .cpp files you can include the heavier .h files.
+When you are writing a system using foundation, your header files typically only need to include the \_types.h files. These are designed to be as compact as possible, meaning your compile times will be short. In the .cpp files you can include the heavier .h files.
 
-mini_foundation uses the following types of data:
+*foundation* uses the following types of data:
 
     // Open structs
     struct Vector3 {
 
     // Closed structs
     struct Object {
-    	Object();
+    	Object(); 
     	unsigned _data;
     };
 
 
 #include <memory>
 
-// TODO:
-// * insert
-// * erase
+namespace foundation {
+	namespace array
+	{
+		template<typename T> inline uint32_t size(const Array<T> &a) 		{return a._size;}
+		template<typename T> inline bool any(const Array<T> &a) 			{return a._size != 0;}
+		template<typename T> inline bool empty(const Array<T> &a) 			{return a._size == 0;}
+		template<typename T> inline uint32_t capacity(const Array<T> &a)	{return a._capacity;}
 
-namespace array
-{
-	template<typename T> inline uint32_t size(const Array<T> &a) 		{return a._size;}
-	template<typename T> inline bool any(const Array<T> &a) 			{return a._size != 0;}
-	template<typename T> inline bool empty(const Array<T> &a) 			{return a._size == 0;}
-	template<typename T> inline uint32_t capacity(const Array<T> &a)	{return a._capacity;}
+		template<typename T> inline T* begin(Array<T> &a) 					{return a._data;}
+		template<typename T> inline const T* begin(const Array<T> &a) 		{return a._data;}
+		template<typename T> inline T* end(Array<T> &a) 					{return a._data + a._size;}
+		template<typename T> inline const T* end(const Array<T> &a) 		{return a._data + a._size;}
+		
+		template<typename T> inline T& front(Array<T> &a) 					{return a._data[0];}
+		template<typename T> inline const T& front(const Array<T> &a) 		{return a._data[0];}
+		template<typename T> inline T& back(Array<T> &a) 					{return a._data[a._size-1];}
+		template<typename T> inline const T& back(const Array<T> &a) 		{return a._data[a._size-1];}
 
-	template<typename T> inline T* begin(Array<T> &a) 					{return a._data;}
-	template<typename T> inline const T* begin(const Array<T> &a) 		{return a._data;}
-	template<typename T> inline T* end(Array<T> &a) 					{return a._data + a._size;}
-	template<typename T> inline const T* end(const Array<T> &a) 		{return a._data + a._size;}
-	
-	template<typename T> inline T& front(Array<T> &a) 					{return a._data[0];}
-	template<typename T> inline const T& front(const Array<T> &a) 		{return a._data[0];}
-	template<typename T> inline T& back(Array<T> &a) 					{return a._data[a._size-1];}
-	template<typename T> inline const T& back(const Array<T> &a) 		{return a._data[a._size-1];}
+		template <typename T> inline void clear(Array<T> &a) {resize(a,0);}
+		template <typename T> inline void trim(Array<T> &a) {set_capacity(a,a._size);}
 
-	template <typename T> inline void clear(Array<T> &a) {resize(a,0);}
-	template <typename T> inline void trim(Array<T> &a) {set_capacity(a,a._size);}
+		template <typename T> void resize(Array<T> &a, uint32_t new_size)
+		{
+			if (new_size > a._capacity)
+				grow(a, new_size);
+			a._size = new_size;
+		}
 
-	template <typename T> void resize(Array<T> &a, uint32_t new_size)
-	{
-		if (new_size > a._capacity)
-			grow(a, new_size);
-		a._size = new_size;
+		template <typename T> inline void reserve(Array<T> &a, uint32_t new_capacity)
+		{
+			if (new_capacity > a._capacity)
+				set_capacity(a, new_capacity);
+		}
+
+		template<typename T> void set_capacity(Array<T> &a, uint32_t new_capacity)
+		{
+			if (new_capacity == a._capacity)
+				return;
+
+			if (new_capacity < a._size)
+				resize(a, new_capacity);
+
+			T *new_data = 0;
+			if (new_capacity > 0) {
+				new_data = (T *)a._allocator->allocate(sizeof(T)*new_capacity, alignof(T));
+				memcpy(new_data, a._data, sizeof(T)*a._size);
+			}
+			a._allocator->deallocate(a._data);
+			a._data = new_data;
+			a._capacity = new_capacity;
+		}
+
+		template<typename T> void grow(Array<T> &a, uint32_t min_capacity = 0)
+		{
+			uint32_t new_capacity = a._capacity*2 + 10;
+			if (new_capacity < min_capacity)
+				new_capacity = min_capacity;
+			set_capacity(a, new_capacity);
+		}
+
+		template<typename T> inline void push_back(Array<T> &a, const T &item)
+		{
+			if (a._size + 1 > a._capacity)
+				grow(a);
+			a._data[a._size++] = item;
+		}
+
+		template<typename T> inline void pop_back(Array<T> &a)
+		{
+			a._size--;
+		}
 	}
 
-	template <typename T> inline void reserve(Array<T> &a, uint32_t new_capacity)
+	template <typename T>
+	inline Array<T>::Array(Allocator &allocator) : _allocator(&allocator), _size(0), _capacity(0), _data(NULL) {}
+
+	template <typename T>
+	inline Array<T>::~Array()
 	{
-		if (new_capacity > a._capacity)
-			set_capacity(a, new_capacity);
+		_allocator->deallocate(_data);
 	}
 
-	template<typename T> void set_capacity(Array<T> &a, uint32_t new_capacity)
+	template <typename T>
+	Array<T>::Array(const Array<T> &other) : _allocator(other._allocator), _size(0), _capacity(0), _data(0)
 	{
-		if (new_capacity == a._capacity)
-			return;
-
-		if (new_capacity < a._size)
-			resize(a, new_capacity);
-
-		T *new_data = 0;
-		if (new_capacity > 0) {
-			new_data = (T *)a._allocator->allocate(sizeof(T)*new_capacity, alignof(T));
-			memcpy(new_data, a._data, sizeof(T)*a._size);
-		}
-		a._allocator->deallocate(a._data);
-		a._data = new_data;
-		a._capacity = new_capacity;
+		const uint32_t n = other._size;
+		array::set_capacity(*this, n);
+		memcpy(_data, other._data, sizeof(T) * n);
+		_size = n;
 	}
 
-	template<typename T> void grow(Array<T> &a, uint32_t min_capacity = 0)
+	template <typename T>
+	Array<T> &Array<T>::operator=(const Array<T> &other)
 	{
-		uint32_t new_capacity = a._capacity*2 + 10;
-		if (new_capacity < min_capacity)
-			new_capacity = min_capacity;
-		set_capacity(a, new_capacity);
+		const uint32_t n = other._size;
+		array::resize(*this, n);
+		memcpy(_data, other._data, sizeof(T)*n);
+		return *this;
 	}
 
-	template<typename T> inline void push_back(Array<T> &a, const T &item)
+	template <typename T>
+	inline T & Array<T>::operator[](uint32_t i)
 	{
-		if (a._size + 1 > a._capacity)
-			grow(a);
-		a._data[a._size++] = item;
+		return _data[i];
 	}
 
-	template<typename T> inline void pop_back(Array<T> &a)
+	template <typename T>
+	inline const T & Array<T>::operator[](uint32_t i) const
 	{
-		a._size--;
+		return _data[i];
 	}
-}
-
-template <typename T>
-inline Array<T>::Array(Allocator &allocator) : _allocator(&allocator), _size(0), _capacity(0), _data(NULL) {}
-
-template <typename T>
-inline Array<T>::~Array()
-{
-	_allocator->deallocate(_data);
-}
-
-template <typename T>
-Array<T>::Array(const Array<T> &other) : _allocator(other._allocator), _size(0), _capacity(0), _data(0)
-{
-	const uint32_t n = other._size;
-	array::set_capacity(*this, n);
-	memcpy(_data, other._data, sizeof(T) * n);
-	_size = n;
-}
-
-template <typename T>
-Array<T> &Array<T>::operator=(const Array<T> &other)
-{
-	const uint32_t n = other._size;
-	array::resize(*this, n);
-	memcpy(_data, other._data, sizeof(T)*n);
-	return *this;
-}
-
-template <typename T>
-inline T & Array<T>::operator[](uint32_t i)
-{
-	return _data[i];
-}
-
-template <typename T>
-inline const T & Array<T>::operator[](uint32_t i) const
-{
-	return _data[i];
 }

collection_types.h

 #include "types.h"
 #include "memory_types.h"
 
-/// Array of POD objects.
-///
-/// * Does not call constructors & destructors on elements.
-/// * Assumes they can be moved with memmove().
-template<typename T> struct Array
+namespace foundation
 {
-	Array(Allocator &a);
-	~Array();
-	Array(const Array &other);
-	Array &operator=(const Array &other);
-	
-	T &operator[](uint32_t i);
-	const T &operator[](uint32_t i) const;
+	/// Array of POD objects.
+	///
+	/// * Does not call constructors & destructors on elements.
+	/// * Assumes they can be moved with memmove().
+	template<typename T> struct Array
+	{
+		Array(Allocator &a);
+		~Array();
+		Array(const Array &other);
+		Array &operator=(const Array &other);
+		
+		T &operator[](uint32_t i);
+		const T &operator[](uint32_t i) const;
 
-	Allocator *_allocator;
-	uint32_t _size;
-	uint32_t _capacity;
-	T *_data;
-};
-
-/// Hash from an uint64_t to POD objects. If you want to use a generic key
-/// object, use a hash function to map that object to an uint64_t.
-///
-/// * Does not call constructors & destructors on elements.
-/// * Assumes they can be moved with memmove().
-template<typename T> struct Hash
-{
-public:
-	Hash(Allocator &a);
-	
-	struct Entry {
-		uint64_t key;
-		uint32_t next;
-		T value;
+		Allocator *_allocator;
+		uint32_t _size;
+		uint32_t _capacity;
+		T *_data;
 	};
 
-	Array<uint32_t> _hash;
-	Array<Entry> _data;
-};
+	/// Hash from an uint64_t to POD objects. If you want to use a generic key
+	/// object, use a hash function to map that object to an uint64_t.
+	///
+	/// * Does not call constructors & destructors on elements.
+	/// * Assumes they can be moved with memmove().
+	template<typename T> struct Hash
+	{
+	public:
+		Hash(Allocator &a);
+		
+		struct Entry {
+			uint64_t key;
+			uint32_t next;
+			T value;
+		};
+
+		Array<uint32_t> _hash;
+		Array<Entry> _data;
+	};
+}
 #include "array.h"
 #include "collection_types.h"
 
-/// The hash function stores its data in a "list-in-an-array" where
-/// indices are used instead of pointers. 
-///
-/// When items are removed, the array-list is repacked to always keep
-/// it tightly ordered.
+namespace foundation {
 
-namespace hash
-{
-	template<typename T> void set(Hash<T> &h, uint64_t key, const T &value);
-}
+	/// The hash function stores its data in a "list-in-an-array" where
+	/// indices are used instead of pointers. 
+	///
+	/// When items are removed, the array-list is repacked to always keep
+	/// it tightly ordered.
 
-namespace hash_internal
-{
-	const uint32_t END_OF_LIST = 0xffffffffu;
-	
-	struct FindResult
+	namespace hash
 	{
-		uint32_t hash_i;
-		uint32_t data_prev;
-		uint32_t data_i;
-	};	
-
-	template<typename T> uint32_t add_entry(Hash<T> &h, uint64_t key)
-	{
-		typename Hash<T>::Entry e;
-		e.key = key;
-		e.next = END_OF_LIST;
-		uint32_t ei = array::size(h._data);
-		array::push_back(h._data, e);
-		return ei;
+		template<typename T> void set(Hash<T> &h, uint64_t key, const T &value);
 	}
 
-	template<typename T> void erase(Hash<T> &h, const FindResult &fr)
+	namespace hash_internal
 	{
-		if (fr.data_prev == END_OF_LIST)
-			h._hash[fr.hash_i] = h._data[fr.data_i].next;
-		else
-			h._data[fr.data_prev].next = h._data[fr.data_i].next;
+		const uint32_t END_OF_LIST = 0xffffffffu;
+		
+		struct FindResult
+		{
+			uint32_t hash_i;
+			uint32_t data_prev;
+			uint32_t data_i;
+		};	
 
-		if (fr.data_i == array::size(h._data) - 1) {
-			array::pop_back(h._data);
-			return;
+		template<typename T> uint32_t add_entry(Hash<T> &h, uint64_t key)
+		{
+			typename Hash<T>::Entry e;
+			e.key = key;
+			e.next = END_OF_LIST;
+			uint32_t ei = array::size(h._data);
+			array::push_back(h._data, e);
+			return ei;
 		}
 
-		h._data[fr.data_i] = h._data[array::size(h._data) - 1];
-		FindResult last = find(h, h._data[fr.data_i].key);
+		template<typename T> void erase(Hash<T> &h, const FindResult &fr)
+		{
+			if (fr.data_prev == END_OF_LIST)
+				h._hash[fr.hash_i] = h._data[fr.data_i].next;
+			else
+				h._data[fr.data_prev].next = h._data[fr.data_i].next;
 
-		if (last.data_prev != END_OF_LIST)
-			h._data[last.data_prev].next = fr.data_i;
-		else
-			h._hash[last.hash_i] = fr.data_i;
+			if (fr.data_i == array::size(h._data) - 1) {
+				array::pop_back(h._data);
+				return;
+			}
+
+			h._data[fr.data_i] = h._data[array::size(h._data) - 1];
+			FindResult last = find(h, h._data[fr.data_i].key);
+
+			if (last.data_prev != END_OF_LIST)
+				h._data[last.data_prev].next = fr.data_i;
+			else
+				h._hash[last.hash_i] = fr.data_i;
+		}
+
+		template<typename T> FindResult find(const Hash<T> &h, uint64_t key)
+		{
+			FindResult fr;
+			fr.hash_i = END_OF_LIST;
+			fr.data_prev = END_OF_LIST;
+			fr.data_i = END_OF_LIST;
+
+			if (array::size(h._hash) == 0)
+				return fr;
+
+			fr.hash_i = key % array::size(h._hash);
+			fr.data_i = h._hash[fr.hash_i];
+			while (fr.data_i != END_OF_LIST) {
+				if (h._data[fr.data_i].key == key)
+					return fr;
+				fr.data_prev = fr.data_i;
+				fr.data_i = h._data[fr.data_i].next;
+			}
+			return fr;
+		}
+
+		template<typename T> uint32_t find_or_fail(const Hash<T> &h, uint64_t key)
+		{
+			return find(h, key).data_i;
+		}
+
+		template<typename T> uint32_t find_or_make(Hash<T> &h, uint64_t key)
+		{
+			FindResult fr = find(h, key);
+			if (fr.data_i != END_OF_LIST)
+				return fr.data_i;
+
+			fr.data_i = add_entry(h, key);
+			if (fr.data_prev == END_OF_LIST)
+				h._hash[fr.hash_i] = fr.data_i;
+			else
+				h._data[fr.data_prev].next = fr.data_i;
+			return fr.data_i;
+		}	
+
+		template<typename T> void find_and_erase(Hash<T> &h, uint64_t key)
+		{
+			const FindResult fr = find(h, key);
+			if (fr.data_i != END_OF_LIST)
+				erase(h, fr);
+		}
+
+		template<typename T> void rehash(Hash<T> &h, uint32_t new_size)
+		{
+			Hash<T> nh(*h._hash._allocator);
+			array::resize(nh._hash, new_size);
+			array::reserve(nh._data, array::size(h._data));
+			for (uint32_t i=0; i<new_size; ++i)
+				nh._hash[i] = END_OF_LIST;
+			for (uint32_t i=0; i<array::size(h._data); ++i) {
+				const typename Hash<T>::Entry &e = h._data[i];
+				hash::set(nh, e.key, e.value);
+			}
+
+			Hash<T> empty(*h._hash._allocator);
+			h.~Hash<T>();
+			memcpy(&h, &nh, sizeof(Hash<T>));
+			memcpy(&nh, &empty, sizeof(Hash<T>));
+		}
+
+		template<typename T> bool full(const Hash<T> &h)
+		{
+			const float max_load_factor = 0.7f;
+			return array::size(h._data) >= array::size(h._hash) * max_load_factor;
+		}
+
+		template<typename T> void grow(Hash<T> &h)
+		{
+			uint32_t new_size = array::size(h._data) * 2 + 10;
+			rehash(h, new_size);
+		}
 	}
 
-	template<typename T> FindResult find(const Hash<T> &h, uint64_t key)
+	namespace hash
 	{
-		FindResult fr;
-		fr.hash_i = END_OF_LIST;
-		fr.data_prev = END_OF_LIST;
-		fr.data_i = END_OF_LIST;
+		const uint32_t END_OF_LIST = 0xffffffffu;
 
-		if (array::size(h._hash) == 0)
-			return fr;
+		template<typename T> bool has(const Hash<T> &h, uint64_t key)
+		{
+			return hash_internal::find_or_fail(h, key) != END_OF_LIST;
+		}
 
-		fr.hash_i = key % array::size(h._hash);
-		fr.data_i = h._hash[fr.hash_i];
-		while (fr.data_i != END_OF_LIST) {
-			if (h._data[fr.data_i].key == key)
-				return fr;
-			fr.data_prev = fr.data_i;
-			fr.data_i = h._data[fr.data_i].next;
+		template<typename T> const T &get(const Hash<T> &h, uint64_t key, const T &deffault)
+		{
+			uint32_t i = hash_internal::find_or_fail(h, key);
+			return i == END_OF_LIST ? deffault : h._data[i].value;
 		}
-		return fr;
+
+		template<typename T> void set(Hash<T> &h, uint64_t key, const T &value)
+		{
+			if (array::size(h._hash) == 0)
+				hash_internal::grow(h);
+
+			uint32_t i = hash_internal::find_or_make(h, key);
+			h._data[i].value = value;
+			if (hash_internal::full(h))
+				hash_internal::grow(h);
+		}
+
+		template<typename T> void remove(Hash<T> &h, uint64_t key)
+		{
+			hash_internal::find_and_erase(h, key);
+		}
+
+		template<typename T> void reserve(Hash<T> &h, uint32_t size)
+		{
+			hash_internal::rehash(h, size);
+		}
+
+		template<typename T> const typename Hash<T>::Entry *begin(const Hash<T> &h)
+		{
+			return array::begin(h._data);
+		}
+
+		template<typename T> const typename Hash<T>::Entry *end(const Hash<T> &h)
+		{
+			return array::end(h._data);
+		}
 	}
 
-	template<typename T> uint32_t find_or_fail(const Hash<T> &h, uint64_t key)
-	{
-		return find(h, key).data_i;
-	}
-
-	template<typename T> uint32_t find_or_make(Hash<T> &h, uint64_t key)
-	{
-		FindResult fr = find(h, key);
-		if (fr.data_i != END_OF_LIST)
-			return fr.data_i;
-
-		fr.data_i = add_entry(h, key);
-		if (fr.data_prev == END_OF_LIST)
-			h._hash[fr.hash_i] = fr.data_i;
-		else
-			h._data[fr.data_prev].next = fr.data_i;
-		return fr.data_i;
-	}	
-
-	template<typename T> void find_and_erase(Hash<T> &h, uint64_t key)
-	{
-		const FindResult fr = find(h, key);
-		if (fr.data_i != END_OF_LIST)
-			erase(h, fr);
-	}
-
-	template<typename T> void rehash(Hash<T> &h, uint32_t new_size)
-	{
-		Hash<T> nh(*h._hash._allocator);
-		array::resize(nh._hash, new_size);
-		array::reserve(nh._data, array::size(h._data));
-		for (uint32_t i=0; i<new_size; ++i)
-			nh._hash[i] = END_OF_LIST;
-		for (uint32_t i=0; i<array::size(h._data); ++i) {
-			const typename Hash<T>::Entry &e = h._data[i];
-			hash::set(nh, e.key, e.value);
-		}
-
-		Hash<T> empty(*h._hash._allocator);
-		h.~Hash<T>();
-		memcpy(&h, &nh, sizeof(Hash<T>));
-		memcpy(&nh, &empty, sizeof(Hash<T>));
-	}
-
-	template<typename T> bool full(const Hash<T> &h)
-	{
-		const float max_load_factor = 0.7f;
-		return array::size(h._data) >= array::size(h._hash) * max_load_factor;
-	}
-
-	template<typename T> void grow(Hash<T> &h)
-	{
-		uint32_t new_size = array::size(h._data) * 2 + 10;
-		rehash(h, new_size);
-	}
-}
-
-namespace hash
-{
-	const uint32_t END_OF_LIST = 0xffffffffu;
-
-	template<typename T> bool has(const Hash<T> &h, uint64_t key)
-	{
-		return hash_internal::find_or_fail(h, key) != END_OF_LIST;
-	}
-
-	template<typename T> const T &get(const Hash<T> &h, uint64_t key, const T &deffault)
-	{
-		uint32_t i = hash_internal::find_or_fail(h, key);
-		return i == END_OF_LIST ? deffault : h._data[i].value;
-	}
-
-	template<typename T> void set(Hash<T> &h, uint64_t key, const T &value)
-	{
-		if (array::size(h._hash) == 0)
-			hash_internal::grow(h);
-
-		uint32_t i = hash_internal::find_or_make(h, key);
-		h._data[i].value = value;
-		if (hash_internal::full(h))
-			hash_internal::grow(h);
-	}
-
-	template<typename T> void remove(Hash<T> &h, uint64_t key)
-	{
-		hash_internal::find_and_erase(h, key);
-	}
-
-	template<typename T> void reserve(Hash<T> &h, uint32_t size)
-	{
-		hash_internal::rehash(h, size);
-	}
-
-	template<typename T> const typename Hash<T>::Entry *begin(const Hash<T> &h)
-	{
-		return array::begin(h._data);
-	}
-
-	template<typename T> const typename Hash<T>::Entry *end(const Hash<T> &h)
-	{
-		return array::end(h._data);
-	}
-}
-
-template <typename T> Hash<T>::Hash(Allocator &a) :
-	_hash(a), _data(a)
-{}
+	template <typename T> Hash<T>::Hash(Allocator &a) :
+		_hash(a), _data(a)
+	{}
+}
 
 #include "types.h"
 
-struct Vector2
+namespace foundation
 {
-	float x, y;
-};
+	struct Vector2
+	{
+		float x, y;
+	};
 
-struct Vector3
-{
-	float x, y, z;
-};
+	struct Vector3
+	{
+		float x, y, z;
+	};
 
-struct Vector4
-{
-	float x, y, z, w;
-};
+	struct Vector4
+	{
+		float x, y, z, w;
+	};
 
-struct Quaternion
-{
-	float x, y, z, w;
-};
+	struct Quaternion
+	{
+		float x, y, z, w;
+	};
 
-struct Matrix3x3
-{
-	Vector3 x, y, z;
-};
+	struct Matrix3x3
+	{
+		Vector3 x, y, z;
+	};
 
-struct Matrix4x4
-{
-	Vector4 x, y, z, t;
-};
+	struct Matrix4x4
+	{
+		Vector4 x, y, z, t;
+	};
 
-struct AABB
-{
-	Vector3 min, max;
-};
+	struct AABB
+	{
+		Vector3 min, max;
+	};
 
-struct OOBB
-{
-	Matrix4x4 tm;
-	AABB aabb;
-};
+	struct OOBB
+	{
+		Matrix4x4 tm;
+		AABB aabb;
+	};
+}
 #include <new>
 
 namespace {
+	using namespace foundation;
+
 	// Header stored at the beginning of a memory allocation to indicate the
 	// size of the allocated data.
 	struct Header {
 	MemoryGlobals _memory_globals;
 }
 
-namespace memory_globals {
-	void init(uint32_t temporary_memory) {
-		char *p = _memory_globals.buffer;
-		_memory_globals.default_allocator = new (p) MallocAllocator();
-		p += sizeof(MallocAllocator);
-		_memory_globals.default_scratch_allocator = new (p) ScratchAllocator(*_memory_globals.default_allocator, temporary_memory);
-	}
+namespace foundation
+{
+	namespace memory_globals
+	{
+		void init(uint32_t temporary_memory) {
+			char *p = _memory_globals.buffer;
+			_memory_globals.default_allocator = new (p) MallocAllocator();
+			p += sizeof(MallocAllocator);
+			_memory_globals.default_scratch_allocator = new (p) ScratchAllocator(*_memory_globals.default_allocator, temporary_memory);
+		}
 
-	Allocator &default_allocator() {
-		return *_memory_globals.default_allocator;
-	}
+		Allocator &default_allocator() {
+			return *_memory_globals.default_allocator;
+		}
 
-	Allocator &default_scratch_allocator() {
-		return *_memory_globals.default_scratch_allocator;
-	}
+		Allocator &default_scratch_allocator() {
+			return *_memory_globals.default_scratch_allocator;
+		}
 
-	void shutdown() {
-		_memory_globals.default_scratch_allocator->~ScratchAllocator();
-		_memory_globals.default_allocator->~MallocAllocator();
-		_memory_globals = MemoryGlobals();
+		void shutdown() {
+			_memory_globals.default_scratch_allocator->~ScratchAllocator();
+			_memory_globals.default_allocator->~MallocAllocator();
+			_memory_globals = MemoryGlobals();
+		}
 	}
 }
-
-
 #include "types.h"
 #include "memory_types.h"
 
-/// Base class for memory allocators.
-///
-/// Note: Regardless of which allocator is used, prefer to allocate memory in larger chunks
-/// instead of in many small allocations. This helps with data locality, fragmentation,
-/// memory usage tracking, etc.
-class Allocator
+namespace foundation
 {
-public:
-	/// Default alignment for memory allocations.
-	static const uint32_t DEFAULT_ALIGN = 4;
+	/// Base class for memory allocators.
+	///
+	/// Note: Regardless of which allocator is used, prefer to allocate memory in larger chunks
+	/// instead of in many small allocations. This helps with data locality, fragmentation,
+	/// memory usage tracking, etc.
+	class Allocator
+	{
+	public:
+		/// Default alignment for memory allocations.
+		static const uint32_t DEFAULT_ALIGN = 4;
 
-	Allocator() {}
-	virtual ~Allocator() {}
-	
-	/// Allocates the specified amount of memory aligned to the specified alignment.
-	virtual void *allocate(uint32_t size, uint32_t align = DEFAULT_ALIGN) = 0;
+		Allocator() {}
+		virtual ~Allocator() {}
+		
+		/// Allocates the specified amount of memory aligned to the specified alignment.
+		virtual void *allocate(uint32_t size, uint32_t align = DEFAULT_ALIGN) = 0;
 
-	/// Frees an allocation previously made with allocate().
-	virtual void deallocate(void *p) = 0;
+		/// Frees an allocation previously made with allocate().
+		virtual void deallocate(void *p) = 0;
 
-	static const uint32_t SIZE_NOT_TRACKED = 0xffffffffu;
+		static const uint32_t SIZE_NOT_TRACKED = 0xffffffffu;
 
-	/// Returns the amount of usable memory allocated at p. p must be a pointer
-	/// returned by allocate() that has not yet been deallocated. The value returned
-	/// will be at least the size specified to allocate(), but it can be bigger.
-	/// (The allocator may round up the allocation to fit into a set of predefined
-	/// slot sizes.)
-	///
-	/// Not all allocators support tracking the size of individual allocations.
-	/// An allocator that doesn't suppor it will return SIZE_NOT_TRACKED.
-	virtual uint32_t allocated_size(void *p) = 0;
+		/// Returns the amount of usable memory allocated at p. p must be a pointer
+		/// returned by allocate() that has not yet been deallocated. The value returned
+		/// will be at least the size specified to allocate(), but it can be bigger.
+		/// (The allocator may round up the allocation to fit into a set of predefined
+		/// slot sizes.)
+		///
+		/// Not all allocators support tracking the size of individual allocations.
+		/// An allocator that doesn't suppor it will return SIZE_NOT_TRACKED.
+		virtual uint32_t allocated_size(void *p) = 0;
 
-	/// Returns the total amount of memory allocated by this allocator. Note that the 
-	/// size returned can be bigger than the size of all individual allocations made,
-	/// because the allocator may keep additional structures.
-	///
-	/// If the allocator doesn't track memory, this function returns SIZE_NOT_TRACKED.
-	virtual uint32_t total_allocated() = 0;
+		/// Returns the total amount of memory allocated by this allocator. Note that the 
+		/// size returned can be bigger than the size of all individual allocations made,
+		/// because the allocator may keep additional structures.
+		///
+		/// If the allocator doesn't track memory, this function returns SIZE_NOT_TRACKED.
+		virtual uint32_t total_allocated() = 0;
 
-private:
-	/// Allocators cannot be copied.
-    Allocator(const Allocator& other);
-    Allocator& operator=(const Allocator& other);
-};
+	private:
+		/// Allocators cannot be copied.
+	    Allocator(const Allocator& other);
+	    Allocator& operator=(const Allocator& other);
+	};
 
-/// Creates a new object of type T using the allocator a to allocate the memory.
-#define MAKE_NEW(a, T, ...)		(new ((a).allocate(sizeof(T), alignof(T))) T(__VA_ARGS__))
+	/// Creates a new object of type T using the allocator a to allocate the memory.
+	#define MAKE_NEW(a, T, ...)		(new ((a).allocate(sizeof(T), alignof(T))) T(__VA_ARGS__))
 
-/// Frees an object allocated with MAKE_NEW.
-#define MAKE_DELETE(a, T, p)	do {if (p) {(p)->~T(); a.deallocate(p);}} while (0)
+	/// Frees an object allocated with MAKE_NEW.
+	#define MAKE_DELETE(a, T, p)	do {if (p) {(p)->~T(); a.deallocate(p);}} while (0)
 
-/// Functions for accessing global memory data.
-namespace memory_globals {
-	/// Initializes the global memory allocators. scratch_buffer_size is the size of the
-	/// memory buffer used by the scratch allocators.
-	void init(uint32_t scratch_buffer_size = 4*1024*1024);
+	/// Functions for accessing global memory data.
+	namespace memory_globals {
+		/// Initializes the global memory allocators. scratch_buffer_size is the size of the
+		/// memory buffer used by the scratch allocators.
+		void init(uint32_t scratch_buffer_size = 4*1024*1024);
 
-	/// Returns a default memory allocator that can be used for most allocations.
-	///
-	/// You need to call init() for this allocator to be available.
-	Allocator &default_allocator();
+		/// Returns a default memory allocator that can be used for most allocations.
+		///
+		/// You need to call init() for this allocator to be available.
+		Allocator &default_allocator();
 
-	/// Returns a "scratch" allocator that can be used for temporary short-lived memory
-	/// allocations. The scratch allocator uses a ring buffer of size scratch_buffer_size
-	/// to service the allocations.
-	///
-	/// If there is not enough memory in the buffer to match requests for scratch
-	/// memory, memory from the default_allocator will be returned instaed.
-	Allocator &default_scratch_allocator();
+		/// Returns a "scratch" allocator that can be used for temporary short-lived memory
+		/// allocations. The scratch allocator uses a ring buffer of size scratch_buffer_size
+		/// to service the allocations.
+		///
+		/// If there is not enough memory in the buffer to match requests for scratch
+		/// memory, memory from the default_allocator will be returned instaed.
+		Allocator &default_scratch_allocator();
 
-	/// Shuts down the global memory allocators created by init().
-	void shutdown();
+		/// Shuts down the global memory allocators created by init().
+		void shutdown();
+	}
+
+	namespace memory {
+		inline void *align_forward(void *p, uint32_t align);
+	}
+
+	// ---------------------------------------------------------------
+	// Inline function implementations
+	// ---------------------------------------------------------------
+
+	// Aligns p to the specified alignment by moving it forward if necessary
+	// and returns the result.
+	inline void *memory::align_forward(void *p, uint32_t align) {
+		uintptr_t pi = uintptr_t(p);
+		const uint32_t mod = pi % align;
+		if (mod)
+			pi += (align - mod);
+		return (void *)pi;
+	}
 }
-
-namespace memory {
-	inline void *align_forward(void *p, uint32_t align);
-}
-
-// ---------------------------------------------------------------
-// Inline function implementations
-// ---------------------------------------------------------------
-
-// Aligns p to the specified alignment by moving it forward if necessary
-// and returns the result.
-inline void *memory::align_forward(void *p, uint32_t align) {
-	uintptr_t pi = uintptr_t(p);
-	const uint32_t mod = pi % align;
-	if (mod)
-		pi += (align - mod);
-	return (void *)pi;
-}
 #pragma once
 
-class Allocator;
+namespace foundation
+{
+	class Allocator;
+}
 #include "murmur_hash.h"
 
-uint64_t murmur_hash_64(const void * key, uint32_t len, uint64_t seed)
+namespace foundation
 {
-	const uint64_t m = 0xc6a4a7935bd1e995ULL;
-	const uint32_t r = 47;
+	uint64_t murmur_hash_64(const void * key, uint32_t len, uint64_t seed)
+	{
+		const uint64_t m = 0xc6a4a7935bd1e995ULL;
+		const uint32_t r = 47;
 
-	uint64_t h = seed ^ (len * m);
+		uint64_t h = seed ^ (len * m);
 
-	const uint64_t * data = (const uint64_t *)key;
-	const uint64_t * end = data + (len/8);
+		const uint64_t * data = (const uint64_t *)key;
+		const uint64_t * end = data + (len/8);
 
-	while(data != end)
-	{
-		#ifdef PLATFORM_BIG_ENDIAN
-			uint64 k = *data++;
-			char *p = (char *)&k;
-			char c;
-			c = p[0]; p[0] = p[7]; p[7] = c;
-			c = p[1]; p[1] = p[6]; p[6] = c;
-			c = p[2]; p[2] = p[5]; p[5] = c;
-			c = p[3]; p[3] = p[4]; p[4] = c;
-		#else
-			uint64_t k = *data++;
-		#endif
+		while(data != end)
+		{
+			#ifdef PLATFORM_BIG_ENDIAN
+				uint64 k = *data++;
+				char *p = (char *)&k;
+				char c;
+				c = p[0]; p[0] = p[7]; p[7] = c;
+				c = p[1]; p[1] = p[6]; p[6] = c;
+				c = p[2]; p[2] = p[5]; p[5] = c;
+				c = p[3]; p[3] = p[4]; p[4] = c;
+			#else
+				uint64_t k = *data++;
+			#endif
 
-		k *= m;
-		k ^= k >> r;
-		k *= m;
+			k *= m;
+			k ^= k >> r;
+			k *= m;
+			
+			h ^= k;
+			h *= m;
+		}
+
+		const unsigned char * data2 = (const unsigned char*)data;
+
+		switch(len & 7)
+		{
+		case 7: h ^= uint64_t(data2[6]) << 48;
+		case 6: h ^= uint64_t(data2[5]) << 40;
+		case 5: h ^= uint64_t(data2[4]) << 32;
+		case 4: h ^= uint64_t(data2[3]) << 24;
+		case 3: h ^= uint64_t(data2[2]) << 16;
+		case 2: h ^= uint64_t(data2[1]) << 8;
+		case 1: h ^= uint64_t(data2[0]);
+				h *= m;
+		};
 		
-		h ^= k;
+		h ^= h >> r;
 		h *= m;
+		h ^= h >> r;
+
+		return h;
 	}
-
-	const unsigned char * data2 = (const unsigned char*)data;
-
-	switch(len & 7)
-	{
-	case 7: h ^= uint64_t(data2[6]) << 48;
-	case 6: h ^= uint64_t(data2[5]) << 40;
-	case 5: h ^= uint64_t(data2[4]) << 32;
-	case 4: h ^= uint64_t(data2[3]) << 24;
-	case 3: h ^= uint64_t(data2[2]) << 16;
-	case 2: h ^= uint64_t(data2[1]) << 8;
-	case 1: h ^= uint64_t(data2[0]);
-			h *= m;
-	};
-	
-	h ^= h >> r;
-	h *= m;
-	h ^= h >> r;
-
-	return h;
 }
 
 #include "types.h"
 
-/// Implementation of the 64 bit MurmurHash2 function
-/// http://murmurhash.googlepages.com/
-uint64_t murmur_hash_64(const void *key, uint32_t len, uint64_t seed);
+namespace foundation
+{
+	/// Implementation of the 64 bit MurmurHash2 function
+	/// http://murmurhash.googlepages.com/
+	uint64_t murmur_hash_64(const void *key, uint32_t len, uint64_t seed);
+}
 
 #include "memory.h"
 
-/// A temporary memory allocator that primarily allocates memory from a
-/// local stack buffer of size BUFFER_SIZE. If that memory is exhausted it will
-/// use the backing allocator (typically a scratch allocator).
-///
-/// Memory allocated with a TempAllocator does not have to be deallocated. It is
-/// automatically deallocated when the TempAllocator is destroyed.
-template <int BUFFER_SIZE>
-class TempAllocator : public Allocator
+namespace foundation
 {
-public:
-	/// Creates a new temporary allocator using the specified backing allocator.
-	TempAllocator(Allocator &backing = memory_globals::default_scratch_allocator());
-	virtual ~TempAllocator();
+	/// A temporary memory allocator that primarily allocates memory from a
+	/// local stack buffer of size BUFFER_SIZE. If that memory is exhausted it will
+	/// use the backing allocator (typically a scratch allocator).
+	///
+	/// Memory allocated with a TempAllocator does not have to be deallocated. It is
+	/// automatically deallocated when the TempAllocator is destroyed.
+	template <int BUFFER_SIZE>
+	class TempAllocator : public Allocator
+	{
+	public:
+		/// Creates a new temporary allocator using the specified backing allocator.
+		TempAllocator(Allocator &backing = memory_globals::default_scratch_allocator());
+		virtual ~TempAllocator();
 
-	virtual void *allocate(uint32_t size, uint32_t align = DEFAULT_ALIGN);
-	
-	/// Deallocation is a NOP for the TempAllocator. The memory is automatically
-	/// deallocated when the TempAllocator is destroyed.
-	virtual void deallocate(void *) {}
+		virtual void *allocate(uint32_t size, uint32_t align = DEFAULT_ALIGN);
+		
+		/// Deallocation is a NOP for the TempAllocator. The memory is automatically
+		/// deallocated when the TempAllocator is destroyed.
+		virtual void deallocate(void *) {}
 
-	/// Returns SIZE_NOT_TRACKED.
-	virtual uint32_t allocated_size(void *) {return SIZE_NOT_TRACKED;}
+		/// Returns SIZE_NOT_TRACKED.
+		virtual uint32_t allocated_size(void *) {return SIZE_NOT_TRACKED;}
 
-	/// Returns SIZE_NOT_TRACKED.
-	virtual uint32_t total_allocated() {return SIZE_NOT_TRACKED;}
+		/// Returns SIZE_NOT_TRACKED.
+		virtual uint32_t total_allocated() {return SIZE_NOT_TRACKED;}
 
-private:
-	char _buffer[BUFFER_SIZE];	//< Local stack buffer for allocations.
-	Allocator &_backing;		//< Backing allocator if local memory is exhausted.
-	char *_start;				//< Start of current allocation region
-	char *_p;					//< Current allocation pointer.
-	char *_end;					//< End of current allocation region
-	unsigned _chunk_size;		//< Chunks to allocate from backing allocator
-};
+	private:
+		char _buffer[BUFFER_SIZE];	//< Local stack buffer for allocations.
+		Allocator &_backing;		//< Backing allocator if local memory is exhausted.
+		char *_start;				//< Start of current allocation region
+		char *_p;					//< Current allocation pointer.
+		char *_end;					//< End of current allocation region
+		unsigned _chunk_size;		//< Chunks to allocate from backing allocator
+	};
 
-// If possible, use one of these predefined sizes for the TempAllocator to avoid
-// unnecessary template instantiation.
-typedef TempAllocator<64> TempAllocator64;
-typedef TempAllocator<128> TempAllocator128;
-typedef TempAllocator<256> TempAllocator256;
-typedef TempAllocator<512> TempAllocator512;
-typedef TempAllocator<1024> TempAllocator1024;
-typedef TempAllocator<2048> TempAllocator2048;
-typedef TempAllocator<4096> TempAllocator4096;
+	// If possible, use one of these predefined sizes for the TempAllocator to avoid
+	// unnecessary template instantiation.
+	typedef TempAllocator<64> TempAllocator64;
+	typedef TempAllocator<128> TempAllocator128;
+	typedef TempAllocator<256> TempAllocator256;
+	typedef TempAllocator<512> TempAllocator512;
+	typedef TempAllocator<1024> TempAllocator1024;
+	typedef TempAllocator<2048> TempAllocator2048;
+	typedef TempAllocator<4096> TempAllocator4096;
 
-// ---------------------------------------------------------------
-// Inline function implementations
-// ---------------------------------------------------------------
+	// ---------------------------------------------------------------
+	// Inline function implementations
+	// ---------------------------------------------------------------
 
-template <int BUFFER_SIZE>
-TempAllocator<BUFFER_SIZE>::TempAllocator(Allocator &backing) : _backing(backing), _chunk_size(4*1024)
-{
-	_p = _start = _buffer;
-	_end = _start + BUFFER_SIZE;
-	*(void **)_start = 0;
-	_p += sizeof(void *);
-}
-
-template <int BUFFER_SIZE>
-TempAllocator<BUFFER_SIZE>::~TempAllocator()
-{
-	void *p = *(void **)_buffer;
-	while (p) {
-		void *next = *(void **)p;
-		_backing.deallocate(p);
-		p = next;
-	}
-}
-
-template <int BUFFER_SIZE>
-void *TempAllocator<BUFFER_SIZE>::allocate(uint32_t size, uint32_t align)
-{
-	_p = (char *)memory::align_forward(_p, align);
-	if ((int)size > _end - _p) {
-		uint32_t to_allocate = sizeof(void *) + size + align;
-		if (to_allocate < _chunk_size)
-			to_allocate = _chunk_size;
-		_chunk_size *= 2;
-		void *p = _backing.allocate(to_allocate);
-		*(void **)_start = p;
-		_p = _start = (char *)p;
-		_end = _start + to_allocate;
+	template <int BUFFER_SIZE>
+	TempAllocator<BUFFER_SIZE>::TempAllocator(Allocator &backing) : _backing(backing), _chunk_size(4*1024)
+	{
+		_p = _start = _buffer;
+		_end = _start + BUFFER_SIZE;
 		*(void **)_start = 0;
 		_p += sizeof(void *);
-		memory::align_forward(p, align);
 	}
-	void *result = _p;
-	_p += size;
-	return result;
-}
+
+	template <int BUFFER_SIZE>
+	TempAllocator<BUFFER_SIZE>::~TempAllocator()
+	{
+		void *p = *(void **)_buffer;
+		while (p) {
+			void *next = *(void **)p;
+			_backing.deallocate(p);
+			p = next;
+		}
+	}
+
+	template <int BUFFER_SIZE>
+	void *TempAllocator<BUFFER_SIZE>::allocate(uint32_t size, uint32_t align)
+	{
+		_p = (char *)memory::align_forward(_p, align);
+		if ((int)size > _end - _p) {
+			uint32_t to_allocate = sizeof(void *) + size + align;
+			if (to_allocate < _chunk_size)
+				to_allocate = _chunk_size;
+			_chunk_size *= 2;
+			void *p = _backing.allocate(to_allocate);
+			*(void **)_start = p;
+			_p = _start = (char *)p;
+			_end = _start + to_allocate;
+			*(void **)_start = 0;
+			_p += sizeof(void *);
+			memory::align_forward(p, align);
+		}
+		void *result = _p;
+		_p += size;
+		return result;
+	}
+}
 #define ASSERT(x) assert(x)
 
 namespace {
+	using namespace foundation;
+	
 	void test_memory() {
 		memory_globals::init();
 		Allocator &a = memory_globals::default_allocator();
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.