Skip to content

Commit d1c1d40

Browse files
committed
feat: add prepend operations
1 parent 7f9e2f4 commit d1c1d40

6 files changed

Lines changed: 614 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
### Added
66

7-
- NIL
7+
- Prepend operations - `StringBuilder::prepend()` methods for inserting content at the beginning of the buffer
88

99
### Changed
1010

include/nfx/detail/string/StringBuilder.inl

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,155 @@ namespace nfx::string
247247
return *this;
248248
}
249249

250+
//----------------------------------------------
251+
// Prepend operations
252+
//----------------------------------------------
253+
254+
inline StringBuilder& StringBuilder::prepend( const std::string& str )
255+
{
256+
prepend( std::string_view{ str } );
257+
return *this;
258+
}
259+
260+
inline StringBuilder& StringBuilder::prepend( const char* str )
261+
{
262+
if ( str )
263+
{
264+
prepend( std::string_view{ str, strlen( str ) } );
265+
}
266+
return *this;
267+
}
268+
269+
inline StringBuilder& StringBuilder::prepend( char c )
270+
{
271+
if ( m_size + 1 > m_capacity ) [[unlikely]]
272+
{
273+
ensureCapacity( m_size + 1 );
274+
}
275+
276+
char* buf = currentBuffer();
277+
278+
// Shift existing content right by 1
279+
if ( m_size > 0 )
280+
{
281+
std::memmove( buf + 1, buf, m_size );
282+
}
283+
284+
buf[0] = c;
285+
++m_size;
286+
return *this;
287+
}
288+
289+
inline StringBuilder& StringBuilder::prepend( std::int8_t value )
290+
{
291+
char buffer[INT8_MAX_DIGITS];
292+
auto [ptr, ec] = std::to_chars( buffer, buffer + INT8_MAX_DIGITS, static_cast<int>( value ) );
293+
if ( ec == std::errc() ) [[likely]]
294+
{
295+
return prepend( std::string_view{ buffer, static_cast<size_t>( ptr - buffer ) } );
296+
}
297+
return *this;
298+
}
299+
300+
inline StringBuilder& StringBuilder::prepend( std::uint8_t value )
301+
{
302+
char buffer[UINT8_MAX_DIGITS];
303+
auto [ptr, ec] = std::to_chars( buffer, buffer + UINT8_MAX_DIGITS, static_cast<unsigned>( value ) );
304+
if ( ec == std::errc() ) [[likely]]
305+
{
306+
return prepend( std::string_view{ buffer, static_cast<size_t>( ptr - buffer ) } );
307+
}
308+
return *this;
309+
}
310+
311+
inline StringBuilder& StringBuilder::prepend( std::int16_t value )
312+
{
313+
char buffer[INT16_MAX_DIGITS];
314+
auto [ptr, ec] = std::to_chars( buffer, buffer + INT16_MAX_DIGITS, value );
315+
if ( ec == std::errc() ) [[likely]]
316+
{
317+
return prepend( std::string_view{ buffer, static_cast<size_t>( ptr - buffer ) } );
318+
}
319+
return *this;
320+
}
321+
322+
inline StringBuilder& StringBuilder::prepend( std::uint16_t value )
323+
{
324+
char buffer[UINT16_MAX_DIGITS];
325+
auto [ptr, ec] = std::to_chars( buffer, buffer + UINT16_MAX_DIGITS, value );
326+
if ( ec == std::errc() ) [[likely]]
327+
{
328+
return prepend( std::string_view{ buffer, static_cast<size_t>( ptr - buffer ) } );
329+
}
330+
return *this;
331+
}
332+
333+
inline StringBuilder& StringBuilder::prepend( std::int32_t value )
334+
{
335+
char buffer[INT32_MAX_DIGITS];
336+
auto [ptr, ec] = std::to_chars( buffer, buffer + INT32_MAX_DIGITS, value );
337+
if ( ec == std::errc() ) [[likely]]
338+
{
339+
return prepend( std::string_view{ buffer, static_cast<size_t>( ptr - buffer ) } );
340+
}
341+
return *this;
342+
}
343+
344+
inline StringBuilder& StringBuilder::prepend( std::uint32_t value )
345+
{
346+
char buffer[UINT32_MAX_DIGITS];
347+
auto [ptr, ec] = std::to_chars( buffer, buffer + UINT32_MAX_DIGITS, value );
348+
if ( ec == std::errc() ) [[likely]]
349+
{
350+
return prepend( std::string_view{ buffer, static_cast<size_t>( ptr - buffer ) } );
351+
}
352+
return *this;
353+
}
354+
355+
inline StringBuilder& StringBuilder::prepend( std::int64_t value )
356+
{
357+
char buffer[INT64_MAX_DIGITS];
358+
auto [ptr, ec] = std::to_chars( buffer, buffer + INT64_MAX_DIGITS, value );
359+
if ( ec == std::errc() ) [[likely]]
360+
{
361+
return prepend( std::string_view{ buffer, static_cast<size_t>( ptr - buffer ) } );
362+
}
363+
return *this;
364+
}
365+
366+
inline StringBuilder& StringBuilder::prepend( std::uint64_t value )
367+
{
368+
char buffer[UINT64_MAX_DIGITS];
369+
auto [ptr, ec] = std::to_chars( buffer, buffer + UINT64_MAX_DIGITS, value );
370+
if ( ec == std::errc() ) [[likely]]
371+
{
372+
return prepend( std::string_view{ buffer, static_cast<size_t>( ptr - buffer ) } );
373+
}
374+
return *this;
375+
}
376+
377+
inline StringBuilder& StringBuilder::prepend( float value )
378+
{
379+
char buffer[FLOAT_MAX_CHARS];
380+
auto [ptr, ec] = std::to_chars( buffer, buffer + FLOAT_MAX_CHARS, value );
381+
if ( ec == std::errc() ) [[likely]]
382+
{
383+
return prepend( std::string_view{ buffer, static_cast<size_t>( ptr - buffer ) } );
384+
}
385+
return *this;
386+
}
387+
388+
inline StringBuilder& StringBuilder::prepend( double value )
389+
{
390+
char buffer[DOUBLE_MAX_CHARS];
391+
auto [ptr, ec] = std::to_chars( buffer, buffer + DOUBLE_MAX_CHARS, value );
392+
if ( ec == std::errc() ) [[likely]]
393+
{
394+
return prepend( std::string_view{ buffer, static_cast<size_t>( ptr - buffer ) } );
395+
}
396+
return *this;
397+
}
398+
250399
//----------------------------------------------
251400
// Batch operations
252401
//----------------------------------------------

