nfx-stringbuilder 0.1.1
High-performance C++20 library for zero-allocation string building with thread-safe pooling
Loading...
Searching...
No Matches
StringBuilder.h
Go to the documentation of this file.
1/*
2 * MIT License
3 *
4 * Copyright (c) 2025 nfx
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
78
79#pragma once
80
81#include <cstdint>
82#include <format>
83#include <memory>
84#include <string>
85#include <string_view>
86
87namespace nfx::string
88{
89 //=====================================================================
90 // DynamicStringBuffer class
91 //=====================================================================
92
104 class DynamicStringBuffer final
105 {
106 friend class DynamicStringBufferPool;
107
108 private:
109 //----------------------------------------------
110 // Construction
111 //----------------------------------------------
112
114 DynamicStringBuffer();
115
121 explicit DynamicStringBuffer( size_t initialCapacity );
122
123 public:
128 DynamicStringBuffer( const DynamicStringBuffer& other );
129
134 DynamicStringBuffer( DynamicStringBuffer&& other ) noexcept;
135
136 //----------------------------------------------
137 // Destruction
138 //----------------------------------------------
139
142
143 //----------------------------------------------
144 // Assignment
145 //----------------------------------------------
146
152 DynamicStringBuffer& operator=( const DynamicStringBuffer& other );
153
159 DynamicStringBuffer& operator=( DynamicStringBuffer&& other ) noexcept;
160
161 //----------------------------------------------
162 // Capacity and size information
163 //----------------------------------------------
164
171 [[nodiscard]] size_t size() const noexcept;
172
179 [[nodiscard]] size_t capacity() const noexcept;
180
186 [[nodiscard]] bool isEmpty() const noexcept;
187
188 //----------------------------------------------
189 // Buffer management
190 //----------------------------------------------
191
196 void clear() noexcept;
197
204 void reserve( size_t newCapacity );
205
212 void resize( size_t newSize );
213
214 //----------------------------------------------
215 // Data access
216 //----------------------------------------------
217
224 [[nodiscard]] char* data() noexcept;
225
232 [[nodiscard]] const char* data() const noexcept;
233
240 char& operator[]( size_t index );
241
248 const char& operator[]( size_t index ) const;
249
250 //----------------------------------------------
251 // Content manipulation
252 //----------------------------------------------
253
260 void append( std::string_view str );
261
268 void append( const std::string& str );
269
276 void append( const char* str );
277
284 void append( char c );
285
286 //----------------------------------------------
287 // String conversion
288 //----------------------------------------------
289
295 [[nodiscard]] std::string toString() const;
296
303 [[nodiscard]] std::string_view toStringView() const noexcept;
304
305 //----------------------------------------------
306 // Iterator interface
307 //----------------------------------------------
308
310 using value_type = char;
311
313 using Iterator = char*;
314
316 using ConstIterator = const char*;
317
320
323
330 [[nodiscard]] Iterator begin() noexcept;
331
338 [[nodiscard]] ConstIterator begin() const noexcept;
339
346 [[nodiscard]] Iterator end() noexcept;
347
354 [[nodiscard]] ConstIterator end() const noexcept;
355
356 private:
357 //----------------------------------------------
358 // Small buffer optimization constants
359 //----------------------------------------------
360
362 static constexpr size_t STACK_BUFFER_SIZE = 256;
363
365 static constexpr auto GROWTH_FACTOR = 1.5;
366
367 //----------------------------------------------
368 // Private members
369 //----------------------------------------------
370
372 alignas( char ) char m_stackBuffer[STACK_BUFFER_SIZE];
373
375 std::unique_ptr<char[]> m_heapBuffer;
376
378 size_t m_size;
379
381 size_t m_capacity;
382
384 bool m_onHeap;
385
386 //----------------------------------------------
387 // Private methods
388 //----------------------------------------------
389
394 void ensureCapacity( size_t needed_capacity );
395
400 char* currentBuffer() noexcept;
401
406 const char* currentBuffer() const noexcept;
407 };
408
409 //=====================================================================
410 // StringBuilder class
411 //=====================================================================
412
429 class StringBuilder final
430 {
431 friend class StringBuilderLease;
432 friend class std::back_insert_iterator<StringBuilder>;
433
434 //----------------------------------------------
435 // Construction
436 //----------------------------------------------
437 private:
439 inline explicit StringBuilder( DynamicStringBuffer& buffer );
440
441 public:
443 StringBuilder() = delete;
444
446 StringBuilder( const StringBuilder& ) = default;
447
449 StringBuilder( StringBuilder&& ) noexcept = delete;
450
451 //----------------------------------------------
452 // Destruction
453 //----------------------------------------------
454
456 ~StringBuilder() = default;
457
458 //----------------------------------------------
459 // Assignment
460 //----------------------------------------------
461
463 StringBuilder& operator=( const StringBuilder& ) = delete;
464
466 StringBuilder& operator=( StringBuilder&& ) noexcept = delete;
467
468 //----------------------------------------------
469 // Array access operators
470 //----------------------------------------------
471
477 inline char& operator[]( size_t index );
478
484 inline const char& operator[]( size_t index ) const;
485
486 //----------------------------------------------
487 // String append operations
488 //----------------------------------------------
489
494 inline void append( std::string_view str );
495
500 inline void append( const std::string& str );
501
506 inline void append( const char* str );
507
512 inline void append( char c );
513
514 //----------------------------------------------
515 // Stream operators
516 //----------------------------------------------
517
523 inline StringBuilder& operator<<( std::string_view str );
524
530 inline StringBuilder& operator<<( const std::string& str );
531
537 inline StringBuilder& operator<<( const char* str );
538
544 inline StringBuilder& operator<<( char c );
545
551 inline StringBuilder& operator<<( std::int32_t value );
552
558 inline StringBuilder& operator<<( std::uint32_t value );
559
565 inline StringBuilder& operator<<( std::int64_t value );
566
572 inline StringBuilder& operator<<( std::uint64_t value );
573
579 inline StringBuilder& operator<<( float value );
580
586 inline StringBuilder& operator<<( double value );
587
588 //----------------------------------------------
589 // Formatting operations
590 //----------------------------------------------
591
602 template <typename... Args>
603 inline StringBuilder& format( std::format_string<Args...> fmt, Args&&... args );
604
605 //----------------------------------------------
606 // Size and capacity management
607 //----------------------------------------------
608
613 inline size_t length() const noexcept;
614
619 inline void resize( size_t newSize );
620
621 //----------------------------------------------
622 // Iterator interface
623 //----------------------------------------------
624
626 using value_type = char;
627
629 using Iterator = char*;
630
632 using ConstIterator = const char*;
633
636
639
644 inline Iterator begin();
645
650 inline ConstIterator begin() const;
651
656 inline Iterator end();
657
662 inline ConstIterator end() const;
663
664 private:
665 //----------------------------------------------
666 // Container interface (for std::back_inserter support)
667 //----------------------------------------------
668
674 inline void push_back( char c ) { append( c ); }
675
676 //----------------------------------------------
677 // Private member variables
678 //----------------------------------------------
679
681 DynamicStringBuffer& m_buffer;
682 };
683
684 //=====================================================================
685 // StringBuilderLease class
686 //=====================================================================
687
705 class StringBuilderLease final
706 {
707 friend class StringBuilderPool;
708
709 //----------------------------------------------
710 // Construction
711 //----------------------------------------------
712 private:
714 inline explicit StringBuilderLease( DynamicStringBuffer* buffer );
715
716 public:
719
721 StringBuilderLease( const StringBuilderLease& ) = delete;
722
727 inline StringBuilderLease( StringBuilderLease&& other ) noexcept;
728
729 //----------------------------------------------
730 // Destruction
731 //----------------------------------------------
732
735
736 //----------------------------------------------
737 // Assignment
738 //----------------------------------------------
739
741 StringBuilderLease& operator=( const StringBuilderLease& ) = delete;
742
748 inline StringBuilderLease& operator=( StringBuilderLease&& other ) noexcept;
749
750 //----------------------------------------------
751 // Public interface methods
752 //----------------------------------------------
753
759 [[nodiscard]] inline StringBuilder create();
760
766 [[nodiscard]] inline DynamicStringBuffer& buffer();
767
773 [[nodiscard]] inline std::string toString() const;
774
775 private:
776 //----------------------------------------------
777 // Private implementation methods
778 //----------------------------------------------
779
781 void dispose();
782
784 [[noreturn]] void throwInvalidOperation() const;
785
786 //----------------------------------------------
787 // Private member variables
788 //----------------------------------------------
789
791 DynamicStringBuffer* m_buffer;
792
794 bool m_valid;
795 };
796
797 //=====================================================================
798 // StringBuilderPool class
799 //=====================================================================
800
867 class StringBuilderPool final
868 {
869 public:
870 //----------------------------------------------
871 // Pool statistics structure
872 //----------------------------------------------
873
876 {
879
882
885
888
890 double hitRate;
891 };
892
893 private:
894 //----------------------------------------------
895 // Construction
896 //----------------------------------------------
897
899 StringBuilderPool() = default;
900
901 public:
902 //----------------------------------------------
903 // Static factory methods
904 //----------------------------------------------
905
922 [[nodiscard]] static StringBuilderLease lease();
923
950 [[nodiscard]] static StringBuilderLease lease( size_t capacityHint );
951
952 //----------------------------
953 // Statistics methods
954 //----------------------------
955
960 static PoolStatistics stats() noexcept;
961
963 static void resetStats() noexcept;
964
965 //----------------------------
966 // Lease management
967 //----------------------------
968
973 static size_t clear();
974
979 static size_t size() noexcept;
980 };
981} // namespace nfx::string
982
983#include "nfx/detail/string/StringBuilder.inl"
High-performance dynamic string buffer with efficient memory management.
Iterator iterator
Type alias for iterator.
Iterator begin() noexcept
Get mutable iterator to beginning of buffer.
void append(std::string_view str)
Append string_view content to buffer.
bool isEmpty() const noexcept
Check if buffer is empty.
DynamicStringBuffer(const DynamicStringBuffer &other)
Copy constructor.
Iterator end() noexcept
Get mutable iterator to end of buffer.
char * data() noexcept
Get mutable pointer to buffer data.
void reserve(size_t newCapacity)
Reserve minimum capacity for buffer.
char value_type
Character type for iterator compatibility.
DynamicStringBuffer & operator=(DynamicStringBuffer &&other) noexcept
Move assignment operator.
void resize(size_t newSize)
Resize buffer to specified size.
DynamicStringBuffer & operator=(const DynamicStringBuffer &other)
Copy assignment operator.
~DynamicStringBuffer()=default
Destructor.
std::string toString() const
Convert buffer content to std::string.
void clear() noexcept
Clear buffer content without deallocating memory.
ConstIterator const_iterator
Type alias for const iterator.
DynamicStringBuffer(DynamicStringBuffer &&other) noexcept
Move constructor.
const char * ConstIterator
Immutable iterator type for buffer traversal.
char * Iterator
Mutable iterator type for buffer traversal.
size_t size() const noexcept
Get current buffer size in bytes.
std::string_view toStringView() const noexcept
Get string_view of buffer content.
size_t capacity() const noexcept
Get current buffer capacity in bytes.
High-performance string builder with fluent interface and efficient memory management.
char * Iterator
Mutable iterator type for buffer traversal.
Iterator end()
Returns mutable iterator to end of character sequence.
StringBuilder & format(std::format_string< Args... > fmt, Args &&... args)
Format and append text using std::format.
ConstIterator const_iterator
Type alias for const iterator.
const char * ConstIterator
Immutable iterator type for buffer traversal.
void append(std::string_view str)
Appends string_view contents to the buffer efficiently.
StringBuilder(StringBuilder &&) noexcept=delete
Move constructor.
StringBuilder(const StringBuilder &)=default
Copy constructor.
char value_type
Character type for iterator compatibility.
void resize(size_t newSize)
Resizes buffer to specified character count.
size_t length() const noexcept
Returns current buffer size in characters.
Iterator begin()
Returns mutable iterator to beginning of character sequence.
Iterator iterator
Type alias for iterator.
StringBuilder()=delete
Default constructor.
RAII lease wrapper for pooled StringBuilder buffers with automatic resource management.
std::string toString() const
Converts buffer contents to std::string.
StringBuilderLease & operator=(const StringBuilderLease &)=delete
Copy assignment operator.
StringBuilderLease(const StringBuilderLease &)=delete
Copy constructor.
StringBuilderLease()=delete
Default constructor.
StringBuilderLease & operator=(StringBuilderLease &&other) noexcept
Move assignment operator.
DynamicStringBuffer & buffer()
Provides direct access to underlying memory buffer.
StringBuilderLease(StringBuilderLease &&other) noexcept
Move constructor.
StringBuilder create()
Creates StringBuilder wrapper for buffer manipulation.
static StringBuilderLease lease(size_t capacityHint)
Creates a new StringBuilder lease with pre-allocated capacity hint.
static size_t clear()
Clears all buffers from the pool and returns the count of cleared buffers.
static PoolStatistics stats() noexcept
Gets current pool statistics.
static void resetStats() noexcept
Resets pool statistics.
static StringBuilderLease lease()
Creates a new StringBuilder lease with an optimally sourced memory buffer.
static size_t size() noexcept
Gets current number of buffers stored in the pool.
Pool performance statistics for external access.
uint64_t dynamicStringBufferPoolHits
Number of successful buffer retrievals from shared cross-thread pool.
uint64_t totalRequests
Total number of buffer requests made to the pool.
double hitRate
Cache hit rate as a percentage (0.0 to 1.0).
uint64_t newAllocations
Number of new buffer allocations when pools were empty.
uint64_t threadLocalHits
Number of successful buffer retrievals from thread-local cache.