alphaindex.h 26 KB

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