I've got a C api that has a lot of common behaviour typedefs (namely the char, wchar_t, char16_t etc lot), I've managed to do this so far:
string.cpp
Code:
#ifdef INC_PAW
#include INC_PAW(paw/global/string.h)
#include INC_PAW(paw/global/_block.h)
#else
#include <paw/global/string.h>
#include <paw/global/_block.h>
#endif
template<typename T> static pawd paw__length( T const *str )
{
if ( str )
{
pawd i;
for ( i = 0; str[i]; ++i );
return i;
}
return -1;
}
template<typename T> static pawd paw__mbslen( T const *mbs )
{
if ( mbs )
{
pawd i, len = 0;
for ( i = 0; mbs[i]; len += !(mbs[i] & 0x80), ++i );
return len;
}
return -1;
}
template<typename T> static T const *paw__locate( T const *src, T const *str )
{
pawd src_len = paw__length<T>( src );
pawd str_len = paw__length<T>( str );
for ( src_len += (src_len >= 0); --src_len >= str_len; ++src )
{
if ( memcmp( src, str, sizeof(T) * str_len ) == 0 )
return src;
}
return NULL;
}
PAW_API pawd paws_length( paws str )
{ return paw__length<pawc>( str ); }
PAW_API pawd paws_mbslen( paws mbs )
{ return paw__mbslen<pawc>( mbs ); }
PAW_API paws paws_locate( paws src, paws str )
{ return paw__locate<pawc>( src, str ); }
PAW_API pawd pawls_length( pawls str )
{ return paw__length<pawlc>( str ); }
PAW_API pawd pawls_mbslen( pawls mbs )
{ return paw__mbslen<pawlc>( mbs ); }
PAW_API pawls pawls_locate( pawls src, pawls str )
{ return paw__locate<pawlc>( src, str ); }
...
paw/global/string.h
Code:
#ifndef INC_PAW_GLOBAL_STRING_H
#define INC_PAW_GLOBAL_STRING_H
#ifdef INC_PAW
#include INC_PAW(paw/global/number.h)
#else
#include <paw/global/number.h>
#endif
PAW_OPEN_C_API
#include <string.h>
#include <wchar.h>
#include <uchar.h>
#include <ctype.h>
typedef char pawc;
typedef char const *paws;
#define PAWC_MAX CHAR_MAX
#define PAWC_MIN CHAR_MIN
typedef wchar_t pawlc;
typedef wchar_t const *pawls;
#define PAWLC_MAX WCHAR_MAX
#define PAWLC_MIN WCHAR_MIN
typedef wint_t pawzc;
#define PAWZC_MAX WINT_MAX
#define PAWZC_MIN WINT_MIN
typedef char16_t pawhc;
typedef char16_t const *pawhs;
typedef char32_t pawllc;
typedef char32_t const *pawlls;
typedef char pawsi[bitsof(pawjd)];
typedef char32_t pawjc;
typedef char32_t const *pawjs;
#define PAWJC_MAX UINT_LEAST32_MAX
#define PAWJC_MIN 0
#if CHAR_BIT >= 8
typedef char pawhhc;
typedef char const *pawhhs;
#define PRIpawhhc "c"
#define SCNpawhhc "c"
#define PRIpawhhs "s"
#define SCNpawhhs "s"
#define PAWHHC_C( LITERAL ) LITERAL
#define PAWHHC_MAX CHAR_MAX
#define PAWHHC_MIN CHAR_MIN
#else
typedef wchar_t pawhhc;
typedef wchar_t const *pawhhs;
#define PRIpawhhc "lc"
#define SCNpawhhc "lc"
#define PRIpawhhs "ls"
#define SCNpawhhs "ls"
#define _PAWHHC_C( LITERAL ) L##LITERAL
#define PAWHHC_C( LITERAL ) _PAWHHC_C( LITERAL )
#define PAWHHC_MAX WCHAR_MAX
#define PAWHHC_MIN WCHAR_MIN
#endif
#ifdef PAW_ON_WINDOWS
typedef TCHAR pawtc;
typedef TCHAR const *pawts;
#define PAWTC_C( LITERAL ) TEXT( LITERAL )
#define PAWTC_MAX TCHAR_MAX
#define PAWTC_MIN TCHAR_MIN
#else
typedef char pawtc;
typedef char const *pawts;
#define PAWTC_C( LITERAL ) LITERAL
#define PAWTC_MAX CHAR_MAX
#define PAWTC_MIN CHAR_MIN
#endif
#if defined(MB_LEN_MAX) && MB_LEN_MAX > 7
#define PAWMBC_MAX_LEN MB_LEN_MAX
#else
#define PAWMBC_MAX_LEN 7
#endif
typedef pawhhc pawmbc[PAWMBC_MAX_LEN+1];
/* By using strings paw doesn't need to check if uppercase or lowercase is to
* be expected */
#define PAW_BASE2 "01"
#define PAW_BASE8 "01234567"
#define PAW_BASE10 "0123456789"
#define PAW_BASE16x PAW_BASE10 "abcdef"
#define PAW_BASE16X PAW_BASE10 "ABCDEF"
#define PAW_BASE16_REM "aA0"
/* e.g. "\x80\x10\x7f" would return 3 */
PAW_API pawd paws_length( paws str );
PAW_API pawd pawls_length( pawls str );
PAW_API pawd pawhhs_length( pawhhs str );
PAW_API pawd pawhs_length( pawhs str );
PAW_API pawd pawlls_length( pawlls str );
PAW_API pawd pawjs_length( pawjs str );
PAW_API pawd pawts_length( pawts str );
/* e.g. "\x80\x10\x7f" would return 2 */
PAW_API pawd paws_mbslen( paws mbs );
PAW_API pawd pawls_mbslen( pawls mbs );
PAW_API pawd pawhhs_mbslen( pawhhs mbs );
PAW_API pawd pawhs_mbslen( pawhs mbs );
PAW_API pawd pawlls_mbslen( pawlls mbs );
PAW_API pawd pawjs_mbslen( pawjs mbs );
PAW_API pawd pawts_mbslen( pawts mbs );
/* Find first instance of str in src */
PAW_API paws paws_locate( paws src, paws str );
PAW_API pawls pawls_locate( pawls src, pawls str );
PAW_API pawhhs pawhhs_locate( pawhhs src, pawhhs str );
PAW_API pawhs pawhs_locate( pawhs src, pawhs str );
PAW_API pawlls pawlls_locate( pawlls src, pawlls str );
PAW_API pawjs pawjs_locate( pawjs src, pawjs str );
PAW_API pawts pawts_locate( pawts src, pawts str );
PAW_API pawd pawu2s( pawsi *dst, pawju src, paws base );
/* e.g.
* pawsi num = "A";
* paws2u( &num, 16, PAW_BASE16_REM );
* // Returns 10
*/
PAW_API pawju paws2u( pawsi *src, pawd base, paws remove );
PAW_API pawzd pawlc2hhc( pawmbc *dst, pawd src );
PAW_API pawzd pawhhc2lc( pawd *dst, pawmbc *src );
PAW_API pawzd pawls2hhs( pawhhc *dst, pawzd cap, pawls src, pawd len );
/* len here means same as result of pawsleng(src) */
PAW_API pawzd pawhhs2ls( pawlc *dst, pawd max, pawhhs src, pawzd len );
PAW_SHUT_C_API
#endif
What tweaks/changes do you lot think may/should be made for this to later be a decent library piece to download and use and why? I'm aiming to ultimately make paw unreliant on the C api so that it doesn't have to deal with the multiple versions of the crt on windows, things like limits.h & stdint.h are fine since neither define any APIs or global variables however malloc.h & and other api containing headers are to be avoided in favour of system headers if possible.