2021-04-28 20:30:34 +02:00
/*
*
* Created by jief in 1997.
* Copyright ( c ) 2020 Jief
* All rights reserved .
*
*/
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
# if !defined(__XString_H__)
# define __XString_H__
2020-03-12 15:40:38 +01:00
2020-04-24 08:36:29 +02:00
# include <XToolsConf.h>
2020-04-23 15:20:48 +02:00
# include "XStringAbstract.h"
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
# include "../../Include/Library/printf_lite.h"
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
# ifndef XString16GrowByDefault
# define XString16GrowByDefault 16
# endif
2020-03-12 15:40:38 +01:00
2020-04-29 22:34:28 +02:00
//------------------------------------------------------------------------------------------------------------------
2020-04-30 08:03:56 +02:00
class XString8 ;
class LString8 : public LString < char , XString8 >
2020-04-29 22:34:28 +02:00
{
public :
constexpr LString8 ( ) = delete ;
2021-04-08 17:07:05 +02:00
# ifdef XSTRING_CACHING_OF_SIZE
LString8 ( const char * s ) : LString < char , XString8 > ( s , utf8_size_of_utf8_string ( s ) ) { } ;
constexpr LString8 ( const char * s , size_t size ) : LString < char , XString8 > ( s , size ) { } ;
# else
constexpr LString8 ( const char * s ) : LString < char , XString8 > ( s ) { } ;
constexpr LString8 ( const char * s , size_t size ) : LString < char , XString8 > ( s ) { } ;
# endif
2020-04-29 22:34:28 +02:00
// no assignement, no destructor
2021-04-08 17:07:05 +02:00
friend constexpr LString8 operator " " _XS8 ( const char * s , size_t size ) { return LString8 ( s , size ) ; }
2020-08-12 17:15:47 +02:00
2021-04-08 17:07:05 +02:00
const char * c_str ( ) const { return data ( ) ; }
2020-08-12 17:15:47 +02:00
2020-04-29 22:34:28 +02:00
} ;
2020-03-12 15:40:38 +01:00
2020-04-30 08:03:56 +02:00
class XString8 : public XStringAbstract < char , XString8 >
2020-03-12 15:40:38 +01:00
{
public :
2020-04-30 08:03:56 +02:00
XString8 ( ) : XStringAbstract < char , XString8 > ( ) { } ;
XString8 ( const XString8 & S ) : XStringAbstract < char , XString8 > ( S ) { }
XString8 ( const LString8 & S ) : XStringAbstract < char , XString8 > ( S ) { }
2020-03-12 15:40:38 +01:00
2020-04-29 22:34:28 +02:00
template < class OtherXStringClass , enable_if ( is___String ( OtherXStringClass ) & & ! is___LString ( OtherXStringClass ) ) > // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
2020-04-30 08:03:56 +02:00
XString8 ( const OtherXStringClass & S ) : XStringAbstract < char , XString8 > ( S ) { }
2020-03-28 17:17:02 +01:00
2020-04-30 08:03:56 +02:00
XString8 & operator = ( const XString8 & S ) { this - > XStringAbstract < char , XString8 > : : operator = ( S ) ; return * this ; }
2020-03-12 15:40:38 +01:00
2020-04-30 08:03:56 +02:00
using XStringAbstract < char , XString8 > : : operator = ;
2020-08-12 17:15:47 +02:00
2021-04-08 17:07:05 +02:00
const char * c_str ( ) const { return data ( ) ; }
2020-08-18 18:45:44 +02:00
// char* copy_str() const { return (char*)AllocateCopyPool(length()+1, m_data); }
2020-08-12 17:15:47 +02:00
2020-04-23 15:20:48 +02:00
protected :
2020-08-11 08:00:19 +02:00
static void transmitS8Printf ( const char * buf , unsigned int nbchar , void * context )
2020-04-23 15:20:48 +02:00
{
2021-03-25 15:32:56 +01:00
( ( XString8 * ) ( context ) ) - > strsicat ( buf , nbchar ) ;
2020-04-23 15:20:48 +02:00
}
public :
2021-02-10 13:32:07 +01:00
void vS8Printf ( const char * format , XTOOLS_VA_LIST va )
2020-04-23 15:20:48 +02:00
{
setEmpty ( ) ;
2020-08-11 08:00:19 +02:00
vprintf_with_callback ( format , va , transmitS8Printf , this ) ;
2020-04-23 15:20:48 +02:00
}
2020-08-11 08:00:19 +02:00
void S8Printf ( const char * format , . . . ) __attribute__ ( ( __format__ ( __printf__ , 2 , 3 ) ) )
2020-04-23 15:20:48 +02:00
{
2021-02-10 13:32:07 +01:00
XTOOLS_VA_LIST va ;
2020-03-12 15:40:38 +01:00
2021-02-10 13:32:07 +01:00
XTOOLS_VA_START ( va , format ) ;
2020-08-11 08:00:19 +02:00
vS8Printf ( format , va ) ;
2021-02-10 13:32:07 +01:00
XTOOLS_VA_END ( va ) ;
2020-04-23 15:20:48 +02:00
}
2021-02-10 13:32:07 +01:00
void vS8Catf ( const char * format , XTOOLS_VA_LIST va )
2020-11-12 22:25:56 +01:00
{
vprintf_with_callback ( format , va , transmitS8Printf , this ) ;
}
void S8Catf ( const char * format , . . . ) __attribute__ ( ( __format__ ( __printf__ , 2 , 3 ) ) )
{
2021-02-10 13:32:07 +01:00
XTOOLS_VA_LIST va ;
2020-11-12 22:25:56 +01:00
2021-02-10 13:32:07 +01:00
XTOOLS_VA_START ( va , format ) ;
2020-11-12 22:25:56 +01:00
vS8Catf ( format , va ) ;
2021-02-10 13:32:07 +01:00
XTOOLS_VA_END ( va ) ;
2020-11-12 22:25:56 +01:00
}
2020-04-29 22:34:28 +02:00
} ;
2020-04-23 15:20:48 +02:00
2020-04-29 22:34:28 +02:00
//------------------------------------------------------------------------------------------------------------------
class XString16 ;
class LString16 : public LString < char16_t , XString16 >
{
2021-04-08 17:07:05 +02:00
# ifdef XSTRING_CACHING_OF_SIZE
constexpr LString16 ( const char16_t * s , size_t size ) : LString < char16_t , XString16 > ( s , size ) { } ;
# else
constexpr LString16 ( const char16_t * s , size_t size ) : LString < char16_t , XString16 > ( s ) { } ;
# endif
2020-04-29 22:34:28 +02:00
2021-04-08 17:07:05 +02:00
friend constexpr LString16 operator " " _XS16 ( const char16_t * s , size_t size ) { return LString16 ( s , size ) ; }
2020-04-23 15:20:48 +02:00
} ;
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
class XString16 : public XStringAbstract < char16_t , XString16 >
{
2020-03-12 15:40:38 +01:00
public :
2020-04-23 15:20:48 +02:00
XString16 ( ) : XStringAbstract < char16_t , XString16 > ( ) { } ;
2020-08-10 13:06:06 +02:00
XString16 ( const XString16 & S ) : XStringAbstract < char16_t , XString16 > ( S ) { }
XString16 ( const LString16 & S ) : XStringAbstract < char16_t , XString16 > ( S ) { }
2020-03-12 15:40:38 +01:00
2020-04-29 22:34:28 +02:00
template < class OtherXStringClass , enable_if ( is___String ( OtherXStringClass ) & & ! is___LString ( OtherXStringClass ) ) > // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
XString16 ( const OtherXStringClass & S ) : XStringAbstract < char16_t , XString16 > ( S ) { }
2020-03-26 13:59:20 +01:00
2020-04-23 15:20:48 +02:00
XString16 & operator = ( const XString16 & S ) { this - > XStringAbstract < char16_t , XString16 > : : operator = ( S ) ; return * this ; }
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
using XStringAbstract < char16_t , XString16 > : : operator = ;
2020-04-29 22:34:28 +02:00
// friend LString16 operator "" _XS16 ( const char16_t* s, size_t len);
} ;
//------------------------------------------------------------------------------------------------------------------
class XString32 ;
class LString32 : public LString < char32_t , XString32 >
{
2021-04-08 17:07:05 +02:00
# ifdef XSTRING_CACHING_OF_SIZE
constexpr LString32 ( const char32_t * s , size_t size ) : LString < char32_t , XString32 > ( s , size ) { } ;
# else
constexpr LString32 ( const char32_t * s , size_t size ) : LString < char32_t , XString32 > ( s ) { } ;
# endif
2020-04-29 22:34:28 +02:00
2021-04-08 17:07:05 +02:00
friend constexpr LString32 operator " " _XS32 ( const char32_t * s , size_t size ) { return LString32 ( s , size ) ; }
2020-04-23 15:20:48 +02:00
} ;
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
class XString32 : public XStringAbstract < char32_t , XString32 >
{
public :
XString32 ( ) : XStringAbstract < char32_t , XString32 > ( ) { } ;
2020-08-10 13:06:06 +02:00
XString32 ( const XString32 & S ) : XStringAbstract < char32_t , XString32 > ( S ) { }
XString32 ( const LString32 & S ) : XStringAbstract < char32_t , XString32 > ( S ) { }
2020-04-05 14:25:39 +02:00
2020-04-29 22:34:28 +02:00
template < class OtherXStringClass , enable_if ( is___String ( OtherXStringClass ) & & ! is___LString ( OtherXStringClass ) ) > // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
XString32 ( const OtherXStringClass & S ) : XStringAbstract < char32_t , XString32 > ( S ) { }
2020-04-05 14:25:39 +02:00
2020-04-23 15:20:48 +02:00
XString32 & operator = ( const XString32 & S ) { this - > XStringAbstract < char32_t , XString32 > : : operator = ( S ) ; return * this ; }
using XStringAbstract < char32_t , XString32 > : : operator = ;
2020-04-29 22:34:28 +02:00
// friend LString32 operator "" _XS32 ( const char32_t* s, size_t len);
} ;
//------------------------------------------------------------------------------------------------------------------
class XStringW ;
class LStringW : public LString < wchar_t , XStringW >
{
public :
constexpr LStringW ( ) = delete ;
2021-04-08 17:07:05 +02:00
# ifdef XSTRING_CACHING_OF_SIZE
LStringW ( const wchar_t * s ) : LString < wchar_t , XStringW > ( s , wchar_size_of_wchar_string ( s ) ) { } ;
constexpr LStringW ( const wchar_t * s , size_t size ) : LString < wchar_t , XStringW > ( s , size ) { } ;
# else
constexpr LStringW ( const wchar_t * s ) : LString < wchar_t , XStringW > ( s ) { } ;
constexpr LStringW ( const wchar_t * s , size_t size ) : LString < wchar_t , XStringW > ( s ) { } ;
# endif
friend constexpr LStringW operator " " _XSW ( const wchar_t * s , size_t size ) { return LStringW ( s , size ) ; }
const wchar_t * wc_str ( ) const { return data ( ) ; }
2020-04-23 15:20:48 +02:00
} ;
2020-04-05 14:25:39 +02:00
2020-04-23 15:20:48 +02:00
class XStringW : public XStringAbstract < wchar_t , XStringW >
{
2020-08-11 08:00:19 +02:00
public :
2020-04-23 15:20:48 +02:00
XStringW ( ) : XStringAbstract < wchar_t , XStringW > ( ) { } ;
XStringW ( const XStringW & S ) : XStringAbstract < wchar_t , XStringW > ( S ) { }
2020-08-10 13:06:06 +02:00
XStringW ( const LStringW & S ) : XStringAbstract < wchar_t , XStringW > ( S ) { }
2020-04-05 14:25:39 +02:00
2020-04-29 22:34:28 +02:00
template < class OtherXStringClass , enable_if ( is___String ( OtherXStringClass ) & & ! is___LString ( OtherXStringClass ) ) > // enable_if is to avoid constructing with a non-corresponding LString. To avoid memory allocation.
2020-04-23 15:20:48 +02:00
XStringW ( const OtherXStringClass & S ) : XStringAbstract < wchar_t , XStringW > ( S ) { }
2020-04-29 22:34:28 +02:00
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
XStringW & operator = ( const XStringW & S ) { this - > XStringAbstract < wchar_t , XStringW > : : operator = ( S ) ; return * this ; }
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
using XStringAbstract < wchar_t , XStringW > : : operator = ;
2020-03-12 15:40:38 +01:00
2021-04-08 17:07:05 +02:00
const wchar_t * wc_str ( ) const { return data ( ) ; }
2021-04-06 15:39:55 +02:00
template < typename IntegralType , enable_if ( is_integral ( IntegralType ) ) >
const wchar_t * wc_str ( IntegralType idx ) const { return data ( idx ) ; }
2020-08-12 17:15:47 +02:00
2020-04-23 15:20:48 +02:00
protected :
2021-02-04 15:04:31 +01:00
static void transmitSWPrintf ( const wchar_t * buf , unsigned int nbchar , void * context )
2020-04-23 15:20:48 +02:00
{
2021-03-25 15:32:56 +01:00
( ( XStringW * ) ( context ) ) - > strsicat ( buf , nbchar ) ;
2020-04-23 15:20:48 +02:00
}
public :
2021-02-10 13:32:07 +01:00
void vSWPrintf ( const char * format , XTOOLS_VA_LIST va )
2020-04-23 15:20:48 +02:00
{
setEmpty ( ) ;
2021-02-04 15:04:31 +01:00
vwprintf_with_callback ( format , va , transmitSWPrintf , this ) ;
2020-04-23 15:20:48 +02:00
}
void SWPrintf ( const char * format , . . . ) __attribute__ ( ( __format__ ( __printf__ , 2 , 3 ) ) )
{
2021-02-10 13:32:07 +01:00
XTOOLS_VA_LIST va ;
2020-03-12 15:40:38 +01:00
2021-02-10 13:32:07 +01:00
XTOOLS_VA_START ( va , format ) ;
2020-04-23 15:20:48 +02:00
vSWPrintf ( format , va ) ;
2021-02-10 13:32:07 +01:00
XTOOLS_VA_END ( va ) ;
2020-04-23 15:20:48 +02:00
}
2021-02-10 13:32:07 +01:00
void vSWCatf ( const char * format , XTOOLS_VA_LIST va )
2021-02-04 15:04:31 +01:00
{
vwprintf_with_callback ( format , va , transmitSWPrintf , this ) ;
}
void SWCatf ( const char * format , . . . ) __attribute__ ( ( __format__ ( __printf__ , 2 , 3 ) ) )
{
2021-02-10 13:32:07 +01:00
XTOOLS_VA_LIST va ;
2021-02-04 15:04:31 +01:00
2021-02-10 13:32:07 +01:00
XTOOLS_VA_START ( va , format ) ;
2021-02-04 15:04:31 +01:00
vSWCatf ( format , va ) ;
2021-02-10 13:32:07 +01:00
XTOOLS_VA_END ( va ) ;
2021-02-04 15:04:31 +01:00
}
2020-03-12 15:40:38 +01:00
} ;
2020-04-29 22:34:28 +02:00
2020-08-09 17:55:30 +02:00
constexpr LString8 operator " " _XS8 ( const char * s , size_t len ) ;
constexpr LString16 operator " " _XS16 ( const char16_t * s , size_t len ) ;
constexpr LString32 operator " " _XS32 ( const char32_t * s , size_t len ) ;
constexpr LStringW operator " " _XSW ( const wchar_t * s , size_t len ) ;
2020-03-29 11:40:13 +02:00
2021-05-08 11:34:17 +02:00
# ifdef _MSC_VER
// I don't know why it's needed with VS.
template < >
struct _xstringarray__char_type < XString8 , void >
{
static const typename XString8 : : char_t * getCharPtr ( const XString8 & t ) { return t . s ( ) ; }
} ;
template < >
struct _xstringarray__char_type < XStringW , void >
{
static const typename XStringW : : char_t * getCharPtr ( const XStringW & t ) { return t . s ( ) ; }
} ;
# endif
2020-08-11 08:00:19 +02:00
extern const XString8 NullXString8 ;
2020-04-23 15:20:48 +02:00
extern const XStringW NullXStringW ;
2020-04-05 14:25:39 +02:00
2020-04-23 15:20:48 +02:00
# ifdef _MSC_VER
# define __attribute__(x)
2020-03-12 15:40:38 +01:00
# endif
2020-04-23 15:20:48 +02:00
2020-08-11 08:00:19 +02:00
XString8 S8Printf ( const char * format , . . . ) __attribute__ ( ( __format__ ( __printf__ , 1 , 2 ) ) ) ;
2020-04-23 15:20:48 +02:00
XStringW SWPrintf ( const char * format , . . . ) __attribute__ ( ( __format__ ( __printf__ , 1 , 2 ) ) ) ;
2020-03-12 15:40:38 +01:00
2020-04-23 22:43:35 +02:00
//
//XStringAbstract SubString(const T *S, size_t pos, size_t count);
2020-03-12 15:40:38 +01:00
# endif