alphaindex.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  1. // © 2016 and later: Unicode, Inc. and others.
  2. // License & terms of use: http://www.unicode.org/copyright.html
  3. /*
  4. *******************************************************************************
  5. *
  6. * Copyright (C) 2011-2014 International Business Machines
  7. * Corporation and others. All Rights Reserved.
  8. *
  9. *******************************************************************************
  10. */
  11. #ifndef INDEXCHARS_H
  12. #define INDEXCHARS_H
  13. #include "unicode/utypes.h"
  14. #if U_SHOW_CPLUSPLUS_API
  15. #include "unicode/uobject.h"
  16. #include "unicode/locid.h"
  17. #include "unicode/unistr.h"
  18. #if !UCONFIG_NO_COLLATION
  19. /**
  20. * \file
  21. * \brief C++ API: Index Characters
  22. */
  23. U_CDECL_BEGIN
  24. /**
  25. * Constants for Alphabetic Index Label Types.
  26. * The form of these enum constants anticipates having a plain C API
  27. * for Alphabetic Indexes that will also use them.
  28. * @stable ICU 4.8
  29. */
  30. typedef enum UAlphabeticIndexLabelType {
  31. /**
  32. * Normal Label, typically the starting letter of the names
  33. * in the bucket with this label.
  34. * @stable ICU 4.8
  35. */
  36. U_ALPHAINDEX_NORMAL = 0,
  37. /**
  38. * Underflow Label. The bucket with this label contains names
  39. * in scripts that sort before any of the bucket labels in this index.
  40. * @stable ICU 4.8
  41. */
  42. U_ALPHAINDEX_UNDERFLOW = 1,
  43. /**
  44. * Inflow Label. The bucket with this label contains names
  45. * in scripts that sort between two of the bucket labels in this index.
  46. * Inflow labels are created when an index contains normal labels for
  47. * multiple scripts, and skips other scripts that sort between some of the
  48. * included scripts.
  49. * @stable ICU 4.8
  50. */
  51. U_ALPHAINDEX_INFLOW = 2,
  52. /**
  53. * Overflow Label. The bucket with this label contains names in scripts
  54. * that sort after all of the bucket labels in this index.
  55. * @stable ICU 4.8
  56. */
  57. U_ALPHAINDEX_OVERFLOW = 3
  58. } UAlphabeticIndexLabelType;
  59. struct UHashtable;
  60. U_CDECL_END
  61. U_NAMESPACE_BEGIN
  62. // Forward Declarations
  63. class BucketList;
  64. class Collator;
  65. class RuleBasedCollator;
  66. class StringEnumeration;
  67. class UnicodeSet;
  68. class UVector;
  69. /**
  70. * AlphabeticIndex supports the creation of a UI index appropriate for a given language.
  71. * It can support either direct use, or use with a client that doesn't support localized collation.
  72. * The following is an example of what an index might look like in a UI:
  73. *
  74. * <pre>
  75. * <b>... A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ...</b>
  76. *
  77. * <b>A</b>
  78. * Addison
  79. * Albertson
  80. * Azensky
  81. * <b>B</b>
  82. * Baker
  83. * ...
  84. * </pre>
  85. *
  86. * The class can generate a list of labels for use as a UI "index", that is, a list of
  87. * clickable characters (or character sequences) that allow the user to see a segment
  88. * (bucket) of a larger "target" list. That is, each label corresponds to a bucket in
  89. * the target list, where everything in the bucket is greater than or equal to the character
  90. * (according to the locale's collation). Strings can be added to the index;
  91. * they will be in sorted order in the right bucket.
  92. * <p>
  93. * The class also supports having buckets for strings before the first (underflow),
  94. * after the last (overflow), and between scripts (inflow). For example, if the index
  95. * is constructed with labels for Russian and English, Greek characters would fall
  96. * into an inflow bucket between the other two scripts.
  97. * <p>
  98. * The AlphabeticIndex class is not intended for public subclassing.
  99. *
  100. * <p><em>Note:</em> If you expect to have a lot of ASCII or Latin characters
  101. * as well as characters from the user's language,
  102. * then it is a good idea to call addLabels(Locale::getEnglish(), status).</p>
  103. *
  104. * <h2>Direct Use</h2>
  105. * <p>The following shows an example of building an index directly.
  106. * The "show..." methods below are just to illustrate usage.
  107. *
  108. * <pre>
  109. * // Create a simple index. "Item" is assumed to be an application
  110. * // defined type that the application's UI and other processing knows about,
  111. * // and that has a name.
  112. *
  113. * UErrorCode status = U_ZERO_ERROR;
  114. * AlphabeticIndex index = new AlphabeticIndex(desiredLocale, status);
  115. * index->addLabels(additionalLocale, status);
  116. * for (Item *item in some source of Items ) {
  117. * index->addRecord(item->name(), item, status);
  118. * }
  119. * ...
  120. * // Show index at top. We could skip or gray out empty buckets
  121. *
  122. * while (index->nextBucket(status)) {
  123. * if (showAll || index->getBucketRecordCount() != 0) {
  124. * showLabelAtTop(UI, index->getBucketLabel());
  125. * }
  126. * }
  127. * ...
  128. * // Show the buckets with their contents, skipping empty buckets
  129. *
  130. * index->resetBucketIterator(status);
  131. * while (index->nextBucket(status)) {
  132. * if (index->getBucketRecordCount() != 0) {
  133. * showLabelInList(UI, index->getBucketLabel());
  134. * while (index->nextRecord(status)) {
  135. * showIndexedItem(UI, static_cast<Item *>(index->getRecordData()))
  136. * </pre>
  137. *
  138. * The caller can build different UIs using this class.
  139. * For example, an index character could be omitted or grayed-out
  140. * if its bucket is empty. Small buckets could also be combined based on size, such as:
  141. *
  142. * <pre>
  143. * <b>... A-F G-N O-Z ...</b>
  144. * </pre>
  145. *
  146. * <h2>Client Support</h2>
  147. * <p>Callers can also use the AlphabeticIndex::ImmutableIndex, or the AlphabeticIndex itself,
  148. * to support sorting on a client that doesn't support AlphabeticIndex functionality.
  149. *
  150. * <p>The ImmutableIndex is both immutable and thread-safe.
  151. * The corresponding AlphabeticIndex methods are not thread-safe because
  152. * they "lazily" build the index buckets.
  153. * <ul>
  154. * <li>ImmutableIndex.getBucket(index) provides random access to all
  155. * buckets and their labels and label types.
  156. * <li>The AlphabeticIndex bucket iterator or ImmutableIndex.getBucket(0..getBucketCount-1)
  157. * can be used to get a list of the labels,
  158. * such as "...", "A", "B",..., and send that list to the client.
  159. * <li>When the client has a new name, it sends that name to the server.
  160. * The server needs to call the following methods,
  161. * and communicate the bucketIndex and collationKey back to the client.
  162. *
  163. * <pre>
  164. * int32_t bucketIndex = index.getBucketIndex(name, status);
  165. * const UnicodeString &label = immutableIndex.getBucket(bucketIndex)->getLabel(); // optional
  166. * int32_t skLength = collator.getSortKey(name, sk, skCapacity);
  167. * </pre>
  168. *
  169. * <li>The client would put the name (and associated information) into its bucket for bucketIndex. The sort key sk is a
  170. * sequence of bytes that can be compared with a binary compare, and produce the right localized result.</li>
  171. * </ul>
  172. *
  173. * @stable ICU 4.8
  174. */
  175. class U_I18N_API AlphabeticIndex: public UObject {
  176. public:
  177. /**
  178. * An index "bucket" with a label string and type.
  179. * It is referenced by getBucketIndex(),
  180. * and returned by ImmutableIndex.getBucket().
  181. *
  182. * The Bucket class is not intended for public subclassing.
  183. * @stable ICU 51
  184. */
  185. class U_I18N_API Bucket : public UObject {
  186. public:
  187. /**
  188. * Destructor.
  189. * @stable ICU 51
  190. */
  191. virtual ~Bucket();
  192. /**
  193. * Returns the label string.
  194. *
  195. * @return the label string for the bucket
  196. * @stable ICU 51
  197. */
  198. const UnicodeString &getLabel() const { return label_; }
  199. /**
  200. * Returns whether this bucket is a normal, underflow, overflow, or inflow bucket.
  201. *
  202. * @return the bucket label type
  203. * @stable ICU 51
  204. */
  205. UAlphabeticIndexLabelType getLabelType() const { return labelType_; }
  206. private:
  207. friend class AlphabeticIndex;
  208. friend class BucketList;
  209. UnicodeString label_;
  210. UnicodeString lowerBoundary_;
  211. UAlphabeticIndexLabelType labelType_;
  212. Bucket *displayBucket_;
  213. int32_t displayIndex_;
  214. UVector *records_; // Records are owned by the inputList_ vector.
  215. Bucket(const UnicodeString &label, // Parameter strings are copied.
  216. const UnicodeString &lowerBoundary,
  217. UAlphabeticIndexLabelType type);
  218. };
  219. /**
  220. * Immutable, thread-safe version of AlphabeticIndex.
  221. * This class provides thread-safe methods for bucketing,
  222. * and random access to buckets and their properties,
  223. * but does not offer adding records to the index.
  224. *
  225. * The ImmutableIndex class is not intended for public subclassing.
  226. *
  227. * @stable ICU 51
  228. */
  229. class U_I18N_API ImmutableIndex : public UObject {
  230. public:
  231. /**
  232. * Destructor.
  233. * @stable ICU 51
  234. */
  235. virtual ~ImmutableIndex();
  236. /**
  237. * Returns the number of index buckets and labels, including underflow/inflow/overflow.
  238. *
  239. * @return the number of index buckets
  240. * @stable ICU 51
  241. */
  242. int32_t getBucketCount() const;
  243. /**
  244. * Finds the index bucket for the given name and returns the number of that bucket.
  245. * Use getBucket() to get the bucket's properties.
  246. *
  247. * @param name the string to be sorted into an index bucket
  248. * @param errorCode Error code, will be set with the reason if the
  249. * operation fails.
  250. * @return the bucket number for the name
  251. * @stable ICU 51
  252. */
  253. int32_t getBucketIndex(const UnicodeString &name, UErrorCode &errorCode) const;
  254. /**
  255. * Returns the index-th bucket. Returns nullptr if the index is out of range.
  256. *
  257. * @param index bucket number
  258. * @return the index-th bucket
  259. * @stable ICU 51
  260. */
  261. const Bucket *getBucket(int32_t index) const;
  262. private:
  263. friend class AlphabeticIndex;
  264. ImmutableIndex(BucketList *bucketList, Collator *collatorPrimaryOnly)
  265. : buckets_(bucketList), collatorPrimaryOnly_(collatorPrimaryOnly) {}
  266. BucketList *buckets_;
  267. Collator *collatorPrimaryOnly_;
  268. };
  269. /**
  270. * Construct an AlphabeticIndex object for the specified locale. If the locale's
  271. * data does not include index characters, a set of them will be
  272. * synthesized based on the locale's exemplar characters. The locale
  273. * determines the sorting order for both the index characters and the
  274. * user item names appearing under each Index character.
  275. *
  276. * @param locale the desired locale.
  277. * @param status Error code, will be set with the reason if the construction
  278. * of the AlphabeticIndex object fails.
  279. * @stable ICU 4.8
  280. */
  281. AlphabeticIndex(const Locale &locale, UErrorCode &status);
  282. /**
  283. * Construct an AlphabeticIndex that uses a specific collator.
  284. *
  285. * The index will be created with no labels; the addLabels() function must be called
  286. * after creation to add the desired labels to the index.
  287. *
  288. * The index adopts the collator, and is responsible for deleting it.
  289. * The caller should make no further use of the collator after creating the index.
  290. *
  291. * @param collator The collator to use to order the contents of this index.
  292. * @param status Error code, will be set with the reason if the
  293. * operation fails.
  294. * @stable ICU 51
  295. */
  296. AlphabeticIndex(RuleBasedCollator *collator, UErrorCode &status);
  297. /**
  298. * Add Labels to this Index. The labels are additions to those
  299. * that are already in the index; they do not replace the existing
  300. * ones.
  301. * @param additions The additional characters to add to the index, such as A-Z.
  302. * @param status Error code, will be set with the reason if the
  303. * operation fails.
  304. * @return this, for chaining
  305. * @stable ICU 4.8
  306. */
  307. virtual AlphabeticIndex &addLabels(const UnicodeSet &additions, UErrorCode &status);
  308. /**
  309. * Add the index characters from a Locale to the index. The labels
  310. * are added to those that are already in the index; they do not replace the
  311. * existing index characters. The collation order for this index is not
  312. * changed; it remains that of the locale that was originally specified
  313. * when creating this Index.
  314. *
  315. * @param locale The locale whose index characters are to be added.
  316. * @param status Error code, will be set with the reason if the
  317. * operation fails.
  318. * @return this, for chaining
  319. * @stable ICU 4.8
  320. */
  321. virtual AlphabeticIndex &addLabels(const Locale &locale, UErrorCode &status);
  322. /**
  323. * Destructor
  324. * @stable ICU 4.8
  325. */
  326. virtual ~AlphabeticIndex();
  327. /**
  328. * Builds an immutable, thread-safe version of this instance, without data records.
  329. *
  330. * @return an immutable index instance
  331. * @stable ICU 51
  332. */
  333. ImmutableIndex *buildImmutableIndex(UErrorCode &errorCode);
  334. /**
  335. * Get the Collator that establishes the ordering of the items in this index.
  336. * Ownership of the collator remains with the AlphabeticIndex instance.
  337. *
  338. * The returned collator is a reference to the internal collator used by this
  339. * index. It may be safely used to compare the names of items or to get
  340. * sort keys for names. However if any settings need to be changed,
  341. * or other non-const methods called, a cloned copy must be made first.
  342. *
  343. * @return The collator
  344. * @stable ICU 4.8
  345. */
  346. virtual const RuleBasedCollator &getCollator() const;
  347. /**
  348. * Get the default label used for abbreviated buckets *between* other index characters.
  349. * For example, consider the labels when Latin (X Y Z) and Greek (Α Β Γ) are used:
  350. *
  351. * X Y Z ... Α Β Γ.
  352. *
  353. * @return inflow label
  354. * @stable ICU 4.8
  355. */
  356. virtual const UnicodeString &getInflowLabel() const;
  357. /**
  358. * Set the default label used for abbreviated buckets <i>between</i> other index characters.
  359. * An inflow label will be automatically inserted if two otherwise-adjacent label characters
  360. * are from different scripts, e.g. Latin and Cyrillic, and a third script, e.g. Greek,
  361. * sorts between the two. The default inflow character is an ellipsis (...)
  362. *
  363. * @param inflowLabel the new Inflow label.
  364. * @param status Error code, will be set with the reason if the operation fails.
  365. * @return this
  366. * @stable ICU 4.8
  367. */
  368. virtual AlphabeticIndex &setInflowLabel(const UnicodeString &inflowLabel, UErrorCode &status);
  369. /**
  370. * Get the special label used for items that sort after the last normal label,
  371. * and that would not otherwise have an appropriate label.
  372. *
  373. * @return the overflow label
  374. * @stable ICU 4.8
  375. */
  376. virtual const UnicodeString &getOverflowLabel() const;
  377. /**
  378. * Set the label used for items that sort after the last normal label,
  379. * and that would not otherwise have an appropriate label.
  380. *
  381. * @param overflowLabel the new overflow label.
  382. * @param status Error code, will be set with the reason if the operation fails.
  383. * @return this
  384. * @stable ICU 4.8
  385. */
  386. virtual AlphabeticIndex &setOverflowLabel(const UnicodeString &overflowLabel, UErrorCode &status);
  387. /**
  388. * Get the special label used for items that sort before the first normal label,
  389. * and that would not otherwise have an appropriate label.
  390. *
  391. * @return underflow label
  392. * @stable ICU 4.8
  393. */
  394. virtual const UnicodeString &getUnderflowLabel() const;
  395. /**
  396. * Set the label used for items that sort before the first normal label,
  397. * and that would not otherwise have an appropriate label.
  398. *
  399. * @param underflowLabel the new underflow label.
  400. * @param status Error code, will be set with the reason if the operation fails.
  401. * @return this
  402. * @stable ICU 4.8
  403. */
  404. virtual AlphabeticIndex &setUnderflowLabel(const UnicodeString &underflowLabel, UErrorCode &status);
  405. /**
  406. * Get the limit on the number of labels permitted in the index.
  407. * The number does not include over, under and inflow labels.
  408. *
  409. * @return maxLabelCount maximum number of labels.
  410. * @stable ICU 4.8
  411. */
  412. virtual int32_t getMaxLabelCount() const;
  413. /**
  414. * Set a limit on the number of labels permitted in the index.
  415. * The number does not include over, under and inflow labels.
  416. * Currently, if the number is exceeded, then every
  417. * nth item is removed to bring the count down.
  418. * A more sophisticated mechanism may be available in the future.
  419. *
  420. * @param maxLabelCount the maximum number of labels.
  421. * @param status error code
  422. * @return This, for chaining
  423. * @stable ICU 4.8
  424. */
  425. virtual AlphabeticIndex &setMaxLabelCount(int32_t maxLabelCount, UErrorCode &status);
  426. /**
  427. * Add a record to the index. Each record will be associated with an index Bucket
  428. * based on the record's name. The list of records for each bucket will be sorted
  429. * based on the collation ordering of the names in the index's locale.
  430. * Records with duplicate names are permitted; they will be kept in the order
  431. * that they were added.
  432. *
  433. * @param name The display name for the Record. The Record will be placed in
  434. * a bucket based on this name.
  435. * @param data An optional pointer to user data associated with this
  436. * item. When iterating the contents of a bucket, both the
  437. * data pointer the name will be available for each Record.
  438. * @param status Error code, will be set with the reason if the operation fails.
  439. * @return This, for chaining.
  440. * @stable ICU 4.8
  441. */
  442. virtual AlphabeticIndex &addRecord(const UnicodeString &name, const void *data, UErrorCode &status);
  443. /**
  444. * Remove all Records from the Index. The set of Buckets, which define the headings under
  445. * which records are classified, is not altered.
  446. *
  447. * @param status Error code, will be set with the reason if the operation fails.
  448. * @return This, for chaining.
  449. * @stable ICU 4.8
  450. */
  451. virtual AlphabeticIndex &clearRecords(UErrorCode &status);
  452. /** Get the number of labels in this index.
  453. * Note: may trigger lazy index construction.
  454. *
  455. * @param status Error code, will be set with the reason if the operation fails.
  456. * @return The number of labels in this index, including any under, over or
  457. * in-flow labels.
  458. * @stable ICU 4.8
  459. */
  460. virtual int32_t getBucketCount(UErrorCode &status);
  461. /** Get the total number of Records in this index, that is, the number
  462. * of <name, data> pairs added.
  463. *
  464. * @param status Error code, will be set with the reason if the operation fails.
  465. * @return The number of records in this index, that is, the total number
  466. * of (name, data) items added with addRecord().
  467. * @stable ICU 4.8
  468. */
  469. virtual int32_t getRecordCount(UErrorCode &status);
  470. /**
  471. * Given the name of a record, return the zero-based index of the Bucket
  472. * in which the item should appear. The name need not be in the index.
  473. * A Record will not be added to the index by this function.
  474. * Bucket numbers are zero-based, in Bucket iteration order.
  475. *
  476. * @param itemName The name whose bucket position in the index is to be determined.
  477. * @param status Error code, will be set with the reason if the operation fails.
  478. * @return The bucket number for this name.
  479. * @stable ICU 4.8
  480. *
  481. */
  482. virtual int32_t getBucketIndex(const UnicodeString &itemName, UErrorCode &status);
  483. /**
  484. * Get the zero based index of the current Bucket from an iteration
  485. * over the Buckets of this index. Return -1 if no iteration is in process.
  486. * @return the index of the current Bucket
  487. * @stable ICU 4.8
  488. */
  489. virtual int32_t getBucketIndex() const;
  490. /**
  491. * Advance the iteration over the Buckets of this index. Return false if
  492. * there are no more Buckets.
  493. *
  494. * @param status Error code, will be set with the reason if the operation fails.
  495. * U_ENUM_OUT_OF_SYNC_ERROR will be reported if the index is modified while
  496. * an enumeration of its contents are in process.
  497. *
  498. * @return true if success, false if at end of iteration
  499. * @stable ICU 4.8
  500. */
  501. virtual UBool nextBucket(UErrorCode &status);
  502. /**
  503. * Return the name of the Label of the current bucket from an iteration over the buckets.
  504. * If the iteration is before the first Bucket (nextBucket() has not been called),
  505. * or after the last, return an empty string.
  506. *
  507. * @return the bucket label.
  508. * @stable ICU 4.8
  509. */
  510. virtual const UnicodeString &getBucketLabel() const;
  511. /**
  512. * Return the type of the label for the current Bucket (selected by the
  513. * iteration over Buckets.)
  514. *
  515. * @return the label type.
  516. * @stable ICU 4.8
  517. */
  518. virtual UAlphabeticIndexLabelType getBucketLabelType() const;
  519. /**
  520. * Get the number of <name, data> Records in the current Bucket.
  521. * If the current bucket iteration position is before the first label or after the
  522. * last, return 0.
  523. *
  524. * @return the number of Records.
  525. * @stable ICU 4.8
  526. */
  527. virtual int32_t getBucketRecordCount() const;
  528. /**
  529. * Reset the Bucket iteration for this index. The next call to nextBucket()
  530. * will restart the iteration at the first label.
  531. *
  532. * @param status Error code, will be set with the reason if the operation fails.
  533. * @return this, for chaining.
  534. * @stable ICU 4.8
  535. */
  536. virtual AlphabeticIndex &resetBucketIterator(UErrorCode &status);
  537. /**
  538. * Advance to the next record in the current Bucket.
  539. * When nextBucket() is called, Record iteration is reset to just before the
  540. * first Record in the new Bucket.
  541. *
  542. * @param status Error code, will be set with the reason if the operation fails.
  543. * U_ENUM_OUT_OF_SYNC_ERROR will be reported if the index is modified while
  544. * an enumeration of its contents are in process.
  545. * @return true if successful, false when the iteration advances past the last item.
  546. * @stable ICU 4.8
  547. */
  548. virtual UBool nextRecord(UErrorCode &status);
  549. /**
  550. * Get the name of the current Record.
  551. * Return an empty string if the Record iteration position is before first
  552. * or after the last.
  553. *
  554. * @return The name of the current index item.
  555. * @stable ICU 4.8
  556. */
  557. virtual const UnicodeString &getRecordName() const;
  558. /**
  559. * Return the data pointer of the Record currently being iterated over.
  560. * Return nullptr if the current iteration position before the first item in this Bucket,
  561. * or after the last.
  562. *
  563. * @return The current Record's data pointer.
  564. * @stable ICU 4.8
  565. */
  566. virtual const void *getRecordData() const;
  567. /**
  568. * Reset the Record iterator position to before the first Record in the current Bucket.
  569. *
  570. * @return This, for chaining.
  571. * @stable ICU 4.8
  572. */
  573. virtual AlphabeticIndex &resetRecordIterator();
  574. private:
  575. /**
  576. * No Copy constructor.
  577. * @internal (private)
  578. */
  579. AlphabeticIndex(const AlphabeticIndex &other) = delete;
  580. /**
  581. * No assignment.
  582. */
  583. AlphabeticIndex &operator =(const AlphabeticIndex & /*other*/) { return *this;}
  584. /**
  585. * No Equality operators.
  586. * @internal (private)
  587. */
  588. virtual bool operator==(const AlphabeticIndex& other) const;
  589. /**
  590. * Inequality operator.
  591. * @internal (private)
  592. */
  593. virtual bool operator!=(const AlphabeticIndex& other) const;
  594. // Common initialization, for use from all constructors.
  595. void init(const Locale *locale, UErrorCode &status);
  596. /**
  597. * This method is called to get the index exemplars. Normally these come from the locale directly,
  598. * but if they aren't available, we have to synthesize them.
  599. */
  600. void addIndexExemplars(const Locale &locale, UErrorCode &status);
  601. /**
  602. * Add Chinese index characters from the tailoring.
  603. */
  604. UBool addChineseIndexCharacters(UErrorCode &errorCode);
  605. UVector *firstStringsInScript(UErrorCode &status);
  606. static UnicodeString separated(const UnicodeString &item);
  607. /**
  608. * Determine the best labels to use.
  609. * This is based on the exemplars, but we also process to make sure that they are unique,
  610. * and sort differently, and that the overall list is small enough.
  611. */
  612. void initLabels(UVector &indexCharacters, UErrorCode &errorCode) const;
  613. BucketList *createBucketList(UErrorCode &errorCode) const;
  614. void initBuckets(UErrorCode &errorCode);
  615. void clearBuckets();
  616. void internalResetBucketIterator();
  617. public:
  618. // The Record is declared public only to allow access from
  619. // implementation code written in plain C.
  620. // It is not intended for public use.
  621. #ifndef U_HIDE_INTERNAL_API
  622. /**
  623. * A (name, data) pair, to be sorted by name into one of the index buckets.
  624. * The user data is not used by the index implementation.
  625. * \cond
  626. * @internal
  627. */
  628. struct Record: public UMemory {
  629. const UnicodeString name_;
  630. const void *data_;
  631. Record(const UnicodeString &name, const void *data);
  632. ~Record();
  633. };
  634. /** \endcond */
  635. #endif /* U_HIDE_INTERNAL_API */
  636. private:
  637. /**
  638. * Holds all user records before they are distributed into buckets.
  639. * Type of contents is (Record *)
  640. * @internal (private)
  641. */
  642. UVector *inputList_;
  643. int32_t labelsIterIndex_; // Index of next item to return.
  644. int32_t itemsIterIndex_;
  645. Bucket *currentBucket_; // While an iteration of the index in underway,
  646. // point to the bucket for the current label.
  647. // nullptr when no iteration underway.
  648. int32_t maxLabelCount_; // Limit on # of labels permitted in the index.
  649. UnicodeSet *initialLabels_; // Initial (unprocessed) set of Labels. Union
  650. // of those explicitly set by the user plus
  651. // those from locales. Raw values, before
  652. // crunching into bucket labels.
  653. UVector *firstCharsInScripts_; // The first character from each script,
  654. // in collation order.
  655. RuleBasedCollator *collator_;
  656. RuleBasedCollator *collatorPrimaryOnly_;
  657. // Lazy evaluated: null means that we have not built yet.
  658. BucketList *buckets_;
  659. UnicodeString inflowLabel_;
  660. UnicodeString overflowLabel_;
  661. UnicodeString underflowLabel_;
  662. UnicodeString overflowComparisonString_;
  663. UnicodeString emptyString_;
  664. };
  665. U_NAMESPACE_END
  666. #endif // !UCONFIG_NO_COLLATION
  667. #endif /* U_SHOW_CPLUSPLUS_API */
  668. #endif