// 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_CORE_ARRAY_HH #define NV_CORE_ARRAY_HH #include #include #include #include #include namespace nv { using std::vector; using std::array; template< class T, std::size_t N > class static_array : public detail::data_base< T, false, N > { 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 reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; // 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 this->m_data[i]; } const_reference operator[]( size_type i ) const { NV_ASSERT( i < N, "Out of range" ); return this->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( this->begin(), this->size(), value ); } static const size_type SIZE = N; static const size_type ELEMENT_SIZE = sizeof(T); }; template< class T > class dynamic_array : public detail::data_base< T, false, 0 > { 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 reverse_iterator; typedef std::reverse_iterator const_reverse_iterator; dynamic_array() : detail::data_base< T, false, 0 >() {} // : m_data( nullptr ), m_size(0) {} explicit dynamic_array( size_type new_size ) : detail::data_base< T, false, 0 >( new value_type[new_size], new_size ) {} // : m_data( new value_type[ new_size ] ), m_size( new_size ) {} dynamic_array( const value_type& value, size_type size ) : detail::data_base< T, false, 0 >() // : m_data( nullptr ), m_size(0) { assign( value, size ); } dynamic_array( const_iterator values, size_type size ) : detail::data_base< T, false, 0 >() // : m_data( nullptr ), m_size(0) { assign( values, size ); } void resize( size_type new_size ) { if ( new_size != this->m_size ) { value_type* old_data = this->m_data; this->m_data = new_size > 0 ? new value_type[new_size] : nullptr; if ( old_data && this->m_data ) { std::copy_n( old_data, new_size > this->m_size ? this->m_size : new_size, this->m_data ); } delete[] old_data; this->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 < this->m_size, "Out of range" ); return this->m_data[i]; } const_reference operator[]( size_type i ) const { NV_ASSERT( i < this->m_size, "Out of range" ); return this->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( this->begin(), this->size(), value ); } void assign( const value_type& value, size_type new_size ) { resize( new_size ); std::fill_n( this->begin(), this->size(), value ); } void assign( const_iterator values, size_type new_size ) { resize( new_size ); std::copy_n( values, this->size(), this->m_data ); } ~dynamic_array() { delete[] this->m_data; } static const size_type ELEMENT_SIZE = sizeof(T); }; } #endif // NV_CORE_ARRAY_HH