1 // ==========================================================================
2 //                 SeqAn - The Library for Sequence Analysis
3 // ==========================================================================
4 // Copyright (c) 2006-2018, 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: Enrico Siragusa <enrico.siragusa@fu-berlin.de>
33 // ==========================================================================
34 // A Position ModifiedString represents a permutation of the host string.
35 
36 #ifndef SEQAN_MODIFIER_MODIFIER_POSITION_H_
37 #define SEQAN_MODIFIER_MODIFIER_POSITION_H_
38 
39 namespace seqan {
40 
41 // ============================================================================
42 // Tags, Classes, Enums
43 // ============================================================================
44 
45 // ----------------------------------------------------------------------------
46 // Tag ModPos
47 // ----------------------------------------------------------------------------
48 
49 template <typename TPositions>
50 struct ModPos {};
51 
52 // ============================================================================
53 // Metafunctions
54 // ============================================================================
55 
56 // --------------------------------------------------------------------------
57 // Metafunction Cargo
58 // --------------------------------------------------------------------------
59 
60 template <typename THost, typename TPositions>
61 struct Cargo<ModifiedString<THost, ModPos<TPositions> > >
62 {
63     typedef typename Pointer_<TPositions>::Type  Type;
64 };
65 
66 template <typename THost, typename TPositions>
67 struct Cargo<ModifiedString<THost, ModPos<TPositions> > const>
68 {
69     typedef typename Pointer_<TPositions>::Type const Type;
70 };
71 
72 // ----------------------------------------------------------------------------
73 // Metafunction Value
74 // ----------------------------------------------------------------------------
75 
76 template <typename THost, typename TPositions>
77 struct Value<ModifiedString<THost, ModPos<TPositions> > > : Value<THost> {};
78 
79 template <typename THost, typename TPositions>
80 struct Value<ModifiedString<THost, ModPos<TPositions> > const> : Value<THost> {};
81 
82 // ----------------------------------------------------------------------------
83 // Metafunction GetValue
84 // ----------------------------------------------------------------------------
85 
86 template <typename THost, typename TPositions>
87 struct GetValue<ModifiedString<THost, ModPos<TPositions> > > : GetValue<THost> {};
88 
89 template <typename THost, typename TPositions>
90 struct GetValue<ModifiedString<THost, ModPos<TPositions> > const> : GetValue<THost> {};
91 
92 // ----------------------------------------------------------------------------
93 // Metafunction Reference
94 // ----------------------------------------------------------------------------
95 
96 template <typename THost, typename TPositions>
97 struct Reference<ModifiedString<THost, ModPos<TPositions> > > : Reference<THost> {};
98 
99 template <typename THost, typename TPositions>
100 struct Reference<ModifiedString<THost, ModPos<TPositions> > const> : Reference<THost> {};
101 
102 // ----------------------------------------------------------------------------
103 // Metafunction Difference
104 // ----------------------------------------------------------------------------
105 
106 template <typename THost, typename TPositions>
107 struct Difference<ModifiedString<THost, ModPos<TPositions> > > : Difference<TPositions> {};
108 
109 // ----------------------------------------------------------------------------
110 // Metafunction Size
111 // ----------------------------------------------------------------------------
112 
113 template <typename THost, typename TPositions>
114 struct Size<ModifiedString<THost, ModPos<TPositions> > > : Size<TPositions> {};
115 
116 // ----------------------------------------------------------------------------
117 // Metafunction Position
118 // ----------------------------------------------------------------------------
119 
120 template <typename THost, typename TPositions>
121 struct Position<ModifiedString<THost, ModPos<TPositions> > > : Position<TPositions> {};
122 
123 // ----------------------------------------------------------------------------
124 // Metafunction Iterator
125 // ----------------------------------------------------------------------------
126 
127 template <typename THost, typename TPositions>
128 struct Iterator<ModifiedString<THost, ModPos<TPositions> >, Standard>
129 {
130     typedef Iter<ModifiedString<THost, ModPos<TPositions> >, PositionIterator>   Type;
131 };
132 
133 template <typename THost, typename TPositions>
134 struct Iterator<ModifiedString<THost, ModPos<TPositions> > const, Standard>
135 {
136     typedef Iter<ModifiedString<THost, ModPos<TPositions> > const, PositionIterator>   Type;
137 };
138 
139 template <typename THost, typename TPositions>
140 struct Iterator<ModifiedString<THost, ModPos<TPositions> >, Rooted>
141 {
142     typedef Iter<ModifiedString<THost, ModPos<TPositions> >, PositionIterator>   Type;
143 };
144 
145 template <typename THost, typename TPositions>
146 struct Iterator<ModifiedString<THost, ModPos<TPositions> > const, Rooted>
147 {
148     typedef Iter<ModifiedString<THost, ModPos<TPositions> > const, PositionIterator>   Type;
149 };
150 
151 // ----------------------------------------------------------------------------
152 // Metafunction Prefix
153 // ----------------------------------------------------------------------------
154 // NOTE(esiragusa): not implemented.
155 
156 // ----------------------------------------------------------------------------
157 // Metafunction Suffix
158 // ----------------------------------------------------------------------------
159 // NOTE(esiragusa): not implemented.
160 
161 // ----------------------------------------------------------------------------
162 // Metafunction Infix
163 // ----------------------------------------------------------------------------
164 
165 template <typename THost, typename TPositions>
166 struct Infix<ModifiedString<THost, ModPos<TPositions> > >
167 {
168     typedef ModifiedString<THost, ModPos<typename Infix<TPositions>::Type> >    Type;
169 };
170 
171 template <typename THost, typename TPositions>
172 struct Infix<ModifiedString<THost, ModPos<TPositions> > const>
173 {
174     typedef ModifiedString<THost, ModPos<typename Infix<TPositions>::Type> > const   Type;
175 };
176 
177 // --------------------------------------------------------------------------
178 // Metafunction AllowsFastRandomAccess
179 // --------------------------------------------------------------------------
180 
181 template <typename THost, typename TPositions>
182 struct AllowsFastRandomAccess<ModifiedString<THost, ModPos<TPositions> > > :
183     And<AllowsFastRandomAccess<THost>, AllowsFastRandomAccess<TPositions> >
184 {};
185 
186 // ============================================================================
187 // Functions
188 // ============================================================================
189 
190 // --------------------------------------------------------------------------
191 // Function cargo()
192 // --------------------------------------------------------------------------
193 
194 template <typename THost, typename TPositions>
195 inline typename Parameter_<TPositions>::Type
196 cargo(ModifiedString<THost, ModPos<TPositions> > & me)
197 {
198     return _toParameter<TPositions>(me._cargo);
199 }
200 
201 template <typename THost, typename TPositions>
202 inline typename Parameter_<TPositions>::Type
203 cargo(ModifiedString<THost, ModPos<TPositions> > const & me)
204 {
205     return _toParameter<TPositions>(me._cargo);
206 }
207 
208 // --------------------------------------------------------------------------
209 // Function setCargo()
210 // --------------------------------------------------------------------------
211 
212 template <typename THost, typename TPositions>
213 inline void
214 setCargo(ModifiedString<THost, ModPos<TPositions> > & me, typename Parameter_<TPositions>::Type _cargo)
215 {
216     me._cargo = _toPointer(_cargo);
217 }
218 
219 // ----------------------------------------------------------------------------
220 // Function begin()
221 // ----------------------------------------------------------------------------
222 
223 template <typename THost, typename TPositions, typename TTagSpec>
224 inline typename Iterator<ModifiedString<THost, ModPos<TPositions> >, Tag<TTagSpec> const>::Type
225 begin(ModifiedString<THost, ModPos<TPositions> > & me, Tag<TTagSpec> const /* tag */)
226 {
227     return typename Iterator<ModifiedString<THost, ModPos<TPositions> >, Tag<TTagSpec> const>::Type(me);
228 }
229 
230 template <typename THost, typename TPositions, typename TTagSpec>
231 inline typename Iterator<ModifiedString<THost, ModPos<TPositions> > const, Tag<TTagSpec> const>::Type
232 begin(ModifiedString<THost, ModPos<TPositions> > const & me, Tag<TTagSpec> const /* tag */)
233 {
234     return typename Iterator<ModifiedString<THost, ModPos<TPositions> > const, Tag<TTagSpec> const>::Type(me);
235 }
236 
237 // ----------------------------------------------------------------------------
238 // Function end()
239 // ----------------------------------------------------------------------------
240 
241 template <typename THost, typename TPositions, typename TTagSpec>
242 inline typename Iterator<ModifiedString<THost, ModPos<TPositions> >, Tag<TTagSpec> const>::Type
243 end(ModifiedString<THost, ModPos<TPositions> > & me, Tag<TTagSpec> const /* tag */)
244 {
245     return typename Iterator<ModifiedString<THost, ModPos<TPositions> >, Tag<TTagSpec> const>::Type(me, length(me));
246 }
247 
248 template <typename THost, typename TPositions, typename TTagSpec>
249 inline typename Iterator<ModifiedString<THost, ModPos<TPositions> > const, Tag<TTagSpec> const>::Type
250 end(ModifiedString<THost, ModPos<TPositions> > const & me, Tag<TTagSpec> const /* tag */)
251 {
252     return typename Iterator<ModifiedString<THost, ModPos<TPositions> > const, Tag<TTagSpec> const>::Type(me, length(me));
253 }
254 
255 // ----------------------------------------------------------------------------
256 // Function value()
257 // ----------------------------------------------------------------------------
258 
259 template <typename THost, typename TPositions, typename TPos>
260 inline typename Reference<ModifiedString<THost, ModPos<TPositions> > >::Type
261 value(ModifiedString<THost, ModPos<TPositions> > & me, TPos pos)
262 {
263     return value(host(me), getValue(cargo(me), pos));
264 }
265 
266 template <typename THost, typename TPositions, typename TPos>
267 inline typename Reference<ModifiedString<THost, ModPos<TPositions> > const>::Type
268 value(ModifiedString<THost, ModPos<TPositions> > const & me, TPos pos)
269 {
270     return value(host(me), getValue(cargo(me), pos));
271 }
272 
273 // ----------------------------------------------------------------------------
274 // Function getValue()
275 // ----------------------------------------------------------------------------
276 
277 template <typename THost, typename TPositions, typename TPos>
278 inline typename GetValue<ModifiedString<THost, ModPos<TPositions> > >::Type
279 getValue(ModifiedString<THost, ModPos<TPositions> > & me, TPos pos)
280 {
281     return getValue(host(me), getValue(cargo(me), pos));
282 }
283 
284 template <typename THost, typename TPositions, typename TPos>
285 inline typename GetValue<ModifiedString<THost, ModPos<TPositions> > const>::Type
286 getValue(ModifiedString<THost, ModPos<TPositions> > const & me, TPos pos)
287 {
288     return getValue(host(me), getValue(cargo(me), pos));
289 }
290 
291 // ----------------------------------------------------------------------------
292 // Function length()
293 // ----------------------------------------------------------------------------
294 
295 template <typename THost, typename TPositions>
296 inline typename Size<ModifiedString<THost, ModPos<TPositions> > >::Type
297 length(ModifiedString<THost, ModPos<TPositions> > const & me)
298 {
299     return length(cargo(me));
300 }
301 
302 // ----------------------------------------------------------------------------
303 // Function empty()
304 // ----------------------------------------------------------------------------
305 
306 template <typename THost, typename TPositions>
307 inline bool empty(ModifiedString<THost, ModPos<TPositions> > const & me)
308 {
309     return empty(cargo(me));
310 }
311 
312 // ----------------------------------------------------------------------------
313 // Function clear()
314 // ----------------------------------------------------------------------------
315 
316 template <typename THost, typename TPositions>
317 inline void clear(ModifiedString<THost, ModPos<TPositions> > & me)
318 {
319     clear(cargo(me));
320 }
321 
322 // ----------------------------------------------------------------------------
323 // Function resize()
324 // ----------------------------------------------------------------------------
325 // NOTE(esiragusa): a dummy implementation like ContainerView could be necessary.
326 
327 // ----------------------------------------------------------------------------
328 // Function prefix()
329 // ----------------------------------------------------------------------------
330 // NOTE(esiragusa): not implemented.
331 
332 // ----------------------------------------------------------------------------
333 // Function suffix()
334 // ----------------------------------------------------------------------------
335 // NOTE(esiragusa): not implemented.
336 
337 // ----------------------------------------------------------------------------
338 // Function infix()
339 // ----------------------------------------------------------------------------
340 
341 template <typename THost, typename TPositions, typename TPosBegin, typename TPosEnd>
342 inline typename Infix<ModifiedString<THost, ModPos<TPositions> > const>::Type
343 infix(ModifiedString<THost, ModPos<TPositions> > const & me, TPosBegin pos_begin, TPosEnd pos_end)
344 {
345     typename Infix<ModifiedString<THost, ModPos<TPositions> > const>::Type other;
346     setHost(other, host(me));
347     setCargo(other, infix(cargo(me), pos_begin, pos_end));
348     return other;
349 }
350 
351 template <typename THost, typename TPositions, typename TPosBegin, typename TPosEnd>
352 inline typename Infix<ModifiedString<THost, ModPos<TPositions> > >::Type
353 infix(ModifiedString<THost, ModPos<TPositions> > & me, TPosBegin pos_begin, TPosEnd pos_end)
354 {
355     typename Infix<ModifiedString<THost, ModPos<TPositions> > >::Type other;
356     setHost(other, host(me));
357     setCargo(other, infix(cargo(me), pos_begin, pos_end));
358     return other;
359 }
360 
361 // ----------------------------------------------------------------------------
362 // Function position()
363 // ----------------------------------------------------------------------------
364 
365 template <typename THost, typename TPositions, typename TPos>
366 inline typename Position<ModifiedString<THost, ModPos<TPositions> > const>::Type
367 position(ModifiedString<THost, ModPos<TPositions> > const & me, TPos i)
368 {
369     return getValue(cargo(me), i);
370 }
371 
372 // ----------------------------------------------------------------------------
373 // Function setPosition()
374 // ----------------------------------------------------------------------------
375 
376 template <typename THost, typename TPositions, typename TPos>
377 inline void setPosition(ModifiedString<THost, ModPos<TPositions> > & me, TPos i, TPos j)
378 {
379     assignValue(cargo(me), i, j);
380 }
381 
382 template <typename THost, typename TPositions, typename TPos>
383 inline void setPosition(ModifiedString<THost, ModPos<TPositions> > const & me, TPos i, TPos j)
384 {
385     assignValue(cargo(me), i, j);
386 }
387 
388 // ----------------------------------------------------------------------------
389 // Functor PosLess_
390 // ----------------------------------------------------------------------------
391 
392 template <typename THost, typename TPos = typename Position<THost>::Type, typename TPredicate = std::less<TPos> >
393 struct PosLess_ : public std::binary_function<TPos, TPos, bool>
394 {
395     THost const & _host;
396     TPredicate pred;
397 
398     PosLess_(THost const & _host) :
399         _host(_host)
400     {}
401 
402     PosLess_(THost const & _host, TPredicate const & pred) :
403         _host(_host),
404         pred(pred)
405     {}
406 
407     bool operator()(TPos a, TPos b)
408     {
409         return pred(getValue(_host, a), getValue(_host, b));
410     }
411 };
412 
413 // ----------------------------------------------------------------------------
414 // Function sort()
415 // ----------------------------------------------------------------------------
416 
417 template <typename THost, typename TPositions, typename TBinaryPredicate, typename TParallelTag>
418 inline void sort(ModifiedString<THost, ModPos<TPositions> > & me, TBinaryPredicate p, Tag<TParallelTag> const & tag)
419 {
420     typedef typename Position<ModifiedString<THost, ModPos<TPositions> > >::Type TPos;
421 
422     sort(cargo(me), PosLess_<THost, TPos, TBinaryPredicate>(host(me), p), tag);
423 }
424 
425 template <typename THost, typename TPositions, typename TParallelTag>
426 inline void sort(ModifiedString<THost, ModPos<TPositions> > & me, Tag<TParallelTag> const & tag)
427 {
428     typedef typename Position<ModifiedString<THost, ModPos<TPositions> > >::Type TPos;
429 
430     sort(cargo(me), PosLess_<THost, TPos>(host(me)), tag);
431 }
432 
433 template <typename THost, typename TPositions, typename TBinaryPredicate, typename TParallelTag>
434 inline void sort(ModifiedString<THost, ModPos<TPositions> > const & me, TBinaryPredicate p, Tag<TParallelTag> const & tag)
435 {
436     typedef typename Position<ModifiedString<THost, ModPos<TPositions> > >::Type TPos;
437 
438     sort(cargo(me), PosLess_<THost, TPos, TBinaryPredicate>(host(me), p), tag);
439 }
440 
441 template <typename THost, typename TPositions, typename TParallelTag>
442 inline void sort(ModifiedString<THost, ModPos<TPositions> > const & me, Tag<TParallelTag> const & tag)
443 {
444     typedef typename Position<ModifiedString<THost, ModPos<TPositions> > >::Type TPos;
445 
446     sort(cargo(me), PosLess_<THost, TPos>(host(me)), tag);
447 }
448 
449 }  // namespace seqan
450 
451 #endif  // SEQAN_MODIFIER_MODIFIER_POSITION_H_
452