/******************************************************************************/ /* STRINGS AND RELATED UTILITIES - INLINE CODE ********************************/ /******************************************************************************/ #ifndef _H_EBCL_INLINE_STRINGS #define _H_EBCL_INLINE_STRINGS #include namespace ebcl { /*= T_Character ==============================================================*/ inline constexpr T_Character::T_Character( ) noexcept : codepoint( 0 ) { } inline constexpr T_Character::T_Character( const T_Character& other ) noexcept : codepoint( other.codepoint ) { } template< typename T , typename > inline constexpr T_Character::T_Character( T codepoint ) noexcept : codepoint( uint32_t( codepoint ) ) { assert( codepoint >= 0 ); } /*----------------------------------------------------------------------------*/ inline constexpr bool T_Character::isValid( ) const { return codepoint < 0x110000; } inline constexpr bool T_Character::isAscii( ) const { return codepoint < 128; } inline constexpr bool T_Character::isControl( ) const { return codepoint < 32; } inline constexpr bool T_Character::isUppercase( ) const { return codepoint >= 'A' && codepoint <= 'Z'; } inline constexpr bool T_Character::isLowercase( ) const { return codepoint >= 'a' && codepoint <= 'z'; } inline constexpr bool T_Character::isAlpha( ) const { return isUppercase( ) || isLowercase( ); } inline constexpr bool T_Character::isNumeric( ) const { return codepoint >= '0' && codepoint <= '9'; } inline constexpr bool T_Character::isAlphanumeric( ) const { return isAlpha( ) || isNumeric( ); } inline constexpr bool T_Character::isWhitespace( ) const { return codepoint == 32 || codepoint == '\t' || codepoint == '\n' || codepoint == '\r'; } /*----------------------------------------------------------------------------*/ inline constexpr bool T_Character::operator== ( T_Character const& other ) const { return codepoint == other.codepoint; } inline constexpr bool T_Character::operator!= ( T_Character const& other ) const { return codepoint != other.codepoint; } inline constexpr bool T_Character::operator< ( T_Character const& other ) const { return codepoint < other.codepoint; } inline constexpr bool T_Character::operator> ( T_Character const& other ) const { return codepoint > other.codepoint; } inline constexpr bool T_Character::operator<= ( T_Character const& other ) const { return codepoint <= other.codepoint; } inline constexpr bool T_Character::operator>= ( T_Character const& other ) const { return codepoint >= other.codepoint; } /*----------------------------------------------------------------------------*/ template< typename T , typename > inline constexpr bool T_Character::operator== ( T other ) const { return codepoint == uint32_t( other ); } template< typename T , typename > inline constexpr bool T_Character::operator!= ( T other ) const { return codepoint != uint32_t( other ); } template< typename T , typename > inline constexpr bool T_Character::operator< ( T other ) const { return codepoint < uint32_t( other ); } template< typename T , typename > inline constexpr bool T_Character::operator<= ( T other ) const { return codepoint <= uint32_t( other ); } template< typename T , typename > inline constexpr bool T_Character::operator> ( T other ) const { return codepoint > uint32_t( other ); } template< typename T , typename > inline constexpr bool T_Character::operator>= ( T other ) const { return codepoint >= uint32_t( other ); } /*----------------------------------------------------------------------------*/ inline constexpr T_Character::operator uint32_t ( ) const { return codepoint; } /*----------------------------------------------------------------------------*/ inline uint32_t T_Character::writeTo( char* output , uint32_t avail ) const { return UTF8PutCodepoint( output , avail , codepoint ); } /*----------------------------------------------------------------------------*/ inline constexpr T_Character T_Character::toUpper( ) const { if ( isLowercase( ) ) { return *this & (~0x20); } else { return *this; } } inline constexpr T_Character T_Character::toLower( ) const { if ( isUppercase( ) ) { return *this | 0x20; } else { return *this; } } /*= A_StringData =============================================================*/ inline bool A_StringData::valid( ) const { return valid_; } inline char const* A_StringData::data( ) const { return data_; } inline uint32_t A_StringData::length( ) const { return length_; } inline uint32_t A_StringData::size( ) const { return size_; } /*= T_String =================================================================*/ inline T_String T_String::Pooled( char const* string ) { return Pooled( string , strlen( string ) ); } /*----------------------------------------------------------------------------*/ inline bool T_String::valid( ) const { return data_->valid( ); } inline uint32_t T_String::size( ) const { return data_->size( ); } inline uint32_t T_String::length( ) const { return data_->length( ); } inline char const* T_String::data( ) const { return data_->data( ); } inline T_String::operator bool ( ) const { return size( ) != 0; } inline bool T_String::operator! ( ) const { return size( ) == 0; } /*----------------------------------------------------------------------------*/ inline T_Character T_String::operator[] ( uint32_t index ) const { assert( index < length( ) ); char const* const d( data( ) ); return UTF8GetCodepoint( d + UTF8GetMemoryOffset( d , index ) ); } inline T_String T_String::range( uint32_t start , uint32_t end ) const { if ( start > end ) { return T_String( ); } return substr( start , end == UINT32_MAX ? UINT32_MAX : ( end - start + 1 ) ); } /*----------------------------------------------------------------------------*/ inline bool T_String::equals( T_String const& other ) const { return data_ == other.data_ || ( other.size( ) == size( ) && ( size( ) == 0 || !memcmp( other.data( ) , data( ) , size( ) ) ) ); } inline bool T_String::equals( char const* string ) const { const auto l( strlen( string ) ); return size( ) == l && ( l == 0 || !memcmp( string , data( ) , l ) ); } /*----------------------------------------------------------------------------*/ inline bool T_String::operator== ( T_String const& other ) const { return equals( other ); } inline bool T_String::operator!= ( T_String const& other ) const { return !equals( other ); } inline bool T_String::operator< ( T_String const& other ) const { return compare( other ) < 0; } inline bool T_String::operator> ( T_String const& other ) const { return compare( other ) > 0; } inline bool T_String::operator>= ( T_String const& other ) const { return compare( other ) >= 0; } inline bool T_String::operator<= ( T_String const& other ) const { return compare( other ) <= 0; } /*----------------------------------------------------------------------------*/ inline bool T_String::operator== ( char const* string ) const { return equals( string ); } inline bool T_String::operator!= ( char const* string ) const { return !equals( string ); } /*----------------------------------------------------------------------------*/ inline int64_t T_String::toInteger( bool * ok , int base , bool useSep , T_Character separator ) const { return UTF8ToInteger( data( ) , size( ) , ok , base , useSep , separator ); } inline uint64_t T_String::toUnsignedInteger( bool * ok , int base , bool useSep , T_Character separator ) const { return UTF8ToUnsignedInteger( data( ) , size( ) , ok , base , useSep , separator ); } inline double T_String::toDouble( bool * ok , T_Character decimalPoint , bool useSep , T_Character separator ) const { return UTF8ToDouble( data( ) , size( ) , ok , decimalPoint , useSep , separator ); } /*----------------------------------------------------------------------------*/ inline T_StringIterator T_String::getIterator( uint32_t offset ) const { if ( offset >= data_->size( ) ) { return T_StringIterator( nullptr , 0 ); } return T_StringIterator( data_ , offset ); } inline T_String::operator T_StringIterator( ) const { return getIterator( 0 ); } /*= T_String helpers =========================================================*/ inline M_DEFINE_HASH( T_String ) { return HashData( reinterpret_cast< uint8_t const* >( item.data( ) ) , item.size( ) ); } inline M_DEFINE_COMPARATOR( T_String ) { return a.compare( b ); } /*= T_StringIterator =========================================================*/ inline T_StringIterator::T_StringIterator( T_StringIterator&& other ) noexcept : data_( other.data_ ) , pos_( other.pos_ ) , index_( other.index_ ) , codepoint_( other.codepoint_ ) , bytes_( other.bytes_ ) { other.data_ = nullptr; } inline T_StringIterator& T_StringIterator::operator= ( T_StringIterator&& other ) noexcept { swap( *this , other ); return *this; } /*----------------------------------------------------------------------------*/ inline uint32_t T_StringIterator::index( ) const { return index_; } inline bool T_StringIterator::atEnd( ) const { return data_ == nullptr || pos_ == data_->size( ); } /*----------------------------------------------------------------------------*/ inline T_Character T_StringIterator::character( ) const { return codepoint_; } inline T_StringIterator::operator T_Character ( ) const { return codepoint_; } /*= T_StringBuilder ==========================================================*/ inline T_StringBuilder::T_StringBuilder( ) noexcept : data_( nullptr ) , capacity_( 0 ) , size_( 0 ) , length_( 0 ) { } inline T_StringBuilder::T_StringBuilder( char const* string ) : T_StringBuilder( string , strlen( string ) ) { } /*----------------------------------------------------------------------------*/ inline char const* T_StringBuilder::data( ) const { return data_; } inline uint32_t T_StringBuilder::capacity( ) const { return capacity_; } inline uint32_t T_StringBuilder::size( ) const { return size_; } inline uint32_t T_StringBuilder::length( ) const { return length_; } inline T_StringBuilder::operator bool ( ) const { return size_ != 0; } inline bool T_StringBuilder::operator! ( ) const { return size_ == 0; } /*----------------------------------------------------------------------------*/ inline T_StringBuilder& T_StringBuilder::clear( ) { size_ = length_ = 0; return *this; } inline T_StringBuilder& T_StringBuilder::truncate( const uint32_t maxLength ) noexcept { if ( maxLength < length_ ) { size_ = UTF8GetMemoryOffset( data_ , maxLength ); length_ = maxLength; } return *this; } /*----------------------------------------------------------------------------*/ inline bool T_StringBuilder::operator== ( T_StringBuilder const& other ) const { return other.size_ == size_ && ( size_ == 0 || !memcmp( other.data_ , data_ , size_ ) ); } inline bool T_StringBuilder::operator!= ( T_StringBuilder const& other ) const { return other.size_ != size_ || ( size_ != 0 && memcmp( other.data_ , data_ , size_ ) ); } /*----------------------------------------------------------------------------*/ inline bool T_StringBuilder::operator== ( T_String const& string ) const { return string.size( ) == size_ && ( size_ == 0 || !memcmp( string.data( ) , data_ , size_ ) ); } inline bool T_StringBuilder::operator!= ( T_String const& string ) const { return string.size( ) != size_ || ( size_ != 0 && memcmp( string.data( ) , data_ , size_ ) ); } /*----------------------------------------------------------------------------*/ inline bool T_StringBuilder::operator== ( char const* string ) const { return strlen( string ) == size_ && ( size_ == 0 || !memcmp( string , data_ , size_ ) ); } inline bool T_StringBuilder::operator!= ( char const* string ) const { return strlen( string ) != size_ || ( size_ != 0 && memcmp( string , data_ , size_ ) ); } /*----------------------------------------------------------------------------*/ inline int64_t T_StringBuilder::toInteger( bool * ok , int base , bool useSep , T_Character separator ) const { return UTF8ToInteger( data_ , size_ , ok , base , useSep , separator ); } inline uint64_t T_StringBuilder::toUnsignedInteger( bool * ok , int base , bool useSep , T_Character separator ) const { return UTF8ToUnsignedInteger( data_ , size_ , ok , base , useSep , separator ); } inline double T_StringBuilder::toDouble( bool * ok , T_Character decimalPoint , bool useSep , T_Character separator ) const { return UTF8ToDouble( data( ) , size( ) , ok , decimalPoint , useSep , separator ); } /*----------------------------------------------------------------------------*/ inline T_StringBuilder& operator<< ( T_StringBuilder& sb , T_StringBuilder const& value ) { return sb.append( value ); } inline T_StringBuilder& operator<< ( T_StringBuilder& sb , T_StringBuilder&& value ) { return sb.append( std::move( value ) ); } inline T_StringBuilder& operator<< ( T_StringBuilder& sb , T_String const& value ) { return sb.append( value ); } inline T_StringBuilder& operator<< ( T_StringBuilder& sb , char const* value ) { return sb.append( value , strlen( value ) ); } inline T_StringBuilder& operator<< ( T_StringBuilder& sb , char value ) { return sb.append( value ); } inline T_StringBuilder& operator<< ( T_StringBuilder& sb , T_Character value ) { return sb.append( value ); } inline T_StringBuilder& operator<< ( T_StringBuilder& sb , int16_t value ) { return sb.appendNumeric( int64_t( value ) ); } inline T_StringBuilder& operator<< ( T_StringBuilder& sb , int32_t value ) { return sb.appendNumeric( int64_t( value ) ); } inline T_StringBuilder& operator<< ( T_StringBuilder& sb , int64_t value ) { return sb.appendNumeric( value ); } inline T_StringBuilder& operator<< ( T_StringBuilder& sb , uint16_t value ) { return sb.appendNumeric( uint64_t( value ) ); } inline T_StringBuilder& operator<< ( T_StringBuilder& sb , uint32_t value ) { return sb.appendNumeric( uint64_t( value ) ); } inline T_StringBuilder& operator<< ( T_StringBuilder& sb , uint64_t value ) { return sb.appendNumeric( value ); } inline T_StringBuilder& operator<< ( T_StringBuilder& sb , float value ) { return sb.appendDouble( double( value ) ); } inline T_StringBuilder& operator<< ( T_StringBuilder& sb , double value ) { return sb.appendDouble( value ); } } // namespace #endif // _H_EBCL_INLINE_STRINGS