usetiter.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // © 2016 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. /*
  4. **********************************************************************
  5. * Copyright (c) 2002-2006, International Business Machines
  6. * Corporation and others. All Rights Reserved.
  7. **********************************************************************
  8. */
  9. #include "unicode/usetiter.h"
  10. #include "unicode/uniset.h"
  11. #include "unicode/unistr.h"
  12. #include "uvector.h"
  13. U_NAMESPACE_BEGIN
  14. UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UnicodeSetIterator)
  15. /**
  16. * Create an iterator
  17. * @param set set to iterate over
  18. */
  19. UnicodeSetIterator::UnicodeSetIterator(const UnicodeSet& uSet) {
  20. cpString = nullptr;
  21. reset(uSet);
  22. }
  23. /**
  24. * Create an iterator. Convenience for when the contents are to be set later.
  25. */
  26. UnicodeSetIterator::UnicodeSetIterator() {
  27. this->set = nullptr;
  28. cpString = nullptr;
  29. reset();
  30. }
  31. UnicodeSetIterator::~UnicodeSetIterator() {
  32. delete cpString;
  33. }
  34. /**
  35. * Returns the next element in the set.
  36. * @return true if there was another element in the set.
  37. * if so, if codepoint == IS_STRING, the value is a string in the string field
  38. * else the value is a single code point in the codepoint field.
  39. * <br>You are guaranteed that the codepoints are in sorted order, and the strings are in sorted order,
  40. * and that all code points are returned before any strings are returned.
  41. * <br>Note also that the codepointEnd is undefined after calling this method.
  42. */
  43. UBool UnicodeSetIterator::next() {
  44. if (nextElement <= endElement) {
  45. codepoint = codepointEnd = nextElement++;
  46. string = nullptr;
  47. return true;
  48. }
  49. if (range < endRange) {
  50. loadRange(++range);
  51. codepoint = codepointEnd = nextElement++;
  52. string = nullptr;
  53. return true;
  54. }
  55. if (nextString >= stringCount) return false;
  56. codepoint = (UChar32)IS_STRING; // signal that value is actually a string
  57. string = (const UnicodeString*) set->strings->elementAt(nextString++);
  58. return true;
  59. }
  60. /**
  61. * @return true if there was another element in the set.
  62. * if so, if codepoint == IS_STRING, the value is a string in the string field
  63. * else the value is a range of codepoints in the <codepoint, codepointEnd> fields.
  64. * <br>Note that the codepoints are in sorted order, and the strings are in sorted order,
  65. * and that all code points are returned before any strings are returned.
  66. * <br>You are guaranteed that the ranges are in sorted order, and the strings are in sorted order,
  67. * and that all ranges are returned before any strings are returned.
  68. * <br>You are also guaranteed that ranges are disjoint and non-contiguous.
  69. * <br>Note also that the codepointEnd is undefined after calling this method.
  70. */
  71. UBool UnicodeSetIterator::nextRange() {
  72. string = nullptr;
  73. if (nextElement <= endElement) {
  74. codepointEnd = endElement;
  75. codepoint = nextElement;
  76. nextElement = endElement+1;
  77. return true;
  78. }
  79. if (range < endRange) {
  80. loadRange(++range);
  81. codepointEnd = endElement;
  82. codepoint = nextElement;
  83. nextElement = endElement+1;
  84. return true;
  85. }
  86. if (nextString >= stringCount) return false;
  87. codepoint = (UChar32)IS_STRING; // signal that value is actually a string
  88. string = (const UnicodeString*) set->strings->elementAt(nextString++);
  89. return true;
  90. }
  91. /**
  92. *@param set the set to iterate over. This allows reuse of the iterator.
  93. */
  94. void UnicodeSetIterator::reset(const UnicodeSet& uSet) {
  95. this->set = &uSet;
  96. reset();
  97. }
  98. /**
  99. * Resets to the start, to allow the iteration to start over again.
  100. */
  101. void UnicodeSetIterator::reset() {
  102. if (set == nullptr) {
  103. // Set up indices to empty iteration
  104. endRange = -1;
  105. stringCount = 0;
  106. } else {
  107. endRange = set->getRangeCount() - 1;
  108. stringCount = set->stringsSize();
  109. }
  110. range = 0;
  111. endElement = -1;
  112. nextElement = 0;
  113. if (endRange >= 0) {
  114. loadRange(range);
  115. }
  116. nextString = 0;
  117. string = nullptr;
  118. }
  119. void UnicodeSetIterator::loadRange(int32_t iRange) {
  120. nextElement = set->getRangeStart(iRange);
  121. endElement = set->getRangeEnd(iRange);
  122. }
  123. const UnicodeString& UnicodeSetIterator::getString() {
  124. if (string==nullptr && codepoint!=(UChar32)IS_STRING) {
  125. if (cpString == nullptr) {
  126. cpString = new UnicodeString();
  127. }
  128. if (cpString != nullptr) {
  129. cpString->setTo((UChar32)codepoint);
  130. }
  131. string = cpString;
  132. }
  133. return *string;
  134. }
  135. U_NAMESPACE_END
  136. //eof