Changeset 375 for trunk


Ignore:
Timestamp:
05/26/15 23:27:51 (10 years ago)
Author:
epyon
Message:
  • massive memory/array/string upgrades
Location:
trunk/nv/stl
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/stl/array.hh

    r374 r375  
    2525{
    2626        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        // TODO: using array =
     87        template< typename T, size_t N >
     88        class array : public array_base< T,
     89                fixed_container_storage< static_storage< T, N > >
     90        >
     91        {
     92
     93        };
     94
     95#if 0
    2796
    2897        template< typename T, size_t N >
     
    82151                }
    83152
    84                 void swap( array<value_type, N>& y )
    85                 {
    86                         for ( size_type i = 0; i < N; ++i )
    87                                 nv::swap( m_data[i], y.m_data[i] );
    88                 }
    89 
    90153                void assign( const value_type& value ) { fill( value ); }
    91154
     
    99162        };
    100163
    101         template< typename T, size_t N >
    102         inline void swap( array<T, N>& lhs, array<T, N>& rhs )
    103         {
    104                 lhs.swap( rhs );
    105         }
    106 
     164#endif
    107165//      template < typename T, typename ContainerAllocator >
    108166//      class vector_base
     
    158216//      };
    159217
    160         template < typename T, typename ContainerAllocator >
    161         class array_base : public detail:: pointer_iterators < array_base< T, ContainerAllocator >, T, false >
    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                 typedef nv::reverse_iterator<iterator>       reverse_iterator;
    174                 typedef nv::reverse_iterator<const_iterator> const_reverse_iterator;
    175 
    176                 inline array_base() : m_storage() {}
    177                 inline array_base( pointer a_data, size_t a_size )
    178                 {
    179 
    180                 }
    181                 inline const_pointer data() const { return m_storage.data(); }
    182                 inline pointer data() { return m_storage.data(); }
    183                 inline size_t size() const { return m_storage.size(); }
    184                 inline bool empty() const { return m_storage.size() != 0; }
    185                 inline size_type   raw_size() const { return sizeof( T ) * m_storage.size(); }
    186                 inline const char* raw_data() const { return (const char*)m_storage.data(); }
    187                 inline char*       raw_data() { return (char*)m_storage.data(); }
    188 
    189                 inline reference       front() { NV_ASSERT( !empty(), "front() called on empty data!" );  return m_storage.data()[0]; }
    190                 inline const_reference front() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_storage.data()[0]; }
    191                 inline reference       back() { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_storage.data()[size() - 1]; }
    192                 inline const_reference back() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_storage.data()[size() - 1]; }
    193         protected:
    194                 void push_values( size_type n, const value_type& value )
    195                 {
    196 
    197                 }
    198                 ContainerAllocator m_storage;
    199         };
    200 
    201         template< class T >
    202         class dynamic_array : public detail::data_base< T, false, 0 >
     218        template< typename T >
     219        class dynamic_array : public detail::data_base< storage_view< T > >
    203220        {
    204221        public:
     
    214231                typedef nv::reverse_iterator<const_iterator> const_reverse_iterator;
    215232
    216                 dynamic_array() : detail::data_base< T, false, 0 >() {}
     233                dynamic_array() : detail::data_base< storage_view< T > >() {}
    217234//                      : m_data( nullptr ), m_size(0) {}
    218                 explicit dynamic_array( size_type new_size ) : detail::data_base< T, false, 0 >( new value_type[new_size], new_size ) {}
     235                explicit dynamic_array( size_type new_size ) : detail::data_base< storage_view< T > >( new value_type[new_size], new_size ) {}
    219236//                      : m_data( new value_type[ new_size ] ), m_size( new_size ) {}
    220                 dynamic_array( const value_type& value, size_type size ) : detail::data_base< T, false, 0 >()
     237                dynamic_array( const value_type& value, size_type size ) : detail::data_base< storage_view< T > >()
    221238//                      : m_data( nullptr ), m_size(0)
    222239                { assign( value, size ); }
    223                 dynamic_array( const_iterator values, size_type size ) : detail::data_base< T, false, 0 >()
     240                dynamic_array( const_iterator values, size_type size ) : detail::data_base< storage_view< T > >()
    224241//                      : m_data( nullptr ), m_size(0)
    225242                { assign( values, size ); }
     
    227244                void resize( size_type new_size )
    228245                {
    229                         if ( new_size != this->m_size )
     246                        if ( new_size != this->size() )
    230247                        {
    231                                 value_type* old_data = this->m_data;
    232                                 this->m_data = new_size > 0 ? new value_type[new_size] : nullptr;
    233                                 if ( old_data && this->m_data )
     248                                value_type* old_data = this->data();
     249                                value_type* new_data = new_size > 0 ? new value_type[new_size] : nullptr;
     250                                if ( old_data && this->data() )
    234251                                {
    235                                         std::copy_n( old_data, new_size > this->m_size ? this->m_size : new_size, this->m_data );
     252                                        std::copy_n( old_data, new_size > this->size() ? this->size() : new_size, new_data );
    236253                                }
    237254                                delete[] old_data;
    238                                 this->m_size = new_size;
     255                                assign( new_data, new_size );
    239256                        }
    240257                }
     
    258275                reference operator[]( size_type i )
    259276                {
    260                         NV_ASSERT( i < this->m_size, "Out of range" );
    261                         return this->m_data[i];
     277                        NV_ASSERT( i < this->size(), "Out of range" );
     278                        return this->data()[i];
    262279                }
    263280
    264281                const_reference operator[]( size_type i ) const
    265282                {     
    266                         NV_ASSERT( i < this->m_size, "Out of range" );
    267                         return this->m_data[i];
     283                        NV_ASSERT( i < this->size(), "Out of range" );
     284                        return this->data()[i];
    268285                }
    269286
     
    292309                {
    293310                        resize( new_size );
    294                         std::copy_n( values, this->size(), this->m_data );
    295                 }
    296 
    297                 ~dynamic_array() { delete[] this->m_data; }
     311                        std::copy_n( values, this->size(), this->data() );
     312                }
     313
     314                ~dynamic_array() { delete[] this->data(); }
    298315
    299316                static const size_type ELEMENT_SIZE = sizeof(T);
  • trunk/nv/stl/memory.hh

    r374 r375  
    2525namespace nv
    2626{
     27        template< typename T >
     28        class storage_view
     29        {
     30        public:
     31                typedef T      value_type;
     32                typedef size_t size_type;
     33                static const bool is_static = false;
     34                static const bool is_fixed  = false;
     35                static const bool is_const  = false;
     36
     37                NV_CONSTEXPR storage_view()
     38                        : m_data( nullptr ), m_size( 0 ) {}
     39                NV_CONSTEXPR storage_view( value_type* a_data, size_type a_size )
     40                        : m_data( a_data ), m_size( a_size ) {}
     41
     42                void assign( value_type* a_data, size_type a_size )
     43                {
     44                        m_data = a_data;
     45                        m_size = a_size;
     46                }
     47
     48                NV_CONSTEXPR size_t size() const { return m_size; }
     49                NV_CONSTEXPR value_type* data() { return m_data; }
     50                NV_CONSTEXPR const value_type* data() const { return m_data; }
     51        protected:
     52                value_type* m_data;
     53                size_type   m_size;
     54        };
     55
     56        template< typename T >
     57        class const_storage_view
     58        {
     59        public:
     60                typedef T      value_type;
     61                typedef size_t size_type;
     62                static const bool is_static = false;
     63                static const bool is_fixed  = false;
     64                static const bool is_const  = true;
     65
     66                NV_CONSTEXPR const_storage_view()
     67                        : m_data( nullptr ), m_size( 0 ) {}
     68                NV_CONSTEXPR const_storage_view( const value_type* a_data, size_type a_size )
     69                        : m_data( a_data ), m_size( a_size ) {}
     70
     71                void assign( const value_type* a_data, size_type a_size )
     72                {
     73                        m_data = a_data;
     74                        m_size = a_size;
     75                }
     76
     77                NV_CONSTEXPR size_t size() const { return m_size; }
     78                NV_CONSTEXPR const value_type* data() const { return m_data; }
     79        protected:
     80                const value_type* m_data;
     81                size_type         m_size;
     82        };
     83
     84
     85        template< typename T, size_t N >
     86        class static_storage
     87        {
     88        public:
     89                typedef T value_type;
     90                static const bool is_static = true;
     91                static const bool is_fixed  = true;
     92                static const bool is_const  = false;
     93
     94                NV_CONSTEXPR T* data() { return static_cast<T*>( m_data ); }
     95                NV_CONSTEXPR const T* data() const { return static_cast<const T*>( m_data ); }
     96                static NV_CONSTEXPR size_t capacity() { return N; }
     97        protected:
     98                typedef typename aligned_array<T, N, NV_ALIGN_OF( T ) >::type storage_type;
     99                storage_type m_data;
     100        };
     101
     102        template< typename T, size_t N >
     103        class fixed_dynamic_storage
     104        {
     105        public:
     106                typedef T value_type;
     107                static const bool is_static = false;
     108                static const bool is_fixed = true;
     109                static const bool is_const = false;
     110
     111                fixed_dynamic_storage()
     112                {
     113                        m_data = malloc( N * sizeof( value_type ) );
     114                }
     115                ~fixed_dynamic_storage()
     116                {
     117                        free( m_data );
     118                }
     119                static NV_CONSTEXPR size_t capacity() { return N; }
     120                NV_CONSTEXPR T* data() { return static_cast<T*>( m_data ); }
     121                NV_CONSTEXPR const T* data() const { return static_cast<const T*>( m_data ); }
     122        protected:
     123                uint8* m_data;
     124        };
     125
    27126
    28127        namespace detail
     
    126225        {
    127226                typedef typename iterator_traits< ForwardIterator >::value_type value_type;
    128                 uninitialized_fill_impl( first, last, value, has_trivial_assign<value_type>() );
     227                detail::uninitialized_fill_impl( first, last, value, has_trivial_assign<value_type>() );
    129228        }
    130229
     
    133232        {
    134233                typedef typename iterator_traits< ForwardIterator >::value_type value_type;
    135                 return uninitialized_fill_n_impl( first, count, value, has_trivial_assign<value_type>() );
     234                return detail::uninitialized_fill_n_impl( first, count, value, has_trivial_assign<value_type>() );
    136235        }
    137236
     
    180279        {
    181280                typedef typename iterator_traits< ForwardIterator >::value_type value_type;
    182                 uninitialized_construct_impl( first, last, has_trivial_constructor<value_type>() );
     281                detail::uninitialized_construct_impl( first, last, has_trivial_constructor<value_type>() );
    183282        }
    184283
     
    187286        {
    188287                typedef typename iterator_traits< ForwardIterator >::value_type value_type;
    189                 return uninitialized_construct_n_impl( first, count, has_trivial_constructor<value_type>() );
     288                return detail::uninitialized_construct_n_impl( first, count, has_trivial_constructor<value_type>() );
    190289        }
    191290
     
    194293        {
    195294                typedef typename iterator_traits< ForwardIterator >::value_type value_type;
    196                 uninitialized_destroy_impl( first, last, has_trivial_destructor<value_type>() );
     295                detail::uninitialized_destroy_impl( first, last, has_trivial_destructor<value_type>() );
    197296        }
    198297
     
    201300        {
    202301                typedef typename iterator_traits< ForwardIterator >::value_type value_type;
    203                 return uninitialized_destroy_n_impl( first, count, has_trivial_destructor<value_type>() );
     302                return detail::uninitialized_destroy_n_impl( first, count, has_trivial_destructor<value_type>() );
    204303        }
    205304
    206305        namespace detail
    207306        {
    208                 template < typename PARENT, typename T, bool CONST, typename BASE = empty_base_class<PARENT> >
     307                template < typename PARENT, typename Storage, bool Const = Storage::is_const >
    209308                class pointer_iterators {};
    210309
    211                 template < typename PARENT, typename T, typename BASE >
    212                 class pointer_iterators< PARENT, T, true, BASE > : public BASE
     310                template < typename PARENT, typename Storage >
     311                class pointer_iterators< PARENT, Storage, true >
    213312                {
    214313                public:
    215                         typedef const T* const_iterator;
     314                        typedef typename Storage::value_type         value_type;
     315                        typedef const value_type*                    const_iterator;
    216316                        typedef nv::reverse_iterator<const_iterator> const_reverse_iterator;
    217317
     
    227327                };
    228328
    229                 template < typename PARENT, typename T, typename BASE >
    230                 class pointer_iterators< PARENT, T, false, BASE > : public BASE
     329                template < typename PARENT, typename Storage >
     330                class pointer_iterators< PARENT, Storage, false >
    231331                {
    232332                public:
    233                         typedef T*       iterator;
    234                         typedef const T* const_iterator;
     333                        typedef typename Storage::value_type         value_type;
     334                        typedef value_type*                          iterator;
     335                        typedef const value_type*                    const_iterator;
    235336                        typedef nv::reverse_iterator<iterator>       reverse_iterator;
    236337                        typedef nv::reverse_iterator<const_iterator> const_reverse_iterator;
     
    252353                };
    253354
    254                 template < typename T, bool CONST, size_t SIZE >
    255                 class data_base
    256                 {
     355                template < typename Storage, bool Const = Storage::is_const >
     356                class data_base;
     357
     358
     359                template < typename Storage >
     360                class data_base < Storage, true >
     361                        : public pointer_iterators < data_base < Storage, true >, Storage >
     362                {
     363                public:
     364                        typedef typename Storage::value_type value_type;
     365                        typedef const value_type*            const_pointer;
     366                        typedef size_t                       size_type;
     367                        typedef const_pointer                const_iterator;
     368                        typedef const value_type&            const_reference;
     369
     370                        inline data_base() {}
     371                        inline data_base( const_pointer a_data, size_t a_size )
     372                                : m_view( a_data, a_size ) {}
     373                        inline const_pointer data() const { return m_view.data(); }
     374                        inline size_t size() const { return m_view.size(); }
     375                        inline bool empty() const { return size() != 0; }
     376                        inline size_type   raw_size() const { return sizeof( value_type ) * size(); }
     377                        inline const char* raw_data() const { return (const char*)data(); }
     378
     379                        inline const_reference front() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return data()[0]; }
     380                        inline const_reference back() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return data()[size() - 1]; }
     381                protected:
     382                        void assign( const_pointer a_data, size_type a_size )
     383                        {
     384                                m_view.assign( a_data, a_size );
     385                        }
     386
     387                        Storage m_view;
    257388                };
    258389
    259                 template < typename T, size_t SIZE >
    260                 class data_base < T, true, SIZE >
    261                         : public pointer_iterators< data_base < T, true, SIZE >, T, true >
     390                template < typename Storage >
     391                class data_base < Storage, false >
     392                        : public pointer_iterators < data_base < Storage, false >, Storage >
    262393                {
    263394                public:
    264                         typedef T                    value_type;
    265                         typedef const value_type*    const_pointer;
    266                         typedef size_t               size_type;
    267                         typedef const_pointer        const_iterator;
    268                         typedef const value_type&    const_reference;
    269 
    270                         inline const_pointer data() const { return m_data; }
    271                         inline size_type size() const { return SIZE; }
    272                         inline bool empty() const { return false; }
    273                         inline size_type   raw_size() const { return SIZE * sizeof( T ); }
    274                         inline const char* raw_data() const { return (const char*)m_data; }
    275 
    276                         inline const_reference front() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[0]; }
    277                         inline const_reference back() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[SIZE - 1]; }
     395                        typedef typename Storage::value_type value_type;
     396                        typedef value_type*                  pointer;
     397                        typedef const value_type*            const_pointer;
     398                        typedef size_t                       size_type;
     399                        typedef pointer                      iterator;
     400                        typedef const_pointer                const_iterator;
     401                        typedef value_type&                          reference;
     402                        typedef const value_type&            const_reference;
     403
     404                        inline data_base() {}
     405                        inline data_base( pointer a_data, size_t a_size ) : m_view( a_data, a_size ) {}
     406                        inline const_pointer data() const { return m_view.data(); }
     407                        inline pointer data() { return m_view.data(); }
     408                        inline size_t size() const { return m_view.size(); }
     409                        inline bool empty() const { return size() != 0; }
     410                        inline size_type   raw_size() const { return sizeof( value_type ) * size(); }
     411                        inline const char* raw_data() const { return (const char*)data(); }
     412                        inline char*       raw_data() { return (char*)data(); }
     413
     414                        inline reference       front() { NV_ASSERT( !empty(), "front() called on empty data!" );  return data()[0]; }
     415                        inline const_reference front() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return data()[0]; }
     416                        inline reference       back() { NV_ASSERT( !empty(), "front() called on empty data!" ); return data()[size() - 1]; }
     417                        inline const_reference back() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return data()[size() - 1]; }
    278418                protected:
    279                         value_type m_data[SIZE];
     419                        void assign( pointer a_data, size_type a_size )
     420                        {
     421                                m_view.assign( a_data, a_size );
     422                        }
     423
     424                        Storage m_view;
    280425                };
    281426
    282                 template < typename T, size_t SIZE >
    283                 class data_base < T, false, SIZE >
    284                         : public pointer_iterators < data_base < T, false, SIZE >, T, false >
    285                 {
    286                 public:
    287                         typedef T                    value_type;
    288                         typedef value_type*          pointer;
    289                         typedef const value_type*    const_pointer;
    290                         typedef size_t               size_type;
    291                         typedef pointer              iterator;
    292                         typedef const_pointer        const_iterator;
    293                         typedef value_type&                  reference;
    294                         typedef const value_type&    const_reference;
    295 
    296                         inline const_pointer data() const { return m_data; }
    297                         inline pointer data() { return m_data; }
    298                         inline size_type size() const { return SIZE; }
    299                         inline bool empty() const { return false; }
    300                         inline size_type   raw_size() const { return SIZE * sizeof( T ); }
    301                         inline const char* raw_data() const { return (const char*)m_data; }
    302                         inline char*       raw_data() { return (char*)m_data; }
    303 
    304                         inline reference       front() { NV_ASSERT( !empty(), "front() called on empty data!" );  return m_data[0]; }
    305                         inline const_reference front() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[0]; }
    306                         inline reference       back() { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[SIZE - 1]; }
    307                         inline const_reference back() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[SIZE - 1]; }
    308                 protected:
    309                         value_type m_data[SIZE];
    310                 };
    311 
    312 
    313                 template < typename T >
    314                 class data_base < T, true, 0 >
    315                         : public pointer_iterators < data_base < T, true, 0 >, T, true >
    316                 {
    317                 public:
    318                         typedef T                    value_type;
    319                         typedef const value_type*    const_pointer;
    320                         typedef size_t               size_type;
    321                         typedef const_pointer        const_iterator;
    322                         typedef const value_type&    const_reference;
    323 
    324                         inline data_base() : m_data( nullptr ), m_size( 0 ) {}
    325                         inline data_base( const_pointer a_data, size_t a_size ) : m_data( a_data ), m_size( a_size ) {}
    326                         inline const T* data() const { return m_data; }
    327                         inline size_t size() const { return m_size; }
    328                         inline bool empty() const { return m_size != 0; }
    329                         inline size_type   raw_size() const { return sizeof( T ) * m_size; }
    330                         inline const char* raw_data() const { return (const char*)m_data; }
    331 
    332                         inline const_reference front() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[0]; }
    333                         inline const_reference back() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[m_size - 1]; }
    334                 protected:
    335                         const_pointer m_data;
    336                         size_type     m_size;
    337                 };
    338 
    339                 template < typename T >
    340                 class data_base < T, false, 0 >
    341                         : public pointer_iterators < data_base < T, false, 0 >, T, false >
    342                 {
    343                 public:
    344                         typedef T                    value_type;
    345                         typedef value_type*          pointer;
    346                         typedef const value_type*    const_pointer;
    347                         typedef size_t               size_type;
    348                         typedef pointer              iterator;
    349                         typedef const_pointer        const_iterator;
    350                         typedef value_type&                  reference;
    351                         typedef const value_type&    const_reference;
    352 
    353                         inline data_base() : m_data( nullptr ), m_size( 0 ) {}
    354                         inline data_base( pointer a_data, size_t a_size ) : m_data( a_data ), m_size( a_size ) {}
    355                         inline const_pointer data() const { return m_data; }
    356                         inline pointer data() { return m_data; }
    357                         inline size_t size() const { return m_size; }
    358                         inline bool empty() const { return m_size != 0; }
    359                         inline size_type   raw_size() const { return sizeof( T ) * m_size; }
    360                         inline const char* raw_data() const { return (const char*)m_data; }
    361                         inline char*       raw_data() { return (char*)m_data; }
    362 
    363                         inline reference       front() { NV_ASSERT( !empty(), "front() called on empty data!" );  return m_data[0]; }
    364                         inline const_reference front() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[0]; }
    365                         inline reference       back() { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[m_size - 1]; }
    366                         inline const_reference back() const { NV_ASSERT( !empty(), "front() called on empty data!" ); return m_data[m_size - 1]; }
    367                 protected:
    368                         pointer   m_data;
    369                         size_type m_size;
    370                 };
    371 
    372         }
    373 
    374         class const_mem_ref : public detail::data_base< char, true, 0 >
     427        }
     428
     429        class const_mem_ref : public detail::data_base< const_storage_view< char > >
    375430        {
    376431        public:
     
    384439                typedef const_pointer        const_iterator;
    385440        public:
    386                 inline const_mem_ref() : detail::data_base< char, true, 0 >() {}
    387                 inline const_mem_ref( const void* p, size_type n ) : detail::data_base< char, true, 0 >( (const char*)p, n ) {}
    388                 inline const_mem_ref( const const_mem_ref& l ) : detail::data_base< char, true, 0 >( l.data(), l.size() ) {}
    389         };
    390 
    391         class mem_ref : public detail::data_base< char, false, 0 >
     441                inline const_mem_ref() : detail::data_base< const_storage_view< char > >() {}
     442                inline const_mem_ref( const void* p, size_type n ) : detail::data_base< const_storage_view< char > >( (const char*)p, n ) {}
     443                inline const_mem_ref( const const_mem_ref& l ) : detail::data_base< const_storage_view< char > >( l.data(), l.size() ) {}
     444        };
     445
     446        class mem_ref : public detail::data_base< storage_view< char > >
    392447        {
    393448        public:
     
    402457                typedef const_pointer        const_iterator;
    403458        public:
    404                 inline mem_ref() : detail::data_base< char, false, 0 >() {}
    405                 inline mem_ref( void* p, size_type n ) : detail::data_base< char, false, 0 >( (char*)p, n ) {}
    406                 inline mem_ref( const mem_ref& l ) : detail::data_base< char, false, 0 >( const_cast< char* >( l.data() ), l.size() ) {}
    407         };
    408 
    409         template < typename T, size_t N >
    410         class static_container_allocator
    411         {
    412         public:
    413                 typedef T value_type;
    414                 typedef typename aligned_array<T, N, NV_ALIGN_OF( T ) >::type storage;
    415 
    416                 static const bool   is_static  = true;
    417                 static const size_t type_align = NV_ALIGN_OF( T );
    418                 static const size_t type_size  = sizeof( T );
    419 
    420                 static_container_allocator()
    421                 {
    422                 }
    423                 bool resize( size_t new_size )
    424                 {
    425                         return true;
    426                 }
    427                 static NV_CONSTEXPR size_t capacity() { return N; }
    428                 static NV_CONSTEXPR size_t size() { return N; }
    429                 NV_CONSTEXPR T* data() { return static_cast<T*>( m_data ); }
    430                 NV_CONSTEXPR const T* data() const { return static_cast<const T*>( m_data ); }
    431 
    432                 storage m_data;
     459                inline mem_ref() : detail::data_base< storage_view< char > >() {}
     460                inline mem_ref( void* p, size_type n ) : detail::data_base< storage_view< char > >( (char*)p, n ) {}
     461                inline mem_ref( const mem_ref& l ) : detail::data_base< storage_view< char > >( const_cast< char* >( l.data() ), l.size() ) {}
     462        };
     463
     464        struct policy_initialize_always
     465        {
     466                template < typename ForwardIterator >
     467                static void initialize( ForwardIterator first, ForwardIterator last )
     468                {
     469                        uninitialized_construct( first, last );
     470                }
     471        };
     472
     473        struct policy_initialize_never
     474        {
     475                template < typename ForwardIterator >
     476                static void initialize( ForwardIterator, ForwardIterator )
     477                {
     478                }
     479        };
     480
     481        struct policy_initialize_standard
     482        {
     483                template < typename ForwardIterator >
     484                static void initialize( ForwardIterator first, ForwardIterator last )
     485                {
     486                        typedef typename iterator_traits< ForwardIterator >::value_type value_type;
     487                        if ( !has_trivial_constructor<value_type>() )
     488                                detail::uninitialized_construct_impl( first, last, false_type() );
     489                }
     490        };
     491
     492
     493        template <
     494                typename Storage,
     495                typename InitializePolicy = policy_initialize_standard
     496        >
     497        class fixed_container_storage
     498        {
     499        public:
     500                typedef typename Storage::value_type   value_type;
     501
     502                static const bool   is_static  = Storage::is_static;
     503                static const bool   is_fixed   = Storage::is_fixed;
     504                static const bool   is_const   = Storage::is_const;
     505                static const size_t type_size  = sizeof( value_type );
     506
     507                fixed_container_storage()
     508                {
     509                        InitializePolicy::initialize( data(), data() + m_data.capacity() );
     510                }
     511
     512                ~fixed_container_storage()
     513                {
     514                        uninitialized_destroy( data(), data() + m_data.capacity() );
     515                }
     516
     517                static NV_CONSTEXPR size_t capacity() { return Storage::capacity(); }
     518                static NV_CONSTEXPR size_t size() { return Storage::capacity(); }
     519                NV_CONSTEXPR value_type* data() { return m_data.data(); }
     520                NV_CONSTEXPR const value_type* data() const { return m_data.data(); }
     521        protected:
     522                Storage m_data;
    433523        };
    434524
     
    438528        public:
    439529                static const bool   is_static = false;
     530                static const bool   is_fixed  = true;
    440531                static const size_t type_size = sizeof( T );
    441                 static const size_t type_align = NV_ALIGN_OF( T );
    442532
    443533                dynamic_container_allocator()
  • trunk/nv/stl/string.hh

    r374 r375  
    337337
    338338        // string base class - will become a base for a string class later
    339         class string_base : public detail::data_base< char, true, 0 >
     339        class string_base : public detail::data_base< const_storage_view< char > >
    340340        {
    341341        public:
     
    354354                inline std::string to_string() const
    355355                {
    356                         return std::string( m_data, m_size );
     356                        return std::string( data(), size() );
    357357                }
    358358
    359                 inline NV_CONSTEXPR size_type length()   const { return m_size; }
     359                inline NV_CONSTEXPR size_type length()   const { return size(); }
    360360
    361361                // access
    362                 inline NV_CONSTEXPR char operator[]( size_type i ) const { return m_data[i]; }
    363                 inline char at( size_t i ) const
     362                inline NV_CONSTEXPR char operator[]( size_type i ) const { return data()[i]; }
     363                inline char at( size_type i ) const
    364364                {
    365365                        //      if ( i >= m_data ) NV_THROW( std::out_of_range( "string_ref::at" ) );
    366                         return m_data[i];
    367                 }
    368 
    369                 inline NV_CONSTEXPR char front()        const { return m_data[0]; }
    370                 inline NV_CONSTEXPR char back()         const { return m_data[m_size - 1]; }
     366                        return data()[i];
     367                }
     368
     369                inline NV_CONSTEXPR char front()        const { return data()[0]; }
     370                inline NV_CONSTEXPR char back()         const { return data()[size() - 1]; }
    371371
    372372                // string operations
    373373                int compare( const string_base& rhs ) const
    374374                {
    375                         int cmp = std::memcmp( m_data, rhs.m_data, ( nv::min )( m_size, rhs.m_size ) );
    376                         return cmp != 0 ? cmp : ( m_size == rhs.m_size ? 0 : m_size < rhs.m_size ? -1 : 1 );
     375                        size_type this_size = size();
     376                        int cmp = std::memcmp( data(), rhs.data(), ( nv::min )( this_size, rhs.size() ) );
     377                        return cmp != 0 ? cmp : ( this_size == rhs.size() ? 0 : this_size < rhs.size() ? -1 : 1 );
    377378                }
    378379                bool starts_with( char c ) const { return !empty() && c == front(); }
    379380                bool starts_with( const string_base& s ) const
    380381                {
    381                         return m_size >= s.m_size && std::memcmp( m_data, s.m_data, s.m_size ) == 0;
     382                        return size() >= s.size() && std::memcmp( data(), s.data(), s.size() ) == 0;
    382383                }
    383384                bool ends_with( char c ) const { return !empty() && c == back(); }
    384385                bool ends_with( const string_base& s ) const
    385386                {
    386                         return m_size >= s.m_size && std::memcmp( m_data + m_size - s.m_size, s.m_data, s.m_size ) == 0;
     387                        return size() >= s.size() && std::memcmp( data() + size() - s.size(), s.data(), s.size() ) == 0;
    387388                }
    388389                size_type find( const string_base& s, size_type pos = 0 ) const
    389390                {
    390                         if ( pos >= m_size ) return npos;
     391                        if ( pos >= size() ) return npos;
    391392                        const_iterator it = search( this->cbegin() + ( difference_type ) pos, this->cend(), s.cbegin(), s.cend() );
    392393                        return it == this->cend() ? npos : ( size_type )distance( this->cbegin(), it );
     
    394395                size_type find( char c, size_type pos = 0 ) const
    395396                {
    396                         if ( pos >= m_size ) return npos;
    397                         const_iterator it = find_if( this->cbegin() + ( difference_type ) pos, this->cend(), [=] ( char val ) { return val == c; } );
     397                        if ( pos >= size() ) return npos;
     398                        const_iterator it = find_if( this->cbegin() + (difference_type)pos, this->cend(), [=] ( char val ) { return val == c; } );
    398399                        return it == this->cend() ? npos : ( size_type )distance( this->cbegin(), it );
    399400                }
    400401                size_type rfind( const string_base& s, size_type pos = 0 ) const
    401402                {
    402                         if ( pos >= m_size ) return npos;
    403                         const_reverse_iterator it = search( this->crbegin() + ( difference_type ) pos, this->crend(), s.crbegin(), s.crend() );
    404                         return it == this->crend() ? npos : m_size - 1 - ( size_type )distance( this->crbegin(), it );
     403                        if ( pos >= size() ) return npos;
     404                        const_reverse_iterator it = search( this->crbegin() + (difference_type)pos, this->crend(), s.crbegin(), s.crend() );
     405                        return it == this->crend() ? npos : size() - 1 - ( size_type )distance( this->crbegin(), it );
    405406                }
    406407                size_type rfind( char c, size_type pos = 0 ) const
    407408                {
    408                         if ( pos >= m_size ) return npos;
    409                         const_reverse_iterator it = find_if( this->crbegin() + ( difference_type ) pos, this->crend(), [=] ( char val ) { return val == c; } );
    410                         return it == this->crend() ? npos : m_size - 1 - ( size_type )distance( this->crbegin(), it );
     409                        if ( pos >= size() ) return npos;
     410                        const_reverse_iterator it = find_if( this->crbegin() + (difference_type)pos, this->crend(), [=] ( char val ) { return val == c; } );
     411                        return it == this->crend() ? npos : size() - 1 - ( size_type )distance( this->crbegin(), it );
    411412                }
    412413                size_type find_first_of( char c ) const { return find( c ); }
     
    420421                {
    421422                        const_reverse_iterator it = nv::find_first_of( this->crbegin(), this->crend(), s.cbegin(), s.cend() );
    422                         return it == this->crend() ? npos : m_size - 1 - ( size_type )distance( this->crbegin(), it );
     423                        return it == this->crend() ? npos : size() - 1 - ( size_type )distance( this->crbegin(), it );
    423424                }
    424425                size_type find_first_not_of( const string_base& s ) const
    425426                {
    426427                        for ( const_iterator it = this->cbegin(); it != this->cend(); ++it )
    427                                 if ( 0 == std::memchr( s.m_data, *it, s.m_size ) )
     428                                if ( 0 == std::memchr( s.data(), *it, s.size() ) )
    428429                                        return ( size_type )distance( this->cbegin(), it );
    429430                        return npos;
     
    439440                {
    440441                        for ( const_reverse_iterator it = this->crbegin(); it != this->crend(); ++it )
    441                                 if ( 0 == std::memchr( s.m_data, *it, s.m_size ) )
    442                                         return m_size - 1 - ( size_type )distance( this->crbegin(), it );;
     442                                if ( 0 == std::memchr( s.data(), *it, s.size() ) )
     443                                        return size() - 1 - (size_type)distance( this->crbegin(), it );
    443444                        return npos;
    444445                }
     
    447448                        for ( const_reverse_iterator it = this->crbegin(); it != this->crend(); ++it )
    448449                                if ( c != *it )
    449                                         return m_size - 1 - ( size_type )distance( this->crbegin(), it );
     450                                        return size() - 1 - ( size_type )distance( this->crbegin(), it );
    450451                        return npos;
    451452                }
     
    456457                inline size_t hash() const
    457458                {
    458                         const char* str = m_data;
    459                         size_type   sz  = m_size;
     459                        const char* str = data();
     460                        size_type   sz  = size();
    460461                        int seed = 131;
    461462                        int result = 0;
     
    470471
    471472        protected:
    472                 inline NV_CONSTEXPR string_base() : detail::data_base< char, true, 0 >() {}
     473                inline NV_CONSTEXPR string_base() : detail::data_base< const_storage_view< char > >() {}
    473474                inline NV_CONSTEXPR string_base( pointer a_data, size_type a_lenght )
    474                         : detail::data_base< char, true, 0 >( a_data, a_lenght ) {}
     475                        : detail::data_base< const_storage_view< char > >( a_data, a_lenght ) {}
    475476        };
    476477
     
    480481                inline NV_CONSTEXPR string_ref() {}
    481482                inline NV_CONSTEXPR string_ref( const string_ref& rhs )
    482                         : string_base( rhs.m_data, rhs.m_size )
     483                        : string_base( rhs.data(), rhs.size() )
    483484                {
    484485                }
     
    514515                inline string_ref& operator=( const string_ref &rhs )
    515516                {
    516                         m_data = rhs.m_data;
    517                         m_size = rhs.m_size;
     517                        assign( rhs.data(), rhs.size() );
    518518                        return *this;
    519519                }
     
    522522                inline void clear()
    523523                {
    524                         m_size = 0;
    525                         m_data = nullptr;
     524                        assign( nullptr, 0 );
    526525                }
    527526                inline void remove_prefix( size_type n )
    528527                {
    529                         if ( n > m_size )       n = m_size;
    530                         m_data += n;
    531                         m_size -= n;
     528                        size_type s = size();
     529                        if ( n > s ) n = s;
     530                        assign( data() + n, s - n );
    532531                }
    533532                inline void remove_suffix( size_type n )
    534533                {
    535                         if ( n > m_size ) n = m_size;
    536                         m_size -= n;
     534                        size_type s = size();
     535                        if ( n > s ) n = s;
     536                        assign( data(), s - n );
    537537                }
    538538
     
    555555                ~const_string()
    556556                {
    557                         if ( m_data ) delete m_data;
     557                        if ( data() )
     558                        {
     559                                delete data();
     560                        }
    558561                }
    559562
    560563                inline const_string( const_string&& other )
    561564                {
    562                         m_data = other.m_data;
    563                         other.m_data = nullptr;
     565                        assign( other.data(), other.size() );
     566                        other.assign( nullptr, 0 );
    564567                }
    565568
    566569                inline const_string& operator=( const_string&& other )
    567570                {
    568                         pointer temp = m_data;
    569                         m_data = other.m_data;
    570                         other.m_data = temp;
     571                        pointer   old_data = data();
     572                        size_type old_size = size();
     573                        assign( other.data(), other.size() );
     574                        other.assign( old_data , old_size );
    571575                        return *this;
    572576                }
     
    584588                        std::memcpy( data, p, s );
    585589                        data[s] = 0;
    586                         m_data = data;
     590                        assign( data, s );
    587591                }
    588592        };
Note: See TracChangeset for help on using the changeset viewer.