1 // ==========================================================================
2 //                 SeqAn - The Library for Sequence Analysis
3 // ==========================================================================
4 // Copyright (c) 2006-2010, 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 
33 #ifndef SEQAN_HEADER_BASIC_DEFINITION_H
34 #define SEQAN_HEADER_BASIC_DEFINITION_H
35 
36 namespace SEQAN_NAMESPACE_MAIN
37 {
38 
39 //////////////////////////////////////////////////////////////////////////////
40 
41 template <typename T>
42 struct Tag
43 {
44 };
45 
46 //////////////////////////////////////////////////////////////////////////////
47 
48 template <typename T>
49 struct Length;
50 
51 template <>
52 struct Length<void>
53 {
54 	enum { VALUE = 0 };
55 };
56 
57 //////////////////////////////////////////////////////////////////////////////
58 /**
59 .Tag.TagList:
60 ..summary:A structure to represent a list of tags.
61 ..signature:TagList<TTag1>
62 ..signature:TagList<TTag1, TagList<TTag2> >
63 ..signature:TagList<TTag1, TagList<TTag2, TagList<TTag3[...]> > >
64 ..param.TTag1:The first tag of the list.
65 ..param.TTag2:The second tag of the list.
66 ..param.TTag3:The third tag of the list.
67 ..include:seqan/basic.h
68 */
69 
70 template <typename TTag = void, typename TSubList = void>
71 struct TagList
72 {
73 	typedef TTag Type;
74 };
75 
76 template <typename TTag>
77 struct Length< TagList<TTag, void> > {
78 	enum { VALUE = 1 };
79 };
80 
81 template <typename TTag, typename TSubList>
82 struct Length< TagList<TTag, TSubList> > {
83 	enum { VALUE = Length<TSubList>::VALUE + 1 };
84 };
85 
86 template <typename TTagList = void>
87 struct TagSelector
88 {
89 	int tagId;
90 
91 	TagSelector()
92 	{
93 		tagId = 0;
94 	}
95 
96     inline bool operator==(TagSelector const & other) const
97     {
98         return other.tagId == tagId;
99     }
100 };
101 
102 /**
103 .Class.TagSelector:
104 ..summary:A structure to select a tag from a @Tag.TagList@.
105 ..signature:TagSelector<TTagList>
106 ..param.TTagList:A tag list.
107 ...type:Tag.TagList
108 .Memvar.TagSelector#tagId:
109 ..class:Class.TagSelector
110 ..type:nolink:int
111 ..cat:Basic
112 ..summary:Stores the index of a @Page.Glossary.Tag@ in the tag list.
113 ..include:seqan/basic.h
114 */
115 
116 ///
117 
118 template <typename TTag, typename TSubList>
119 struct TagSelector< TagList<TTag, TSubList> >:
120 	TagSelector<TSubList>
121 {
122 	typedef TTag					Type;
123 	typedef TagSelector<TSubList>	Base;
124 };
125 
126 //////////////////////////////////////////////////////////////////////////////
127 /**
128 .Tag.Default:
129 ..summary:Tag that specifies default behavior.
130 ..tag.Default:Use default behavior.
131 ..include:seqan/basic.h
132 */
133 struct Default_;
134 typedef Tag<Default_> const Default;
135 
136 //////////////////////////////////////////////////////////////////////////////
137 /**
138 .Tag.Move Switch:
139 ..summary:Switch to force move.
140 ..tag.Move:Move instead of assign.
141 ..remarks.text:The difference between move constructor and copy constructor
142 is that the source object is not copied but moved into the target object.
143 The source object can lose its content and will be empty after
144 this operation in this case.
145 A move constructor can sigificantly faster than a copy constructor.
146 ..example.code:String source("hello");
147 String target(source, Move()); // source is moved to target
148 std::cout << source; //nothing printed since source lost content
149 std::cout << target; //"hello"
150 ..see:Function.move
151 ..include:seqan/basic.h
152 */
153 
154 struct Move_;
155 typedef Tag<Move_> const Move;
156 
157 //////////////////////////////////////////////////////////////////////////////
158 
159 //Pass to c'tor of iterator to move it to the end
160 struct GoEnd_;
161 typedef Tag<GoEnd_> const GoEnd;
162 
163 
164 //////////////////////////////////////////////////////////////////////////////
165 
166 //construct without initializing
167 struct MinimalCtor_;
168 typedef Tag<MinimalCtor_> const MinimalCtor;
169 
170 //construct with initializing
171 struct NonMinimalCtor_;
172 typedef Tag<NonMinimalCtor_> const NonMinimalCtor;
173 
174 //////////////////////////////////////////////////////////////////////////////
175 
176 /**
177 .Tag.Nothing:
178 ..summary:Tag that represents an absent parameter or an absent type.
179 ..tag.Nothing:Omit parameter.
180 ..include:seqan/basic.h
181 */
182 ///Empty Data Class.
183 struct Nothing {};
184 
185 
186 
187 //////////////////////////////////////////////////////////////////////////////
188 // returns TTo const, if TFrom is const, TTo otherwise
189 
190 template <typename TFrom, typename TTo>
191 struct CopyConst_
192 {
193 	typedef TTo Type;
194 };
195 template <typename TFrom, typename TTo>
196 struct CopyConst_<TFrom const, TTo>
197 {
198 	typedef TTo const Type;
199 };
200 
201 //////////////////////////////////////////////////////////////////////////////
202 
203 /**
204 .Internal.RemoveConst_:
205 ..signature:RemoveConst_<T>
206 ..returns:$t$ if $T$ is $t const$, otherwise $T$.
207 */
208 template <typename T>
209 struct RemoveConst_
210 {
211 	typedef T Type;
212 };
213 template <typename T>
214 struct RemoveConst_<T const>:
215 	public RemoveConst_<T> {};
216 
217 template <typename T>
218 struct RemoveConst_<T &>
219 {
220 	typedef typename RemoveConst_<T>::Type & Type;
221 };
222 template <typename T>
223 struct RemoveConst_<T *>
224 {
225 	typedef typename RemoveConst_<T>::Type * Type;
226 };
227 template <typename T, size_t I>
228 struct RemoveConst_<T const [I]>
229 {
230 	typedef T * Type;
231 };
232 
233 //////////////////////////////////////////////////////////////////////////////
234 /**
235 .Internal.MakeUnsigned_:
236 ..signature:MakeUnsigned_<T>
237 ..returns:$unsigned t$ if $T$ is not $unsigned t$, otherwise $T$.
238 */
239 template <typename T>
240 struct MakeUnsigned_
241 {
242 	typedef
243 		typename If< IsSameType<T, char>::VALUE,         unsigned char,
244 		typename If< IsSameType<T, signed char>::VALUE,  unsigned char,
245 		typename If< IsSameType<T, signed short>::VALUE, unsigned short,
246 		typename If< IsSameType<T, signed int>::VALUE,   unsigned int,
247 		typename If< IsSameType<T, signed long>::VALUE,  unsigned long,
248 		typename If< IsSameType<T, __int64>::VALUE,      __uint64, T
249 		>::Type>::Type>::Type>::Type>::Type>::Type Type;
250 };
251 
252 template <typename T>
253 struct MakeUnsigned_<T const> {
254 	typedef typename MakeUnsigned_<T>::Type const Type;
255 };
256 
257 //////////////////////////////////////////////////////////////////////////////
258 /**
259 .Internal.MakeSigned_:
260 ..signature:MakeSigned_<T>
261 ..returns:$signed t$ if $T$ is not $signed t$, otherwise $T$.
262 */
263 template <typename T>
264 struct MakeSigned_
265 {
266 	typedef
267 		typename If< IsSameType<T, char>::VALUE,           signed char,
268 		typename If< IsSameType<T, unsigned char>::VALUE,  signed char,
269 		typename If< IsSameType<T, unsigned short>::VALUE, signed short,
270 		typename If< IsSameType<T, unsigned int>::VALUE,   signed int,
271 		typename If< IsSameType<T, unsigned long>::VALUE,  signed long,
272 		typename If< IsSameType<T, __uint64>::VALUE,       __int64, T
273 		>::Type>::Type>::Type>::Type>::Type>::Type Type;
274 };
275 
276 template <typename T>
277 struct MakeSigned_<T const> {
278 	typedef typename MakeSigned_<T>::Type const Type;
279 };
280 
281 //////////////////////////////////////////////////////////////////////////////
282 /**
283 .Internal.ClassIdentifier_:
284 ..signature:void * ClassIdentifier_<T>::getID()
285 ..returns:A void * that identifies $T$.
286 ...text:The returned values of two calls of $getID$ are equal if and only if
287 the used type $T$ was the same.
288 */
289 template <typename T>
290 struct ClassIdentifier_
291 {
292 	static inline void *
293 	getID()
294 	{
295 SEQAN_CHECKPOINT
296 		static bool _id_dummy;
297 		return &_id_dummy;
298 	}
299 };
300 
301 //////////////////////////////////////////////////////////////////////////////
302 /**
303 .Function.log2:
304 ..cat:Miscellaneous
305 ..summary:Computes logarithm of base 2 for integer types
306 ..signature:unsigned int log2(i)
307 ..param.i:An integer type.
308 ..returns:The largest integer smaller or equal than
309 the logarithm of $i$.
310 ..include:seqan/basic.h
311 */
312 
313 template <int BITS_MAX>
314 struct Log2Impl_
315 {
316 	template <typename T>
317 	static inline unsigned int
318 	log2(T val, unsigned int offset)
319 	{
320 		unsigned int val2 = val >> (BITS_MAX / 2);
321 		if (val2)
322 		{
323 			val = val2;
324 			offset += BITS_MAX / 2;
325 		}
326 		return Log2Impl_<BITS_MAX / 2>::log2(val, offset);
327 	}
328 };
329 
330 template <>
331 struct Log2Impl_<1>
332 {
333 	template <typename T>
334 	static inline unsigned int
335 	log2(T /*val*/, unsigned int offset)
336 	{
337 		return offset;
338 	}
339 };
340 
341 
342 template <typename T>
343 inline unsigned int
344 log2(T val)
345 {
346 	enum
347 	{
348 //		BITS_PER_VALUE = BitsPerValue<T>::VALUE //TODO???
349 		BITS_PER_VALUE = sizeof(T) * 8
350 	};
351 
352 	return Log2Impl_<BITS_PER_VALUE>::log2(val, 0);
353 }
354 
355 template <typename TValue, typename TExponent>
356 inline TValue _intPow(TValue a, TExponent b)
357 {
358 SEQAN_CHECKPOINT
359 	TValue ret = 1;
360 	while (b != 0)
361 	{
362 		if (b & 1) ret *= a;
363 		a *= a;
364 		b >>= 1;
365 	}
366 	return ret;
367 }
368 
369 //////////////////////////////////////////////////////////////////////////////
370 // to avoid conflicts with non-standard macros and namespaces
371 // we define our own Min/Max functions
372 
373 template<typename Tx_> inline
374 const Tx_& _min(const Tx_& _Left, const Tx_& Right_)
375 {	// return smaller of _Left and Right_
376 	if (_Left < Right_)
377 		return _Left;
378 	else
379 		return Right_;
380 }
381 
382 template<typename Tx_, typename Ty_> inline
383 Tx_ _min(const Tx_& _Left, const Ty_& Right_)
384 {	// return smaller of _Left and Right_
385     return (Right_ < _Left ? Right_ : _Left);
386 }
387 
388 template<typename Ty_> inline
389 const Ty_& _max(const Ty_& _Left, const Ty_& Right_)
390 {	// return larger of _Left and Right_
391 	if (_Left < Right_)
392 		return Right_;
393 	else
394 		return _Left;
395 }
396 
397 template<typename Tx_, typename Ty_> inline
398 Tx_ _max(const Tx_& _Left, const Ty_& Right_)
399 {	// return smaller of _Left and Right_
400     return (Right_ < _Left ? _Left : Right_);
401 }
402 
403 //////////////////////////////////////////////////////////////////////////////
404 
405 template <typename T>
406 inline
407 T _abs(T const & x)
408 {
409     if (x < static_cast<T>(0))
410         return -x;
411     else
412         return x;
413 }
414 
415 //////////////////////////////////////////////////////////////////////////////
416 
417 template <typename T1, typename T2>
418 inline bool
419 _isSameType()
420 {
421 	return IsSameType<T1, T2>::VALUE;
422 }
423 
424 //////////////////////////////////////////////////////////////////////////////
425 
426 } //namespace SEQAN_NAMESPACE_MAIN
427 
428 #endif //#ifndef SEQAN_HEADER_...
429 
430