#pragma once #include "StringCommon.hpp" #ifndef SPRAWL_STRING_NO_STL_COMPAT # include <string> #endif #ifndef SPRAWL_STRINGBUILDER_FAVOR_SPEED_OVER_MEMORY # define SPRAWL_STRINGBUILDER_FAVOR_SPEED_OVER_MEMORY 1 #endif namespace sprawl { class String; class StringLiteral; class StringBuilder { public: StringBuilder(size_t startingBufferSize = 512, bool allowGrowth = true); StringBuilder& operator<<(signed char const elem); StringBuilder& operator<<(short const elem); StringBuilder& operator<<(int const elem); StringBuilder& operator<<(long int const elem); StringBuilder& operator<<(long long int const elem); StringBuilder& operator<<(unsigned char const elem); StringBuilder& operator<<(unsigned short const elem); StringBuilder& operator<<(unsigned int const elem); StringBuilder& operator<<(unsigned long int const elem); StringBuilder& operator<<(unsigned long long int const elem); StringBuilder& operator<<(float const elem); StringBuilder& operator<<(double const elem); StringBuilder& operator<<(long double const elem); StringBuilder& operator<<(void const* const elem); StringBuilder& operator<<(bool const elem); StringBuilder& operator<<(char const elem); StringBuilder& operator<<(char const* const elem); StringBuilder& operator<<(char* const elem); StringBuilder& operator<<(String const& elem); StringBuilder& operator<<(StringLiteral const& elem); #ifndef SPRAWL_STRING_NO_STL_COMPAT StringBuilder& operator<<(std::string const& elem); #endif void AppendElementToBuffer(signed char const elem, char const* const modifiers); void AppendElementToBuffer(short const elem, char const* const modifiers); void AppendElementToBuffer(int const elem, char const* const modifiers); void AppendElementToBuffer(long int const elem, char const* const modifiers); void AppendElementToBuffer(long long int const elem, char const* const modifiers); void AppendElementToBuffer(unsigned char const elem, char const* const modifiers); void AppendElementToBuffer(unsigned short const elem, char const* const modifiers); void AppendElementToBuffer(unsigned int const elem, char const* const modifiers); void AppendElementToBuffer(unsigned long int const elem, char const* const modifiers); void AppendElementToBuffer(unsigned long long int const elem, char const* const modifiers); void AppendElementToBuffer(float const elem, char const* const modifiers); void AppendElementToBuffer(double const elem, char const* const modifiers); void AppendElementToBuffer(long double const elem, char const* const modifiers); void AppendElementToBuffer(void const* const elem, char const* const modifiers); void AppendElementToBuffer(void* const elem, char const* const modifiers); void AppendElementToBuffer(bool const elem, char const* const modifiers); void AppendElementToBuffer(char const elem, char const* const modifiers); void AppendElementToBuffer(char const* const elem, char const* const modifiers); void AppendElementToBuffer(char* const elem, char const* const modifiers); void AppendElementToBuffer(String const& elem, char const* const modifiers); void AppendElementToBuffer(StringLiteral const& elem, char const* const modifiers); #ifndef SPRAWL_STRING_NO_STL_COMPAT void AppendElementToBuffer(std::string const& elem, char const* const modifiers); #endif template<typename T> void AppendElementToBuffer(T const& elem, char const* const /*modifiers*/, typename std::enable_if<!std::is_pointer<T>::value>::type* = 0) { *this << elem; } template<typename T> StringBuilder& operator<<(T const& elem) { *this << (void const* const)&elem; return *this; } template<typename T> void AppendElementToBuffer(T const& elem, char const* const modifiers, typename std::enable_if<std::is_pointer<T>::value>::type* = 0) { if(elem != nullptr && strchr(modifiers, 'p') == nullptr) { *this << *elem; } else { char buf[15]; sprintf(buf, "%%%sp", modifiers); checkedSnprintf_(buf, (void*)elem); } } String Str(); String TempStr(); ~StringBuilder(); size_t Size() { return m_pos; } void Reset() { m_pos = 0; m_bufferPos = m_buffer; m_remainingCapacity = m_bufferSize; } private: template<typename T> void checkedSnprintf_(char const* const pattern, T elem); void checkGrow_(size_t amount); static constexpr size_t staticBufferSize = SPRAWL_STATIC_STRING_SIZE; char m_staticBuffer[staticBufferSize]; char* m_dynamicBuffer; char* m_buffer; size_t m_bufferSize; size_t m_pos; char* m_bufferPos; size_t m_remainingCapacity; bool m_allowGrowth; }; }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#6 | 19906 | ShadauxCat |
- Added tag, compile time string type - Since tag requires visual studio 2015, removed compatibility code for earlier versions of visual studio - Improved compiler detection - Added endianness detection - Added template if/else helper - Fixed bug with murmur3 64 bit - Added seed argument for murmur3 #review-19907 |
||
#5 | 16052 | ShadauxCat |
- Changed default block size for concurrent queue to a more reasonable value - Changed some memory orders to memory_order_seq_cst when they don't actually need to be that to get around a bug in visual studio 2013 - debug builds assert when memory_order_acq_rel is used for a compare_exchange_strong (this is a standard library bug and is fixed in VS2015) - Added Event API - events are an alternative to condition variables that do not require a mutex and are guaranteed not to miss any signals, even if the signal comes while the thread is not listening for it. Unlike condition variables, however, they do not support broadcasting (and in fact, in general, are not safe to use with multiple threads listening for the same event simultaneously - though notifying on the same event is fine) - Rewrote ThreadManager around ConcurrentQueue and Event API so it is now lock-free. Also improved some behaviors of the staged thread manager operation so it now supports tasks that can be run on multiple stages via a bitmask. - Fixed an issue where the Coroutine copy constructor was calling the std::function constructor instead and another where initializing with a stack might try to call the wrong constructor and vice-versa - Fixed Coroutine never calling munmap() on its stack in linux and causing a memory leak - Added default arguments to time functions - Attempted to fix some issues with BinaryTree. Fixed some but not all. It's currently not suitable for use, sadly. - Logging Improvements: - - Added thread ID to logging - - Fixed some issues with category handlers - - Added backtraces - - Added the following additional log macros: - - - LOG_IF - - - LOG_EVERY_N - - - LOG_FIRST_N - - - LOG_IF_EVERY_N - - - LOG_IF_FIRST_N - - - LOG_ASSERT - - Added the ability to set extra info callbacks to get data such as script backtraces - - Removed the thread-related handlers and replaced them with RunHandler_Threaded and RunHandler_ThreadManager, which will enable any passed-in handler to be run in a threaded fashion - Removed StaticPoolAllocator and renamed DynamicPoolAllocator to PoolAllocator; adjusted unit tests accordingly - PoolAllocator now allocates its pool with mmap and VirtualAlloc, rather than with malloc - Fixed a bug with Vector copy assignment operator - Improved performance of StringBuilder considerably for cases where there are no modifier strings - Removed Copy-On-Write behavior of JSONToken as it was broken; copies are now performed with explicit DeepCopy() and ShallowCopy() functions - Fixed some parser bugs with JSONToken - Added iteration to JSONToken to iterate its children - Fixed crash when reading a negative number of bytes from a file - Changed StringBuilder to favor speed instead of memory by default - Added some performance unit tests for JSON token #review-16053 |
||
#4 | 14833 | ShadauxCat |
First checkin of logging module. Also fixes the following issues: -Added UpperBound() and LowerBound() to BinaryTree and created appropriate unit tests -Added Sync() to ThreadManager to force it to run all tasks to completion and not return until it has no tasks left -Fixed a bug in String::format() where a non-numeric value inside {} would be treated as an empty {}; it now simply prints whatever the value was. (i.e., "{blah}".format(foo) simply returns "{blah}") -Added Reset() to sprawl::StringBuilder -Disabled the switch-enum warning flag in gcc because it's stupid and ridiculous that a default case doesn't shut it up -Made sprawl::Mutex movable. This may turn out to be a bad idea but it enabled keeping them in a map. -Fixed a name collission between HashMap and BinaryTree; both defined sprawl::collections::detail::UnderlyingType and ::MethodType. Prefixed the ones in BinaryTree with "Tree". This isn't the best solution, but it works for now. #review-14834 |
||
#3 | 14822 | ShadauxCat |
Last batch of filesystem code for now, added MakeSymlink and GetPid, removed other todo functions for the time being. Also fixed some bugs: -Linux IsLink() implementation not using lstat = broken -File::IsClosed() would crash if file were created via default constructor or null handle -Remove() and RmDir() on Windows were inconsistent with Linux - in Linux all symlinks are removed with Remove() even if they point to directories. Forced windows to work the same way. -Asked RmTree to please not descend into symbolic links to directories, but just to remove them, thanks. -Removed starting \\?\ from result of RealPath() on Windows -Fixed IsFile() on Windows just not working - assuming anything that's not a directory is a file now. -Fixed StringBuilder only printing the first character if you passed it type char* instead of type char const* #review-14823 |
||
#2 | 13650 | ShadauxCat |
- Windows implementations of thread and time libraries - Added coroutines - Added some more unit tests, fixed some unit tests in windows environments - Fixed an issue where multi threading was not properly detected on Linux - Fixed the makefiles to build with threading by default on linux - Changed the pool allocator to use thread-local pools instead of locking mutexes - Fixed output of sprawl::string in the StringBuilder library to take length into account - Added string builder options for StringLiteral - Added thread local implementation #review |
||
#1 | 11496 | ShadauxCat | Initial checkin: Current states for csbuild and libSprawl |