1 // ==========================================================================
2 //                 SeqAn - The Library for Sequence Analysis
3 // ==========================================================================
4 // Copyright (c) 2006-2010, Knut Reinert, FU Berlin
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 //     * Redistributions of source code must retain the above copyright
11 //       notice, this list of conditions and the following disclaimer.
12 //     * Redistributions in binary form must reproduce the above copyright
13 //       notice, this list of conditions and the following disclaimer in the
14 //       documentation and/or other materials provided with the distribution.
15 //     * Neither the name of Knut Reinert or the FU Berlin nor the names of
16 //       its contributors may be used to endorse or promote products derived
17 //       from this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
23 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 // DAMAGE.
30 //
31 // ==========================================================================
32 // Author: Andreas Gogol-Doering <andreas.doering@mdc-berlin.de>
33 // ==========================================================================
34 // Definition of the class Pattern and supporting functions and
35 // metafunctions.
36 // ==========================================================================
37 
38 #ifndef SEQAN_HEADER_FIND_PATTERN_BASE_H
39 #define SEQAN_HEADER_FIND_PATTERN_BASE_H
40 
41 
42 //////////////////////////////////////////////////////////////////////////////
43 
44 namespace SEQAN_NAMESPACE_MAIN
45 {
46 
47 //////////////////////////////////////////////////////////////////////////////
48 
49 /**
50 .Class.Pattern:
51 ..summary:Holds the needle and preprocessing data (depends on algorithm).
52 ..cat:Searching
53 ..signature:Pattern<TNeedle[, TSpec]>
54 ..param.TNeedle:The needle type.
55 ...type:Class.String
56 ..param.TSpec:The online-algorithm to search with.
57 ...remarks:Leave empty for index-based pattern matching (see @Class.Index@).
58 ...default:The result of @Metafunction.DefaultPattern@
59 ..remarks:If $TNeedle$ is a set of strings, then $position(pattern)$ returns the index of the currently matching needle.
60 ..include:seqan/find.h
61 */
62 
63 template < typename TNeedle, typename TSpec = typename DefaultPattern<TNeedle>::Type >
64 class Pattern;
65 
66 //default implementation
67 template < typename TNeedle >
68 class Pattern<TNeedle, void>
69 {
70 public:
71 	typedef typename Position<TNeedle>::Type TNeedlePosition;
72 
73 	Holder<TNeedle> data_host;
74 	TNeedlePosition data_begin_position;
75 	TNeedlePosition data_end_position;
76 
Pattern()77 	Pattern() {}
78 
79 	template <typename TNeedle_>
Pattern(TNeedle_ & ndl)80 	Pattern(TNeedle_ & ndl):
81 		data_host(ndl) {}
82 
83 	template <typename TNeedle_>
Pattern(TNeedle_ const & ndl)84 	Pattern(TNeedle_ const & ndl):
85 		data_host(ndl) {}
86 
87 };
88 //////////////////////////////////////////////////////////////////////////////
89 
90 
91 template <typename TNeedle, typename TSpec>
92 struct Container< Pattern<TNeedle, TSpec> > {
93 	typedef TNeedle Type;
94 };
95 
96 template <typename TNeedle, typename TSpec>
97 struct Container< Pattern<TNeedle, TSpec> const > {
98 	typedef TNeedle const Type;
99 };
100 
101 ///.Metafunction.Host.param.T.type:Class.Pattern
102 template <typename TNeedle, typename TSpec>
103 struct Host< Pattern<TNeedle, TSpec> > {
104 	typedef TNeedle Type;
105 };
106 
107 template <typename TNeedle, typename TSpec>
108 struct Host< Pattern<TNeedle, TSpec> const > {
109 	typedef TNeedle const Type;
110 };
111 
112 
113 template <typename TPattern, typename TSpec>
114 struct Value< Pattern<TPattern, TSpec> > {
115 	typedef typename Value<TPattern>::Type Type;
116 };
117 
118 template <typename TPattern, typename TSpec>
119 struct Position< Pattern<TPattern, TSpec> > {
120 	typedef typename Position<TPattern>::Type Type;
121 };
122 
123 template <typename TPattern, typename TSpec>
124 struct Difference< Pattern<TPattern, TSpec> > {
125 	typedef typename Difference<TPattern>::Type Type;
126 };
127 
128 template <typename TPattern, typename TSpec>
129 struct Size< Pattern<TPattern, TSpec> > {
130 	typedef typename Size<TPattern>::Type Type;
131 };
132 
133 
134 //////////////////////////////////////////////////////////////////////////////
135 
136 /**
137 .Metafunction.ScoringScheme:
138 ..summary:Returns the scoring scheme of an approximate searching algorithm.
139 ..cat:Searching
140 ..signature:ScoringScheme<TPattern>::Type
141 ..param.TPattern:A @Class.Pattern@ type.
142 ...type:Class.Pattern
143 ..returns:The scoring scheme.
144 ...default:@Shortcut.EditDistanceScore@
145 ..include:seqan/find.h
146 */
147 
148 template <typename TNeedle>
149 struct ScoringScheme
150 {
151 	typedef EditDistanceScore Type;
152 };
153 template <typename TNeedle>
154 struct ScoringScheme<TNeedle const>:
155 	ScoringScheme<TNeedle>
156 {
157 };
158 
159 //////////////////////////////////////////////////////////////////////////////
160 
161 template <typename TNeedle, typename TSpec>
162 inline Holder<TNeedle> &
163 _dataHost(Pattern<TNeedle, TSpec> & me)
164 {
165 	return me.data_host;
166 }
167 template <typename TNeedle, typename TSpec>
168 inline Holder<TNeedle> &
169 _dataHost(Pattern<TNeedle, TSpec> const & me)
170 {
171 	return const_cast<Holder<TNeedle> &>(me.data_host);
172 }
173 
174 //host access: see basic_host.h
175 
176 
177 //???TODO: Diese Funktion entfernen! (sobald setHost bei anderen pattern nicht mehr eine Art "assignHost" ist)
178 template <typename TNeedle, typename TSpec, typename TNeedle2>
179 inline void
180 setHost(Pattern<TNeedle, TSpec> & me,
181 		TNeedle2 const & ndl)
182 {
183 	 me.data_host = ndl; //assign => Pattern haelt eine Kopie => doof!
184 }
185 template <typename TNeedle, typename TSpec, typename TNeedle2>
186 inline void
187 setHost(Pattern<TNeedle, TSpec> & me,
188 		TNeedle2 & ndl)
189 {
190 	 me.data_host = ndl; //assign => Pattern haelt eine Kopie => doof!
191 }
192 //////////////////////////////////////////////////////////////////////////////
193 
194 template <typename TNeedle, typename TSpec>
195 inline typename Position<Pattern<TNeedle, TSpec> >::Type &
196 beginPosition(Pattern<TNeedle, TSpec> & me)
197 {
198 	return me.data_begin_position;
199 }
200 template <typename TNeedle, typename TSpec>
201 inline typename Position<Pattern<TNeedle, TSpec> const >::Type &
202 beginPosition(Pattern<TNeedle, TSpec> const & me)
203 {
204 	return me.data_begin_position;
205 }
206 
207 
208 template <typename TNeedle, typename TSpec, typename TPosition>
209 inline void
210 setBeginPosition(Pattern<TNeedle, TSpec> & me,
211 				 TPosition _pos)
212 {
213 	me.data_begin_position = _pos;
214 }
215 
216 //////////////////////////////////////////////////////////////////////////////
217 
218 template <typename TNeedle, typename TSpec>
219 inline typename Position<Pattern<TNeedle, TSpec> >::Type &
220 endPosition(Pattern<TNeedle, TSpec> & me)
221 {
222 	return me.data_end_position;
223 }
224 template <typename TNeedle, typename TSpec>
225 inline typename Position<Pattern<TNeedle, TSpec> const >::Type &
226 endPosition(Pattern<TNeedle, TSpec> const & me)
227 {
228 	return me.data_end_position;
229 }
230 
231 template <typename TNeedle, typename TSpec, typename TPosition>
232 inline void
233 setEndPosition(Pattern<TNeedle, TSpec> & me,
234 			   TPosition _pos)
235 {
236 	me.data_end_position = _pos;
237 }
238 
239 //////////////////////////////////////////////////////////////////////////////
240 
241 template <typename TNeedle, typename TSpec>
242 inline typename Infix<TNeedle>::Type
243 segment(Pattern<TNeedle, TSpec> & me)
244 {
245 	typedef typename Infix<TNeedle>::Type TInfix;
246 	return TInfix(host(me), me.data_begin_position, me.data_end_position);
247 }
248 template <typename TNeedle, typename TSpec>
249 inline typename Infix<TNeedle>::Type
250 segment(Pattern<TNeedle, TSpec> const & me)
251 {
252 	typedef typename Infix<TNeedle>::Type TInfix;
253 	return TInfix(host(me), me.data_begin_position, me.data_end_position);
254 }
255 
256 //////////////////////////////////////////////////////////////////////////////
257 
258 ///.Function.host.param.object.type:Class.Pattern
259 
260 template <typename TNeedle, typename TSpec>
261 inline typename Host<Pattern<TNeedle, TSpec> >::Type &
262 host(Pattern<TNeedle, TSpec> & me)
263 {
264 SEQAN_CHECKPOINT
265 	return value(me.data_host);
266 }
267 
268 template <typename TNeedle, typename TSpec>
269 inline typename Host<Pattern<TNeedle, TSpec> const>::Type &
270 host(Pattern<TNeedle, TSpec> const & me)
271 {
272 SEQAN_CHECKPOINT
273 	return value(me.data_host);
274 }
275 
276 
277 //////////////////////////////////////////////////////////////////////////////
278 
279 /**
280 .Function.needle:
281 ..summary:Returns the needle of a @Class.Pattern@ object (not implemented for some online-algorithms).
282 ..cat:Searching
283 ..signature:needle(pattern)
284 ..param.pattern:The @Class.Pattern@ object to search with.
285 ...type:Class.Pattern
286 ..returns:The needle object to search for.
287 ..remarks:The result type is @Metafunction.Needle@$<TPattern>::Type$ for pattern of type $TPattern$.
288 This is an alias to function @Function.host@ of the pattern function.
289 ..see:Function.host
290 ..include:seqan/find.h
291 */
292 ///.Function.host.remarks:Aliased to @Function.needle@ and @Function.haystack@ for classes @Class.Pattern@ and @Class.Finder@.
293 
294 
295 template < typename TObject >
296 inline typename Needle<TObject>::Type &
297 needle(TObject &obj)
298 {
299 	return obj;
300 }
301 
302 template < typename TObject >
303 inline typename Needle<TObject const>::Type &
304 needle(TObject const &obj)
305 {
306 	return obj;
307 }
308 
309 
310 ///.Function.position.param.iterator.type:Class.Pattern
311 
312 template < typename TNeedle, typename TSpec >
313 inline typename Needle< Pattern<TNeedle, TSpec> >::Type &
314 needle(Pattern<TNeedle, TSpec> & obj)
315 {
316 	return host(obj);
317 }
318 
319 template < typename TNeedle, typename TSpec >
320 inline typename Needle< Pattern<TNeedle, TSpec> const>::Type &
321 needle(Pattern<TNeedle, TSpec> const & obj)
322 {
323 	return host(obj);
324 }
325 
326 /**
327 .Function.setNeedle:
328 ..summary:Sets the needle of a @Class.Pattern@ object and optionally induces preprocessing.
329 ..cat:Searching
330 ..signature:setNeedle(pattern, needle)
331 ..param.pattern:The @Class.Pattern@ object to search with.
332 ...type:Class.Pattern
333 ..param.needle:The needle object to search for.
334 ...type:Class.String
335 ..include:seqan/find.h
336 */
337 
338 template < typename TNeedle, typename TSpec >
339 inline void
340 setNeedle(Pattern<TNeedle, TSpec> &obj, TNeedle const &ndl) {
341 	setHost(obj, ndl);
342 }
343 
344 
345 //____________________________________________________________________________
346 
347 /**.Function.scoringScheme
348 ..cat:Searching
349 ..summary:The @glos:scoring scheme@ used for finding or aligning.
350 ..signature:scoringScheme(obj)
351 ..param.obj:Object that holds a @glos:scoring scheme@
352 ...type:Class.Pattern
353 ..returns:The @glos:scoring scheme@ used in $obj$
354 ...default:@Shortcut.EditDistanceScore@
355 ..see:glos:scoring scheme
356 ..see:Metafunction.ScoringScheme
357 */
358 
359 template <typename TNeedle, typename TSpec>
360 inline typename ScoringScheme<Pattern<TNeedle, TSpec> >::Type
361 scoringScheme(Pattern<TNeedle, TSpec> &)
362 {
363 SEQAN_CHECKPOINT
364 	return typename ScoringScheme<Pattern<TNeedle, TSpec> >::Type();
365 }
366 template <typename TNeedle, typename TSpec>
367 inline typename ScoringScheme<Pattern<TNeedle, TSpec> const>::Type
368 scoringScheme(Pattern<TNeedle, TSpec> const &)
369 {
370 SEQAN_CHECKPOINT
371 	return typename ScoringScheme<Pattern<TNeedle, TSpec> const>::Type();
372 }
373 
374 //____________________________________________________________________________
375 
376 /**.Function.setScoringScheme
377 ..cat:Searching
378 ..summary:Sets the @glos:scoring scheme@ used for finding or aligning.
379 ..signature:setScoringScheme(obj, score)
380 ..param.obj:Object that holds a @glos:scoring scheme@.
381 ...type:Class.Pattern
382 ..param.score:The new @glos:scoring scheme@ used by $obj$.
383 ..see:glos:scoring scheme
384 ..see:Function.scoringScheme
385 */
386 
387 template <typename TNeedle, typename TSpec, typename TScore2>
388 inline void
389 setScoringScheme(Pattern<TNeedle, TSpec> & /*me*/,
390 				 TScore2 & /*score*/)
391 {
392 //dummy implementation for compatibility reasons
393 }
394 //////////////////////////////////////////////////////////////////////////////
395 
396 }// namespace SEQAN_NAMESPACE_MAIN
397 
398 #endif //#ifndef SEQAN_HEADER_...
399