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 // Implementation of the Holder base class. 35 // ========================================================================== 36 37 #ifndef SEQAN_BASIC_HOLDER_BASE_H_ 38 #define SEQAN_BASIC_HOLDER_BASE_H_ 39 40 // By default, disable holders to pointers, this is used/tested nowhere and does probably not work. 41 #ifndef SEQAN_ENABLE_POINTER_HOLDER 42 #define SEQAN_ENABLE_POINTER_HOLDER 0 43 #endif //#ifndef SEQAN_ENABLE_POINTER_HOLDER 44 45 namespace seqan { 46 47 // ============================================================================ 48 // Forwards 49 // ============================================================================ 50 51 // ============================================================================ 52 // Tags, Classes, Enums 53 // ============================================================================ 54 55 // ---------------------------------------------------------------------------- 56 // Class Holder 57 // ---------------------------------------------------------------------------- 58 59 /*! 60 * @class Holder 61 * @headerfile <seqan/basic.h> 62 * @brief Manages relationship to another object. 63 * 64 * @signature template <typename TValue[, typename TSpec> 65 * class Holder; 66 * 67 * @tparam TSpec The specializing type. Default: <tt>Tristate</tt> 68 * @tparam TValue Type of the managed object. 69 * 70 * @section Remarks 71 * 72 * The main purpose of this class is to facilitate the handling of member objects. If we want class <tt>A</tt> to be 73 * dependent on or the owner of another object of class <tt>B</tt>, then we add a data member of type <tt>Holder<B></tt> 74 * to <tt>A</tt>. <tt>Holder</tt> offers some useful access functions and stores the kind of relationship between 75 * <tt>A</tt> and <tt>B</tt>. 76 * 77 * @see Holder#create 78 * @see Holder#setValue 79 */ 80 81 /* 82 * @fn Holder::Holder 83 * @brief Constructor. 84 * 85 * You can construct a Holder using the default constructor, copy from another Holder, or directly with a value to hold. 86 * 87 * @signature Holder::Holder(); 88 * @signature Holder::Holder(other); 89 * @signature Holder::Holder(value); 90 * 91 * @param[in] other Other Holder to copy from. 92 * @param[in] value The value to hold. 93 * 94 * The main purpose of this class is to facilitate the handling of member objects. If we want a class <tt>A</tt> to be 95 * dependent on or the owner or another object of class <tt>B</tt> then we add a data member of type 96 * <tt>Holder<B></tt> to <tt>A</tt>. Holder offers some useful access functions and stores the kind of 97 * relationship between <tt>A</tt> and <tt>B</tt>. 98 */ 99 100 // Tag for default Holder specialization. 101 struct Tristate_; 102 typedef Tag<Tristate_> Tristate; 103 104 // Tag for default Simple specialization. 105 struct Simple_; 106 typedef Tag<Simple_> Simple; 107 108 template <typename TValue, typename TSpec = Tristate> 109 struct Holder; 110 111 // ============================================================================ 112 // Metafunctions 113 // ============================================================================ 114 115 /*! 116 * @mfn Holder#GetValue 117 * @brief Return get-value type of Holder. 118 * 119 * @signature GetValue<THolder>::Type; 120 * 121 * @tparam THolder The Holder to query for its value type. 122 * 123 * @return Type The get-value type for its holder. 124 */ 125 126 // ---------------------------------------------------------------------------- 127 // Metafunction Value 128 // ---------------------------------------------------------------------------- 129 130 /*! 131 * @mfn Holder#Value 132 * @brief Return value type of Holder. 133 * 134 * @signature Value<THolder>::Type; 135 * 136 * @tparam THolder The Holder to query for its value type. 137 * 138 * @return Type The value type for its holder. 139 */ 140 141 template <typename TValue, typename TSpec> 142 struct Value<Holder<TValue, TSpec> > 143 { 144 typedef TValue Type; 145 }; 146 147 template <typename TValue, typename TSpec> 148 struct Value<Holder<TValue, TSpec> const> 149 { 150 typedef TValue Type; 151 }; 152 153 #if SEQAN_ENABLE_POINTER_HOLDER 154 // TODO(holtgrew): What about holders on pointers? 155 template <typename TValue, typename TSpec> 156 struct Value<Holder<TValue * const, TSpec> > 157 { 158 typedef TValue * Type; 159 }; 160 #endif // #if SEQAN_ENABLE_POINTER_HOLDER 161 162 // ---------------------------------------------------------------------------- 163 // Metafunction Spec 164 // ---------------------------------------------------------------------------- 165 166 /*! 167 * @mfn Holder#Spec 168 * @brief Return the specialization tag for a Holder. 169 * 170 * @signature Spec<THolder>::Type; 171 * 172 * @tparam THolder The Holder to query for its value type. 173 * 174 * @return Type The resulting specialization tag. 175 */ 176 177 template <typename TValue, typename TSpec> 178 struct Spec<Holder<TValue, TSpec> > 179 { 180 typedef TSpec Type; 181 }; 182 183 template <typename TValue, typename TSpec> 184 struct Spec<Holder<TValue, TSpec> const> 185 { 186 typedef TSpec Type; 187 }; 188 189 // ---------------------------------------------------------------------------- 190 // Metafunction Reference 191 // ---------------------------------------------------------------------------- 192 193 /*! 194 * @mfn Holder#Reference 195 * @brief Return the reference type of a Holder. 196 * 197 * @signature Reference<THolder>::Type; 198 * 199 * @tparam THolder The holder to query for its reference type. 200 * 201 * @return Type The resulting reference type. 202 */ 203 204 template <typename TValue, typename TSpec> 205 struct Reference<Holder<TValue, TSpec> > 206 { 207 typedef typename Value<Holder<TValue, TSpec> >::Type & Type; 208 }; 209 210 template <typename TValue, typename TSpec> 211 struct Reference< Holder<TValue, TSpec> const> 212 { 213 typedef typename Value<Holder<TValue, TSpec> const>::Type & Type; 214 }; 215 216 #if SEQAN_ENABLE_POINTER_HOLDER 217 template <typename TValue, typename TSpec> 218 struct Reference<Holder<TValue *, TSpec> const> 219 { 220 typedef typename Value<Holder<TValue *, TSpec> const>::Type const & Type; 221 }; 222 #endif // #if SEQAN_ENABLE_POINTER_HOLDER 223 224 // ============================================================================ 225 // Functions 226 // ============================================================================ 227 228 // ---------------------------------------------------------------------------- 229 // Function create() 230 // ---------------------------------------------------------------------------- 231 232 /*! 233 * @fn Holder#create 234 * @brief Makes an object to owner of its content. 235 * 236 * @signature void create(holder[, object]); 237 * 238 * @param[in,out] holder The Holder to create the object of. 239 * @param[in] object Object from which a copy is made and stored in <tt>holder</tt>. 240 * 241 * After this operation, <tt>holder</tt> will be in state 'owner'. If <tt>object</tt> is specified, <tt>holder</tt> 242 * will hold a copy of <tt>object</tt> at the end of this function. If <tt>object</tt> is not specified, the action 243 * depends on the former state of <tt>holder</tt>: 244 * 245 * <ul> 246 * <li>If the state of <tt>holder</tt> was 'empty', a new object is default constructed and stored into 247 * <tt>holder</tt>.</li> 248 * <li>If the state of <tt>holder</tt> was 'dependent', a copy of the former object is made and stored into 249 * <tt>holder</tt>.</li> 250 * <li>If the state of <tt>holder</tt> was already 'owner', nothing happens.</li> 251 * </ul> 252 * 253 * It is guaranteed, that after calling this function <tt>source</tt> and <tt>target</tt> can be used independently. 254 */ 255 256 // ---------------------------------------------------------------------------- 257 // Function detach() 258 // ---------------------------------------------------------------------------- 259 260 /*! 261 * @fn Holder#detach 262 * @brief Makes an object independent from other objects. 263 264 * @signature void detach(holder); 265 * 266 * @param[in,out] holder The Holder to detach. 267 * 268 * @section Remarks 269 * 270 * After this function, <tt>holder</tt> does not depends from any other entity outside of <tt>holder</tt>, like a source 271 * or a host, and dependent(holer) returns <tt>false</tt> 272 */ 273 274 // ---------------------------------------------------------------------------- 275 // Function setValue() 276 // ---------------------------------------------------------------------------- 277 278 /*! 279 * @fn Holder#setValue 280 * @brief Makes holder dependent. 281 * 282 * @signature void setValue(holder, object); 283 * 284 * @param[in,out] holder A holder object. Types: Holder 285 * @param[in] object Object from which <tt>holder</tt> will be dependent. 286 * 287 * After this operation, <tt>holder</tt> will be dependent in state 'dependent'. 288 */ 289 290 // ---------------------------------------------------------------------------- 291 // Function empty() 292 // ---------------------------------------------------------------------------- 293 294 /*! 295 * @fn Holder#empty 296 * @brief Test a Holder for being empty. 297 * 298 * @signature bool empty(holder); 299 * 300 * @param[in] holder A Holder. 301 * 302 * @return bool <tt>true</tt> if <tt>holder</tt> contains no elements, otherwise <tt>false</tt>. 303 * 304 * @section Remarks 305 * 306 * <tt>empty(x)</tt> is guaranteed to be at least as fast as <tt>length(me) == 0</tt>, but can be significantly faster 307 * in some cases. 308 * 309 * @see HostedConcept#emptyHost 310 */ 311 312 // ---------------------------------------------------------------------------- 313 // Function assignValue() 314 // ---------------------------------------------------------------------------- 315 316 /*! 317 * @fn Holder#assignValue 318 * 319 * @headerfile <seqan/basic.h> 320 * @headerfile <seqan/sequence.h> 321 * 322 * @brief Assigns value to item. 323 * 324 * @signature void assignValue(object, value); 325 * 326 * @param[in,out] object An object that holds a value or points to a value. Types: 327 * Holder, Iter Concepts: Concept.BasicOutputIteratorConcept 328 * @param[in] value A value that is assigned to the item <tt>object</tt> holds or points to. 329 * 330 * This function is similar to @link AssignableConcept#assign @endlink. The difference is, that 331 * <tt>assignValue</tt> just changes a value stored in <tt>object</tt> or the 332 * value <tt>object</tt> points to, while @link AssignableConcept#assign @endlink changes the 333 * whole object. 334 * 335 * If <tt>object</tt> is a container (that is <tt>pos</tt> is not specified), 336 * the whole content of <tt>object</tt> is replaced by <tt>value</tt>. 337 * 338 * If <tt>value</tt> is not used again after calling this function, then 339 * consider to use @link Holder#moveValue @endlink that could be faster in some cases 340 * instead. 341 * 342 * @see AssignableConcept#assign 343 * @see Holder#moveValue 344 */ 345 346 // ---------------------------------------------------------------------------- 347 // Function dependent() 348 // ---------------------------------------------------------------------------- 349 350 /* 351 * @fn Holder#dependent 352 * @headerfile <seqan/basic.h> 353 * @brief Test whether Holder depends on other objects. 354 * 355 * @signature bool dependent(holder); 356 * 357 * @param[in] holder The Holder to query; 358 * 359 * @return bool <tt>true</tt> if <tt>object</tt> depends one some other object, <tt>false</tt> otherwise. 360 * 361 * An object "<tt>a</tt>" depends on another object "<tt>b</tt>", if changing "<tt>b</tt>" can invalidate "<tt>a</tt>"; 362 * especially the destruction of "<tt>b</tt>" invalidates "<tt>a</tt>". 363 */ 364 365 // ---------------------------------------------------------------------------- 366 // Function clear() 367 // ---------------------------------------------------------------------------- 368 369 /*! 370 * @fn Holder#clear 371 * @brief Clear/destruct the Holder's value. 372 * 373 * @signature void clear(holder); 374 * 375 * @param[in,out] holder The Holder to clear. 376 */ 377 378 // ---------------------------------------------------------------------------- 379 // Function value() 380 // ---------------------------------------------------------------------------- 381 382 /*! 383 * @fn Holder#value 384 * @brief Return a reference to the value of the holder. 385 * 386 * @signature TReference value(holder); 387 * 388 * @param[in] holder The Holder to query for its reference. 389 * 390 * @return TReference The reference of the Holder's value. 391 */ 392 393 // ---------------------------------------------------------------------------- 394 // Function moveValue() 395 // ---------------------------------------------------------------------------- 396 397 /*! 398 * @fn Holder#moveValue 399 * 400 * @headerfile <seqan/sequence.h> 401 * 402 * @brief Move a value of into a holder. 403 * 404 * @signature void moveValue(holder, value); 405 * 406 * @param[in,out] holder The Holder to manipulate. 407 * @param[in,out] value The value to move into <tt>holder</tt>. 408 */ 409 410 // ---------------------------------------------------------------------------- 411 // Function getValue() 412 // ---------------------------------------------------------------------------- 413 414 /*! 415 * @fn Holder#getValue 416 * @brief Return the get-value of the holder. 417 * 418 * @signature TGetValue getValue(holder); 419 * 420 * @param[in] holder The Holder to query for its get-value type. 421 * 422 * @return TGetValue The get-value of the Holder. 423 */ 424 425 // TODO(holtgrew): We would rather have only one here. 426 427 template <typename TValue, typename TSpec> 428 inline typename GetValue<Holder<TValue, TSpec> >::Type 429 getValue(Holder<TValue, TSpec> const & holder) 430 { 431 return value(holder); 432 } 433 434 template <typename TValue, typename TSpec> 435 inline typename GetValue<Holder<TValue, TSpec> >::Type 436 getValue(Holder<TValue, TSpec> & holder) 437 { 438 return value(holder); 439 } 440 441 } // namespace seqan 442 443 #endif // #ifndef SEQAN_BASIC_HOLDER_BASE_H_ 444