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: Andreas Gogol-Döring <andreas.doering@mdc-berlin.de>
33 // ==========================================================================
34 // Proxy base class definition.
35 // ==========================================================================
36 
37 #ifndef SEQAN_INCLUDE_SEQAN_BASIC_PROXY_BASE_H_
38 #define SEQAN_INCLUDE_SEQAN_BASIC_PROXY_BASE_H_
39 
40 namespace seqan {
41 
42 // ============================================================================
43 // Forwards
44 // ============================================================================
45 
46 // ============================================================================
47 // Tags, Classes, Enums
48 // ============================================================================
49 
50 /*!
51  * @class Proxy
52  * @headerfile <seqan/basic.h>
53  * @brief Emulates object of another class.
54  *
55  * @signature template <typename TSpec>
56  *            class Proxy;
57  *
58  * @tparam TSpec The specializing types.
59  *
60  * Use Value to get the emulated type. An instance of <tt>Proxy</tt> behaves like an object of its value
61  * type.  <tt>Proxy</tt> can be used as reference type (see Reference).
62  *
63  * Note that functions that are both general and specialized for the value type should be specialized for
64  * <tt>Proxy&lt;TSpec&gt;</tt> too, since otherwise the general version will be called.
65  */
66 
67 template <typename TSpec>
68 class Proxy;
69 
70 // ============================================================================
71 // Metafunctions
72 // ============================================================================
73 
74 // ----------------------------------------------------------------------------
75 // Metafunction Value
76 // ----------------------------------------------------------------------------
77 
78 /*!
79  * @mfn Proxy#Value
80  * @brief Return emulated type.
81  *
82  * @signature Value<TProxy>::Type;
83  *
84  * @tparam TProxy The proxy type to query.
85  *
86  * @return Type The emulated type.
87  */
88 
89 // ----------------------------------------------------------------------------
90 // Metafunction Spec
91 // ----------------------------------------------------------------------------
92 
93 /*!
94  * @mfn Proxy#Spec
95  * @brief Return specialization tag of Proxy.
96  *
97  * @signature Spec<TProxy>::Type;
98  *
99  * @tparam TProxy The proxy type to query.
100  *
101  * @return Type The specializing tag.
102  */
103 
104 template <typename TSpec>
105 struct Spec<Proxy<TSpec> >
106 {
107     typedef TSpec Type;
108 };
109 
110 template <typename TSpec>
111 struct Spec<Proxy<TSpec> const>
112 {
113     typedef TSpec Type;
114 };
115 
116 // ----------------------------------------------------------------------------
117 // Metafunction CompareType
118 // ----------------------------------------------------------------------------
119 
120 template <typename TSpec, typename T>
121 struct CompareType<Proxy<TSpec>, T>
122 {
123     typedef typename Value<Proxy<TSpec> >::Type TValue;
124     typedef typename RemoveConst_<TValue>::Type TValue_NoConst;
125     typedef typename CompareType<TValue_NoConst, T>::Type Type;
126 };
127 
128 // ============================================================================
129 // Functions
130 // ============================================================================
131 
132 // ----------------------------------------------------------------------------
133 // Function convertImpl()
134 // ----------------------------------------------------------------------------
135 
136 // TODO(holtgrew): First variant even necessary?
137 
138 template <typename TTarget, typename T, typename TSpec>
139 inline typename Convert<TTarget, Proxy<TSpec> >::Type
140 convertImpl(Convert<TTarget, T> const,
141             Proxy<TSpec> & source)
142 {
143     return convert<TTarget>(getValue(source));
144 }
145 
146 template <typename TTarget, typename T, typename TSpec>
147 inline typename Convert<TTarget, Proxy<TSpec> const>::Type
148 convertImpl(Convert<TTarget, T> const,
149             Proxy<TSpec> const & source)
150 {
151     return convert<TTarget>(getValue(source));
152 }
153 
154 // ----------------------------------------------------------------------------
155 // Function operator==()
156 // ----------------------------------------------------------------------------
157 
158 template <typename TSpec, typename TRight>
159 inline bool
160 operator==(Proxy<TSpec> const & left_,
161            TRight const & right_)
162 {
163     typedef Proxy<TSpec> TLeft;
164     typedef typename CompareType<TLeft, TRight>::Type TCompareType;
165     return convert<TCompareType>(left_) == convert<TCompareType>(right_);
166 }
167 
168 template <typename TLeft, typename TSpec>
169 inline bool
170 operator==(TLeft const & left_,
171            Proxy<TSpec> const & right_)
172 {
173     typedef Proxy<TSpec> TRight;
174     typedef typename CompareType<TRight, TLeft>::Type TCompareType;
175     return convert<TCompareType>(left_) == convert<TCompareType>(right_);
176 }
177 
178 template <typename TLeftSpec, typename TRightSpec>
179 inline bool
180 operator==(Proxy<TLeftSpec> const & left_,
181            Proxy<TRightSpec> const & right_)
182 {
183     typedef Proxy<TLeftSpec> TLeft;
184     typedef Proxy<TRightSpec> TRight;
185     typedef typename CompareType<TLeft, TRight>::Type TCompareType;
186     return convert<TCompareType>(left_) == convert<TCompareType>(right_);
187 }
188 
189 template <typename TSpec>
190 inline bool
191 operator==(Proxy<TSpec> const & left_,
192            Proxy<TSpec> const & right_)
193 {
194     typedef typename GetValue<Proxy<TSpec> >::Type TAccessor;
195     return convert<TAccessor>(left_) == convert<TAccessor>(right_);
196 }
197 
198 // ----------------------------------------------------------------------------
199 // Function operator!=()
200 // ----------------------------------------------------------------------------
201 
202 template <typename TSpec, typename TRight>
203 inline bool
204 operator!=(Proxy<TSpec> const & left_,
205            TRight const & right_)
206 {
207     typedef Proxy<TSpec> TLeft;
208     typedef typename CompareType<TLeft, TRight>::Type TCompareType;
209     return convert<TCompareType>(left_) != convert<TCompareType>(right_);
210 }
211 
212 template <typename TLeft, typename TSpec>
213 inline bool
214 operator!=(TLeft const & left_,
215            Proxy<TSpec> const & right_)
216 {
217     typedef Proxy<TSpec> TRight;
218     typedef typename CompareType<TRight, TLeft>::Type TCompareType;
219     return convert<TCompareType>(left_) != convert<TCompareType>(right_);
220 }
221 
222 template <typename TLeftSpec, typename TRightSpec>
223 inline bool
224 operator!=(Proxy<TLeftSpec> const & left_,
225            Proxy<TRightSpec> const & right_)
226 {
227     typedef Proxy<TLeftSpec> TLeft;
228     typedef Proxy<TRightSpec> TRight;
229     typedef typename CompareType<TLeft, TRight>::Type TCompareType;
230     return convert<TCompareType>(left_) != convert<TCompareType>(right_);
231 }
232 
233 template <typename TSpec>
234 inline bool
235 operator!=(Proxy<TSpec> const & left_,
236            Proxy<TSpec> const & right_)
237 {
238     typedef typename GetValue<Proxy<TSpec> >::Type TAccessor;
239     return convert<TAccessor>(left_) != convert<TAccessor>(right_);
240 }
241 
242 // ----------------------------------------------------------------------------
243 // Function operator<()
244 // ----------------------------------------------------------------------------
245 
246 template <typename TSpec, typename TRight>
247 inline bool
248 operator<(Proxy<TSpec> const & left_,
249           TRight const & right_)
250 {
251     typedef Proxy<TSpec> TLeft;
252     typedef typename CompareType<TLeft, TRight>::Type TCompareType;
253     return convert<TCompareType>(left_) < convert<TCompareType>(right_);
254 }
255 
256 template <typename TLeft, typename TSpec>
257 inline bool
258 operator<(TLeft const & left_,
259           Proxy<TSpec> const & right_)
260 {
261     typedef Proxy<TSpec> TRight;
262     typedef typename CompareType<TRight, TLeft>::Type TCompareType;
263     return convert<TCompareType>(left_) < convert<TCompareType>(right_);
264 }
265 
266 template <typename TLeftSpec, typename TRightSpec>
267 inline bool
268 operator<(Proxy<TLeftSpec> const & left_,
269           Proxy<TRightSpec> const & right_)
270 {
271     typedef Proxy<TLeftSpec> TLeft;
272     typedef Proxy<TRightSpec> TRight;
273     typedef typename CompareType<TLeft, TRight>::Type TCompareType;
274     return convert<TCompareType>(left_) < convert<TCompareType>(right_);
275 }
276 
277 template <typename TSpec>
278 inline bool
279 operator<(Proxy<TSpec> const & left_,
280           Proxy<TSpec> const & right_)
281 {
282     typedef typename GetValue<Proxy<TSpec> >::Type TAccessor;
283     return convert<TAccessor>(left_) < convert<TAccessor>(right_);
284 }
285 
286 // ----------------------------------------------------------------------------
287 // Function operator<=()
288 // ----------------------------------------------------------------------------
289 
290 template <typename TSpec, typename TRight>
291 inline bool
292 operator<=(Proxy<TSpec> const & left_,
293            TRight const & right_)
294 {
295     typedef Proxy<TSpec> TLeft;
296     typedef typename CompareType<TLeft, TRight>::Type TCompareType;
297     return convert<TCompareType>(left_) <= convert<TCompareType>(right_);
298 }
299 
300 template <typename TLeft, typename TSpec>
301 inline bool
302 operator<=(TLeft const & left_,
303            Proxy<TSpec> const & right_)
304 {
305     typedef Proxy<TSpec> TRight;
306     typedef typename CompareType<TRight, TLeft>::Type TCompareType;
307     return convert<TCompareType>(left_) <= convert<TCompareType>(right_);
308 }
309 
310 template <typename TLeftSpec, typename TRightSpec>
311 inline bool
312 operator<=(Proxy<TLeftSpec> const & left_,
313            Proxy<TRightSpec> const & right_)
314 {
315     typedef Proxy<TLeftSpec> TLeft;
316     typedef Proxy<TRightSpec> TRight;
317     typedef typename CompareType<TLeft, TRight>::Type TCompareType;
318     return convert<TCompareType>(left_) <= convert<TCompareType>(right_);
319 }
320 
321 template <typename TSpec>
322 inline bool
323 operator<=(Proxy<TSpec> const & left_,
324            Proxy<TSpec> const & right_)
325 {
326     typedef typename GetValue<Proxy<TSpec> >::Type TAccessor;
327     return convert<TAccessor>(left_) <= convert<TAccessor>(right_);
328 }
329 
330 
331 // ----------------------------------------------------------------------------
332 // Function operator>()
333 // ----------------------------------------------------------------------------
334 
335 template <typename TSpec, typename TRight>
336 inline bool
337 operator>(Proxy<TSpec> const & left_,
338           TRight const & right_)
339 {
340     typedef Proxy<TSpec> TLeft;
341     typedef typename CompareType<TLeft, TRight>::Type TCompareType;
342     return convert<TCompareType>(left_) > convert<TCompareType>(right_);
343 }
344 
345 template <typename TLeft, typename TSpec>
346 inline bool
347 operator>(TLeft const & left_,
348           Proxy<TSpec> const & right_)
349 {
350     typedef Proxy<TSpec> TRight;
351     typedef typename CompareType<TRight, TLeft>::Type TCompareType;
352     return convert<TCompareType>(left_) > convert<TCompareType>(right_);
353 }
354 
355 template <typename TLeftSpec, typename TRightSpec>
356 inline bool
357 operator>(Proxy<TLeftSpec> const & left_,
358           Proxy<TRightSpec> const & right_)
359 {
360     typedef Proxy<TLeftSpec> TLeft;
361     typedef Proxy<TRightSpec> TRight;
362     typedef typename CompareType<TLeft, TRight>::Type TCompareType;
363     return convert<TCompareType>(left_) > convert<TCompareType>(right_);
364 }
365 
366 template <typename TSpec>
367 inline bool
368 operator>(Proxy<TSpec> const & left_,
369           Proxy<TSpec> const & right_)
370 {
371     typedef typename GetValue<Proxy<TSpec> >::Type TAccessor;
372     return convert<TAccessor>(left_) > convert<TAccessor>(right_);
373 }
374 
375 // ----------------------------------------------------------------------------
376 // Function operator>=()
377 // ----------------------------------------------------------------------------
378 
379 template <typename TSpec, typename TRight>
380 inline bool
381 operator>=(Proxy<TSpec> const & left_,
382            TRight const & right_)
383 {
384     typedef Proxy<TSpec> TLeft;
385     typedef typename CompareType<TLeft, TRight>::Type TCompareType;
386     return convert<TCompareType>(left_) >= convert<TCompareType>(right_);
387 }
388 
389 template <typename TLeft, typename TSpec>
390 inline bool
391 operator>=(TLeft const & left_,
392            Proxy<TSpec> const & right_)
393 {
394     typedef Proxy<TSpec> TRight;
395     typedef typename CompareType<TRight, TLeft>::Type TCompareType;
396     return convert<TCompareType>(left_) >= convert<TCompareType>(right_);
397 }
398 
399 template <typename TLeftSpec, typename TRightSpec>
400 inline bool
401 operator>=(Proxy<TLeftSpec> const & left_,
402            Proxy<TRightSpec> const & right_)
403 {
404     typedef Proxy<TLeftSpec> TLeft;
405     typedef Proxy<TRightSpec> TRight;
406     typedef typename CompareType<TLeft, TRight>::Type TCompareType;
407     return convert<TCompareType>(left_) >= convert<TCompareType>(right_);
408 }
409 
410 template <typename TSpec>
411 inline bool
412 operator>=(Proxy<TSpec> const & left_,
413            Proxy<TSpec> const & right_)
414 {
415     typedef typename GetValue<Proxy<TSpec> >::Type TAccessor;
416     return convert<TAccessor>(left_) >= convert<TAccessor>(right_);
417 }
418 
419 // ----------------------------------------------------------------------------
420 // Function operator>>();  Reading from streams.
421 // ----------------------------------------------------------------------------
422 
423 template <typename TStream, typename TSpec>
424 inline TStream &
425 operator>>(TStream & strm,
426            Proxy<TSpec> & proxy)
427 {
428     typedef Proxy<TSpec> TProxy;
429     typedef typename Value<TProxy>::Type TValue;
430     TValue temp;
431     strm >> temp;
432     *iter(proxy) = temp;
433     return strm;
434 }
435 
436 template <typename TStream, typename TSpec>
437 inline TStream &
438 operator>>(TStream & strm,
439            Proxy<TSpec> const& proxy)
440 {
441     typedef Proxy<TSpec> TProxy;
442     typedef typename Value<TProxy>::Type TValue;
443     TValue temp;
444     strm >> temp;
445     *iter(proxy) = temp;
446     return strm;
447 }
448 
449 // ----------------------------------------------------------------------------
450 // Function operator<<();  Writing to streams.
451 // ----------------------------------------------------------------------------
452 
453 // TODO(holtgrew): Is the first variant even necessary?
454 
455 template <typename TStream, typename TSpec>
456 inline TStream &
457 operator<<(TStream & strm,
458            Proxy<TSpec> & proxy)
459 {
460     strm << getValue(proxy);
461     return strm;
462 }
463 
464 template <typename TStream, typename TSpec>
465 inline TStream &
466 operator<<(TStream & strm,
467            Proxy<TSpec> const & proxy)
468 {
469     strm << getValue(proxy);
470     return strm;
471 }
472 
473 }  // namespace seqan
474 
475 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_BASIC_PROXY_BASE_H_
476