Coverage Report

Created: 2026-04-12 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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