jack06215

[Windows] fixed string buffer

Jul 17th, 2020 (edited)
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.83 KB | None | 0 0
  1. #pragma warning(disable:4996)
  2.  
  3. #include <array>
  4. #include <cassert>
  5. #include <stdarg.h> // va_list
  6. #define WIN32_LEAN_AND_MEAN
  7. #include <windows.h> // _vsnprintf_s
  8.  
  9. // just to show that there's not a single heap allocation involved in this code...
  10. void* operator new (size_t) { throw "Unexpected!"; }
  11. void operator delete (void*) { throw "Unexpected!"; }
  12.  
  13. /// A fixed-size string buffer (typically stack-allocated).
  14. template <size_t N>
  15. class String_buf
  16. {
  17. public:
  18.  
  19.     /// Constructs from a C string if provided, or sets to "" if nullptr passed.
  20.     String_buf(const char* cstr = nullptr)
  21.     {
  22.         static_assert(N > 0, "String_buf of zero size!");
  23.  
  24.         if (cstr)
  25.         {
  26.             assert(strlen(cstr) < N && "String_buf too small!");
  27.             strcpy(_data.data(), cstr);
  28.         }
  29.         else
  30.         {
  31.             _data[0] = '\0';
  32.         }
  33.     }
  34.  
  35.     /// Constructs from a String_buf of a bigger or equal static size.
  36.     template <size_t M>
  37.     String_buf(const String_buf<M>& rhs)
  38.     {
  39.         static_assert(M <= N, "String_buf too small!");
  40.         strcpy(_data.data(), rhs.cstr());
  41.     }
  42.  
  43.     /// Copies from a C string if provided, or sets to "" if nullptr passed.
  44.     String_buf& operator = (const char* cstr)
  45.     {
  46.         static_assert(N > 0, "String_buf of zero size!");
  47.  
  48.         if (cstr)
  49.         {
  50.             assert(strlen(cstr) < N && "String_buf too small!");
  51.             strcpy(_data.data(), cstr);
  52.         }
  53.         else
  54.         {
  55.             _data[0] = '\0';
  56.         }
  57.  
  58.         return *this;
  59.     }
  60.  
  61.     /// Copies from a String_buf of a bigger or equal static size.
  62.     template <size_t M>
  63.     String_buf& operator = (const String_buf<M>& rhs)
  64.     {
  65.         static_assert(M <= N, "String_buf too small!");
  66.         strcpy(_data.data(), rhs.cstr());
  67.         return *this;
  68.     }
  69.  
  70.     /// Returns a C string (always valid).
  71.     const char* cstr() const { return _data.data(); }
  72.  
  73.     /// Formats a string in a good old printf style.
  74.     void format(const char* format, ...)
  75.     {
  76.         va_list args;
  77.         va_start(args, format);
  78.         // if truncated, '\0' is automatically appended
  79.         _vsnprintf_s(_data.data(), N, _TRUNCATE, format, args);
  80.         va_end(args);
  81.     }
  82.  
  83. private:
  84.  
  85.     std::array<char, N> _data;
  86. };
  87.  
  88. int main()
  89. {
  90.     String_buf<8> str1 = "foo";
  91.     String_buf<6> str2 = "bar";
  92.     str1 = "foo2";
  93.     str2 = "bar2";
  94.     str1 = str2;
  95.     //str2 = str1; // doesn't compile, static size of 'str1'<8> is bigger than 'str2'<6>!
  96.     str2 = str1.cstr(); // this would assert if the actual size of 'str1'(4) is bigger than 'str2'<6>
  97.     printf("%s %s\n", str1.cstr(), str2.cstr());
  98.  
  99.     String_buf<20> msg;
  100.     msg.format("%s %s 0123456789", "Hello", "World!"); // truncated to 'Hello World! 012345'
  101.     printf("'%s'\n", msg.cstr());
  102.  
  103.     return 0;
  104. }
Add Comment
Please, Sign In to add comment