Index: trunk/nv/array.hh
===================================================================
--- trunk/nv/array.hh	(revision 260)
+++ trunk/nv/array.hh	(revision 260)
@@ -0,0 +1,193 @@
+// Copyright (C) 2014 ChaosForge Ltd
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+/**
+ * @file array.hh
+ * @author Kornel Kisielewicz epyon@chaosforge.org
+ * @brief exception free array classes
+ */
+
+#ifndef NV_ARRAY_HH
+#define NV_ARRAY_HH
+
+#include <nv/common.hh>
+#include <vector>
+#include <array>
+
+namespace nv
+{
+	namespace detail
+	{
+		template < typename T >
+		class array_base
+		{
+		public:
+			typedef T              value_type;
+			typedef T*             iterator;
+			typedef const T*       const_iterator;
+			typedef T&             reference;
+			typedef const T&       const_reference;
+			typedef std::size_t    size_type;
+			typedef std::ptrdiff_t difference_type;
+
+			typedef std::reverse_iterator<iterator>       reverse_iterator;
+			typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+		};
+	}
+
+	using std::vector;
+	using std::array;
+
+	template< class T, std::size_t N >
+	class static_array : public detail::array_base<T>
+	{
+	public:
+		iterator        begin()        { return m_data; }
+		const_iterator  begin()  const { return m_data; }
+		const_iterator  cbegin() const { return m_data; }
+
+		iterator        end()        { return m_data+N; }
+		const_iterator  end()  const { return m_data+N; }
+		const_iterator  cend() const { return m_data+N; }
+
+		reverse_iterator rbegin()              { return reverse_iterator( end() ); }
+		const_reverse_iterator rbegin() const  { return const_reverse_iterator( end() ); }
+		const_reverse_iterator crbegin() const { return const_reverse_iterator( end() ); }
+
+		reverse_iterator rend()                { return reverse_iterator( begin() ); }
+		const_reverse_iterator rend() const    { return const_reverse_iterator( begin() ); }
+		const_reverse_iterator crend() const   { return const_reverse_iterator( begin() ); }
+
+		reference operator[]( size_type i ) 
+		{ 
+			NV_ASSERT( i < N, "Out of range" ); 
+			return m_data[i];
+		}
+
+		const_reference operator[]( size_type i ) const 
+		{     
+			NV_ASSERT( i < N, "Out of range" ); 
+			return m_data[i]; 
+		}
+
+		reference       front()       { return m_data[0]; }
+		const_reference front() const { return m_data[0]; }
+		reference       back()        { return m_data[N-1]; }
+		const_reference back() const  { return m_data[N-1]; }
+
+		static size_type size()     { return N; }
+		static bool      empty()    { return false; }
+		static size_type max_size() { return N; }
+
+		const value_type* data() const { return m_data; }
+		value_type*       data()       { return m_data; }
+
+		size_type   raw_size() const { return N * ELEMENT_SIZE; }
+		const char* raw_data() const { return (const char*)m_data; }
+		char*       raw_data()       { return (char*)m_data; }
+
+		void assign( const value_type& value ) { std::fill_n( begin(), size(), value ); }
+
+		static const size_type SIZE = N;
+		static const size_type ELEMENT_SIZE = sizeof(T);
+	public:
+		value_type m_data[N];
+	};
+
+	template< class T >
+	class dynamic_array : public detail::array_base<T>
+	{
+	public:
+		dynamic_array() 
+			: m_data( nullptr ), m_size(0) {}
+		explicit dynamic_array( size_type new_size )
+			: m_data( new value_type[ new_size ] ), m_size( new_size ) {}
+		dynamic_array( const value_type& value, size_type size )
+			: m_data( nullptr ), m_size(0) { assign( value, size ); }
+		dynamic_array( const_iterator values, size_type size )
+			: m_data( nullptr ), m_size(0) { assign( values, size ); }
+
+		void resize( size_type new_size )
+		{
+			if ( new_size != m_size ) 
+			{
+				value_type* old_data = m_data;
+				m_data = new_size > 0 ? new value_type[ new_size ] : nullptr;
+				if ( old_data && m_data )
+				{
+					std::copy_n( old_data, new_size > m_size ? m_size : new_size, m_data );
+				}
+				delete[] old_data;
+				m_size = new_size;
+			}
+		}
+
+		iterator        begin()        { return m_data; }
+		const_iterator  begin()  const { return m_data; }
+		const_iterator  cbegin() const { return m_data; }
+
+		iterator        end()        { return m_data+m_size; }
+		const_iterator  end()  const { return m_data+m_size; }
+		const_iterator  cend() const { return m_data+m_size; }
+
+		reverse_iterator rbegin()              { return reverse_iterator( end() ); }
+		const_reverse_iterator rbegin() const  { return const_reverse_iterator( end() ); }
+		const_reverse_iterator crbegin() const { return const_reverse_iterator( end() ); }
+
+		reverse_iterator rend()                { return reverse_iterator( begin() ); }
+		const_reverse_iterator rend() const    { return const_reverse_iterator( begin() ); }
+		const_reverse_iterator crend() const   { return const_reverse_iterator( begin() ); }
+
+		reference operator[]( size_type i ) 
+		{ 
+			NV_ASSERT( i < m_size, "Out of range" ); 
+			return m_data[i];
+		}
+
+		const_reference operator[]( size_type i ) const 
+		{     
+			NV_ASSERT( i < m_size, "Out of range" ); 
+			return m_data[i]; 
+		}
+
+		reference       front()       { return m_data[0]; }
+		const_reference front() const { return m_data[0]; }
+		reference       back()        { return m_data[m_size-1]; }
+		const_reference back() const  { return m_data[m_size-1]; }
+
+		size_type        size() const     { return m_size; }
+		bool             empty() const    { return m_size == 0; }
+		static size_type max_size()       { return std::numeric_limits< size_type >::max(); }
+		const value_type* data() const { return m_data; }
+		value_type*       data()       { return m_data; }
+
+		size_type   raw_size() const { return m_size * ELEMENT_SIZE; }
+		const char* raw_data() const { return (const char*)m_data; }
+		char*       raw_data()       { return (char*)m_data; }
+
+		void assign( const value_type& value ) { std::fill_n( begin(), size(), value ); }
+		void assign( const value_type& value, size_type new_size ) 
+		{
+			resize( new_size );
+			std::fill_n( begin(), size(), value );
+		}
+		void assign( const_iterator values, size_type new_size )
+		{
+			resize( new_size );
+			std::copy_n( values, size(), m_data );
+		}
+
+		~dynamic_array() { delete[] m_data; }
+
+		static const size_type ELEMENT_SIZE = sizeof(T);
+	public:
+		value_type* m_data;
+		size_type   m_size;
+	};
+
+}
+
+#endif // NV_ARRAY_HH
