Advertisement
Guest User

QTS #07 - Improved attempt

a guest
Jul 16th, 2015
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.25 KB | None | 0 0
  1. #include <Windows.h>
  2. #include <vector>
  3.  
  4. #include <iostream> //std::cout, std::endl
  5.  
  6. /////////////////////////////////////////////////////////////////
  7.  
  8. /*
  9. /   The class is templates, put both declaration and definition in headers
  10. /   (either both in the same file or #include the template header after the declaration)
  11. /
  12. /   !There might be errors, haven't slept the night :/
  13. /
  14. /   *required includes:
  15. /       - vector
  16. /       - windows.h
  17.  
  18. */
  19.  
  20. // ------------- Declaration -------------
  21.  
  22. template <typename _TValueType = TCHAR> //Default it with TCHAR
  23. class C_Strings
  24. {
  25. public:
  26.     using value_type = std::remove_reference <
  27.         std::remove_const<_TValueType>::type > ::type;
  28.     using result_type = value_type;
  29.  
  30. private:
  31.  
  32.     std::vector<result_type*> m_Queue;
  33.  
  34.     result_type *AddToQueue(value_type *pValue);
  35.     result_type *GetLastItem();
  36.  
  37. public:
  38.  
  39.     C_Strings() = default;
  40.     ~C_Strings() {
  41.         this->ClearQueue();
  42.     }
  43.  
  44.     //Returns the number of elements it deleted
  45.     size_t ClearQueue();
  46.  
  47.     //Formats a new string
  48.     result_type *Format(value_type *fmt, ...);
  49.  
  50.     //Formats and appends to an existing string (allocates a new object, doesn't free the old one)
  51.     result_type *FormatAppend(value_type *destination, value_type *fmt, ...);
  52. };
  53.  
  54. // ------------- Definition -------------
  55.  
  56. template <typename _TValueType>
  57. auto C_Strings<_TValueType>::AddToQueue(value_type *pValue) -> result_type * {
  58.     this->m_Queue.push_back(pValue);
  59.     return pValue;
  60. }
  61.  
  62. template <typename _TValueType>
  63. auto C_Strings<_TValueType>::GetLastItem() -> result_type * {
  64.     return this->m_Queue.back();
  65. }
  66.  
  67. template <typename _TValueType>
  68. size_t C_Strings<_TValueType>::ClearQueue() {
  69.     size_t counter = 0;
  70.     for(result_type *p : m_Queue) {
  71.         free(p);
  72.         counter++;
  73.     }
  74.     return counter;
  75. }
  76.  
  77. template <typename _TValueType>
  78. auto C_Strings<_TValueType>::Format(value_type *fmt, ...) -> result_type * {
  79.     va_list va;
  80.     va_start(va, fmt);
  81.  
  82.     size_t requiredBufferSize = static_cast<size_t>(vsnprintf(nullptr, 0, fmt, va)) + 1;
  83.  
  84.     if(requiredBufferSize) {
  85.         vsnprintf(this->AddToQueue(static_cast<value_type*>(memset(new value_type[requiredBufferSize], 0, requiredBufferSize))),
  86.                   requiredBufferSize, fmt, va);
  87.         return this->GetLastItem();
  88.     }
  89.  
  90.     return nullptr;
  91. }
  92.  
  93. template <typename _TValueType>
  94. auto C_Strings<_TValueType>::FormatAppend(value_type *destination, value_type *fmt, ...) -> result_type * {
  95.     va_list va;
  96.     va_start(va, fmt);
  97.  
  98.     size_t existingBufferSize = strlen(destination);
  99.     size_t requiredBufferSize = static_cast<size_t>(vsnprintf(nullptr, 0, fmt, va)) + 1;
  100.  
  101.     if(requiredBufferSize) {
  102.         this->AddToQueue(static_cast<value_type*>(memset(new value_type[existingBufferSize + requiredBufferSize], 0, existingBufferSize + requiredBufferSize)));
  103.         value_type *pBuffer = this->GetLastItem();
  104.         value_type *pFmtBuffer = pBuffer + existingBufferSize;
  105.  
  106.         strncpy(pBuffer, destination, existingBufferSize);
  107.         vsnprintf(pFmtBuffer, requiredBufferSize, fmt, va);
  108.  
  109.         return pBuffer;
  110.     }
  111.  
  112.     return nullptr;
  113. }
  114.  
  115. ///////////////////////////////////////////////////////
  116.  
  117. //! Simple tests.
  118. int main() {
  119.  
  120.     C_Strings <> x;
  121.  
  122.     std::cout << x.Format("Fmt: %s %d", "test", 1337) << std::endl;
  123.     std::cout << x.FormatAppend("Append ", "Fmt: %s %d", "test", 1337) << std::endl;
  124.  
  125.     system("PAUSE");
  126.  
  127. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement