1 /*==========================================================================
2 SeqAn - The Library for Sequence Analysis
4 ============================================================================
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 3 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 ============================================================================
18 $Id: string_alloc.h,v 1.1 2008/08/25 16:20:04 langmead Exp $
19 ==========================================================================*/
21 #ifndef SEQAN_HEADER_SEQUENCE_STRING_ALLOC_H
22 #define SEQAN_HEADER_SEQUENCE_STRING_ALLOC_H
25 namespace SEQAN_NAMESPACE_MAIN
31 ..general:Class.String
32 ..summary:Expandable string that is stored on heap.
33 ..signature:String<TValue, Alloc<TSpec> >
34 ..param.TValue:The value type, that is the type of the items/characters stored in the string.
35 ...remarks:Use @Metafunction.Value@ to get the value type for a given class.
36 ..param.TSpec:The specializing type.
39 //////////////////////////////////////////////////////////////////////////////
41 //////////////////////////////////////////////////////////////////////////////
42 //Default: TSpec == void
44 template <typename TValue>
45 class String<TValue, Alloc<void> >
48 typename Value<String>::Type * data_begin;
49 typename Value<String>::Type * data_end;
52 //____________________________________________________________________________
63 template <typename TSource>
64 String(TSource & source):
70 assign(*this, source);
72 template <typename TSource>
73 String(TSource const & source):
79 assign(*this, source);
81 String(String const & source):
87 assign(*this, source);
89 String(String const & source, Move):
97 template <typename TSource, typename TSize>
98 String(TSource & source, TSize limit):
104 assign(*this, source, limit);
106 template <typename TSource, typename TSize>
107 String(TSource const & source, TSize limit):
113 assign(*this, source, limit);
117 template <typename TSource>
118 String & operator =(TSource const & source)
121 assign(*this, source);
124 String & operator =(String const & source)
127 assign(*this, source);
134 arrayDestruct(this->data_begin, this->data_end);
135 _deallocateStorage(*this, this->data_begin, data_capacity);
139 //____________________________________________________________________________
141 template <typename TPos>
142 inline typename Reference<String>::Type
143 operator [] (TPos pos)
146 return value(*this, pos);
149 template <typename TPos>
150 inline typename Reference<String const>::Type
151 operator [] (TPos pos) const
154 return value(*this, pos);
157 //____________________________________________________________________________
159 friend inline typename Iterator<String, Standard>::Type
164 return me.data_begin;
166 friend inline typename Iterator<String const, Standard>::Type
167 begin(String const & me,
171 return me.data_begin;
174 //____________________________________________________________________________
176 friend inline typename Iterator<String, Standard>::Type
183 friend inline typename Iterator<String const, Standard>::Type
184 end(String const & me,
191 //____________________________________________________________________________
194 capacity(String & me)
197 return me.data_capacity;
201 capacity(String const & me)
204 return me.data_capacity;
207 //____________________________________________________________________________
208 /* Entwicklungsschrott?
210 move(String & target,
214 target.data_begin = source.data_begin;
215 target.data_end = source.data_end;
216 target.data_capacity = source.data_capacity;
218 source.data_begin = 0;
220 source.data_capacity = 0;
223 //____________________________________________________________________________
231 typename Value<String>::Type * new_begin)
234 me.data_begin = new_begin;
237 //____________________________________________________________________________
240 .Internal._setLength:
242 ..summary:Set the length of container.
243 ..signature:_setLength(object, new_length)
244 ..param.object:A container.
245 ..param.object.type:Spec.Alloc String
246 ..param.new_length:The new length.
254 me.data_end = me.data_begin + new_length;
257 //____________________________________________________________________________
260 .Internal._setCapacity:
268 me.data_capacity = new_capacity;
271 //____________________________________________________________________________
274 .Internal._allocateStorage:
276 ..summary:Allocates a new buffer for a container.
277 ..signature:_allocateStorage(object, new_capacity)
278 ..param.object:A container.
279 ..param.object.type:Spec.Alloc String
280 ..param.new_capacity:The capacity of the new allocated buffer.
281 ..returns:The old butter $object$, that is replaced by the new allocated buffer.
282 ..remarks:The returned buffer must be deallocated by @Internal._deallocateStorage@.
283 ..remarks:This function does not construct objects in the allocated buffer.
284 ..see:Internal._reallocateStorage
286 friend inline typename Value<String>::Type *
292 size_t size = _computeSize4Capacity(me, new_capacity);
293 typename Value<String>::Type * return_value = me.data_begin;
294 allocate(me, me.data_begin, size, TagAllocateStorage());
295 me.data_capacity = new_capacity;
299 //____________________________________________________________________________
302 .Internal._deallocateStorage:
304 ..summary:Deallocates a buffer of a container.
305 ..signature:_deallocateStorage(object, buffer, capacity)
306 ..param.object:A container.
307 ..param.object.type:Spec.Alloc String
308 ..param.buffer:The buffer that will be deallocated.
309 ..param.capacity:The capacity of $buffer$.
310 ..remarks:All objects in the buffer must be destroyed before calling $_deallocateStorage$.
311 ..see:Internal._allocateStorage
312 ..see:Internal._reallocateStorage
317 typename Value<String>::Type * ptr,
321 size_t size = _computeSize4Capacity(me, capacity);
322 deallocate(me, ptr, size, TagAllocateStorage());
325 //____________________________________________________________________________
330 //////////////////////////////////////////////////////////////////////////////
332 template <typename TValue, typename TSpec>
333 struct DefaultOverflowImplicit<String<TValue, Alloc<TSpec> > >
335 typedef Generous Type;
338 template <typename TValue, typename TSpec>
339 struct DefaultOverflowImplicit<String<TValue, Alloc<TSpec> > const >
341 typedef Generous Type;
344 //////////////////////////////////////////////////////////////////////////////
346 template <typename TValue, typename TSpec>
347 struct IsContiguous< String<TValue, Alloc<TSpec> > >
350 enum { VALUE = true };
354 //////////////////////////////////////////////////////////////////////////////
356 template <typename TTargetValue, typename TSourceValue, typename TSpec>
358 move(String<TTargetValue, Alloc<TSpec> > & target,
359 String<TSourceValue, Alloc<TSpec> > & source)
361 _moveContiguous(target, source);
363 template <typename TTargetValue, typename TSourceValue, typename TSpec>
365 move(String<TTargetValue, Alloc<TSpec> > & target,
366 String<TSourceValue, Alloc<TSpec> > const & source)
368 _moveContiguous(target, source);
371 template <typename TValue, typename TSpec>
373 move(String<TValue, Alloc<TSpec> > & target,
374 String<TValue, Alloc<TSpec> > & source)
377 target.data_begin = source.data_begin;
378 target.data_end = source.data_end;
379 target.data_capacity = source.data_capacity;
381 source.data_begin = 0;
383 source.data_capacity = 0;
385 template <typename TValue, typename TSpec>
387 move(String<TValue, Alloc<TSpec> > & target,
388 String<TValue, Alloc<TSpec> > const & source)
391 target.data_begin = source.data_begin;
392 target.data_end = source.data_end;
393 target.data_capacity = source.data_capacity;
395 source.data_begin = 0;
397 source.data_capacity = 0;
400 //////////////////////////////////////////////////////////////////////////////
402 ///.Function.reserve.param.object.type:Spec.Alloc String
404 template <typename TValue, typename TSpec, typename _TSize, typename TExpand>
405 inline typename Size< String<TValue, Alloc<TSpec> > >::Type
407 String<TValue, Alloc<TSpec> > & seq,
409 Tag<TExpand> const tag)
412 typedef typename Size< String<TValue, Alloc<TSpec> > >::Type TSize;
414 TSize old_capacity = capacity(seq);
415 if (old_capacity >= (TSize)new_capacity) return new_capacity;
417 TSize seq_length = length(seq);
418 typename Value< String<TValue, Alloc<TSpec> > >::Type * old_array = _reallocateStorage(seq, new_capacity, tag);
420 {//buffer was replaced, destruct old buffer
421 arrayConstructCopy(old_array, old_array + seq_length, begin(seq, Standard()));
422 arrayDestruct(old_array, old_array + seq_length);
423 _deallocateStorage(seq, old_array, old_capacity);
424 _setLength(seq, seq_length);
426 else if (!old_capacity)
427 {//new buffer created and the string had no buffer yet
428 _setLength(seq, seq_length);
433 template <typename TValue, typename TSpec, typename _TSize>
434 inline typename Size< String<TValue, Alloc<TSpec> > >::Type
436 String<TValue, Alloc<TSpec> > & me,
441 typedef typename Size< String<TValue, Alloc<TSpec> > >::Type TSize;
443 TSize me_capacity = capacity(me);
444 if (me_capacity < (TSize)new_capacity) return me_capacity;
448 template <typename TValue, typename TSpec, typename _TSize>
449 inline typename Size< String<TValue, Alloc<TSpec> > >::Type
451 String<TValue, Alloc<TSpec> > & /*me*/,
456 typedef typename Size< String<TValue, Alloc<TSpec> > >::Type TSize;
461 //////////////////////////////////////////////////////////////////////////////
465 } //namespace SEQAN_NAMESPACE_MAIN
467 #endif //#ifndef SEQAN_HEADER_...