Changeset 407
- Timestamp:
- 06/20/15 18:42:05 (10 years ago)
- Location:
- trunk/nv/stl
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/nv/stl/iterator.hh
r402 r407 104 104 105 105 public: 106 reverse_iterator() : m_base() {}107 explicit reverse_iterator( iterator_type i ) : m_base( i ) {}106 constexpr reverse_iterator() : m_base() {} 107 constexpr explicit reverse_iterator( iterator_type i ) : m_base( i ) {} 108 108 109 109 template <typename U> 110 reverse_iterator( const reverse_iterator<U>& ri ) : m_base( ri.base() ) {}111 112 iterator_type base() const { return m_base; }113 reference operator*( ) const { iterator_type i( m_base ); return *--i; }114 pointer operator->( ) const { return &( operator*( ) ); }115 reverse_iterator& operator++( ) { --m_base; return *this; }116 reverse_iterator operator++( int ) { reverse_iterator ri( *this ); --m_base; return ri; }117 reverse_iterator& operator--( ) { ++m_base; return *this; }118 reverse_iterator operator--( int ) { reverse_iterator ri( *this ); ++m_base; return ri; }119 reverse_iterator operator+( difference_type n ) const { return reverse_iterator( m_base - n ); }120 reverse_iterator& operator+=( difference_type n ) { m_base -= n; return *this; }121 reverse_iterator operator-( difference_type n ) const { return reverse_iterator( m_base + n ); }122 reverse_iterator& operator-=( difference_type n ) { m_base += n; return *this; }123 reference operator[]( difference_type n ) const { return m_base[-n - 1]; }110 constexpr reverse_iterator( const reverse_iterator<U>& ri ) : m_base( ri.base() ) {} 111 112 constexpr iterator_type base() const { return m_base; } 113 inline reference operator*( ) const { iterator_type i( m_base ); return *--i; } 114 inline pointer operator->( ) const { return &( operator*( ) ); } 115 inline reverse_iterator& operator++( ) { --m_base; return *this; } 116 inline reverse_iterator operator++( int ) { reverse_iterator ri( *this ); --m_base; return ri; } 117 inline reverse_iterator& operator--( ) { ++m_base; return *this; } 118 inline reverse_iterator operator--( int ) { reverse_iterator ri( *this ); ++m_base; return ri; } 119 inline reverse_iterator operator+( difference_type n ) const { return reverse_iterator( m_base - n ); } 120 inline reverse_iterator& operator+=( difference_type n ) { m_base -= n; return *this; } 121 inline reverse_iterator operator-( difference_type n ) const { return reverse_iterator( m_base + n ); } 122 inline reverse_iterator& operator-=( difference_type n ) { m_base += n; return *this; } 123 constexpr reference operator[]( difference_type n ) const { return m_base[-n - 1]; } 124 124 protected: 125 125 iterator_type m_base; … … 127 127 128 128 template < typename Iterator1, typename Iterator2 > 129 inlinebool operator==( const reverse_iterator< Iterator1 >& lhs, const reverse_iterator< Iterator2 >& rhs )129 constexpr bool operator==( const reverse_iterator< Iterator1 >& lhs, const reverse_iterator< Iterator2 >& rhs ) 130 130 { return lhs.base() == rhs.base(); } 131 131 template < typename Iterator1, typename Iterator2 > 132 inlinebool operator!=( const reverse_iterator< Iterator1 >& lhs, const reverse_iterator< Iterator2 >& rhs )132 constexpr bool operator!=( const reverse_iterator< Iterator1 >& lhs, const reverse_iterator< Iterator2 >& rhs ) 133 133 { return lhs.base() != rhs.base(); } 134 134 template < typename Iterator1, typename Iterator2 > 135 inlinebool operator<( const reverse_iterator< Iterator1 >& lhs, const reverse_iterator< Iterator2 >& rhs )135 constexpr bool operator<( const reverse_iterator< Iterator1 >& lhs, const reverse_iterator< Iterator2 >& rhs ) 136 136 { return lhs.base() > rhs.base(); } 137 137 template < typename Iterator1, typename Iterator2 > 138 inlinebool operator>( const reverse_iterator< Iterator1>& lhs, const reverse_iterator< Iterator2 >& rhs )138 constexpr bool operator>( const reverse_iterator< Iterator1>& lhs, const reverse_iterator< Iterator2 >& rhs ) 139 139 { return lhs.base() < rhs.base(); } 140 140 template < typename Iterator1, typename Iterator2 > 141 inlinebool operator<=( const reverse_iterator< Iterator1 >& lhs, const reverse_iterator<Iterator2 >& rhs )141 constexpr bool operator<=( const reverse_iterator< Iterator1 >& lhs, const reverse_iterator<Iterator2 >& rhs ) 142 142 { return lhs.base() >= rhs.base(); } 143 143 template < typename Iterator1, typename Iterator2 > 144 inlinebool operator>=( const reverse_iterator< Iterator1 >& lhs, const reverse_iterator<Iterator2 >& rhs )144 constexpr bool operator>=( const reverse_iterator< Iterator1 >& lhs, const reverse_iterator<Iterator2 >& rhs ) 145 145 { return lhs.base() <= rhs.base(); } 146 146 template < typename Iterator1, typename Iterator2 > 147 inlinetypename reverse_iterator<Iterator1>::difference_type operator-( const reverse_iterator<Iterator1>& lhs, const reverse_iterator<Iterator2>& rhs )147 constexpr typename reverse_iterator<Iterator1>::difference_type operator-( const reverse_iterator<Iterator1>& lhs, const reverse_iterator<Iterator2>& rhs ) 148 148 { return rhs.base() - lhs.base(); } 149 template < typename Iterator > inlinereverse_iterator<Iterator> operator+( typename reverse_iterator<Iterator>::difference_type n, const reverse_iterator<Iterator>& iter )149 template < typename Iterator > constexpr reverse_iterator<Iterator> operator+( typename reverse_iterator<Iterator>::difference_type n, const reverse_iterator<Iterator>& iter ) 150 150 { return reverse_iterator<Iterator>( iter.base() - n ); } 151 151 -
trunk/nv/stl/memory.hh
r404 r407 36 36 37 37 template< typename T > 38 class storage_ref38 class array_ref 39 39 { 40 40 public: 41 typedef T value_type; 42 typedef size_t size_type; 43 typedef ptrdiff_t difference_type; 44 typedef value_type* pointer; 45 typedef const value_type* const_pointer; 46 typedef value_type& reference; 47 typedef const value_type& const_reference; 48 41 typedef T value_type; 42 typedef size_t size_type; 43 typedef ptrdiff_t difference_type; 44 typedef value_type* pointer; 45 typedef const value_type* const_pointer; 46 typedef value_type& reference; 47 typedef const value_type& const_reference; 48 typedef value_type* iterator; 49 typedef const value_type* const_iterator; 50 typedef nv::reverse_iterator<iterator> reverse_iterator; 51 typedef nv::reverse_iterator<const_iterator> const_reverse_iterator; 49 52 50 53 static constexpr bool is_static = false; … … 52 55 static constexpr bool is_const = false; 53 56 54 constexpr storage_ref()57 constexpr array_ref() 55 58 : m_data( nullptr ), m_size( 0 ) {} 56 constexpr storage_ref( value_type* a_data, size_type a_size )59 constexpr array_ref( value_type* a_data, size_type a_size ) 57 60 : m_data( a_data ), m_size( a_size ) {} 58 61 … … 70 73 constexpr const char* raw_data() const { return reinterpret_cast<const char*>( m_data ); } 71 74 inline char* raw_data() { return reinterpret_cast<char*>( m_data ); } 75 76 constexpr const_iterator begin() const { return const_iterator( m_data ); } 77 constexpr const_iterator end() const { return const_iterator( m_data + m_size ); } 78 inline iterator begin() { return iterator( m_data ); } 79 inline iterator end() { return iterator( m_data + m_size ); } 80 constexpr const_iterator cbegin() const { return const_iterator( m_data ); } 81 constexpr const_iterator cend() const { return const_iterator( m_data + m_size ); } 82 inline reverse_iterator rbegin() { return reverse_iterator( end() ); } 83 inline reverse_iterator rend() { return reverse_iterator( begin() ); } 84 constexpr const_reverse_iterator rbegin() const { return const_reverse_iterator( end() ); } 85 constexpr const_reverse_iterator rend() const { return const_reverse_iterator( begin() ); } 86 constexpr const_reverse_iterator crbegin() const { return const_reverse_iterator( end() ); } 87 constexpr const_reverse_iterator crend() const { return const_reverse_iterator( begin() ); } 88 inline const_iterator iat( size_t i ) const { NV_ASSERT_ALWAYS( i <= m_size, "Index out of range" ); return begin() + i; } 89 inline iterator iat( size_t i ) { NV_ASSERT_ALWAYS( i <= m_size, "Index out of range" ); return begin() + i; } 90 91 inline reference front() { NV_ASSERT_ALWAYS( !empty(), "front() called on empty data!" ); return m_data[0]; } 92 inline const_reference front() const { NV_ASSERT_ALWAYS( !empty(), "front() called on empty data!" ); return m_data[0]; } 93 inline reference back() { NV_ASSERT_ALWAYS( !empty(), "front() called on empty data!" ); return m_data[m_size - 1]; } 94 inline const_reference back() const { NV_ASSERT_ALWAYS( !empty(), "front() called on empty data!" ); return m_data[m_size - 1]; } 95 96 reference operator[]( size_type i ) { NV_ASSERT_ALWAYS( i < m_size, "Out of range" ); return m_data[i]; } 97 const_reference operator[]( size_type i ) const { NV_ASSERT_ALWAYS( i < m_size, "Out of range" ); return m_data[i]; } 98 inline void fill( const value_type& value ) { fill_n( iterator( m_data ), iterator( m_data + m_size ), value ); } 99 72 100 protected: 73 101 value_type* m_data; … … 76 104 77 105 template< typename T > 78 class storage_view106 class array_view 79 107 { 80 108 public: 81 typedef T value_type; 82 typedef size_t size_type; 83 typedef ptrdiff_t difference_type; 84 typedef const value_type* pointer; 85 typedef const value_type* const_pointer; 86 typedef const value_type& reference; 87 typedef const value_type& const_reference; 109 typedef T value_type; 110 typedef size_t size_type; 111 typedef ptrdiff_t difference_type; 112 typedef const value_type* pointer; 113 typedef const value_type* const_pointer; 114 typedef const value_type& reference; 115 typedef const value_type& const_reference; 116 typedef const value_type* iterator; 117 typedef nv::reverse_iterator<iterator> reverse_iterator; 118 typedef const value_type* const_iterator; 119 typedef nv::reverse_iterator<const_iterator> const_reverse_iterator; 88 120 89 121 static constexpr bool is_static = false; … … 91 123 static constexpr bool is_const = true; 92 124 93 constexpr storage_view()125 constexpr array_view() 94 126 : m_data( nullptr ), m_size( 0 ) {} 95 constexpr storage_view( const value_type* a_data, size_type a_size )127 constexpr array_view( const value_type* a_data, size_type a_size ) 96 128 : m_data( a_data ), m_size( a_size ) {} 97 constexpr storage_view( const storage_ref<T>& view )129 constexpr array_view( const array_ref<T>& view ) 98 130 : m_data( view.data() ), m_size( view.size() ) {} 99 131 … … 109 141 constexpr size_type raw_size() const { return sizeof( value_type ) * m_size; } 110 142 constexpr const char* raw_data() const { return reinterpret_cast<const char*>( m_data ); } 143 144 constexpr const_iterator begin() const { return const_iterator( m_data ); } 145 constexpr const_iterator end() const { return const_iterator( m_data + m_size ); } 146 constexpr const_iterator cbegin() const { return const_iterator( m_data ); } 147 constexpr const_iterator cend() const { return const_iterator( m_data + m_size ); } 148 constexpr const_reverse_iterator rbegin() const { return const_reverse_iterator( end() ); } 149 constexpr const_reverse_iterator crbegin() const { return const_reverse_iterator( end() ); } 150 constexpr const_reverse_iterator rend() const { return const_reverse_iterator( begin() ); } 151 constexpr const_reverse_iterator crend() const { return const_reverse_iterator( begin() ); } 152 153 inline const_reference front() const { NV_ASSERT_ALWAYS( !empty(), "front() called on empty data!" ); return m_data[0]; } 154 inline const_reference back() const { NV_ASSERT_ALWAYS( !empty(), "front() called on empty data!" ); return m_data[m_size - 1]; } 155 156 inline const_iterator iat( size_t i ) const { NV_ASSERT_ALWAYS( i <= m_size, "Index out of range" ); return begin() + i; } 157 const_reference operator[]( size_type i ) const { NV_ASSERT_ALWAYS( i < m_size, "Out of range" ); return m_data[i]; } 158 111 159 protected: 112 160 const value_type* m_data; … … 161 209 { 162 210 object->~T(); 211 NV_UNUSED( object ); // MSVC bug - if destructing basic type 163 212 } 164 213 … … 489 538 } 490 539 491 template < typename T >492 using array_view = detail::add_random_access< detail::add_iterators < storage_view< T > > >;493 template < typename T >494 using array_ref = detail::add_random_access< detail::add_iterators < storage_ref< T > > >;495 using mem_view = array_view< char >;496 using mem_ref = array_ref< char >;497 498 540 } 499 541 -
trunk/nv/stl/string.hh
r403 r407 35 35 36 36 37 // short_string< size_t >38 // string3239 // string6440 // string37 // short_string< size_t > 38 // string32 39 // string64 40 // string 41 41 42 42 template<> … … 63 63 { 64 64 typedef conditional_t < is_array<T>::value, remove_extent_t<T>*, remove_cv_t<T> > decayed_type; 65 typedef bool_constant < 66 is_same< char *, decayed_type >::value || 65 typedef bool_constant < 66 is_same< char *, decayed_type >::value || 67 67 is_same< const char *, decayed_type >::value > type; 68 68 }; … … 74 74 class string_view; 75 75 76 // Stronger version77 // template < typename T >78 // struct is_string_base : is_template_base_of< T, string_base > {};76 // Stronger version 77 // template < typename T > 78 // struct is_string_base : is_template_base_of< T, string_base > {}; 79 79 80 80 template < typename T, typename Enable = void > … … 94 94 // string base class - will become a base for a string class later 95 95 template < typename Storage > 96 class string_base : public detail::add_iterators< Storage >97 { 98 typedef detail::add_iterators< Storage >base_type;99 typedef string_base< detail::add_iterators< Storage > >this_type;96 class string_base : public Storage 97 { 98 typedef Storage base_type; 99 typedef string_base< base_type > this_type; 100 100 public: 101 101 typedef Storage storage_type; … … 115 115 116 116 // conversion to std::string 117 118 119 120 117 inline std::string to_string() const 118 { 119 return std::string( this->data(), this->size() ); 120 } 121 121 122 122 inline size_type length() const { return this->size(); } 123 124 // access125 inline value_type operator[]( size_type i ) const { return this->data()[i]; }126 inline value_type at( size_type i ) const127 {128 // if ( i >= m_data ) NV_THROW( out_of_range( "string_ref::at" ) );129 return this->data()[i];130 }131 132 inline value_type front() const { return this->data()[0]; }133 inline value_type back() const { return this->data()[this->size() - 1]; }134 123 135 124 // string operations … … 139 128 bool ends_with( value_type c ) const; 140 129 bool ends_with( const string_view& s ) const; 141 auto find( value_type c, size_type pos = 0 ) const ->size_type;142 auto find( const string_view& s, size_type pos = 0 ) const ->size_type;143 auto rfind( value_type c, size_type pos = 0 ) const ->size_type;144 auto rfind( const string_view& s, size_type pos = 0 ) const ->size_type;145 auto find_first_of( value_type c ) const ->size_type;146 auto find_first_of( const string_view& s ) const ->size_type;147 auto find_last_of( value_type c ) const ->size_type;148 auto find_last_of( const string_view& s ) const ->size_type;149 auto find_first_not_of( value_type c ) const ->size_type;150 auto find_first_not_of( const string_view& s ) const ->size_type;151 auto find_last_not_of( value_type c ) const ->size_type;152 auto find_last_not_of( const string_view& s ) const ->size_type;130 auto find( value_type c, size_type pos = 0 ) const->size_type; 131 auto find( const string_view& s, size_type pos = 0 ) const->size_type; 132 auto rfind( value_type c, size_type pos = 0 ) const->size_type; 133 auto rfind( const string_view& s, size_type pos = 0 ) const->size_type; 134 auto find_first_of( value_type c ) const->size_type; 135 auto find_first_of( const string_view& s ) const->size_type; 136 auto find_last_of( value_type c ) const->size_type; 137 auto find_last_of( const string_view& s ) const->size_type; 138 auto find_first_not_of( value_type c ) const->size_type; 139 auto find_first_not_of( const string_view& s ) const->size_type; 140 auto find_last_not_of( value_type c ) const->size_type; 141 auto find_last_not_of( const string_view& s ) const->size_type; 153 142 154 143 // string operations … … 163 152 protected: 164 153 using base_type::base_type; 154 constexpr string_base() : base_type() {} 155 constexpr string_base( pointer str, size_type len ) : base_type( str, len ) {} 165 156 166 157 template < typename ReverseIterator > … … 181 172 }; 182 173 183 class string_view : public string_base< storage_view< char > >174 class string_view : public string_base< array_view< char > > 184 175 { 185 176 public: 186 typedef string_base< storage_view< char > > this_type; 187 188 inline string_view() {} 189 inline string_view( const string_view& rhs ) 190 : this_type( rhs.data(), rhs.size() ) 191 { 192 } 177 typedef string_base< array_view< char > > this_type; 178 179 constexpr string_view() : this_type() {} 180 inline string_view( const string_view& rhs ) : this_type( rhs.data(), rhs.size() ) {} 193 181 template < typename S > 194 inline string_view( const string_base<S>& rhs ) 195 : this_type( rhs.data(), rhs.size() ) 196 { 197 } 198 199 inline string_view( const std::string& str ) 200 : this_type( str.data(), str.size() ) 201 { 202 } 203 204 inline string_view( const char* str, size_type len ) 205 : this_type( str, len ) 206 { 207 } 182 inline string_view( const string_base<S>& rhs ) : this_type( rhs.data(), rhs.size() ) {} 183 inline string_view( const std::string& str ) : this_type( str.data(), str.size() ) {} 184 constexpr string_view( const char* str, size_type len ) : this_type( str, len ) {} 208 185 209 186 // Literal constructors 210 187 template< size_t N > 211 inlinestring_view( char( &s )[N] ) : this_type( s, N - 1 ) {}188 constexpr string_view( char( &s )[N] ) : this_type( s, N - 1 ) {} 212 189 template< size_t N > 213 inlinestring_view( const char( &s )[N] ) : this_type( s, N - 1 ) {}190 constexpr string_view( const char( &s )[N] ) : this_type( s, N - 1 ) {} 214 191 215 192 // Non-literal constructors … … 256 233 257 234 template < typename Storage > 258 inline bool string_base< Storage >::starts_with( value_type c ) const 259 { 260 return !this->empty() && c == this->front(); 235 inline bool string_base< Storage >::starts_with( value_type c ) const 236 { 237 return !this->empty() && c == this->front(); 261 238 } 262 239 template < typename Storage > … … 267 244 268 245 template < typename Storage > 269 inline bool string_base< Storage >::ends_with( value_type c ) const 270 { 246 inline bool string_base< Storage >::ends_with( value_type c ) const 247 { 271 248 return !this->empty() && c == this->back(); 272 249 } … … 323 300 { 324 301 return this->rfind( c ); 325 } 302 } 326 303 template < typename Storage > 327 304 inline auto string_base< Storage >::find_last_of( const string_view& s ) const -> size_type … … 423 400 } 424 401 425 NV_STRING_BASE_CAST_OPERATORS( == )426 NV_STRING_BASE_CAST_OPERATORS( != )427 NV_STRING_BASE_CAST_OPERATORS( < )428 NV_STRING_BASE_CAST_OPERATORS( > )429 NV_STRING_BASE_CAST_OPERATORS( <= )430 NV_STRING_BASE_CAST_OPERATORS( >= )402 NV_STRING_BASE_CAST_OPERATORS( == ) 403 NV_STRING_BASE_CAST_OPERATORS( != ) 404 NV_STRING_BASE_CAST_OPERATORS( < ) 405 NV_STRING_BASE_CAST_OPERATORS( > ) 406 NV_STRING_BASE_CAST_OPERATORS( <= ) 407 NV_STRING_BASE_CAST_OPERATORS( >= ) 431 408 432 409 … … 447 424 448 425 // const string is movable but not copyable 449 class const_string : public string_base< storage_view< char > >426 class const_string : public string_base< array_view< char > > 450 427 { 451 428 public: … … 479 456 size_type old_size = size(); 480 457 assign( other.data(), other.size() ); 481 other.assign( old_data 458 other.assign( old_data, old_size ); 482 459 return *this; 483 460 } … … 499 476 }; 500 477 501 class literal_string : public string_base< storage_view< char > > 502 { 478 class literal_string : public string_base< array_view< char > > 479 { 480 constexpr literal_string( const char* str, size_t len ) : this_type( str, len ) {} 503 481 public: 504 typedef string_base< storage_view< char > > this_type;505 506 // Literal constructors 482 typedef string_base< array_view< char > > this_type; 483 friend constexpr literal_string operator "" _ls( const char* str, size_t len ); 484 507 485 template< size_t N > 508 inlineliteral_string( char( &s )[N] ) : this_type( s, N - 1 ) {}486 constexpr literal_string( char( &s )[N] ) : this_type( s, N - 1 ) {} 509 487 template< size_t N > 510 inline literal_string( const char( &s )[N] ) : this_type( s, N - 1 ) {} 511 }; 512 513 514 inline string_view trimmed( const string_view& str ) 515 { 516 size_t endpos = str.find_last_not_of( " \r\n\t" ); 517 size_t startpos = str.find_first_not_of( " \r\n\t" ); 518 519 if ( string_view::npos != endpos || string_view::npos != startpos ) 520 { 521 if ( string_view::npos == startpos ) startpos = 0; 522 if ( string_view::npos != endpos ) endpos = endpos + 1 - startpos; 523 return str.substr( startpos, endpos ); 524 } 525 return str; 488 constexpr literal_string( const char( &s )[N] ) : this_type( s, N - 1 ) {} 489 }; 490 491 constexpr literal_string operator "" _ls( const char* str, size_t len ) 492 { 493 return literal_string( str, len ); 494 } 495 496 template < typename H > 497 class hashed_literal_string; 498 using hashed_literal_string_32 = hashed_literal_string< uint32 >; 499 using hashed_literal_string_64 = hashed_literal_string< uint64 >; 500 501 template < typename H > 502 class hashed_literal_string : public string_base< array_view< char > > 503 { 504 constexpr hashed_literal_string( const char* str, size_t len, H hash_code ) 505 : this_type( str, len ), m_hash( hash_code ) {} 506 public: 507 typedef string_base< array_view< char > > this_type; 508 509 template< size_t N > 510 constexpr hashed_literal_string( char( &s )[N] ) 511 : this_type( s, N - 1 ), m_hash( detail::fnv_hash<H>::hash( s, len-1 ) ) {} 512 template< size_t N > 513 constexpr hashed_literal_string( const char( &s )[N] ) 514 : this_type( s, N - 1 ), m_hash( detail::fnv_hash<H>::hash( s, len - 1 ) ) {} 515 516 template < typename H2 > 517 constexpr H get_hash() const 518 { 519 static_assert( is_same< H, H2 >::value, "32/64 bit hash mismatch on hash_literal_string!" ); 520 return m_hash; 521 } 522 523 friend constexpr hashed_literal_string_32 operator "" _hls32( const char* str, size_t len ); 524 friend constexpr hashed_literal_string_64 operator "" _hls64( const char* str, size_t len ); 525 protected: 526 H m_hash; 527 }; 528 529 constexpr hashed_literal_string_32 operator "" _hls32( const char* str, size_t len ) 530 { 531 return hashed_literal_string_32( str, len, detail::fnv_hash< uint32 >::hash( str, len ) ); 532 } 533 534 constexpr hashed_literal_string_64 operator "" _hls64( const char* str, size_t len ) 535 { 536 return hashed_literal_string_64( str, len, detail::fnv_hash< uint64 >::hash( str, len ) ); 537 } 538 539 template< typename H > 540 struct hash< hashed_literal_string_32, H > 541 { 542 static_assert( is_same< uint32, H >::value, "hashed_literal_string_32 used with non-32 bit hash!" ); 543 static constexpr H get( const hashed_literal_string_32& value ) 544 { 545 return value.get_hash< H >(); 546 } 547 constexpr H operator()( const hashed_literal_string_32& value ) const { return get( value ); } 548 }; 549 550 template< typename H > 551 struct hash< hashed_literal_string_64, H > 552 { 553 static_assert( is_same< uint64, H >::value, "hashed_literal_string_64 used with non-64 bit hash!" ); 554 static constexpr H get( const hashed_literal_string_64& value ) 555 { 556 return value.get_hash< H >(); 557 } 558 constexpr H operator()( const hashed_literal_string_64& value ) const { return get( value ); } 559 }; 560 561 inline string_view trimmed( const string_view& str ) 562 { 563 size_t endpos = str.find_last_not_of( " \r\n\t" ); 564 size_t startpos = str.find_first_not_of( " \r\n\t" ); 565 566 if ( string_view::npos != endpos || string_view::npos != startpos ) 567 { 568 if ( string_view::npos == startpos ) startpos = 0; 569 if ( string_view::npos != endpos ) endpos = endpos + 1 - startpos; 570 return str.substr( startpos, endpos ); 571 } 572 return str; 573 } 574 575 inline string_view rtrimmed( const string_view& str ) 576 { 577 size_t endpos = str.find_last_not_of( " \r\n\t" ); 578 if ( string_view::npos != endpos ) 579 { 580 return str.substr( 0, endpos + 1 ); 581 } 582 return str; 583 } 584 585 inline string_view ltrimmed( const string_view& str ) 586 { 587 size_t startpos = str.find_first_not_of( " \r\n\t" ); 588 if ( string_view::npos != startpos ) 589 { 590 return str.substr( startpos ); 591 } 592 return str; 593 } 594 595 596 inline string_view extract_extension( string_view filename ) 597 { 598 size_t lastdot = filename.find_last_of( '.' ); 599 if ( string_view::npos != lastdot ) 600 return filename.substr( lastdot + 1 ); 601 return filename; 602 } 603 526 604 } 527 605 528 inline string_view rtrimmed( const string_view& str ) 529 { 530 size_t endpos = str.find_last_not_of( " \r\n\t" ); 531 if ( string_view::npos != endpos ) 532 { 533 return str.substr( 0, endpos + 1 ); 534 } 535 return str; 536 } 537 538 inline string_view ltrimmed( const string_view& str ) 539 { 540 size_t startpos = str.find_first_not_of( " \r\n\t" ); 541 if ( string_view::npos != startpos ) 542 { 543 return str.substr( startpos ); 544 } 545 return str; 546 } 547 548 549 inline string_view extract_extension( string_view filename ) 550 { 551 size_t lastdot = filename.find_last_of( '.' ); 552 if ( string_view::npos != lastdot ) 553 return filename.substr( lastdot + 1 ); 554 return filename; 555 } 556 557 558 } 606 using nv::operator "" _ls; 607 using nv::operator "" _hls32; 608 using nv::operator "" _hls64; 559 609 560 610 #endif // NV_STL_STRING_HH
Note: See TracChangeset
for help on using the changeset viewer.