@ -214,6 +214,7 @@ namespace ImStb
# define IM_NEWLINE "\n"
# endif
# define IM_TABSIZE (4)
# define IM_MEMALIGN(_OFF,_ALIGN) (((_OFF) + (_ALIGN - 1)) & ~(_ALIGN - 1)) // Memory align e.g. IM_ALIGN(0,4)=0, IM_ALIGN(1,4)=4, IM_ALIGN(4,4)=4, IM_ALIGN(5,4)=8
# define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
# define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
# define IM_FLOOR(_VAL) ((float)(int)(_VAL)) // ImFloor() is not inlined in MSVC debug builds
@ -545,20 +546,22 @@ struct ImSpan
// Helper: ImSpanAllocator<>
// Facilitate storing multiple chunks into a single large block (the "arena")
// - Usage: call Reserve() N times, allocate GetArenaSizeInBytes() worth, pass it to SetArenaBasePtr(), call GetSpan() N times to retrieve the aligned ranges.
template < int CHUNKS >
struct ImSpanAllocator
{
char * BasePtr ;
int TotalSize ;
int Curr Span ;
int CurrOff ;
int Curr Idx ;
int Offsets [ CHUNKS ] ;
int Sizes [ CHUNKS ] ;
ImSpanAllocator ( ) { memset ( this , 0 , sizeof ( * this ) ) ; }
inline void Reserve Bytes ( int n , size_t sz ) { IM_ASSERT ( n = = CurrSpan & & n < CHUNKS ) ; IM_UNUSED ( n ) ; Offsets [ CurrSpan + + ] = TotalSize ; TotalSize + = ( int ) sz ; }
inline int GetArenaSizeInBytes ( ) { return TotalSize ; }
inline void Reserve ( int n , size_t sz , int a = 4 ) { IM_ASSERT ( n = = CurrIdx & & n < CHUNKS ) ; CurrOff = IM_MEMALIGN ( CurrOff , a ) ; Offsets [ n ] = CurrOff ; Sizes [ n ] = ( int ) sz ; CurrIdx + + ; CurrOff + = ( int ) sz ; }
inline int GetArenaSizeInBytes ( ) { return CurrOff ; }
inline void SetArenaBasePtr ( void * base_ptr ) { BasePtr = ( char * ) base_ptr ; }
inline void * GetSpanPtrBegin ( int n ) { IM_ASSERT ( n > = 0 & & n < CHUNKS & & Curr Span = = CHUNKS ) ; return ( void * ) ( BasePtr + Offsets [ n ] ) ; }
inline void * GetSpanPtrEnd ( int n ) { IM_ASSERT ( n > = 0 & & n < CHUNKS & & Curr Span = = CHUNKS ) ; return ( n + 1 < CHUNKS ) ? BasePtr + Offsets [ n + 1 ] : ( void * ) ( BasePtr + TotalSize ) ; }
inline void * GetSpanPtrBegin ( int n ) { IM_ASSERT ( n > = 0 & & n < CHUNKS & & Curr Idx = = CHUNKS ) ; return ( void * ) ( BasePtr + Offsets [ n ] ) ; }
inline void * GetSpanPtrEnd ( int n ) { IM_ASSERT ( n > = 0 & & n < CHUNKS & & Curr Idx = = CHUNKS ) ; return ( void * ) ( BasePtr + Offsets [ n ] + Sizes [ n ] ) ; }
template < typename T >
inline void GetSpan ( int n , ImSpan < T > * span ) { span - > set ( ( T * ) GetSpanPtrBegin ( n ) , ( T * ) GetSpanPtrEnd ( n ) ) ; }
} ;
@ -592,7 +595,7 @@ struct IMGUI_API ImPool
// Helper: ImChunkStream<>
// Build and iterate a contiguous stream of variable-sized structures.
// This is used by Settings to store persistent data while reducing allocation count.
// We store the chunk size first, and align the final size on 4 bytes boundaries (this what the '(X + 3) & ~3' statement is for)
// We store the chunk size first, and align the final size on 4 bytes boundaries .
// The tedious/zealous amount of casting is to avoid -Wcast-align warnings.
template < typename T >
struct IMGUI_API ImChunkStream
@ -602,7 +605,7 @@ struct IMGUI_API ImChunkStream
void clear ( ) { Buf . clear ( ) ; }
bool empty ( ) const { return Buf . Size = = 0 ; }
int size ( ) const { return Buf . Size ; }
T * alloc_chunk ( size_t sz ) { size_t HDR_SZ = 4 ; sz = ( ( HDR_SZ + sz ) + 3u ) & ~ 3u ; int off = Buf . Size ; Buf . resize ( off + ( int ) sz ) ; ( ( int * ) ( void * ) ( Buf . Data + off ) ) [ 0 ] = ( int ) sz ; return ( T * ) ( void * ) ( Buf . Data + off + ( int ) HDR_SZ ) ; }
T * alloc_chunk ( size_t sz ) { size_t HDR_SZ = 4 ; sz = IM_MEMALIGN ( HDR_SZ + sz , 4u ) ; int off = Buf . Size ; Buf . resize ( off + ( int ) sz ) ; ( ( int * ) ( void * ) ( Buf . Data + off ) ) [ 0 ] = ( int ) sz ; return ( T * ) ( void * ) ( Buf . Data + off + ( int ) HDR_SZ ) ; }
T * begin ( ) { size_t HDR_SZ = 4 ; if ( ! Buf . Data ) return NULL ; return ( T * ) ( void * ) ( Buf . Data + HDR_SZ ) ; }
T * next_chunk ( T * p ) { size_t HDR_SZ = 4 ; IM_ASSERT ( p > = begin ( ) & & p < end ( ) ) ; p = ( T * ) ( void * ) ( ( char * ) ( void * ) p + chunk_size ( p ) ) ; if ( p = = ( T * ) ( void * ) ( ( char * ) end ( ) + HDR_SZ ) ) return ( T * ) 0 ; IM_ASSERT ( p < end ( ) ) ; return p ; }
int chunk_size ( const T * p ) { return ( ( const int * ) p ) [ - 1 ] ; }