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) 1999-2014, International Business Machines
7* Corporation and others. All Rights Reserved.
8*
9*******************************************************************************
10* file name: collationweights.h
11* encoding: UTF-8
12* tab size: 8 (not used)
13* indentation:4
14*
15* created on: 2001mar08 as ucol_wgt.h
16* created by: Markus W. Scherer
17*/
18
19#ifndef __COLLATIONWEIGHTS_H__
20#define __COLLATIONWEIGHTS_H__
21
22#include "unicode/utypes.h"
23
24#if !UCONFIG_NO_COLLATION
25
26#include "unicode/uobject.h"
27
28U_NAMESPACE_BEGIN
29
30/**
31 * Allocates n collation element weights between two exclusive limits.
32 * Used only internally by the collation tailoring builder.
33 */
34class U_I18N_API CollationWeights : public UMemory {
35public:
36 CollationWeights();
37
38 static inline int32_t lengthOfWeight(uint32_t weight) {
39 if((weight&0xffffff)==0) {
40 return 1;
41 } else if((weight&0xffff)==0) {
42 return 2;
43 } else if((weight&0xff)==0) {
44 return 3;
45 } else {
46 return 4;
47 }
48 }
49
50 void initForPrimary(UBool compressible);
51 void initForSecondary();
52 void initForTertiary();
53
54 /**
55 * Determine heuristically
56 * what ranges to use for a given number of weights between (excluding)
57 * two limits.
58 *
59 * @param lowerLimit A collation element weight; the ranges will be filled to cover
60 * weights greater than this one.
61 * @param upperLimit A collation element weight; the ranges will be filled to cover
62 * weights less than this one.
63 * @param n The number of collation element weights w necessary such that
64 * lowerLimit<w<upperLimit in lexical order.
65 * @return TRUE if it is possible to fit n elements between the limits
66 */
67 UBool allocWeights(uint32_t lowerLimit, uint32_t upperLimit, int32_t n);
68
69 /**
70 * Given a set of ranges calculated by allocWeights(),
71 * iterate through the weights.
72 * The ranges are modified to keep the current iteration state.
73 *
74 * @return The next weight in the ranges, or 0xffffffff if there is none left.
75 */
76 uint32_t nextWeight();
77
78 /** @internal */
79 struct WeightRange {
80 uint32_t start, end;
81 int32_t length, count;
82 };
83
84private:
85 /** @return number of usable byte values for byte idx */
86 inline int32_t countBytes(int32_t idx) const {
87 return (int32_t)(maxBytes[idx] - minBytes[idx] + 1);
88 }
89
90 uint32_t incWeight(uint32_t weight, int32_t length) const;
91 uint32_t incWeightByOffset(uint32_t weight, int32_t length, int32_t offset) const;
92 void lengthenRange(WeightRange &range) const;
93 /**
94 * Takes two CE weights and calculates the
95 * possible ranges of weights between the two limits, excluding them.
96 * For weights with up to 4 bytes there are up to 2*4-1=7 ranges.
97 */
98 UBool getWeightRanges(uint32_t lowerLimit, uint32_t upperLimit);
99 UBool allocWeightsInShortRanges(int32_t n, int32_t minLength);
100 UBool allocWeightsInMinLengthRanges(int32_t n, int32_t minLength);
101
102 int32_t middleLength;
103 uint32_t minBytes[5]; // for byte 1, 2, 3, 4
104 uint32_t maxBytes[5];
105 WeightRange ranges[7];
106 int32_t rangeIndex;
107 int32_t rangeCount;
108};
109
110U_NAMESPACE_END
111
112#endif // !UCONFIG_NO_COLLATION
113#endif // __COLLATIONWEIGHTS_H__
114