/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 | 36.3M | N * & operator() (N * n) const {return n->next;}acommon::Next<aspeller::PfxEntry>::operator()(aspeller::PfxEntry*) const Line | Count | Source | 38 | 36.0k | N * & operator() (N * n) const {return n->next;} |
acommon::Next<aspeller::SfxEntry>::operator()(aspeller::SfxEntry*) const Line | Count | Source | 38 | 36.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 | 699k | { |
49 | 699k | if (lt(y,x)) swap(x,y); |
50 | 699k | N * first = x; |
51 | 7.52M | while (nx(x) && y) { |
52 | 6.82M | if (lt(y,nx(x))) { |
53 | 3.29M | N * xn = nx(x); |
54 | 3.29M | N * yn = nx(y); |
55 | 3.29M | nx(x) = y; |
56 | 3.29M | nx(y) = xn; |
57 | 3.29M | y = yn; |
58 | 3.29M | } |
59 | 6.82M | x = nx(x); |
60 | 6.82M | } |
61 | 699k | if (y) { |
62 | 570k | nx(x) = y; |
63 | 570k | } |
64 | 699k | return first; |
65 | 699k | } 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 | 3.50k | { | 49 | 3.50k | if (lt(y,x)) swap(x,y); | 50 | 3.50k | N * first = x; | 51 | 7.61k | while (nx(x) && y) { | 52 | 4.10k | if (lt(y,nx(x))) { | 53 | 1.97k | N * xn = nx(x); | 54 | 1.97k | N * yn = nx(y); | 55 | 1.97k | nx(x) = y; | 56 | 1.97k | nx(y) = xn; | 57 | 1.97k | y = yn; | 58 | 1.97k | } | 59 | 4.10k | x = nx(x); | 60 | 4.10k | } | 61 | 3.50k | if (y) { | 62 | 2.95k | nx(x) = y; | 63 | 2.95k | } | 64 | 3.50k | return first; | 65 | 3.50k | } |
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 | 695k | { | 49 | 695k | if (lt(y,x)) swap(x,y); | 50 | 695k | N * first = x; | 51 | 7.51M | while (nx(x) && y) { | 52 | 6.81M | if (lt(y,nx(x))) { | 53 | 3.29M | N * xn = nx(x); | 54 | 3.29M | N * yn = nx(y); | 55 | 3.29M | nx(x) = y; | 56 | 3.29M | nx(y) = xn; | 57 | 3.29M | y = yn; | 58 | 3.29M | } | 59 | 6.81M | x = nx(x); | 60 | 6.81M | } | 61 | 695k | if (y) { | 62 | 567k | nx(x) = y; | 63 | 567k | } | 64 | 695k | return first; | 65 | 695k | } |
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 | 8.92k | { |
102 | 8.92k | if (!first) return first; |
103 | | |
104 | 8.92k | N * carry = 0; |
105 | 8.92k | N * counter[sizeof(void *)*8] = {0}; |
106 | 8.92k | int fill = 0; |
107 | | |
108 | 717k | while (first) { |
109 | | |
110 | 708k | N * tmp = nx(first); |
111 | 708k | nx(first) = carry; |
112 | 708k | carry = first; |
113 | 708k | first = tmp; |
114 | | |
115 | 708k | int i = 0; |
116 | 1.40M | while (i < fill && counter[i]) { |
117 | 694k | carry = merge(counter[i], carry, lt, nx); |
118 | 694k | counter[i] = 0; |
119 | 694k | ++i; |
120 | 694k | } |
121 | | |
122 | 708k | swap(carry, counter[i]); |
123 | | |
124 | 708k | if (i == fill) { |
125 | 26.7k | ++fill; |
126 | 26.7k | } |
127 | 708k | } |
128 | | |
129 | 26.7k | for (int i = 1; i < fill; ++i) { |
130 | 17.8k | if (!counter[i]) counter[i] = counter[i-1]; |
131 | 10.3k | else if (counter[i-1]) counter[i] = merge(counter[i], counter[i-1], lt, nx); |
132 | 17.8k | } |
133 | | |
134 | 8.92k | return counter[fill-1]; |
135 | 8.92k | } 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.19k | { | 102 | 1.19k | if (!first) return first; | 103 | | | 104 | 1.19k | N * carry = 0; | 105 | 1.19k | N * counter[sizeof(void *)*8] = {0}; | 106 | 1.19k | int fill = 0; | 107 | | | 108 | 5.88k | while (first) { | 109 | | | 110 | 4.69k | N * tmp = nx(first); | 111 | 4.69k | nx(first) = carry; | 112 | 4.69k | carry = first; | 113 | 4.69k | first = tmp; | 114 | | | 115 | 4.69k | int i = 0; | 116 | 7.88k | while (i < fill && counter[i]) { | 117 | 3.19k | carry = merge(counter[i], carry, lt, nx); | 118 | 3.19k | counter[i] = 0; | 119 | 3.19k | ++i; | 120 | 3.19k | } | 121 | | | 122 | 4.69k | swap(carry, counter[i]); | 123 | | | 124 | 4.69k | if (i == fill) { | 125 | 2.87k | ++fill; | 126 | 2.87k | } | 127 | 4.69k | } | 128 | | | 129 | 2.87k | for (int i = 1; i < fill; ++i) { | 130 | 1.68k | if (!counter[i]) counter[i] = counter[i-1]; | 131 | 1.37k | else if (counter[i-1]) counter[i] = merge(counter[i], counter[i-1], lt, nx); | 132 | 1.68k | } | 133 | | | 134 | 1.19k | return counter[fill-1]; | 135 | 1.19k | } |
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.73k | { | 102 | 7.73k | if (!first) return first; | 103 | | | 104 | 7.73k | N * carry = 0; | 105 | 7.73k | N * counter[sizeof(void *)*8] = {0}; | 106 | 7.73k | int fill = 0; | 107 | | | 108 | 711k | while (first) { | 109 | | | 110 | 703k | N * tmp = nx(first); | 111 | 703k | nx(first) = carry; | 112 | 703k | carry = first; | 113 | 703k | first = tmp; | 114 | | | 115 | 703k | int i = 0; | 116 | 1.39M | while (i < fill && counter[i]) { | 117 | 690k | carry = merge(counter[i], carry, lt, nx); | 118 | 690k | counter[i] = 0; | 119 | 690k | ++i; | 120 | 690k | } | 121 | | | 122 | 703k | swap(carry, counter[i]); | 123 | | | 124 | 703k | if (i == fill) { | 125 | 23.8k | ++fill; | 126 | 23.8k | } | 127 | 703k | } | 128 | | | 129 | 23.8k | for (int i = 1; i < fill; ++i) { | 130 | 16.1k | if (!counter[i]) counter[i] = counter[i-1]; | 131 | 8.93k | else if (counter[i-1]) counter[i] = merge(counter[i], counter[i-1], lt, nx); | 132 | 16.1k | } | 133 | | | 134 | 7.73k | return counter[fill-1]; | 135 | 7.73k | } |
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 | 8.92k | { |
140 | 8.92k | return sort(first, lt, Next<N>()); |
141 | 8.92k | } affix.cpp:aspeller::PfxEntry* acommon::sort<aspeller::PfxEntry, aspeller::AffixLess<aspeller::PfxEntry> >(aspeller::PfxEntry*, aspeller::AffixLess<aspeller::PfxEntry> const&) Line | Count | Source | 139 | 1.19k | { | 140 | 1.19k | return sort(first, lt, Next<N>()); | 141 | 1.19k | } |
affix.cpp:aspeller::SfxEntry* acommon::sort<aspeller::SfxEntry, aspeller::AffixLess<aspeller::SfxEntry> >(aspeller::SfxEntry*, aspeller::AffixLess<aspeller::SfxEntry> const&) Line | Count | Source | 139 | 7.73k | { | 140 | 7.73k | return sort(first, lt, Next<N>()); | 141 | 7.73k | } |
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 | | |