include/nfx/string/StringBuilder.h

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ namespace nfx::string
236236
void resize( size_t newSize );
237237

238238
//----------------------------------------------
239-
// Content manipulation
239+
// Append operations
240240
//----------------------------------------------
241241

242242
/**
@@ -337,6 +337,110 @@ namespace nfx::string
337337
*/
338338
inline StringBuilder& append( double value );
339339

340+
//----------------------------------------------
341+
// Prepend operations
342+
//----------------------------------------------
343+
344+
/**
345+
* @brief Prepends string_view contents to the buffer
346+
* @param str String view to prepend
347+
* @return Reference to this StringBuilder for chaining
348+
* @details Shifts existing content and inserts at the beginning.
349+
* Performance: O(n) due to memory shift operation.
350+
*/
351+
StringBuilder& prepend( std::string_view str );
352+
353+
/**
354+
* @brief Prepends std::string contents to the buffer
355+
* @param str String to prepend
356+
* @return Reference to this StringBuilder for chaining
357+
*/
358+
inline StringBuilder& prepend( const std::string& str );
359+
360+
/**
361+
* @brief Prepends null-terminated C-string to the buffer
362+
* @param str Null-terminated C-string to prepend (null pointer handled gracefully)
363+
* @return Reference to this StringBuilder for chaining
364+
*/
365+
inline StringBuilder& prepend( const char* str );
366+
367+
/**
368+
* @brief Prepends single character to the buffer
369+
* @param c Character to prepend
370+
* @return Reference to this StringBuilder for chaining
371+
*/
372+
inline StringBuilder& prepend( char c );
373+
374+
/**
375+
* @brief Prepends 8-bit signed integer to the buffer
376+
* @param value Integer value to prepend
377+
* @return Reference to this StringBuilder for chaining
378+
*/
379+
inline StringBuilder& prepend( std::int8_t value );
380+
381+
/**
382+
* @brief Prepends 8-bit unsigned integer to the buffer
383+
* @param value Integer value to prepend
384+
* @return Reference to this StringBuilder for chaining
385+
*/
386+
inline StringBuilder& prepend( std::uint8_t value );
387+
388+
/**
389+
* @brief Prepends 16-bit signed integer to the buffer
390+
* @param value Integer value to prepend
391+
* @return Reference to this StringBuilder for chaining
392+
*/
393+
inline StringBuilder& prepend( std::int16_t value );
394+
395+
/**
396+
* @brief Prepends 16-bit unsigned integer to the buffer
397+
* @param value Integer value to prepend
398+
* @return Reference to this StringBuilder for chaining
399+
*/
400+
inline StringBuilder& prepend( std::uint16_t value );
401+
402+
/**
403+
* @brief Prepends 32-bit signed integer to the buffer
404+
* @param value Integer value to prepend
405+
* @return Reference to this StringBuilder for chaining
406+
*/
407+
inline StringBuilder& prepend( std::int32_t value );
408+
409+
/**
410+
* @brief Prepends 32-bit unsigned integer to the buffer
411+
* @param value Integer value to prepend
412+
* @return Reference to this StringBuilder for chaining
413+
*/
414+
inline StringBuilder& prepend( std::uint32_t value );
415+
416+
/**
417+
* @brief Prepends 64-bit signed integer to the buffer
418+
* @param value Integer value to prepend
419+
* @return Reference to this StringBuilder for chaining
420+
*/
421+
inline StringBuilder& prepend( std::int64_t value );
422+
423+
/**
424+
* @brief Prepends 64-bit unsigned integer to the buffer
425+
* @param value Integer value to prepend
426+
* @return Reference to this StringBuilder for chaining
427+
*/
428+
inline StringBuilder& prepend( std::uint64_t value );
429+
430+
/**
431+
* @brief Prepends single-precision floating-point to the buffer
432+
* @param value Floating-point value to prepend
433+
* @return Reference to this StringBuilder for chaining
434+
*/
435+
inline StringBuilder& prepend( float value );
436+
437+
/**
438+
* @brief Prepends double-precision floating-point to the buffer
439+
* @param value Floating-point value to prepend
440+
* @return Reference to this StringBuilder for chaining
441+
*/
442+
inline StringBuilder& prepend( double value );
443+
340444
//----------------------------------------------
341445
// Batch operations
342446
//----------------------------------------------

0 commit comments

Comments
 (0)