@ -1157,55 +1157,57 @@ enum ImGuiCond_
// Helper: ImVector<>
// Lightweight std::vector<>-like class to avoid dragging dependencies (also: some implementations of STL with debug enabled are absurdly slow, we bypass it so our code runs fast in debug).
// You generally do NOT need to care or use this ever. But we need to make it available in imgui.h because some of our data structures are relying on it.
// Important: clear() frees memory, resize(0) keep the allocated buffer. We use resize(0) a lot to intentionally recycle allocated buffers across frames and amortize our costs.
// Important: our implementation does NOT call C++ constructors/destructors, we treat everything as raw data! This is intentional but be extra mindful of that,
// do NOT use this class as a std::vector replacement in your own code!
//-----------------------------------------------------------------------------
template < typename T >
class ImVector
struct ImVector
{
public :
int Size ;
int Capacity ;
T * Data ;
int Size ;
int Capacity ;
T * Data ;
// Provide standard typedefs but we don't use them ourselves.
typedef T value_type ;
typedef value_type * iterator ;
typedef const value_type * const_iterator ;
inline ImVector ( ) { Size = Capacity = 0 ; Data = NULL ; }
inline ~ ImVector ( ) { if ( Data ) ImGui : : MemFree ( Data ) ; }
inline ImVector ( const ImVector < T > & src ) { Size = Capacity = 0 ; Data = NULL ; operator = ( src ) ; }
inline ImVector < T > & operator = ( const ImVector < T > & src ) { clear ( ) ; resize ( src . Size ) ; memcpy ( Data , src . Data , ( size_t ) Size * sizeof ( value_type ) ) ; return * this ; }
inline bool empty ( ) const { return Size = = 0 ; }
inline int size ( ) const { return Size ; }
inline int capacity ( ) const { return Capacity ; }
inline value_type & operator [ ] ( int i ) { IM_ASSERT ( i < Size ) ; return Data [ i ] ; }
inline const value_type & operator [ ] ( int i ) const { IM_ASSERT ( i < Size ) ; return Data [ i ] ; }
inline void clear ( ) { if ( Data ) { Size = Capacity = 0 ; ImGui : : MemFree ( Data ) ; Data = NULL ; } }
inline iterator begin ( ) { return Data ; }
inline const_iterator begin ( ) const { return Data ; }
inline iterator end ( ) { return Data + Size ; }
inline const_iterator end ( ) const { return Data + Size ; }
inline value_type & front ( ) { IM_ASSERT ( Size > 0 ) ; return Data [ 0 ] ; }
inline const value_type & front ( ) const { IM_ASSERT ( Size > 0 ) ; return Data [ 0 ] ; }
inline value_type & back ( ) { IM_ASSERT ( Size > 0 ) ; return Data [ Size - 1 ] ; }
inline const value_type & back ( ) const { IM_ASSERT ( Size > 0 ) ; return Data [ Size - 1 ] ; }
inline void swap ( ImVector < value_type > & rhs ) { int rhs_size = rhs . Size ; rhs . Size = Size ; Size = rhs_size ; int rhs_cap = rhs . Capacity ; rhs . Capacity = Capacity ; Capacity = rhs_cap ; value_type * rhs_data = rhs . Data ; rhs . Data = Data ; Data = rhs_data ; }
inline int _grow_capacity ( int sz ) const { int new_capacity = Capacity ? ( Capacity + Capacity / 2 ) : 8 ; return new_capacity > sz ? new_capacity : sz ; }
inline void resize ( int new_size ) { if ( new_size > Capacity ) reserve ( _grow_capacity ( new_size ) ) ; Size = new_size ; }
inline void resize ( int new_size , const value_type & v ) { if ( new_size > Capacity ) reserve ( _grow_capacity ( new_size ) ) ; if ( new_size > Size ) for ( int n = Size ; n < new_size ; n + + ) memcpy ( & Data [ n ] , & v , sizeof ( v ) ) ; Size = new_size ; }
// Constructors, destructor
inline ImVector ( ) { Size = Capacity = 0 ; Data = NULL ; }
inline ImVector ( const ImVector < T > & src ) { Size = Capacity = 0 ; Data = NULL ; operator = ( src ) ; }
inline ImVector < T > & operator = ( const ImVector < T > & src ) { clear ( ) ; resize ( src . Size ) ; memcpy ( Data , src . Data , ( size_t ) Size * sizeof ( T ) ) ; return * this ; }
inline ~ ImVector ( ) { if ( Data ) ImGui : : MemFree ( Data ) ; }
inline bool empty ( ) const { return Size = = 0 ; }
inline int size ( ) const { return Size ; }
inline int capacity ( ) const { return Capacity ; }
inline T & operator [ ] ( int i ) { IM_ASSERT ( i < Size ) ; return Data [ i ] ; }
inline const T & operator [ ] ( int i ) const { IM_ASSERT ( i < Size ) ; return Data [ i ] ; }
inline void clear ( ) { if ( Data ) { Size = Capacity = 0 ; ImGui : : MemFree ( Data ) ; Data = NULL ; } }
inline T * begin ( ) { return Data ; }
inline const T * begin ( ) const { return Data ; }
inline T * end ( ) { return Data + Size ; }
inline const T * end ( ) const { return Data + Size ; }
inline T & front ( ) { IM_ASSERT ( Size > 0 ) ; return Data [ 0 ] ; }
inline const T & front ( ) const { IM_ASSERT ( Size > 0 ) ; return Data [ 0 ] ; }
inline T & back ( ) { IM_ASSERT ( Size > 0 ) ; return Data [ Size - 1 ] ; }
inline const T & back ( ) const { IM_ASSERT ( Size > 0 ) ; return Data [ Size - 1 ] ; }
inline void swap ( ImVector < T > & rhs ) { int rhs_size = rhs . Size ; rhs . Size = Size ; Size = rhs_size ; int rhs_cap = rhs . Capacity ; rhs . Capacity = Capacity ; Capacity = rhs_cap ; T * rhs_data = rhs . Data ; rhs . Data = Data ; Data = rhs_data ; }
inline int _grow_capacity ( int sz ) const { int new_capacity = Capacity ? ( Capacity + Capacity / 2 ) : 8 ; return new_capacity > sz ? new_capacity : sz ; }
inline void resize ( int new_size ) { if ( new_size > Capacity ) reserve ( _grow_capacity ( new_size ) ) ; Size = new_size ; }
inline void resize ( int new_size , const T & v ) { if ( new_size > Capacity ) reserve ( _grow_capacity ( new_size ) ) ; if ( new_size > Size ) for ( int n = Size ; n < new_size ; n + + ) memcpy ( & Data [ n ] , & v , sizeof ( v ) ) ; Size = new_size ; }
inline void reserve ( int new_capacity )
{
if ( new_capacity < = Capacity )
return ;
value_type* new_data = ( value_type * ) ImGui : : MemAlloc ( ( size_t ) new_capacity * sizeof ( value_type ) ) ;
T* new_data = ( T * ) ImGui : : MemAlloc ( ( size_t ) new_capacity * sizeof ( T ) ) ;
if ( Data )
{
memcpy ( new_data , Data , ( size_t ) Size * sizeof ( value_type ) ) ;
memcpy ( new_data , Data , ( size_t ) Size * sizeof ( T ) ) ;
ImGui : : MemFree ( Data ) ;
}
Data = new_data ;
@ -1213,15 +1215,15 @@ public:
}
// NB: It is illegal to call push_back/push_front/insert with a reference pointing inside the ImVector data itself! e.g. v.push_back(v[10]) is forbidden.
inline void push_back ( const value_type& v ) { if ( Size = = Capacity ) reserve ( _grow_capacity ( Size + 1 ) ) ; memcpy ( & Data [ Size ] , & v , sizeof ( v ) ) ; Size + + ; }
inline void pop_back ( ) { IM_ASSERT ( Size > 0 ) ; Size - - ; }
inline void push_front ( const value_type& v ) { if ( Size = = 0 ) push_back ( v ) ; else insert ( Data , v ) ; }
inline iterator erase ( const_iterator it ) { IM_ASSERT ( it > = Data & & it < Data + Size ) ; const ptrdiff_t off = it - Data ; memmove ( Data + off , Data + off + 1 , ( ( size_t ) Size - ( size_t ) off - 1 ) * sizeof ( value_type ) ) ; Size - - ; return Data + off ; }
inline iterator erase ( const_iterator it , const_iterator it_last ) { IM_ASSERT ( it > = Data & & it < Data + Size & & it_last > it & & it_last < = Data + Size ) ; const ptrdiff_t count = it_last - it ; const ptrdiff_t off = it - Data ; memmove ( Data + off , Data + off + count , ( ( size_t ) Size - ( size_t ) off - count ) * sizeof ( value_type ) ) ; Size - = ( int ) count ; return Data + off ; }
inline iterator erase_unsorted ( const_iterator it ) { IM_ASSERT ( it > = Data & & it < Data + Size ) ; const ptrdiff_t off = it - Data ; if ( it < Data + Size - 1 ) memcpy ( Data + off , Data + Size - 1 , sizeof ( value_type ) ) ; Size - - ; return Data + off ; }
inline iterator insert ( const_iterator it , const value_type & v ) { IM_ASSERT ( it > = Data & & it < = Data + Size ) ; const ptrdiff_t off = it - Data ; if ( Size = = Capacity ) reserve ( _grow_capacity ( Size + 1 ) ) ; if ( off < ( int ) Size ) memmove ( Data + off + 1 , Data + off , ( ( size_t ) Size - ( size_t ) off ) * sizeof ( value_type ) ) ; memcpy ( & Data [ off ] , & v , sizeof ( v ) ) ; Size + + ; return Data + off ; }
inline bool contains ( const value_type& v ) const { const T * data = Data ; const T * data_end = Data + Size ; while ( data < data_end ) if ( * data + + = = v ) return true ; return false ; }
inline int index_from_p ointer( const_iterator it ) const { IM_ASSERT ( it > = Data & & it < = Data + Size ) ; const ptrdiff_t off = it - Data ; return ( int ) off ; }
inline void push_back ( const T& v ) { if ( Size = = Capacity ) reserve ( _grow_capacity ( Size + 1 ) ) ; memcpy ( & Data [ Size ] , & v , sizeof ( v ) ) ; Size + + ; }
inline void pop_back ( ) { IM_ASSERT ( Size > 0 ) ; Size - - ; }
inline void push_front ( const T& v ) { if ( Size = = 0 ) push_back ( v ) ; else insert ( Data , v ) ; }
inline T* erase ( const T * it ) { IM_ASSERT ( it > = Data & & it < Data + Size ) ; const ptrdiff_t off = it - Data ; memmove ( Data + off , Data + off + 1 , ( ( size_t ) Size - ( size_t ) off - 1 ) * sizeof ( T ) ) ; Size - - ; return Data + off ; }
inline T* erase ( const T * it , const T * it_last ) { IM_ASSERT ( it > = Data & & it < Data + Size & & it_last > it & & it_last < = Data + Size ) ; const ptrdiff_t count = it_last - it ; const ptrdiff_t off = it - Data ; memmove ( Data + off , Data + off + count , ( ( size_t ) Size - ( size_t ) off - count ) * sizeof ( T ) ) ; Size - = ( int ) count ; return Data + off ; }
inline T* erase_unsorted ( const T * it ) { IM_ASSERT ( it > = Data & & it < Data + Size ) ; const ptrdiff_t off = it - Data ; if ( it < Data + Size - 1 ) memcpy ( Data + off , Data + Size - 1 , sizeof ( T ) ) ; Size - - ; return Data + off ; }
inline T* insert ( const T * it , const T & v ) { IM_ASSERT ( it > = Data & & it < = Data + Size ) ; const ptrdiff_t off = it - Data ; if ( Size = = Capacity ) reserve ( _grow_capacity ( Size + 1 ) ) ; if ( off < ( int ) Size ) memmove ( Data + off + 1 , Data + off , ( ( size_t ) Size - ( size_t ) off ) * sizeof ( T ) ) ; memcpy ( & Data [ off ] , & v , sizeof ( v ) ) ; Size + + ; return Data + off ; }
inline bool contains ( const T& v ) const { const T * data = Data ; const T * data_end = Data + Size ; while ( data < data_end ) if ( * data + + = = v ) return true ; return false ; }
inline int index_from_p tr( const T * it ) const { IM_ASSERT ( it > = Data & & it < = Data + Size ) ; const ptrdiff_t off = it - Data ; return ( int ) off ; }
} ;
//-----------------------------------------------------------------------------