NCBI C++ ToolKit
range.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef RANGE__HPP
2 #define RANGE__HPP
3 
4 /* $Id: range.hpp 50621 2011-07-27 15:46:03Z grichenk $
5 * ===========================================================================
6 *
7 * PUBLIC DOMAIN NOTICE
8 * National Center for Biotechnology Information
9 *
10 * This software/database is a "United States Government Work" under the
11 * terms of the United States Copyright Act. It was written as part of
12 * the author's official duties as a United States Government employee and
13 * thus cannot be copyrighted. This software/database is freely available
14 * to the public for use. The National Library of Medicine and the U.S.
15 * Government have not placed any restriction on its use or reproduction.
16 *
17 * Although all reasonable efforts have been taken to ensure the accuracy
18 * and reliability of the software and data, the NLM and the U.S.
19 * Government do not and cannot warrant the performance or results that
20 * may be obtained by using this software or data. The NLM and the U.S.
21 * Government disclaim all warranties, express or implied, including
22 * warranties of performance, merchantability or fitness for any particular
23 * purpose.
24 *
25 * Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 * Author: Eugene Vasilchenko
30 *
31 * File Description:
32 * CRange<> class represents interval
33 *
34 * ===========================================================================
35 */
36 
37 #include <corelib/ncbistd.hpp>
38 #include <corelib/ncbi_limits.hpp>
39 
40 
41 /** @addtogroup RangeSupport
42  *
43  * @{
44  */
45 
46 
48 
49 
50 /////////////////////////////////////////////////////////////////////////////
51 // The SPositionTraits template is necessary to make comparison with 0
52 // optional only if the position type is signed.
53 // Many other implementation of this optional check make ICC to issue warning
54 // about meaningless comparison with 0 if the position type is signed.
55 /////////////////////////////////////////////////////////////////////////////
56 
57 template<bool Signed, class Position>
59 {
60 };
61 
62 
63 // An instantiation of SPositionTraitsBySignedness for signed position types.
64 template<class Position>
66 {
67  static bool IsNegative(Position pos)
68  {
69  return pos < 0;
70  }
71 };
72 
73 
74 // An instantiation of SPositionTraitsBySignedness for unsigned position types.
75 template<class Position>
77 {
78  static bool IsNegative(Position )
79  {
80  return false;
81  }
82 };
83 
84 
85 // Select an instantiation depending on signedness of the position type.
86 template<class Position>
88  SPositionTraitsBySignedness<(Position(-1)<Position(1)), Position>
89 {
90 };
91 
92 // Explicitly specialize for floating-point types, as only integral or
93 // enumeration types can technically appear in constant expressions.
94 template<>
95 struct SPositionTraits<float> : SPositionTraitsBySignedness<true, float>
96 {
97 };
98 
99 template<>
100 struct SPositionTraits<double> : SPositionTraitsBySignedness<true, double>
101 {
102 };
103 
104 template<>
105 struct SPositionTraits<long double>
106  : SPositionTraitsBySignedness<true, long double>
107 {
108 };
109 
110 /////////////////////////////////////////////////////////////////////////////
111 // End of SPositionTraits implementation
112 /////////////////////////////////////////////////////////////////////////////
113 
114 
115 // range
116 template<class Position>
117 class COpenRange
118 {
119 public:
120  typedef Position position_type;
121  typedef COpenRange<Position> TThisType;
122 
123  // constructors
124  COpenRange(void)
125  : m_From(GetEmptyFrom()), m_ToOpen(GetEmptyToOpen())
126  {
127  }
128  COpenRange(position_type from, position_type toOpen)
129  : m_From(from), m_ToOpen(toOpen)
130  {
131  }
132 
133  // parameters
134  position_type GetFrom(void) const
135  {
136  return m_From;
137  }
138  position_type GetToOpen(void) const
139  {
140  return m_ToOpen;
141  }
142  position_type GetTo(void) const
143  {
144  return GetToOpen()-1;
145  }
146 
147  // state
148  bool Empty(void) const
149  {
150  return GetToOpen() <= GetFrom();
151  }
152  bool NotEmpty(void) const
153  {
154  return GetToOpen() > GetFrom();
155  }
156 
157  // return length of regular region
158  position_type GetLength(void) const
159  {
160  position_type from = GetFrom(), toOpen = GetToOpen();
161  if ( toOpen <= from )
162  return 0;
163  position_type len = toOpen - from;
164  if ( SPositionTraits<position_type>::IsNegative(len) )
165  len = GetWholeLength();
166  return len;
167  }
168 
169  // modifiers
170  TThisType& SetFrom(position_type from)
171  {
172  m_From = from;
173  return *this;
174  }
175  TThisType& SetToOpen(position_type toOpen)
176  {
177  m_ToOpen = toOpen;
178  return *this;
179  }
180  TThisType& SetTo(position_type to)
181  {
182  return SetToOpen(to+1);
183  }
184  TThisType& SetOpen(position_type from, position_type toOpen)
185  {
186  return SetFrom(from).SetToOpen(toOpen);
187  }
188  TThisType& Set(position_type from, position_type to)
189  {
190  return SetFrom(from).SetTo(to);
191  }
192 
193  // length must be >= 0
194  TThisType& SetLength(position_type length)
195  {
196  _ASSERT(!SPositionTraits<position_type>::IsNegative(length));
197  position_type from = GetFrom();
198  position_type toOpen = from + length;
199  if ( toOpen < from )
200  toOpen = GetWholeToOpen();
201  return SetToOpen(toOpen);
202  }
203  // length must be >= 0
204  TThisType& SetLengthDown(position_type length)
205  {
206  _ASSERT(length >= 0);
207  position_type toOpen = GetToOpen();
208  position_type from = toOpen - length;
209  if ( from > toOpen )
210  from = GetWholeFrom();
211  return SetFrom(from);
212  }
213 
214  // comparison
215  bool operator==(const TThisType& r) const
216  {
217  return GetFrom() == r.GetFrom() && GetToOpen() == r.GetToOpen();
218  }
219  bool operator!=(const TThisType& r) const
220  {
221  return !(*this == r);
222  }
223  bool operator<(const TThisType& r) const
224  {
225  return GetFrom() < r.GetFrom() ||
226  (GetFrom() == r.GetFrom() && GetToOpen() < r.GetToOpen());
227  }
228  bool operator<=(const TThisType& r) const
229  {
230  return GetFrom() < r.GetFrom() ||
231  (GetFrom() == r.GetFrom() && GetToOpen() <= r.GetToOpen());
232  }
233  bool operator>(const TThisType& r) const
234  {
235  return GetFrom() > r.GetFrom() ||
236  (GetFrom() == r.GetFrom() && GetToOpen() > r.GetToOpen());
237  }
238  bool operator>=(const TThisType& r) const
239  {
240  return GetFrom() > r.GetFrom() ||
241  (GetFrom() == r.GetFrom() && GetToOpen() >= r.GetToOpen());
242  }
243 
244 
245  // special values
246  static position_type GetPositionMin(void)
247  {
248  return numeric_limits<position_type>::min();
249  }
250  static position_type GetPositionMax(void)
251  {
252  return numeric_limits<position_type>::max();
253  }
254 
255  // whole range
256  static position_type GetWholeFrom(void)
257  {
258  return GetPositionMin();
259  }
260  static position_type GetWholeToOpen(void)
261  {
262  return GetPositionMax();
263  }
264  static position_type GetWholeTo(void)
265  {
266  return GetWholeToOpen()-1;
267  }
268  static position_type GetWholeLength(void)
269  {
270  return GetPositionMax();
271  }
272  static TThisType GetWhole(void)
273  {
274  return TThisType(GetWholeFrom(), GetWholeToOpen());
275  }
276  bool IsWholeFrom(void) const
277  {
278  return GetFrom() == GetWholeFrom();
279  }
280  bool IsWholeTo(void) const
281  {
282  return GetToOpen() == GetWholeToOpen();
283  }
284  bool IsWhole(void) const
285  {
286  return IsWholeFrom() && IsWholeTo();
287  }
288 
289  // empty range
290  static position_type GetEmptyFrom(void)
291  {
292  return GetPositionMax();
293  }
294  static position_type GetEmptyToOpen(void)
295  {
296  return GetPositionMax();
297  }
298  static position_type GetEmptyTo(void)
299  {
300  return GetEmptyToOpen()-1;
301  }
302  static position_type GetEmptyLength(void)
303  {
304  return 0;
305  }
306  static TThisType GetEmpty(void)
307  {
308  return TThisType(GetEmptyFrom(), GetEmptyToOpen());
309  }
310 
311  // intersecting ranges
312  TThisType IntersectionWith(const TThisType& r) const
313  {
314  return TThisType(max(GetFrom(), r.GetFrom()),
315  min(GetToOpen(), r.GetToOpen()));
316  }
317  TThisType& IntersectWith(const TThisType& r)
318  {
319  m_From = max(GetFrom(), r.GetFrom());
320  m_ToOpen = min(GetToOpen(), r.GetToOpen());
321  return *this;
322  }
323  TThisType operator&(const TThisType& r) const
324  {
325  return IntersectionWith(r);
326  }
327  TThisType& operator&=(const TThisType& r)
328  {
329  return IntersectWith(r);
330  }
331  bool IntersectingWith(const TThisType& r) const
332  {
333  return IntersectionWith(r).NotEmpty();
334  }
335 
336  bool AbuttingWith(const TThisType& r) const
337  {
338  if (Empty() || IsWhole() || r.Empty() || r.IsWhole()) {
339  return false;
340  }
341  return GetToOpen() == r.GetFrom() || GetFrom() == r.GetToOpen();
342  }
343 
344  // combine ranges
345  TThisType& CombineWith(const TThisType& r)
346  {
347  if ( !r.Empty() ) {
348  if ( !Empty() ) {
349  m_From = min(m_From, r.GetFrom());
350  m_ToOpen = max(m_ToOpen, r.GetToOpen());
351  }
352  else {
353  *this = r;
354  }
355  }
356  return *this;
357  }
358  TThisType CombinationWith(const TThisType& r) const
359  {
360  if ( !r.Empty() ) {
361  if ( !Empty() ) {
362  return TThisType(min(m_From, r.GetFrom()),
363  max(m_ToOpen, r.GetToOpen()));
364  }
365  else {
366  return r;
367  }
368  }
369  return *this;
370  }
371  TThisType& operator+=(const TThisType& r)
372  {
373  return CombineWith(r);
374  }
375  TThisType operator+(const TThisType& r) const
376  {
377  return CombinationWith(r);
378  }
379 
380 private:
381  position_type m_From, m_ToOpen;
382 };
383 
384 
385 // range
386 template<class Position>
387 class CRange : public COpenRange<Position>
388 {
389 public:
390  typedef COpenRange<Position> TParent;
391  typedef typename TParent::position_type position_type;
392  typedef CRange<Position> TThisType;
393 
394  // constructors
395  CRange(void)
396  {
397  }
398  CRange(position_type from, position_type to)
399  : TParent(from, to+1)
400  {
401  }
402  CRange(const TParent& range)
403  : TParent(range)
404  {
405  }
406 
407  // modifiers
408  TThisType& operator=(const TParent& range)
409  {
410  static_cast<TParent&>(*this) = range;
411  return *this;
412  }
413 };
414 
415 ///
416 /// typedefs for sequence ranges
417 ///
418 
419 typedef CRange<TSeqPos> TSeqRange;
420 typedef CRange<TSignedSeqPos> TSignedSeqRange;
421 
422 /* @} */
423 
424 template<class Position>
425 inline
426 CNcbiOstream& operator<<(CNcbiOstream& out, const COpenRange<Position>& range)
427 {
428  return out << range.GetFrom() << ".." << range.GetTo();
429 }
430 
431 //#include <util/range.inl>
432 
433 END_NCBI_SCOPE
434 
435 #endif /* RANGE__HPP */
Include a standard set of the NCBI C++ Toolkit most basic headers.
#define true
Definition: bool.h:35
#define false
Definition: bool.h:36
static bool IsNegative(Position pos)
Definition: range.hpp:67
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
Modified on Fri Apr 26 16:28:52 2024 by modify_doxy.py rev. 669887