StringList.inl.h 3.5 KB

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