Last active
October 30, 2015 22:52
-
-
Save facontidavide/782fab7c706f4fd0539f to your computer and use it in GitHub Desktop.
StringBuffer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
(c) 2013 +++ Filip Stoklas, aka FipS, http://www.4FipS.com +++ | |
THIS CODE IS FREE - LICENSED UNDER THE MIT LICENSE | |
ARTICLE URL: http://forums.4fips.com/viewtopic.php?f=3&t=1075 | |
*/ | |
#include <array> | |
#include <cassert> | |
#include <stdarg.h> // va_list | |
#define WIN32_LEAN_AND_MEAN | |
#include <windows.h> // _vsnprintf_s | |
// just to show that there's not a single heap allocation involved in this code... | |
void * operator new (size_t) { throw "Unexpected!"; } | |
void operator delete (void *) { throw "Unexpected!"; } | |
/// A fixed-size string buffer (typically stack-allocated). | |
template <size_t N> | |
class String_buf | |
{ | |
public: | |
/// Constructs from a C string if provided, or sets to "" if nullptr passed. | |
String_buf(const char *cstr = nullptr) | |
{ | |
static_assert(N > 0, "String_buf of zero size!"); | |
if(cstr) | |
{ | |
assert(strlen(cstr) < N && "String_buf too small!"); | |
strcpy(_data.data(), cstr); | |
} | |
else | |
{ | |
_data[0] = '\0'; | |
} | |
} | |
/// Constructs from a String_buf of a bigger or equal static size. | |
template <size_t M> | |
String_buf(const String_buf<M> &rhs) | |
{ | |
static_assert(M <= N, "String_buf too small!"); | |
strcpy(_data.data(), rhs.cstr()); | |
} | |
/// Copies from a C string if provided, or sets to "" if nullptr passed. | |
String_buf & operator = (const char *cstr) | |
{ | |
static_assert(N > 0, "String_buf of zero size!"); | |
if(cstr) | |
{ | |
assert(strlen(cstr) < N && "String_buf too small!"); | |
strcpy(_data.data(), cstr); | |
} | |
else | |
{ | |
_data[0] = '\0'; | |
} | |
return *this; | |
} | |
/// Copies from a String_buf of a bigger or equal static size. | |
template <size_t M> | |
String_buf & operator = (const String_buf<M> &rhs) | |
{ | |
static_assert(M <= N, "String_buf too small!"); | |
strcpy(_data.data(), rhs.cstr()); | |
return *this; | |
} | |
/// Returns a C string (always valid). | |
const char * cstr() const { return _data.data(); } | |
/// Formats a string in a good old printf style. | |
void format(const char *format, ...) | |
{ | |
va_list args; | |
va_start(args, format); | |
// if truncated, '\0' is automatically appended | |
_vsnprintf_s(_data.data(), N, _TRUNCATE, format, args); | |
va_end(args); | |
} | |
private: | |
std::array<char, N> _data; | |
}; | |
int main() | |
{ | |
String_buf<8> str1 = "foo"; | |
String_buf<6> str2 = "bar"; | |
str1 = "foo2"; | |
str2 = "bar2"; | |
str1 = str2; | |
//str2 = str1; // doesn't compile, static size of 'str1'<8> is bigger than 'str2'<6>! | |
str2 = str1.cstr(); // this would assert if the actual size of 'str1'(4) is bigger than 'str2'<6> | |
printf("%s %s\n", str1.cstr(), str2.cstr()); | |
String_buf<20> msg; | |
msg.format("%s %s 0123456789", "Hello", "World!"); // truncated to 'Hello World! 012345' | |
printf("'%s'\n", msg.cstr()); | |
return 0; | |
} | |
// Compiled under Visual C++ 2012, output: | |
// bar2 bar2 | |
// 'Hello World! 012345' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment