/src/aspell/common/lsort.hpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2004 |
3 | | * Kevin Atkinson |
4 | | * |
5 | | * Permission to use, copy, modify, distribute and sell this software |
6 | | * and its documentation for any purpose is hereby granted without |
7 | | * fee, provided that the above copyright notice appear in all copies |
8 | | * and that both that copyright notice and this permission notice |
9 | | * appear in supporting documentation. I make no representations about |
10 | | * the suitability of this software for any purpose. It is provided |
11 | | * "as is" without express or implied warranty. |
12 | | * |
13 | | * This code was originally adopted from the slist implementation |
14 | | * found in the SGI STL under the following copyright: |
15 | | * |
16 | | * Copyright (c) 1997 |
17 | | * Silicon Graphics Computer Systems, Inc. |
18 | | * |
19 | | * Permission to use, copy, modify, distribute and sell this software |
20 | | * and its documentation for any purpose is hereby granted without fee, |
21 | | * provided that the above copyright notice appear in all copies and |
22 | | * that both that copyright notice and this permission notice appear |
23 | | * in supporting documentation. Silicon Graphics makes no |
24 | | * representations about the suitability of this software for any |
25 | | * purpose. It is provided "as is" without express or implied warranty. |
26 | | * |
27 | | */ |
28 | | |
29 | | #ifndef ACOMMON_LSORT__HPP |
30 | | #define ACOMMON_LSORT__HPP |
31 | | |
32 | | namespace acommon { |
33 | | |
34 | | using std::swap; |
35 | | |
36 | | template <class N> |
37 | | struct Next { |
38 | 25.2M | N * & operator() (N * n) const {return n->next;}acommon::Next<aspeller::PfxEntry>::operator()(aspeller::PfxEntry*) const Line | Count | Source | 38 | 26.8k | N * & operator() (N * n) const {return n->next;} |
acommon::Next<aspeller::SfxEntry>::operator()(aspeller::SfxEntry*) const Line | Count | Source | 38 | 25.2M | N * & operator() (N * n) const {return n->next;} |
Unexecuted instantiation: readonly_ws.cpp:acommon::Next<(anonymous namespace)::WordData>::operator()((anonymous namespace)::WordData*) const |
39 | | }; |
40 | | template <class N> |
41 | | struct Less { |
42 | | bool operator() (N * x, N * y) const {return x->data < y->data;} |
43 | | }; |
44 | | |
45 | | |
46 | | template <class N, class LT, class NX> |
47 | | static inline N * merge(N * x, N * y, const LT & lt, const NX & nx) |
48 | 495k | { |
49 | 495k | if (lt(y,x)) swap(x,y); |
50 | 495k | N * first = x; |
51 | 5.23M | while (nx(x) && y) { |
52 | 4.73M | if (lt(y,nx(x))) { |
53 | 2.28M | N * xn = nx(x); |
54 | 2.28M | N * yn = nx(y); |
55 | 2.28M | nx(x) = y; |
56 | 2.28M | nx(y) = xn; |
57 | 2.28M | y = yn; |
58 | 2.28M | } |
59 | 4.73M | x = nx(x); |
60 | 4.73M | } |
61 | 495k | if (y) { |
62 | 403k | nx(x) = y; |
63 | 403k | } |
64 | 495k | return first; |
65 | 495k | } affix.cpp:aspeller::PfxEntry* acommon::merge<aspeller::PfxEntry, aspeller::AffixLess<aspeller::PfxEntry>, acommon::Next<aspeller::PfxEntry> >(aspeller::PfxEntry*, aspeller::PfxEntry*, aspeller::AffixLess<aspeller::PfxEntry> const&, acommon::Next<aspeller::PfxEntry> const&) Line | Count | Source | 48 | 2.74k | { | 49 | 2.74k | if (lt(y,x)) swap(x,y); | 50 | 2.74k | N * first = x; | 51 | 5.58k | while (nx(x) && y) { | 52 | 2.84k | if (lt(y,nx(x))) { | 53 | 1.36k | N * xn = nx(x); | 54 | 1.36k | N * yn = nx(y); | 55 | 1.36k | nx(x) = y; | 56 | 1.36k | nx(y) = xn; | 57 | 1.36k | y = yn; | 58 | 1.36k | } | 59 | 2.84k | x = nx(x); | 60 | 2.84k | } | 61 | 2.74k | if (y) { | 62 | 2.36k | nx(x) = y; | 63 | 2.36k | } | 64 | 2.74k | return first; | 65 | 2.74k | } |
affix.cpp:aspeller::SfxEntry* acommon::merge<aspeller::SfxEntry, aspeller::AffixLess<aspeller::SfxEntry>, acommon::Next<aspeller::SfxEntry> >(aspeller::SfxEntry*, aspeller::SfxEntry*, aspeller::AffixLess<aspeller::SfxEntry> const&, acommon::Next<aspeller::SfxEntry> const&) Line | Count | Source | 48 | 492k | { | 49 | 492k | if (lt(y,x)) swap(x,y); | 50 | 492k | N * first = x; | 51 | 5.22M | while (nx(x) && y) { | 52 | 4.73M | if (lt(y,nx(x))) { | 53 | 2.28M | N * xn = nx(x); | 54 | 2.28M | N * yn = nx(y); | 55 | 2.28M | nx(x) = y; | 56 | 2.28M | nx(y) = xn; | 57 | 2.28M | y = yn; | 58 | 2.28M | } | 59 | 4.73M | x = nx(x); | 60 | 4.73M | } | 61 | 492k | if (y) { | 62 | 401k | nx(x) = y; | 63 | 401k | } | 64 | 492k | return first; | 65 | 492k | } |
Unexecuted instantiation: readonly_ws.cpp:(anonymous namespace)::WordData* acommon::merge<(anonymous namespace)::WordData, (anonymous namespace)::SoundslikeLess, acommon::Next<(anonymous namespace)::WordData> >((anonymous namespace)::WordData*, (anonymous namespace)::WordData*, (anonymous namespace)::SoundslikeLess const&, acommon::Next<(anonymous namespace)::WordData> const&) |
66 | | |
67 | | // THIS is SLOWER!!! |
68 | | // and even slower when condational move is used!!!! |
69 | | template <class N, class LT, class NX> |
70 | | static inline N * merge1(N * x, N * y, const LT & lt, const NX & nx) |
71 | | { |
72 | | N * * cur = lt(x,y) ? &x : &y; |
73 | | N * first = *cur; |
74 | | N * last = *cur; |
75 | | *cur = nx(*cur); |
76 | | while (x && y) { |
77 | | cur = lt(x,y) ? &x : &y; |
78 | | nx(last) = *cur; |
79 | | last = *cur; |
80 | | *cur = nx(*cur); |
81 | | } |
82 | | if (x) {nx(last) = x;} |
83 | | else if (y) {nx(last) = y;} |
84 | | return first; |
85 | | } |
86 | | |
87 | | template <class N, class LT> |
88 | | static inline N * merge(N * x, N * y, const LT & lt) |
89 | | { |
90 | | return sort(x, y, lt, Next<N>()); |
91 | | } |
92 | | |
93 | | template <class N> |
94 | | static inline N * merge(N * x, N * y) |
95 | | { |
96 | | return sort(x, y, Less<N>(), Next<N>()); |
97 | | } |
98 | | |
99 | | template <class N, class LT, class NX> |
100 | | N * sort(N * first, const LT & lt, const NX & nx) |
101 | 9.00k | { |
102 | 9.00k | if (!first) return first; |
103 | | |
104 | 9.00k | N * carry = 0; |
105 | 9.00k | N * counter[sizeof(void *)*8] = {0}; |
106 | 9.00k | int fill = 0; |
107 | | |
108 | 513k | while (first) { |
109 | | |
110 | 504k | N * tmp = nx(first); |
111 | 504k | nx(first) = carry; |
112 | 504k | carry = first; |
113 | 504k | first = tmp; |
114 | | |
115 | 504k | int i = 0; |
116 | 994k | while (i < fill && counter[i]) { |
117 | 490k | carry = merge(counter[i], carry, lt, nx); |
118 | 490k | counter[i] = 0; |
119 | 490k | ++i; |
120 | 490k | } |
121 | | |
122 | 504k | swap(carry, counter[i]); |
123 | | |
124 | 504k | if (i == fill) { |
125 | 26.3k | ++fill; |
126 | 26.3k | } |
127 | 504k | } |
128 | | |
129 | 26.3k | for (int i = 1; i < fill; ++i) { |
130 | 17.3k | if (!counter[i]) counter[i] = counter[i-1]; |
131 | 9.95k | else if (counter[i-1]) counter[i] = merge(counter[i], counter[i-1], lt, nx); |
132 | 17.3k | } |
133 | | |
134 | 9.00k | return counter[fill-1]; |
135 | 9.00k | } aspeller::PfxEntry* acommon::sort<aspeller::PfxEntry, aspeller::AffixLess<aspeller::PfxEntry>, acommon::Next<aspeller::PfxEntry> >(aspeller::PfxEntry*, aspeller::AffixLess<aspeller::PfxEntry> const&, acommon::Next<aspeller::PfxEntry> const&) Line | Count | Source | 101 | 1.13k | { | 102 | 1.13k | if (!first) return first; | 103 | | | 104 | 1.13k | N * carry = 0; | 105 | 1.13k | N * counter[sizeof(void *)*8] = {0}; | 106 | 1.13k | int fill = 0; | 107 | | | 108 | 5.01k | while (first) { | 109 | | | 110 | 3.87k | N * tmp = nx(first); | 111 | 3.87k | nx(first) = carry; | 112 | 3.87k | carry = first; | 113 | 3.87k | first = tmp; | 114 | | | 115 | 3.87k | int i = 0; | 116 | 6.40k | while (i < fill && counter[i]) { | 117 | 2.52k | carry = merge(counter[i], carry, lt, nx); | 118 | 2.52k | counter[i] = 0; | 119 | 2.52k | ++i; | 120 | 2.52k | } | 121 | | | 122 | 3.87k | swap(carry, counter[i]); | 123 | | | 124 | 3.87k | if (i == fill) { | 125 | 2.61k | ++fill; | 126 | 2.61k | } | 127 | 3.87k | } | 128 | | | 129 | 2.61k | for (int i = 1; i < fill; ++i) { | 130 | 1.48k | if (!counter[i]) counter[i] = counter[i-1]; | 131 | 1.26k | else if (counter[i-1]) counter[i] = merge(counter[i], counter[i-1], lt, nx); | 132 | 1.48k | } | 133 | | | 134 | 1.13k | return counter[fill-1]; | 135 | 1.13k | } |
aspeller::SfxEntry* acommon::sort<aspeller::SfxEntry, aspeller::AffixLess<aspeller::SfxEntry>, acommon::Next<aspeller::SfxEntry> >(aspeller::SfxEntry*, aspeller::AffixLess<aspeller::SfxEntry> const&, acommon::Next<aspeller::SfxEntry> const&) Line | Count | Source | 101 | 7.86k | { | 102 | 7.86k | if (!first) return first; | 103 | | | 104 | 7.86k | N * carry = 0; | 105 | 7.86k | N * counter[sizeof(void *)*8] = {0}; | 106 | 7.86k | int fill = 0; | 107 | | | 108 | 508k | while (first) { | 109 | | | 110 | 500k | N * tmp = nx(first); | 111 | 500k | nx(first) = carry; | 112 | 500k | carry = first; | 113 | 500k | first = tmp; | 114 | | | 115 | 500k | int i = 0; | 116 | 988k | while (i < fill && counter[i]) { | 117 | 487k | carry = merge(counter[i], carry, lt, nx); | 118 | 487k | counter[i] = 0; | 119 | 487k | ++i; | 120 | 487k | } | 121 | | | 122 | 500k | swap(carry, counter[i]); | 123 | | | 124 | 500k | if (i == fill) { | 125 | 23.7k | ++fill; | 126 | 23.7k | } | 127 | 500k | } | 128 | | | 129 | 23.7k | for (int i = 1; i < fill; ++i) { | 130 | 15.8k | if (!counter[i]) counter[i] = counter[i-1]; | 131 | 8.69k | else if (counter[i-1]) counter[i] = merge(counter[i], counter[i-1], lt, nx); | 132 | 15.8k | } | 133 | | | 134 | 7.86k | return counter[fill-1]; | 135 | 7.86k | } |
Unexecuted instantiation: readonly_ws.cpp:(anonymous namespace)::WordData* acommon::sort<(anonymous namespace)::WordData, (anonymous namespace)::SoundslikeLess, acommon::Next<(anonymous namespace)::WordData> >((anonymous namespace)::WordData*, (anonymous namespace)::SoundslikeLess const&, acommon::Next<(anonymous namespace)::WordData> const&) |
136 | | |
137 | | template <class N, class LT> |
138 | | static inline N * sort(N * first, const LT & lt) |
139 | 9.00k | { |
140 | 9.00k | return sort(first, lt, Next<N>()); |
141 | 9.00k | } affix.cpp:aspeller::PfxEntry* acommon::sort<aspeller::PfxEntry, aspeller::AffixLess<aspeller::PfxEntry> >(aspeller::PfxEntry*, aspeller::AffixLess<aspeller::PfxEntry> const&) Line | Count | Source | 139 | 1.13k | { | 140 | 1.13k | return sort(first, lt, Next<N>()); | 141 | 1.13k | } |
affix.cpp:aspeller::SfxEntry* acommon::sort<aspeller::SfxEntry, aspeller::AffixLess<aspeller::SfxEntry> >(aspeller::SfxEntry*, aspeller::AffixLess<aspeller::SfxEntry> const&) Line | Count | Source | 139 | 7.86k | { | 140 | 7.86k | return sort(first, lt, Next<N>()); | 141 | 7.86k | } |
Unexecuted instantiation: readonly_ws.cpp:(anonymous namespace)::WordData* acommon::sort<(anonymous namespace)::WordData, (anonymous namespace)::SoundslikeLess>((anonymous namespace)::WordData*, (anonymous namespace)::SoundslikeLess const&) |
142 | | |
143 | | template <class N> |
144 | | static inline N * sort(N * first) |
145 | | { |
146 | | return sort(first, Less<N>(), Next<N>()); |
147 | | } |
148 | | |
149 | | |
150 | | template <class N> |
151 | | static inline N * fix_links(N * cur) |
152 | | { |
153 | | N * prev = 0; |
154 | | while (cur) { |
155 | | cur->prev = prev; |
156 | | prev = cur; |
157 | | cur = cur->next; |
158 | | } |
159 | | } |
160 | | |
161 | | } |
162 | | |
163 | | #endif |
164 | | |