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<TSpec></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