StringList.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // Copyright (C) 2009-2022, 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. #include <cstdarg>
  7. namespace anki {
  8. void StringList::destroy(Allocator alloc)
  9. {
  10. auto it = Base::getBegin();
  11. auto endit = Base::getEnd();
  12. for(; it != endit; ++it)
  13. {
  14. (*it).destroy(alloc);
  15. }
  16. Base::destroy(alloc);
  17. }
  18. void StringList::join(Allocator alloc, const CString& separator, String& out) const
  19. {
  20. StringAuto outl(alloc);
  21. join(separator, outl);
  22. out = std::move(outl);
  23. }
  24. void StringList::join(const CString& separator, StringAuto& out) const
  25. {
  26. if(Base::isEmpty())
  27. {
  28. return;
  29. }
  30. // Count the characters
  31. const I sepLen = separator.getLength();
  32. I charCount = 0;
  33. for(const String& str : *this)
  34. {
  35. charCount += str.getLength() + sepLen;
  36. }
  37. charCount -= sepLen; // Remove last separator
  38. ANKI_ASSERT(charCount > 0);
  39. // Allocate
  40. out.create('?', charCount);
  41. // Append to output
  42. Char* to = &out[0];
  43. typename Base::ConstIterator it = Base::getBegin();
  44. for(; it != Base::getEnd(); it++)
  45. {
  46. const String& from = *it;
  47. memcpy(to, &from[0], from.getLength() * sizeof(Char));
  48. to += from.getLength();
  49. if(it != Base::end() - 1)
  50. {
  51. memcpy(to, &separator[0], sepLen * sizeof(Char));
  52. to += sepLen;
  53. }
  54. }
  55. }
  56. void StringList::splitString(Allocator alloc, const CString& s, const Char separator, Bool keepEmpty)
  57. {
  58. ANKI_ASSERT(Base::isEmpty());
  59. const Char* begin = &s[0];
  60. const Char* end = begin;
  61. while(1)
  62. {
  63. if(*end == '\0')
  64. {
  65. if(begin < end)
  66. {
  67. Base::emplaceBack(alloc);
  68. String str;
  69. str.create(alloc, begin, end);
  70. Base::getBack() = std::move(str);
  71. }
  72. break;
  73. }
  74. else if(*end == separator)
  75. {
  76. if(begin < end)
  77. {
  78. Base::emplaceBack(alloc);
  79. String str;
  80. str.create(alloc, begin, end);
  81. Base::getBack() = std::move(str);
  82. begin = end + 1;
  83. }
  84. else
  85. {
  86. if(keepEmpty)
  87. {
  88. Base::emplaceBack(alloc);
  89. }
  90. ++begin;
  91. }
  92. }
  93. ++end;
  94. }
  95. }
  96. void StringList::sortAll(const Sort method)
  97. {
  98. if(method == Sort::ASCENDING)
  99. {
  100. Base::sort([](const String& a, const String& b) {
  101. return a < b;
  102. });
  103. }
  104. else
  105. {
  106. ANKI_ASSERT(method == Sort::DESCENDING);
  107. Base::sort([](const String& a, const String& b) {
  108. return a < b;
  109. });
  110. }
  111. }
  112. I StringList::getIndexOf(const CString& value) const
  113. {
  114. U pos = 0;
  115. for(auto it = Base::getBegin(); it != Base::getEnd(); ++it)
  116. {
  117. if(*it == value)
  118. {
  119. break;
  120. }
  121. ++pos;
  122. }
  123. return (pos == Base::getSize()) ? -1 : pos;
  124. }
  125. void StringList::pushBackSprintf(Allocator alloc, const Char* fmt, ...)
  126. {
  127. String str;
  128. va_list args;
  129. va_start(args, fmt);
  130. str.sprintf(alloc, fmt, args);
  131. va_end(args);
  132. Base::emplaceBack(alloc);
  133. Base::getBack() = std::move(str);
  134. }
  135. void StringList::pushFrontSprintf(Allocator alloc, const Char* fmt, ...)
  136. {
  137. String str;
  138. va_list args;
  139. va_start(args, fmt);
  140. str.sprintf(alloc, fmt, args);
  141. va_end(args);
  142. Base::emplaceFront(alloc);
  143. Base::getFront() = std::move(str);
  144. }
  145. void StringListAuto::pushBackSprintf(const Char* fmt, ...)
  146. {
  147. String str;
  148. va_list args;
  149. va_start(args, fmt);
  150. str.sprintf(m_alloc, fmt, args);
  151. va_end(args);
  152. Base::emplaceBack(m_alloc);
  153. Base::getBack() = std::move(str);
  154. }
  155. void StringListAuto::pushFrontSprintf(const Char* fmt, ...)
  156. {
  157. String str;
  158. va_list args;
  159. va_start(args, fmt);
  160. str.sprintf(m_alloc, fmt, args);
  161. va_end(args);
  162. Base::emplaceFront(m_alloc);
  163. Base::getFront() = std::move(str);
  164. }
  165. } // end namespace anki