source: trunk/nv/stl/array.hh @ 376

Last change on this file since 376 was 376, checked in by epyon, 10 years ago
  • stl/assert.hh, stl/capi.hh, size_t independent
  • GCC 4.8 compatibility
  • using template usage
  • various minor changes
File size: 11.1 KB
Line 
1// Copyright (C) 2014 ChaosForge Ltd
2// http://chaosforge.org/
3//
4// This file is part of NV Libraries.
5// For conditions of distribution and use, see copyright notice in nv.hh
6
7/**
8 * @file array.hh
9 * @author Kornel Kisielewicz epyon@chaosforge.org
10 * @brief exception free array classes
11 */
12
13#ifndef NV_CORE_ARRAY_HH
14#define NV_CORE_ARRAY_HH
15
16#include <nv/core/common.hh>
17#include <nv/stl/memory.hh>
18#include <nv/stl/iterator.hh>
19#include <nv/stl/utility.hh>
20#include <vector>
21#include <algorithm>
22#include <array>
23
24namespace nv
25{
26        using std::vector;
27
28        template < typename T, typename Storage >
29        class array_base
30                : public detail::pointer_iterators < array_base< T, Storage >, Storage >
31        {
32        public:
33                typedef T         value_type;
34                typedef size_t    size_type;
35                typedef ptrdiff_t difference_type;
36                typedef T*        pointer;
37                typedef const T*  const_pointer;
38                typedef T*        iterator;
39                typedef const T*  const_iterator;
40                typedef T&        reference;
41                typedef const T&  const_reference;
42                typedef nv::reverse_iterator<iterator>       reverse_iterator;
43                typedef nv::reverse_iterator<const_iterator> const_reverse_iterator;
44
45                inline const_pointer data() const { return m_storage.data(); }
46                inline pointer data() { return m_storage.data(); }
47                inline size_t size() const { return m_storage.size(); }
48                inline bool empty() const { return m_storage.size() == 0; }
49                inline size_type   raw_size() const { return m_storage.size() * sizeof( value_type ); }
50                inline const char* raw_data() const { return (const char*)m_storage.data(); }
51                inline char*       raw_data() { return (char*)m_storage.data(); }
52
53                inline reference       front() { NV_ASSERT( !empty(), "front() called on empty data!" );  return m_storage.data()[0]; }
54                inline const_reference front() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_storage.data()[0]; }
55                inline reference       back() { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_storage.data()[size() - 1]; }
56                inline const_reference back() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_storage.data()[size() - 1]; }
57
58                reference operator[]( size_type i )
59                {
60                        NV_ASSERT( i < m_storage.size(), "Out of range" );
61                        return m_storage.data()[i];
62                }
63
64                const_reference operator[]( size_type i ) const
65                {
66                        NV_ASSERT( i < m_storage.size(), "Out of range" );
67                        return m_storage.data()[i];
68                }
69
70                inline void assign( const value_type& value ) { fill( value ); }
71
72                inline void fill( const value_type& value )
73                {
74                        fill_n( this->begin(), this->size(), value );
75                }
76
77                inline void clear()
78                {
79                        fill_default_n( this->begin(), this->size() );
80                }
81
82        protected:
83                Storage m_storage;
84        };
85
86        template< typename T, size_t N >
87        using array = array_base < T, fixed_container_storage < static_storage< T, N > > >;
88       
89
90#if 0
91
92        template< typename T, size_t N >
93        class array : public detail::pointer_iterators < array< T, N >, T, false >
94        {
95        public:
96                typedef T         value_type;
97                typedef size_t    size_type;
98                typedef ptrdiff_t difference_type;
99                typedef T*        pointer;
100                typedef const T*  const_pointer;
101                typedef T*        iterator;
102                typedef const T*  const_iterator;
103                typedef T&        reference;
104                typedef const T&  const_reference;
105                typedef nv::reverse_iterator<iterator>       reverse_iterator;
106                typedef nv::reverse_iterator<const_iterator> const_reverse_iterator;
107
108                static const size_type SIZE = N;
109                static const size_type ELEMENT_SIZE = sizeof( value_type );
110
111                inline const_pointer data() const { return m_data; }
112                inline pointer data() { return m_data; }
113                inline size_type size() const { return SIZE; }
114                inline bool empty() const { return false; }
115                inline size_type   raw_size() const { return SIZE * sizeof( T ); }
116                inline const char* raw_data() const { return (const char*)m_data; }
117                inline char*       raw_data() { return (char*)m_data; }
118
119                inline reference       front() { NV_ASSERT( !empty(), "front() called on empty data!" );  return m_data[0]; }
120                inline const_reference front() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[0]; }
121                inline reference       back() { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[SIZE - 1]; }
122                inline const_reference back() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[SIZE - 1]; }
123
124                reference operator[]( size_type i )
125                {
126                        NV_ASSERT( i < N, "Out of range" );
127                        return this->m_data[i];
128                }
129
130                const_reference operator[]( size_type i ) const
131                {     
132                        NV_ASSERT( i < N, "Out of range" );
133                        return this->m_data[i];
134                }
135
136                reference at( size_type i )
137                {
138                        NV_ASSERT( i < N, "Out of range" );
139                        return this->m_data[i];
140                }
141
142                const_reference at( size_type i ) const
143                {
144                        NV_ASSERT( i < N, "Out of range" );
145                        return this->m_data[i];
146                }
147
148                void assign( const value_type& value ) { fill( value ); }
149
150                void fill( const value_type& value )
151                {
152                        std::fill_n( this->begin(), this->size(), value );
153                }
154
155        private:
156                value_type m_data[SIZE];
157        };
158
159#endif
160//      template < typename T, typename ContainerAllocator >
161//      class vector_base
162//      {
163//      public:
164//              typedef T         value_type;
165//              typedef size_t    size_type;
166//              typedef ptrdiff_t difference_type;
167//              typedef T*        pointer;
168//              typedef const T*  const_pointer;
169//              typedef T*        iterator;
170//              typedef const T*  const_iterator;
171//              typedef T&        reference;
172//              typedef const T&  const_reference;
173//
174//      protected:
175//              ContainerAllocator m_storage;
176//      };
177
178//      template< typename T, size_t N >
179//      class static_vector : public detail::pointer_iterators < static_vector< T, N >, T, false >
180//      {
181//      public:
182//              typedef T         value_type;
183//              typedef size_t    size_type;
184//              typedef ptrdiff_t difference_type;
185//              typedef T*        pointer;
186//              typedef const T*  const_pointer;
187//              typedef T*        iterator;
188//              typedef const T*  const_iterator;
189//              typedef T&        reference;
190//              typedef const T&  const_reference;
191//              typedef nv::reverse_iterator<iterator>       reverse_iterator;
192//              typedef nv::reverse_iterator<const_iterator> const_reverse_iterator;
193//
194//              static_vector() : m_size(0) {}
195//
196//              inline const_pointer data() const { return m_data; }
197//              inline pointer data() { return m_data; }
198//              inline size_type size() const { return m_size; }
199//              inline bool empty() const { return !m_size; }
200//              inline size_type   raw_size() const { return N * sizeof( T ); }
201//              inline const char* raw_data() const { return (const char*)m_data; }
202//              inline char*       raw_data() { return (char*)m_data; }
203//
204//              inline reference       front() { NV_ASSERT( !empty(), "front() called on empty data!" );  return m_data[0]; }
205//              inline const_reference front() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[0]; }
206//              inline reference       back() { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[m_size - 1]; }
207//              inline const_reference back() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[m_size - 1]; }
208//      protected:
209//              value_type m_data[N];
210//              size_type  m_size;
211//      };
212
213        template< typename T >
214        class dynamic_array : public detail::data_base< storage_view< T > >
215        {
216        public:
217                typedef T         value_type;
218                typedef T*        iterator;
219                typedef const T*  const_iterator;
220                typedef T&        reference;
221                typedef const T&  const_reference;
222                typedef size_t    size_type;
223                typedef ptrdiff_t difference_type;
224
225                typedef nv::reverse_iterator<iterator>       reverse_iterator;
226                typedef nv::reverse_iterator<const_iterator> const_reverse_iterator;
227
228                dynamic_array() : detail::data_base< storage_view< T > >() {}
229//                      : m_data( nullptr ), m_size(0) {}
230                explicit dynamic_array( size_type new_size ) : detail::data_base< storage_view< T > >( new value_type[new_size], new_size ) {}
231//                      : m_data( new value_type[ new_size ] ), m_size( new_size ) {}
232                dynamic_array( const value_type& value, size_type size ) : detail::data_base< storage_view< T > >()
233//                      : m_data( nullptr ), m_size(0)
234                { assign( value, size ); }
235                dynamic_array( const_iterator values, size_type size ) : detail::data_base< storage_view< T > >()
236//                      : m_data( nullptr ), m_size(0)
237                { assign( values, size ); }
238
239                void resize( size_type new_size )
240                {
241                        if ( new_size != this->size() )
242                        {
243                                value_type* old_data = this->data();
244                                value_type* new_data = new_size > 0 ? new value_type[new_size] : nullptr;
245                                if ( old_data && this->data() )
246                                {
247                                        std::copy_n( old_data, new_size > this->size() ? this->size() : new_size, new_data );
248                                }
249                                delete[] old_data;
250                                assign( new_data, new_size );
251                        }
252                }
253
254//              iterator        begin()        { return m_data; }
255//              const_iterator  begin()  const { return m_data; }
256//              const_iterator  cbegin() const { return m_data; }
257//
258//              iterator        end()        { return m_data+m_size; }
259//              const_iterator  end()  const { return m_data+m_size; }
260//              const_iterator  cend() const { return m_data+m_size; }
261//
262//              reverse_iterator rbegin()              { return reverse_iterator( end() ); }
263//              const_reverse_iterator rbegin() const  { return const_reverse_iterator( end() ); }
264//              const_reverse_iterator crbegin() const { return const_reverse_iterator( end() ); }
265//
266//              reverse_iterator rend()                { return reverse_iterator( begin() ); }
267//              const_reverse_iterator rend() const    { return const_reverse_iterator( begin() ); }
268//              const_reverse_iterator crend() const   { return const_reverse_iterator( begin() ); }
269
270                reference operator[]( size_type i )
271                {
272                        NV_ASSERT( i < this->size(), "Out of range" );
273                        return this->data()[i];
274                }
275
276                const_reference operator[]( size_type i ) const
277                {     
278                        NV_ASSERT( i < this->size(), "Out of range" );
279                        return this->data()[i];
280                }
281
282//              reference       front()       { return m_data[0]; }
283//              const_reference front() const { return m_data[0]; }
284//              reference       back()        { return m_data[m_size-1]; }
285//              const_reference back() const  { return m_data[m_size-1]; }
286//
287//              size_type        size() const     { return m_size; }
288//              bool             empty() const    { return m_size == 0; }
289//              static size_type max_size()       { return numeric_limits< size_type >::max(); }
290//              const value_type* data() const { return m_data; }
291//              value_type*       data()       { return m_data; }
292//
293//              size_type   raw_size() const { return m_size * ELEMENT_SIZE; }
294//              const char* raw_data() const { return (const char*)m_data; }
295//              char*       raw_data()       { return (char*)m_data; }
296
297                void assign( const value_type& value ) { std::fill_n( this->begin(), this->size(), value ); }
298                void assign( const value_type& value, size_type new_size )
299                {
300                        resize( new_size );
301                        std::fill_n( this->begin(), this->size(), value );
302                }
303                void assign( const_iterator values, size_type new_size )
304                {
305                        resize( new_size );
306                        std::copy_n( values, this->size(), this->data() );
307                }
308
309                ~dynamic_array() { delete[] this->data(); }
310
311                static const size_type ELEMENT_SIZE = sizeof(T);
312        };
313
314
315
316}
317
318#endif // NV_CORE_ARRAY_HH
Note: See TracBrowser for help on using the repository browser.