StringList.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Copyright (C) 2009-2021, 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. {
  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) { return a < b; });
  101. }
  102. else
  103. {
  104. ANKI_ASSERT(method == Sort::DESCENDING);
  105. Base::sort([](const String& a, const String& b) { return a < b; });
  106. }
  107. }
  108. I StringList::getIndexOf(const CString& value) const
  109. {
  110. U pos = 0;
  111. for(auto it = Base::getBegin(); it != Base::getEnd(); ++it)
  112. {
  113. if(*it == value)
  114. {
  115. break;
  116. }
  117. ++pos;
  118. }
  119. return (pos == Base::getSize()) ? -1 : pos;
  120. }
  121. } // end namespace anki