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&lt;B&gt;</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&lt;B&gt;</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