Changeset 407


Ignore:
Timestamp:
06/20/15 18:42:05 (10 years ago)
Author:
epyon
Message:
  • iterator - constexpr reverse_iterator as possible
  • memory - array_ref/view folded into storage_ref/view - made constexpr as possible
  • string - string_base inhertits storage directly
  • string - constexpr guarantee
  • string - added literal constructors, added hashed_string_literal
Location:
trunk/nv/stl
Files:
3 edited

Legend:

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

    r402 r407  
    104104
    105105        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 ) {}
    108108
    109109                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]; }
    124124        protected:
    125125                iterator_type m_base;
     
    127127
    128128        template < typename Iterator1, typename Iterator2 >
    129         inline bool 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 )
    130130        { return lhs.base() == rhs.base(); }
    131131        template < typename Iterator1, typename Iterator2 >
    132         inline bool 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 )
    133133        { return lhs.base() != rhs.base(); }
    134134        template < typename Iterator1, typename Iterator2 >
    135         inline bool 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 )
    136136        { return lhs.base() > rhs.base(); }
    137137        template < typename Iterator1, typename Iterator2 >
    138         inline bool 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 )
    139139        { return lhs.base() < rhs.base(); }
    140140        template < typename Iterator1, typename Iterator2 >
    141         inline bool 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 )
    142142        { return lhs.base() >= rhs.base(); }
    143143        template < typename Iterator1, typename Iterator2 >
    144         inline bool 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 )
    145145        { return lhs.base() <= rhs.base(); }
    146146        template < typename Iterator1, typename Iterator2 >
    147         inline typename 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 )
    148148        { return rhs.base() - lhs.base(); }
    149         template < typename Iterator > inline reverse_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 )
    150150        { return reverse_iterator<Iterator>( iter.base() - n ); }
    151151
  • trunk/nv/stl/memory.hh

    r404 r407  
    3636
    3737        template< typename T >
    38         class storage_ref
     38        class array_ref
    3939        {
    4040        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;
    4952
    5053                static constexpr bool is_static   = false;
     
    5255                static constexpr bool is_const    = false;
    5356
    54                 constexpr storage_ref()
     57                constexpr array_ref()
    5558                        : 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 )
    5760                        : m_data( a_data ), m_size( a_size ) {}
    5861
     
    7073                constexpr const char* raw_data() const { return reinterpret_cast<const char*>( m_data ); }
    7174                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
    72100        protected:
    73101                value_type* m_data;
     
    76104
    77105        template< typename T >
    78         class storage_view
     106        class array_view
    79107        {
    80108        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;
    88120
    89121                static constexpr bool is_static   = false;
     
    91123                static constexpr bool is_const    = true;
    92124
    93                 constexpr storage_view()
     125                constexpr array_view()
    94126                        : 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 )
    96128                        : 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 )
    98130                        : m_data( view.data() ), m_size( view.size() ) {}
    99131
     
    109141                constexpr size_type   raw_size() const { return sizeof( value_type ) * m_size; }
    110142                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
    111159        protected:
    112160                const value_type* m_data;
     
    161209        {
    162210                object->~T();
     211                NV_UNUSED( object ); // MSVC bug - if destructing basic type
    163212        }
    164213
     
    489538        }
    490539
    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 
    498540}
    499541
  • trunk/nv/stl/string.hh

    r403 r407  
    3535
    3636
    37 //      short_string< size_t >
    38 //      string32
    39 //      string64
    40 //      string
     37        //      short_string< size_t >
     38        //      string32
     39        //      string64
     40        //      string
    4141
    4242        template<>
     
    6363                {
    6464                        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 ||
    6767                                is_same< const char *, decayed_type >::value > type;
    6868                };
     
    7474        class string_view;
    7575
    76 // Stronger version
    77 //      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 > {};
    7979
    8080        template < typename T, typename Enable = void >
     
    9494        // string base class - will become a base for a string class later
    9595        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;
    100100        public:
    101101                typedef Storage                                     storage_type;
     
    115115
    116116                // conversion to std::string
    117                 inline std::string to_string() const
    118                 {
    119                         return std::string( this->data(), this->size() );
    120                 }
     117                inline std::string to_string() const
     118                {
     119                        return std::string( this->data(), this->size() );
     120                }
    121121
    122122                inline size_type length()   const { return this->size(); }
    123 
    124                 // access
    125                 inline value_type operator[]( size_type i ) const { return this->data()[i]; }
    126                 inline value_type at( size_type i ) const
    127                 {
    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]; }
    134123
    135124                // string operations
     
    139128                bool ends_with( value_type c ) const;
    140129                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;
    153142
    154143                // string operations
     
    163152        protected:
    164153                using base_type::base_type;
     154                constexpr string_base() : base_type() {}
     155                constexpr string_base( pointer str, size_type len ) : base_type( str, len ) {}
    165156
    166157                template < typename ReverseIterator >
     
    181172        };
    182173
    183         class string_view : public string_base< storage_view< char > >
     174        class string_view : public string_base< array_view< char > >
    184175        {
    185176        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() ) {}
    193181                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 ) {}
    208185
    209186                // Literal constructors
    210187                template< size_t N >
    211                 inline string_view( char( &s )[N] ) : this_type( s, N - 1 ) {}
     188                constexpr string_view( char( &s )[N] ) : this_type( s, N - 1 ) {}
    212189                template< size_t N >
    213                 inline string_view( const char( &s )[N] ) : this_type( s, N - 1 ) {}
     190                constexpr string_view( const char( &s )[N] ) : this_type( s, N - 1 ) {}
    214191
    215192                // Non-literal constructors
     
    256233
    257234        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();
    261238        }
    262239        template < typename Storage >
     
    267244
    268245        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        {
    271248                return !this->empty() && c == this->back();
    272249        }
     
    323300        {
    324301                return this->rfind( c );
    325         } 
     302        }
    326303        template < typename Storage >
    327304        inline auto string_base< Storage >::find_last_of( const string_view& s ) const -> size_type
     
    423400        }
    424401
    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( >= )
    431408
    432409
     
    447424
    448425        // 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 > >
    450427        {
    451428        public:
     
    479456                        size_type old_size = size();
    480457                        assign( other.data(), other.size() );
    481                         other.assign( old_data , old_size );
     458                        other.assign( old_data, old_size );
    482459                        return *this;
    483460                }
     
    499476        };
    500477
    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 ) {}
    503481        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
    507485                template< size_t N >
    508                 inline literal_string( char( &s )[N] ) : this_type( s, N - 1 ) {}
     486                constexpr literal_string( char( &s )[N] ) : this_type( s, N - 1 ) {}
    509487                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
    526604}
    527605
    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 }
     606using nv::operator "" _ls;
     607using nv::operator "" _hls32;
     608using nv::operator "" _hls64;
    559609
    560610#endif // NV_STL_STRING_HH
Note: See TracChangeset for help on using the changeset viewer.