Changeset 400


Ignore:
Timestamp:
06/13/15 15:48:08 (10 years ago)
Author:
epyon
Message:
  • string_base now templated
  • hash support for enable_if
  • type_traits - is_template_base_of
Location:
trunk/nv/stl
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/nv/stl/functional/hash.hh

    r395 r400  
    7878        }
    7979
    80         template < typename T, typename H = size_t >
     80        template < typename T, typename H = size_t, typename Enable = void >
    8181        struct hash : detail::hash_base< T, H >
    8282        {
  • trunk/nv/stl/memory.hh

    r399 r400  
    3737        {
    3838        public:
    39                 typedef T      value_type;
    40                 typedef size_t size_type;
     39                typedef T                 value_type;
     40                typedef size_t            size_type;
     41                typedef ptrdiff_t         difference_type;
     42                typedef value_type*       pointer;
     43                typedef const value_type* const_pointer;
     44                typedef value_type&       reference;
     45                typedef const value_type& const_reference;
     46
     47
    4148                static constexpr bool is_static   = false;
    4249                static constexpr bool is_fixed    = false;
     
    7077        {
    7178        public:
    72                 typedef T        value_type;
    73                 typedef size_t   size_type;
     79                typedef T                 value_type;
     80                typedef size_t            size_type;
     81                typedef ptrdiff_t         difference_type;
     82                typedef const value_type* pointer;
     83                typedef const value_type* const_pointer;
     84                typedef const value_type& reference;
     85                typedef const value_type& const_reference;
     86
    7487                static constexpr bool is_static   = false;
    7588                static constexpr bool is_fixed    = false;
     
    365378                public:
    366379                        typedef typename Super::value_type           value_type;
     380                        typedef const value_type*                    iterator;
     381                        typedef nv::reverse_iterator<iterator>       reverse_iterator;
    367382                        typedef const value_type*                    const_iterator;
    368383                        typedef nv::reverse_iterator<const_iterator> const_reverse_iterator;
  • trunk/nv/stl/string.hh

    r399 r400  
    6969                };
    7070
    71         }
     71
     72        }
     73
     74        template < typename Storage > class string_base;
     75        class string_view;
     76
     77// Stronger version
     78//      template < typename T >
     79//      struct is_string_base : is_template_base_of< T, string_base > {};
     80
     81        template < typename T, typename Enable = void >
     82        struct is_string_base : false_type {};
     83        template < typename T >
     84        struct is_string_base < T,
     85                typename enable_if<
     86                is_base_of< string_base< typename T::storage_type >, T >::value,
     87                void >::type > : true_type{};
    7288
    7389        template < typename T >
     
    7692
    7793        };
    78        
    79         class string_view;
    8094
    8195        // string base class - will become a base for a string class later
    82         class string_base : public detail::add_iterators< storage_view< char > >
    83         {
    84                 typedef detail::add_iterators< storage_view< char > > inherited;
     96        template < typename Storage >
     97        class string_base : public detail::add_iterators< Storage >
     98        {
     99                typedef detail::add_iterators< Storage >                base_type;
     100                typedef string_base< detail::add_iterators< Storage > > this_type;
    85101        public:
    86                 typedef char           value_type;
    87                 typedef const char*    pointer;
    88                 typedef const char&    reference;
    89                 typedef const char&    const_reference;
    90                 typedef pointer        const_iterator;
    91                 typedef const_iterator iterator;
    92                 typedef size_t         size_type;
    93                 typedef ptrdiff_t      difference_type;
     102                typedef Storage                             storage_type;
     103                typedef typename base_type::value_type      value_type;
     104                typedef typename base_type::pointer         pointer;
     105                typedef typename base_type::const_pointer   const_pointer;
     106                typedef typename base_type::reference       reference;
     107                typedef typename base_type::const_reference const_reference;
     108                typedef typename base_type::iterator        iterator;
     109                typedef typename base_type::const_iterator  const_iterator;
     110                typedef typename base_type::size_type       size_type;
     111                typedef typename base_type::difference_type difference_type;
    94112
    95113                static constexpr size_type npos = size_type( -1 );
     
    104122
    105123                // access
    106                 inline char operator[]( size_type i ) const { return data()[i]; }
    107                 inline char at( size_type i ) const
     124                inline value_type operator[]( size_type i ) const { return data()[i]; }
     125                inline value_type at( size_type i ) const
    108126                {
    109127                        //      if ( i >= m_data ) NV_THROW( out_of_range( "string_ref::at" ) );
     
    111129                }
    112130
    113                 inline char front()        const { return data()[0]; }
    114                 inline char back()         const { return data()[size() - 1]; }
     131                inline value_type front()        const { return data()[0]; }
     132                inline value_type back()         const { return data()[size() - 1]; }
    115133
    116134                // string operations
    117                 int compare( const string_base& rhs ) const
    118                 {
    119                         size_type this_size = size();
    120                         int cmp = nvmemcmp( data(), rhs.data(), ( nv::min )( this_size, rhs.size() ) );
    121                         return cmp != 0 ? cmp : ( this_size == rhs.size() ? 0 : this_size < rhs.size() ? -1 : 1 );
    122                 }
    123                 bool starts_with( char c ) const { return !empty() && c == front(); }
    124                 bool starts_with( const string_base& s ) const
    125                 {
    126                         return size() >= s.size() && nvmemcmp( data(), s.data(), s.size() ) == 0;
    127                 }
    128                 bool ends_with( char c ) const { return !empty() && c == back(); }
    129                 bool ends_with( const string_base& s ) const
    130                 {
    131                         return size() >= s.size() && nvmemcmp( data() + size() - s.size(), s.data(), s.size() ) == 0;
    132                 }
    133                 size_type find( const string_base& s, size_type pos = 0 ) const
    134                 {
    135                         if ( pos >= size() ) return npos;
    136                         const_iterator it = search( this->cbegin() + ( difference_type ) pos, this->cend(), s.cbegin(), s.cend() );
    137                         return it == this->cend() ? npos : ( size_type )distance( this->cbegin(), it );
    138                 }
    139                 size_type find( char c, size_type pos = 0 ) const
    140                 {
    141                         if ( pos >= size() ) return npos;
    142                         const_iterator it = find_if( this->cbegin() + (difference_type)pos, this->cend(), [=] ( char val ) { return val == c; } );
    143                         return it == this->cend() ? npos : ( size_type )distance( this->cbegin(), it );
    144                 }
    145                 size_type rfind( const string_base& s, size_type pos = 0 ) const
    146                 {
    147                         if ( pos >= size() ) return npos;
    148                         const_reverse_iterator it = search( this->crbegin() + (difference_type)pos, this->crend(), s.crbegin(), s.crend() );
    149                         return it == this->crend() ? npos : reverse_distance( this->crbegin(), it );
    150                 }
    151                 size_type rfind( char c, size_type pos = 0 ) const
    152                 {
    153                         if ( pos >= size() ) return npos;
    154                         const_reverse_iterator it = find_if( this->crbegin() + (difference_type)pos, this->crend(), [=] ( char val ) { return val == c; } );
    155                         return it == this->crend() ? npos : reverse_distance( this->crbegin(), it );
    156                 }
    157                 size_type find_first_of( char c ) const { return find( c ); }
    158                 size_type find_first_of( const string_base& s ) const
    159                 {
    160                         const_iterator it = nv::find_first_of( this->cbegin(), this->cend(), s.cbegin(), s.cend() );
    161                         return it == this->cend() ? npos : ( size_type )distance( this->cbegin(), it );
    162                 }
    163                 size_type find_last_of( char c )  const { return rfind( c ); }
    164                 size_type find_last_of( const string_base& s ) const
    165                 {
    166                         const_reverse_iterator it = nv::find_first_of( this->crbegin(), this->crend(), s.cbegin(), s.cend() );
    167                         return it == this->crend() ? npos : reverse_distance( this->crbegin(), it );
    168                 }
    169                 size_type find_first_not_of( const string_base& s ) const
    170                 {
    171                         for ( const_iterator it = this->cbegin(); it != this->cend(); ++it )
    172                                 if ( 0 == nvmemchr( s.data(), (uchar8)*it, s.size() ) )
    173                                         return ( size_type )distance( this->cbegin(), it );
    174                         return npos;
    175                 }
    176                 size_type find_first_not_of( char c ) const
    177                 {
    178                         for ( const_iterator it = this->cbegin(); it != this->cend(); ++it )
    179                                 if ( c != *it )
    180                                         return ( size_type )distance( this->cbegin(), it );
    181                         return npos;
    182                 }
    183                 size_type find_last_not_of( const string_base& s ) const
    184                 {
    185                         for ( const_reverse_iterator it = this->crbegin(); it != this->crend(); ++it )
    186                                 if ( 0 == nvmemchr( s.data(), (uchar8)*it, s.size() ) )
    187                                         return reverse_distance( this->crbegin(), it );
    188                         return npos;
    189                 }
    190                 size_type find_last_not_of( char c ) const
    191                 {
    192                         for ( const_reverse_iterator it = this->crbegin(); it != this->crend(); ++it )
    193                                 if ( c != *it )
    194                                         return reverse_distance( this->crbegin(), it );
    195                         return npos;
    196                 }
     135                int compare( const string_view& rhs ) const;
     136                bool starts_with( value_type c ) const;
     137                bool starts_with( const string_view& s ) const;
     138                bool ends_with( value_type c ) const;
     139                bool ends_with( const string_view& s ) const;
     140                auto find( value_type c, size_type pos = 0 ) const -> size_type;
     141                auto find( const string_view& s, size_type pos = 0 ) const -> size_type;
     142                auto rfind( value_type c, size_type pos = 0 ) const -> size_type;
     143                auto rfind( const string_view& s, size_type pos = 0 ) const -> size_type;
     144                auto find_first_of( value_type c ) const -> size_type;
     145                auto find_first_of( const string_view& s ) const -> size_type;
     146                auto find_last_of( value_type c )  const -> size_type;
     147                auto find_last_of( const string_view& s ) const -> size_type;
     148                auto find_first_not_of( value_type c ) const -> size_type;
     149                auto find_first_not_of( const string_view& s ) const -> size_type;
     150                auto find_last_not_of( value_type c ) const -> size_type;
     151                auto find_last_not_of( const string_view& s ) const -> size_type;
    197152
    198153                // string operations
    199154                string_view substr( size_type p, size_type n = npos ) const;
    200155
    201                 inline size_t hash() const
    202                 {
    203                         return hash_string< size_t >( data(), size() );
     156                template < typename H = size_type >
     157                inline H hash() const
     158                {
     159                        return hash_string< size_type >( this->data(), this->size() );
     160                }
     161
     162        protected:
     163                using base_type::base_type;
     164
     165                template < typename ReverseIterator >
     166                size_type reverse_distance( ReverseIterator first, ReverseIterator last ) const
     167                {
     168                        return this->size() - 1 - (size_t)nv::distance( first, last );
     169                }
     170        };
     171
     172        template< typename T, typename H >
     173        struct hash< T, H, typename enable_if< is_string_base<T>::value, void >::type >
     174        {
     175                static H get( const T& value )
     176                {
     177                        return value.hash< H >();
     178                }
     179                inline H operator()( const T& value ) const { return get( value ); }
     180        };
     181
     182        class string_view : public string_base< storage_view< char > >
     183        {
     184        public:
     185                typedef string_base< storage_view< char > > this_type;
     186
     187                inline string_view() {}
     188                inline string_view( const string_view& rhs )
     189                        : this_type( rhs.data(), rhs.size() )
     190                {
     191                }
     192                template < typename S >
     193                inline string_view( const string_base<S>& rhs )
     194                        : this_type( rhs.data(), rhs.size() )
     195                {
     196                }
     197
     198                inline string_view( const std::string& str )
     199                        : this_type( str.data(), str.size() )
     200                {
     201                }
     202
     203                inline string_view( const char* str, size_type len )
     204                        : this_type( str, len )
     205                {
    204206                }
    205207
    206208                // Literal constructors
    207209                template< size_t N >
    208                 inline string_base( char( &s )[N] ) : inherited( s, N - 1 ) {}
     210                inline string_view( char( &s )[N] ) : this_type( s, N - 1 ) {}
    209211                template< size_t N >
    210                 inline string_base( const char( &s )[N] ) : inherited( s, N - 1 ) {}
    211 
    212         protected:
    213                 inline string_base() {}
    214                 inline string_base( pointer a_data, size_type a_lenght ) : inherited( a_data, a_lenght ) {}
    215 
    216                 template < typename ReverseIterator >
    217                 size_type reverse_distance( ReverseIterator first, ReverseIterator last ) const
    218                 {
    219                         return size() - 1 - (size_t)distance( first, last );
    220                 }
    221         };
    222 
    223         template< typename H >
    224         struct hash< string_base, H >
    225         {
    226                 static H get( const string_base& value )
    227                 {
    228                         return hash_string< H >( value.data(), value.length() );
    229                 }
    230                 inline H operator()( const string_base& value ) const { return get( value ); }
    231         };
    232 
    233         class literal_string : public string_base
    234         {
    235         public:
    236                 // Literal constructors
    237                 template< size_t N >
    238                 inline literal_string( char( &s )[N] ) : string_base( s, N - 1 ) {}
    239                 template< size_t N >
    240                 inline literal_string( const char( &s )[N] ) : string_base( s, N - 1 ) {}
    241         };
    242 
    243         template< typename H >
    244         struct hash< literal_string, H > : hash< string_base, H >{};
    245 
    246 
    247         class string_view : public string_base
    248         {
    249         public:
    250                 inline string_view() {}
    251                 inline string_view( const string_view& rhs )
    252                         : string_base( rhs.data(), rhs.size() )
    253                 {
    254                 }
    255                 inline string_view( const string_base& rhs )
    256                         : string_base( rhs.data(), rhs.size() )
    257                 {
    258                 }
    259 
    260                 inline string_view( const std::string& str )
    261                         : string_base( str.data(), str.size() )
    262                 {
    263                 }
    264 
    265                 inline string_view( const char* str, size_type len )
    266                         : string_base( str, len )
    267                 {
    268                 }
    269 
    270                 // Literal constructors
    271                 template< size_t N >
    272                 inline string_view( char( &s )[N] ) : string_base( s, N - 1 ) {}
    273                 template< size_t N >
    274                 inline string_view( const char( &s )[N] ) : string_base( s, N - 1 ) {}
     212                inline string_view( const char( &s )[N] ) : this_type( s, N - 1 ) {}
    275213
    276214                // Non-literal constructors
    277215                template< typename U >
    278                 inline string_view( U str, typename enable_if<is_same<U, const char*>::value>::type* = nullptr ) : string_base( str, nvstrlen( str ) ) {}
     216                inline string_view( U str, typename enable_if<is_same<U, const char*>::value>::type* = nullptr ) : this_type( str, nvstrlen( str ) ) {}
    279217
    280218                // Non-literal constructors
    281219                template< typename U >
    282                 inline string_view( U str, typename enable_if<is_same<U, char*>::value>::type* = nullptr ) : string_base( str, nvstrlen( str ) ) {}
     220                inline string_view( U str, typename enable_if<is_same<U, char*>::value>::type* = nullptr ) : this_type( str, nvstrlen( str ) ) {}
    283221
    284222                inline string_view& operator=( const string_view &rhs )
     
    308246        };
    309247
    310         template< typename H >
    311         struct hash< string_view, H > : hash< string_base, H >{};
    312 
    313         // const string is movable but not copyable
    314         class const_string : public string_base
    315         {
    316         public:
    317                 inline const_string() {}
    318                 inline const_string( const char* str, size_type len )
    319                 {
    320                         initialize( str, len );
    321                 }
    322                 inline explicit const_string( const char* str )
    323                 {
    324                         initialize( str, nvstrlen( str ) );
    325                 }
    326 
    327                 ~const_string()
    328                 {
    329                         if ( data() )
    330                         {
    331                                 delete data();
    332                         }
    333                 }
    334 
    335                 inline const_string( const_string&& other )
    336                 {
    337                         assign( other.data(), other.size() );
    338                         other.assign( nullptr, 0 );
    339                 }
    340 
    341                 inline const_string& operator=( const_string&& other )
    342                 {
    343                         pointer   old_data = data();
    344                         size_type old_size = size();
    345                         assign( other.data(), other.size() );
    346                         other.assign( old_data , old_size );
    347                         return *this;
    348                 }
    349 
    350                 // blocked copy constructor
    351                 const_string( const const_string & ) = delete;
    352                 // blocked copy operator
    353                 const_string& operator=( const const_string& ) = delete;
    354 
    355         private:
    356 
    357                 void initialize( const char* p, size_type s )
    358                 {
    359                         char* data = new char[s + 1];
    360                         nvmemcpy( data, p, s );
    361                         data[s] = 0;
    362                         assign( data, s );
    363                 }
    364         };
    365 
    366         inline string_view string_base::substr( size_type p, size_type n ) const
    367         {
    368                 if ( p > size() ) return string_view(); // NV_THROW( out_of_range( "substr" ) );
    369                 if ( n == p || p + n > size() ) n = size() - p;
    370                 return string_view( data() + p, n );
     248        template < typename Storage >
     249        inline int string_base< Storage >::compare( const string_view& rhs ) const
     250        {
     251                size_type this_size = this->size();
     252                int cmp = nvmemcmp( this->data(), rhs.data(), ( nv::min )( this_size, rhs.size() ) );
     253                return cmp != 0 ? cmp : ( this_size == rhs.size() ? 0 : this_size < rhs.size() ? -1 : 1 );
     254        }
     255
     256        template < typename Storage >
     257        inline bool string_base< Storage >::starts_with( value_type c ) const
     258        {
     259                return !this->empty() && c == this->front();
     260        }
     261        template < typename Storage >
     262        inline bool string_base< Storage >::starts_with( const string_view& s ) const
     263        {
     264                return this->size() >= s.size() && nvmemcmp( this->data(), s.data(), s.size() ) == 0;
     265        }
     266
     267        template < typename Storage >
     268        inline bool string_base< Storage >::ends_with( value_type c ) const
     269        {
     270                return !this->empty() && c == this->back();
     271        }
     272        template < typename Storage >
     273        inline bool string_base< Storage >::ends_with( const string_view& s ) const
     274        {
     275                return this->size() >= s.size() && nvmemcmp( this->data() + this->size() - s.size(), s.data(), s.size() ) == 0;
     276        }
     277
     278        template < typename Storage >
     279        inline auto string_base< Storage >::find( value_type c, size_type pos = 0 ) const -> size_type
     280        {
     281                if ( pos >= this->size() ) return npos;
     282                const_iterator it = nv::find_if( this->cbegin() + (difference_type)pos, this->cend(), [=] ( value_type val ) { return val == c; } );
     283                return it == this->cend() ? npos : (size_type)nv::distance( this->cbegin(), it );
     284        }
     285        template < typename Storage >
     286        inline auto string_base< Storage >::find( const string_view& s, size_type pos = 0 ) const -> size_type
     287        {
     288                if ( pos >= this->size() ) return npos;
     289                const_iterator it = nv::search( this->cbegin() + (difference_type)pos, this->cend(), s.cbegin(), s.cend() );
     290                return it == this->cend() ? npos : (size_type)nv::distance( this->cbegin(), it );
     291        }
     292
     293        template < typename Storage >
     294        inline auto string_base< Storage >::rfind( value_type c, size_type pos = 0 ) const -> size_type
     295        {
     296                if ( pos >= this->size() ) return npos;
     297                const_reverse_iterator it = nv::find_if( this->crbegin() + (difference_type)pos, this->crend(), [=] ( value_type val ) { return val == c; } );
     298                return it == this->crend() ? npos : this->reverse_distance( this->crbegin(), it );
     299        }
     300        template < typename Storage >
     301        inline auto string_base< Storage >::rfind( const string_view& s, size_type pos = 0 ) const -> size_type
     302        {
     303                if ( pos >= this->size() ) return npos;
     304                const_reverse_iterator it = nv::search( this->crbegin() + (difference_type)pos, this->crend(), s.crbegin(), s.crend() );
     305                return it == this->crend() ? npos : this->reverse_distance( this->crbegin(), it );
     306        }
     307
     308        template < typename Storage >
     309        inline auto string_base< Storage >::find_first_of( value_type c ) const -> size_type
     310        {
     311                return this->find( c );
     312        }
     313        template < typename Storage >
     314        inline auto string_base< Storage >::find_first_of( const string_view& s ) const -> size_type
     315        {
     316                const_iterator it = nv::find_first_of( this->cbegin(), this->cend(), s.cbegin(), s.cend() );
     317                return it == this->cend() ? npos : (size_type)nv::distance( this->cbegin(), it );
     318        }
     319
     320        template < typename Storage >
     321        inline auto string_base< Storage >::find_last_of( value_type c ) const -> size_type
     322        {
     323                return this->rfind( c );
     324        }
     325        template < typename Storage >
     326        inline auto string_base< Storage >::find_last_of( const string_view& s ) const -> size_type
     327        {
     328                const_reverse_iterator it = nv::find_first_of( this->crbegin(), this->crend(), s.cbegin(), s.cend() );
     329                return it == this->crend() ? npos : this->reverse_distance( this->crbegin(), it );
     330        }
     331
     332        template < typename Storage >
     333        inline auto string_base< Storage >::find_first_not_of( value_type c ) const -> size_type
     334        {
     335                for ( const_iterator it = this->cbegin(); it != this->cend(); ++it )
     336                        if ( c != *it )
     337                        return (size_type)distance( this->cbegin(), it );
     338                return npos;
     339        }
     340        template < typename Storage >
     341        inline auto string_base< Storage >::find_first_not_of( const string_view& s ) const -> size_type
     342        {
     343                for ( const_iterator it = this->cbegin(); it != this->cend(); ++it )
     344                        if ( 0 == nvmemchr( s.data(), (uchar8)*it, s.size() ) )
     345                        return (size_type)distance( this->cbegin(), it );
     346                return npos;
     347        }
     348
     349        template < typename Storage >
     350        inline auto string_base< Storage >::find_last_not_of( value_type c ) const -> size_type
     351        {
     352                for ( const_reverse_iterator it = this->crbegin(); it != this->crend(); ++it )
     353                        if ( c != *it )
     354                        return this->reverse_distance( this->crbegin(), it );
     355                return npos;
     356        }
     357        template < typename Storage >
     358        inline auto string_base< Storage >::find_last_not_of( const string_view& s ) const -> size_type
     359        {
     360                for ( const_reverse_iterator it = this->crbegin(); it != this->crend(); ++it )
     361                        if ( 0 == nvmemchr( s.data(), (uchar8)*it, s.size() ) )
     362                        return this->reverse_distance( this->crbegin(), it );
     363                return npos;
     364        }
     365
     366        template < typename Storage >
     367        inline string_view string_base< Storage >::substr( size_type p, size_type n ) const
     368        {
     369                if ( p > this->size() ) return string_view(); // NV_THROW( out_of_range( "substr" ) );
     370                if ( n == p || p + n > this->size() ) n = this->size() - p;
     371                return string_view( this->data() + p, n );
    371372        }
    372373
    373374#define NV_STRING_BASE_CAST_OPERATORS( OPERATOR )\
    374 inline bool operator OPERATOR ( const string_base& lhs, const std::string& rhs )\
     375template < typename S > inline bool operator OPERATOR ( const string_base< S >& lhs, const std::string& rhs )\
    375376{\
    376377        return lhs OPERATOR string_view( rhs );\
    377378}\
    378 inline bool operator OPERATOR ( const std::string& lhs, const string_base& rhs )\
     379template < typename S > inline bool operator OPERATOR ( const std::string& lhs, const string_base< S >& rhs )\
    379380{\
    380381        return string_view( lhs ) OPERATOR rhs;\
    381382}\
    382 inline bool operator OPERATOR ( const string_base& lhs, const char* rhs )\
     383template < typename S > inline bool operator OPERATOR ( const string_base< S >& lhs, const char* rhs )\
    383384{\
    384385        return lhs OPERATOR string_view( rhs );\
    385386}\
    386 inline bool operator OPERATOR ( const char* lhs, const string_base& rhs )\
     387template < typename S > inline bool operator OPERATOR ( const char* lhs, const string_base< S >& rhs )\
    387388{\
    388389        return string_view( lhs ) OPERATOR rhs;\
     
    390391
    391392        // Base operators
    392         inline bool operator==( const string_base& lhs, const string_base& rhs )
     393        template < typename S1, typename S2 >
     394        inline bool operator==( const string_base< S1 >& lhs, const string_base< S2 >& rhs )
    393395        {
    394396                return lhs.size() != rhs.size() ? false : ( lhs.compare( rhs ) == 0 );
    395397        }
    396         inline bool operator!=( const string_base& lhs, const string_base& rhs )
     398        template < typename S1, typename S2 >
     399        inline bool operator!=( const string_base< S1 >& lhs, const string_base< S2 >& rhs )
    397400        {
    398401                return lhs.size() != rhs.size() ? true : ( lhs.compare( rhs ) != 0 );
    399402        }
    400         inline bool operator<( const string_base& lhs, const string_base& rhs )
     403        template < typename S1, typename S2 >
     404        inline bool operator<( const string_base< S1 >& lhs, const string_base< S2 >& rhs )
    401405        {
    402406                return lhs.compare( rhs ) < 0;
    403407        }
    404         inline bool operator>( const string_base& lhs, const string_base& rhs )
     408        template < typename S1, typename S2 >
     409        inline bool operator>( const string_base< S1 >& lhs, const string_base< S2 >& rhs )
    405410        {
    406411                return lhs.compare( rhs ) > 0;
    407412        }
    408         inline bool operator<=( const string_base& lhs, const string_base& rhs )
     413        template < typename S1, typename S2 >
     414        inline bool operator<=( const string_base< S1 >& lhs, const string_base< S2 >& rhs )
    409415        {
    410416                return lhs.compare( rhs ) <= 0;
    411417        }
    412         inline bool operator>=( const string_base& lhs, const string_base& rhs )
     418        template < typename S1, typename S2 >
     419        inline bool operator>=( const string_base< S1 >& lhs, const string_base< S2 >& rhs )
    413420        {
    414421                return lhs.compare( rhs ) >= 0;
     
    431438size_t f32_to_buffer( f32 n, char* str );
    432439size_t f64_to_buffer( f64 n, char* str );
     440
     441        // const string is movable but not copyable
     442        class const_string : public string_base< storage_view< char > >
     443        {
     444        public:
     445                inline const_string() {}
     446                inline const_string( const char* str, size_type len )
     447                {
     448                        initialize( str, len );
     449                }
     450                inline explicit const_string( const char* str )
     451                {
     452                        initialize( str, nvstrlen( str ) );
     453                }
     454
     455                ~const_string()
     456                {
     457                        if ( data() )
     458                        {
     459                                delete data();
     460                        }
     461                }
     462
     463                inline const_string( const_string&& other )
     464                {
     465                        assign( other.data(), other.size() );
     466                        other.assign( nullptr, 0 );
     467                }
     468
     469                inline const_string& operator=( const_string&& other )
     470                {
     471                        pointer   old_data = data();
     472                        size_type old_size = size();
     473                        assign( other.data(), other.size() );
     474                        other.assign( old_data , old_size );
     475                        return *this;
     476                }
     477
     478                // blocked copy constructor
     479                const_string( const const_string & ) = delete;
     480                // blocked copy operator
     481                const_string& operator=( const const_string& ) = delete;
     482
     483        private:
     484
     485                void initialize( const char* p, size_type s )
     486                {
     487                        char* new_data = new char[s + 1];
     488                        nvmemcpy( new_data, p, s );
     489                        new_data[s] = 0;
     490                        assign( new_data, s );
     491                }
     492        };
     493
     494        class literal_string : public string_base< storage_view< char > >
     495        {
     496        public:
     497                typedef string_base< storage_view< char > > this_type;
     498
     499                // Literal constructors
     500                template< size_t N >
     501                inline literal_string( char( &s )[N] ) : this_type( s, N - 1 ) {}
     502                template< size_t N >
     503                inline literal_string( const char( &s )[N] ) : this_type( s, N - 1 ) {}
     504        };
     505
    433506
    434507inline string_view trimmed( const string_view& str )
  • trunk/nv/stl/type_traits/properties.hh

    r395 r400  
    284284#endif
    285285
     286        namespace detail
     287        {
     288                template < typename T, template<typename...> class Template >
     289                class is_template_base_of_impl : sfinae_types
     290                {
     291                        template < typename... Args >
     292                        static size_one test( const Template< Args... >* );
     293                        static size_two test( ... );
     294                public:
     295                        static constexpr bool value = sizeof( test<T>( 0 ) ) == 1;
     296                };
     297        }
     298
     299        template < typename T, template<typename...> class Template >
     300        struct is_template_base_of : bool_constant< detail::is_template_base_of_impl< T, Template >::value > {};
     301
    286302
    287303// TODO: non-standard, remove?
Note: See TracChangeset for help on using the changeset viewer.