Changeset 400
- Timestamp:
- 06/13/15 15:48:08 (10 years ago)
- Location:
- trunk/nv/stl
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/stl/functional/hash.hh
r395 r400 78 78 } 79 79 80 template < typename T, typename H = size_t >80 template < typename T, typename H = size_t, typename Enable = void > 81 81 struct hash : detail::hash_base< T, H > 82 82 { -
trunk/nv/stl/memory.hh
r399 r400 37 37 { 38 38 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 41 48 static constexpr bool is_static = false; 42 49 static constexpr bool is_fixed = false; … … 70 77 { 71 78 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 74 87 static constexpr bool is_static = false; 75 88 static constexpr bool is_fixed = false; … … 365 378 public: 366 379 typedef typename Super::value_type value_type; 380 typedef const value_type* iterator; 381 typedef nv::reverse_iterator<iterator> reverse_iterator; 367 382 typedef const value_type* const_iterator; 368 383 typedef nv::reverse_iterator<const_iterator> const_reverse_iterator; -
trunk/nv/stl/string.hh
r399 r400 69 69 }; 70 70 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{}; 72 88 73 89 template < typename T > … … 76 92 77 93 }; 78 79 class string_view;80 94 81 95 // 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; 85 101 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; 94 112 95 113 static constexpr size_type npos = size_type( -1 ); … … 104 122 105 123 // access 106 inline charoperator[]( size_type i ) const { return data()[i]; }107 inline charat( size_type i ) const124 inline value_type operator[]( size_type i ) const { return data()[i]; } 125 inline value_type at( size_type i ) const 108 126 { 109 127 // if ( i >= m_data ) NV_THROW( out_of_range( "string_ref::at" ) ); … … 111 129 } 112 130 113 inline charfront() const { return data()[0]; }114 inline charback() const { return data()[size() - 1]; }131 inline value_type front() const { return data()[0]; } 132 inline value_type back() const { return data()[size() - 1]; } 115 133 116 134 // 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; 197 152 198 153 // string operations 199 154 string_view substr( size_type p, size_type n = npos ) const; 200 155 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 { 204 206 } 205 207 206 208 // Literal constructors 207 209 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 ) {} 209 211 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 ) {} 275 213 276 214 // Non-literal constructors 277 215 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 ) ) {} 279 217 280 218 // Non-literal constructors 281 219 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 ) ) {} 283 221 284 222 inline string_view& operator=( const string_view &rhs ) … … 308 246 }; 309 247 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 ); 371 372 } 372 373 373 374 #define NV_STRING_BASE_CAST_OPERATORS( OPERATOR )\ 374 inline bool operator OPERATOR ( const string_base& lhs, const std::string& rhs )\375 template < typename S > inline bool operator OPERATOR ( const string_base< S >& lhs, const std::string& rhs )\ 375 376 {\ 376 377 return lhs OPERATOR string_view( rhs );\ 377 378 }\ 378 inline bool operator OPERATOR ( const std::string& lhs, const string_base& rhs )\379 template < typename S > inline bool operator OPERATOR ( const std::string& lhs, const string_base< S >& rhs )\ 379 380 {\ 380 381 return string_view( lhs ) OPERATOR rhs;\ 381 382 }\ 382 inline bool operator OPERATOR ( const string_base& lhs, const char* rhs )\383 template < typename S > inline bool operator OPERATOR ( const string_base< S >& lhs, const char* rhs )\ 383 384 {\ 384 385 return lhs OPERATOR string_view( rhs );\ 385 386 }\ 386 inline bool operator OPERATOR ( const char* lhs, const string_base& rhs )\387 template < typename S > inline bool operator OPERATOR ( const char* lhs, const string_base< S >& rhs )\ 387 388 {\ 388 389 return string_view( lhs ) OPERATOR rhs;\ … … 390 391 391 392 // 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 ) 393 395 { 394 396 return lhs.size() != rhs.size() ? false : ( lhs.compare( rhs ) == 0 ); 395 397 } 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 ) 397 400 { 398 401 return lhs.size() != rhs.size() ? true : ( lhs.compare( rhs ) != 0 ); 399 402 } 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 ) 401 405 { 402 406 return lhs.compare( rhs ) < 0; 403 407 } 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 ) 405 410 { 406 411 return lhs.compare( rhs ) > 0; 407 412 } 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 ) 409 415 { 410 416 return lhs.compare( rhs ) <= 0; 411 417 } 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 ) 413 420 { 414 421 return lhs.compare( rhs ) >= 0; … … 431 438 size_t f32_to_buffer( f32 n, char* str ); 432 439 size_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 433 506 434 507 inline string_view trimmed( const string_view& str ) -
trunk/nv/stl/type_traits/properties.hh
r395 r400 284 284 #endif 285 285 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 286 302 287 303 // TODO: non-standard, remove?
Note: See TracChangeset
for help on using the changeset viewer.