StringList.inl.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Util/StringList.h>
  6. namespace anki {
  7. template<typename TMemoryPool>
  8. template<typename TStringMemoryPool>
  9. void BaseStringList<TMemoryPool>::join(const CString& separator, BaseString<TStringMemoryPool>& out) const
  10. {
  11. if(Base::isEmpty())
  12. {
  13. return;
  14. }
  15. // Count the characters
  16. const I sepLen = separator.getLength();
  17. I charCount = 0;
  18. for(const auto& str : *this)
  19. {
  20. charCount += str.getLength() + sepLen;
  21. }
  22. charCount -= sepLen; // Remove last separator
  23. ANKI_ASSERT(charCount > 0);
  24. // Allocate
  25. out = std::move(BaseString<TStringMemoryPool>('?', charCount, out.getMemoryPool()));
  26. // Append to output
  27. Char* to = &out[0];
  28. typename Base::ConstIterator it = Base::getBegin();
  29. for(; it != Base::getEnd(); it++)
  30. {
  31. const auto& from = *it;
  32. memcpy(to, &from[0], from.getLength() * sizeof(Char));
  33. to += from.getLength();
  34. if(it != Base::end() - 1)
  35. {
  36. memcpy(to, &separator[0], sepLen * sizeof(Char));
  37. to += sepLen;
  38. }
  39. }
  40. }
  41. template<typename TMemoryPool>
  42. I BaseStringList<TMemoryPool>::getIndexOf(const CString& value) const
  43. {
  44. U pos = 0;
  45. for(auto it = Base::getBegin(); it != Base::getEnd(); ++it)
  46. {
  47. if(*it == value)
  48. {
  49. break;
  50. }
  51. ++pos;
  52. }
  53. return (pos == Base::getSize()) ? -1 : pos;
  54. }
  55. template<typename TMemoryPool>
  56. void BaseStringList<TMemoryPool>::sortAll(const Sort method)
  57. {
  58. if(method == Sort::kAscending)
  59. {
  60. Base::sort([](const StringType& a, const StringType& b) {
  61. return a < b;
  62. });
  63. }
  64. else
  65. {
  66. ANKI_ASSERT(method == Sort::kDescending);
  67. Base::sort([](const StringType& a, const StringType& b) {
  68. return a > b;
  69. });
  70. }
  71. }
  72. template<typename TMemoryPool>
  73. void BaseStringList<TMemoryPool>::splitString(const CString& s, const Char separator, Bool keepEmpty)
  74. {
  75. ANKI_ASSERT(Base::isEmpty());
  76. const Char* begin = &s[0];
  77. const Char* end = begin;
  78. while(1)
  79. {
  80. if(*end == '\0')
  81. {
  82. if(begin < end)
  83. {
  84. Base::emplaceBack(std::move(StringType(begin, end, Base::getMemoryPool())));
  85. }
  86. break;
  87. }
  88. else if(*end == separator)
  89. {
  90. if(begin < end)
  91. {
  92. Base::emplaceBack(StringType(begin, end, Base::getMemoryPool()));
  93. begin = end + 1;
  94. }
  95. else
  96. {
  97. if(keepEmpty)
  98. {
  99. Base::emplaceBack(Base::getMemoryPool());
  100. }
  101. ++begin;
  102. }
  103. }
  104. ++end;
  105. }
  106. }
  107. template<typename TMemoryPool>
  108. void BaseStringList<TMemoryPool>::pushBackSprintf(const Char* fmt, ...)
  109. {
  110. StringType str(Base::getMemoryPool());
  111. va_list args;
  112. va_start(args, fmt);
  113. str.sprintfInternal(fmt, args);
  114. va_end(args);
  115. Base::emplaceBack(std::move(str));
  116. }
  117. template<typename TMemoryPool>
  118. void BaseStringList<TMemoryPool>::pushFrontSprintf(const Char* fmt, ...)
  119. {
  120. StringType str(Base::getMemoryPool());
  121. va_list args;
  122. va_start(args, fmt);
  123. str.sprintfInternal(fmt, args);
  124. va_end(args);
  125. Base::emplaceFront(std::move(str));
  126. }
  127. } // end namespace anki