Skip to content

Commit aaf01d4

Browse files
committed
musser_nishanov inherits accelerated_linear as a / implemented in terms of.
Moved accelerated_linear into namespace detail.
1 parent 0429c34 commit aaf01d4

File tree

1 file changed

+35
-52
lines changed

1 file changed

+35
-52
lines changed

include/boost/algorithm/searching/musser_nishanov.hpp

Lines changed: 35 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,30 @@
1919

2020
namespace boost { namespace algorithm {
2121

22+
namespace detail {
23+
2224
/**
23-
* One class, two identities.
25+
* @brief Accelerated Linear search.
26+
*
27+
* Accelerated Linear (AL) search by Musser & Nishanov.
28+
*
2429
*/
25-
template <typename PatIter, typename CorpusIter = PatIter, typename Trait = search_trait<typename std::iterator_traits<PatIter>::value_type>, typename Enable = void>
26-
class musser_nishanov;
27-
2830
template <typename PatIter, typename CorpusIter = PatIter, typename Trait = search_trait<typename std::iterator_traits<PatIter>::value_type> >
2931
class accelerated_linear
3032
{
3133
BOOST_STATIC_ASSERT (( boost::is_same<
3234
typename std::iterator_traits<PatIter>::value_type,
3335
typename std::iterator_traits<CorpusIter>::value_type>::value ));
34-
36+
public:
3537
typedef typename std::iterator_traits<PatIter>::difference_type pattern_difference_type;
3638
typedef typename std::iterator_traits<CorpusIter>::difference_type corpus_difference_type;
3739

40+
protected:
3841
PatIter pat_first, pat_last;
3942
std::vector<corpus_difference_type> next_;
4043
pattern_difference_type k_pattern_length;
41-
44+
45+
private:
4246
void compute_next()
4347
{
4448
pattern_difference_type j = 0, t = -1;
@@ -55,7 +59,7 @@ class accelerated_linear
5559
}
5660

5761
public:
58-
std::pair<CorpusIter, CorpusIter> AL(CorpusIter corpus_first, CorpusIter corpus_last) const
62+
std::pair<CorpusIter, CorpusIter> operator()(CorpusIter corpus_first, CorpusIter corpus_last) const
5963
{
6064
using std::find;
6165
using std::make_pair;
@@ -131,6 +135,15 @@ class accelerated_linear
131135

132136
};
133137

138+
} // namespace detail
139+
140+
141+
/**
142+
* One class, two identities based on corpus iterator and the suffix size trait.
143+
*/
144+
template <typename PatIter, typename CorpusIter = PatIter, typename Trait = search_trait<typename std::iterator_traits<PatIter>::value_type>, typename Enable = void>
145+
class musser_nishanov;
146+
134147

135148
/**
136149
* Musser-Nishanov Accelerated Linear search algorithm.
@@ -142,20 +155,12 @@ typename disable_if<
142155
boost::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<CorpusIter>::iterator_category>,
143156
boost::mpl::bool_<Trait::suffix_size>
144157
>::type
145-
>::type> : private accelerated_linear<PatIter, CorpusIter, Trait>
158+
>::type> : public boost::algorithm::detail::accelerated_linear<PatIter, CorpusIter, Trait>
146159
{
147-
using accelerated_linear<PatIter, CorpusIter, Trait>::AL;
160+
typedef boost::algorithm::detail::accelerated_linear<PatIter, CorpusIter, Trait> AcceleratedLinear;
161+
148162
public:
149-
musser_nishanov(PatIter pat_first, PatIter pat_last) : accelerated_linear<PatIter, CorpusIter, Trait>(pat_first, pat_last) {}
150-
151-
/**
152-
* Run the search object on a corpus with forward or bidirectional iterators.
153-
*/
154-
std::pair<CorpusIter, CorpusIter>
155-
operator()(CorpusIter corpus_first, CorpusIter corpus_last) const
156-
{
157-
return AL(corpus_first, corpus_last);
158-
}
163+
musser_nishanov(PatIter pat_first, PatIter pat_last) : AcceleratedLinear(pat_first, pat_last) {}
159164
};
160165

161166

@@ -169,19 +174,18 @@ typename enable_if<
169174
boost::is_base_of<std::random_access_iterator_tag, typename std::iterator_traits<CorpusIter>::iterator_category>,
170175
boost::mpl::bool_<Trait::suffix_size>
171176
>::type
172-
>::type>
177+
>::type> : public boost::algorithm::detail::accelerated_linear<PatIter, CorpusIter, Trait>
173178
{
174-
BOOST_STATIC_ASSERT (( boost::is_same<
175-
typename std::iterator_traits<PatIter>::value_type,
176-
typename std::iterator_traits<CorpusIter>::value_type>::value ));
179+
typedef boost::algorithm::detail::accelerated_linear<PatIter, CorpusIter, Trait> AcceleratedLinear;
177180

178-
typedef typename std::iterator_traits<PatIter>::difference_type pattern_difference_type;
179-
typedef typename std::iterator_traits<CorpusIter>::difference_type corpus_difference_type;
181+
using typename AcceleratedLinear::pattern_difference_type;
182+
using typename AcceleratedLinear::corpus_difference_type;
183+
using AcceleratedLinear::k_pattern_length;
184+
using AcceleratedLinear::pat_first;
185+
using AcceleratedLinear::pat_last;
186+
using AcceleratedLinear::next_;
180187

181-
PatIter pat_first, pat_last;
182-
std::vector<corpus_difference_type> next_;
183188
boost::array<corpus_difference_type, Trait::hash_range_max> skip;
184-
pattern_difference_type k_pattern_length;
185189
corpus_difference_type mismatch_shift;
186190
boost::function<std::pair<CorpusIter, CorpusIter>(CorpusIter, CorpusIter)> search;
187191

@@ -206,7 +210,6 @@ typename enable_if<
206210
if (k >= 0) break;
207211
do // this loop is hot for data read
208212
{
209-
// unsigned char const index = Trait::hash(corpus_last + k);
210213
corpus_difference_type const increment = skip[Trait::hash(corpus_last + k)];
211214
k += increment;
212215
}
@@ -262,27 +265,7 @@ typename enable_if<
262265
return make_pair(corpus_last, corpus_last);
263266
}
264267

265-
std::pair<CorpusIter, CorpusIter> AL(CorpusIter corpus_first, CorpusIter corpus_last)
266-
{
267-
throw std::runtime_error("Not implemented!");
268-
return std::make_pair(corpus_first, corpus_last);
269-
}
270268

271-
void compute_next()
272-
{
273-
pattern_difference_type j = 0, t = -1;
274-
next_.reserve(k_pattern_length);
275-
next_.push_back(-1);
276-
while (j < k_pattern_length - 1)
277-
{
278-
while (t >= 0 && pat_first[j] != pat_first[t])
279-
t = next_[t];
280-
++j;
281-
++t;
282-
next_.push_back(pat_first[j] == pat_first[t] ? next_[t] : t);
283-
}
284-
}
285-
286269
void compute_skip()
287270
{
288271
pattern_difference_type const m = next_.size();
@@ -294,13 +277,12 @@ typename enable_if<
294277
}
295278

296279
public:
297-
musser_nishanov(PatIter pat_first, PatIter pat_last) : pat_first(pat_first), pat_last(pat_last), k_pattern_length(std::distance(pat_first, pat_last))
280+
musser_nishanov(PatIter pat_first, PatIter pat_last) : AcceleratedLinear(pat_first, pat_last)
298281
{
299282
if (k_pattern_length > 0)
300283
{
301-
compute_next();
302284
if (k_pattern_length < Trait::suffix_size)
303-
search = bind(&musser_nishanov::AL, this, _1, _2);
285+
search = bind(&AcceleratedLinear::operator(), this, _1, _2);
304286
else
305287
{
306288
search = bind(&musser_nishanov::HAL, this, _1, _2);
@@ -317,6 +299,7 @@ typename enable_if<
317299
}
318300
};
319301

302+
320303
template <typename PatIter, typename CorpusIter>
321304
std::pair<CorpusIter, CorpusIter> musser_nishanov_search(CorpusIter corpus_first, CorpusIter corpus_last, PatIter pat_first, PatIter pat_last)
322305
{

0 commit comments

Comments
 (0)