StringList.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. void StringList::destroy(Allocator alloc)
  8. {
  9. auto it = Base::getBegin();
  10. auto endit = Base::getEnd();
  11. for(; it != endit; ++it)
  12. {
  13. (*it).destroy(alloc);
  14. }
  15. Base::destroy(alloc);
  16. }
  17. void StringList::join(Allocator alloc, const CString& separator, String& out) const
  18. {
  19. StringAuto outl(alloc);
  20. join(separator, outl);
  21. out = std::move(outl);
  22. }
  23. void StringList::join(const CString& separator, StringAuto& out) const
  24. {
  25. if(Base::isEmpty())
  26. {
  27. return;
  28. }
  29. // Count the characters
  30. const I sepLen = separator.getLength();
  31. I charCount = 0;
  32. for(const String& str : *this)
  33. {
  34. charCount += str.getLength() + sepLen;
  35. }
  36. charCount -= sepLen; // Remove last separator
  37. ANKI_ASSERT(charCount > 0);
  38. // Allocate
  39. out.create('?', charCount);
  40. // Append to output
  41. Char* to = &out[0];
  42. typename Base::ConstIterator it = Base::getBegin();
  43. for(; it != Base::getEnd(); it++)
  44. {
  45. const String& from = *it;
  46. memcpy(to, &from[0], from.getLength() * sizeof(Char));
  47. to += from.getLength();
  48. if(it != Base::end() - 1)
  49. {
  50. memcpy(to, &separator[0], sepLen * sizeof(Char));
  51. to += sepLen;
  52. }
  53. }
  54. }
  55. void StringList::splitString(Allocator alloc, const CString& s, const Char separator, Bool keepEmpty)
  56. {
  57. ANKI_ASSERT(Base::isEmpty());
  58. const Char* begin = &s[0];
  59. const Char* end = begin;
  60. while(1)
  61. {
  62. if(*end == '\0')
  63. {
  64. if(begin < end)
  65. {
  66. Base::emplaceBack(alloc);
  67. String str;
  68. str.create(alloc, begin, end);
  69. Base::getBack() = std::move(str);
  70. }
  71. break;
  72. }
  73. else if(*end == separator)
  74. {
  75. if(begin < end)
  76. {
  77. Base::emplaceBack(alloc);
  78. String str;
  79. str.create(alloc, begin, end);
  80. Base::getBack() = std::move(str);
  81. begin = end + 1;
  82. }
  83. else
  84. {
  85. if(keepEmpty)
  86. {
  87. Base::emplaceBack(alloc);
  88. }
  89. ++begin;
  90. }
  91. }
  92. ++end;
  93. }
  94. }
  95. void StringList::sortAll(const Sort method)
  96. {
  97. if(method == Sort::ASCENDING)
  98. {
  99. Base::sort([](const String& a, const String& b) {
  100. return a < b;
  101. });
  102. }
  103. else
  104. {
  105. ANKI_ASSERT(method == Sort::DESCENDING);
  106. Base::sort([](const String& a, const String& b) {
  107. return a < b;
  108. });
  109. }
  110. }
  111. I StringList::getIndexOf(const CString& value) const
  112. {
  113. U pos = 0;
  114. for(auto it = Base::getBegin(); it != Base::getEnd(); ++it)
  115. {
  116. if(*it == value)
  117. {
  118. break;
  119. }
  120. ++pos;
  121. }
  122. return (pos == Base::getSize()) ? -1 : pos;
  123. }
  124. } // end namespace anki