range_coll.hpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:12k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: range_coll.hpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 19:38:30  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.4
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef UTIL___RANGE_COLL__HPP
  10. #define UTIL___RANGE_COLL__HPP
  11. /*  $Id: range_coll.hpp,v 1000.2 2004/06/01 19:38:30 gouriano Exp $
  12.  * ===========================================================================
  13.  *
  14.  *                            PUBLIC DOMAIN NOTICE
  15.  *               National Center for Biotechnology Information
  16.  *
  17.  *  This software/database is a "United States Government Work" under the
  18.  *  terms of the United States Copyright Act.  It was written as part of
  19.  *  the author's official duties as a United States Government employee and
  20.  *  thus cannot be copyrighted.  This software/database is freely available
  21.  *  to the public for use. The National Library of Medicine and the U.S.
  22.  *  Government have not placed any restriction on its use or reproduction.
  23.  *
  24.  *  Although all reasonable efforts have been taken to ensure the accuracy
  25.  *  and reliability of the software and data, the NLM and the U.S.
  26.  *  Government do not and cannot warrant the performance or results that
  27.  *  may be obtained by using this software or data. The NLM and the U.S.
  28.  *  Government disclaim all warranties, express or implied, including
  29.  *  warranties of performance, merchantability or fitness for any particular
  30.  *  purpose.
  31.  *
  32.  *  Please cite the author in any work or product based on this material.
  33.  *
  34.  * ===========================================================================
  35.  *
  36.  * Authors:  Andrey Yazhuk
  37.  *
  38.  * File Description:
  39.  *  class CRangeCollection - sorted collection of non-overlapping CRange-s
  40.  */
  41. #include <corelib/ncbistd.hpp>
  42. #include <corelib/ncbistl.hpp>
  43. #include <util/range.hpp>
  44. #include <algorithm>
  45. BEGIN_NCBI_SCOPE
  46. template<class Range, class Position>
  47. struct PRangeLessPos
  48. {
  49.     bool    operator()(const Range &R, Position Pos)  { return R.GetToOpen() <= Pos;  }    
  50. };
  51.     
  52. ///////////////////////////////////////////////////////////////////////////////
  53. // class CRangeCollection<Position> represent a sorted collection of 
  54. // CRange<Position>. It is guaranteed that ranges in collection do not overlap
  55. // and aren't adjacent so that there is no gap beween them.
  56. // Adding an interval to the collection leads to possible merging it with 
  57. // existing intervals.
  58. template<class Position>
  59. class CRangeCollection 
  60. {
  61. public:
  62.     typedef Position    position_type;
  63.     typedef CRangeCollection<position_type>  TThisType;
  64.     typedef CRange<position_type>    TRange;
  65.     typedef vector<TRange>      TRangeVector;    
  66.     typedef typename TRangeVector::const_iterator    const_iterator;
  67.     typedef typename TRangeVector::const_reverse_iterator    const_reverse_iterator;
  68.     typedef typename TRangeVector::size_type size_type;
  69.     
  70.     CRangeCollection()   { }
  71.     explicit CRangeCollection(const TRange& r)
  72.     {
  73.         m_vRanges.push_back(r);
  74.     }
  75.     CRangeCollection(const CRangeCollection &c)
  76.     {
  77.         m_vRanges = c.m_vRanges;
  78.     }
  79.     
  80.     // immitating vector, but providing only "const" access to elements
  81.     const_iterator  begin() const   
  82.     {   
  83.         return m_vRanges.begin();   
  84.     }
  85.     const_iterator  end() const     
  86.     {   
  87.         return m_vRanges.end(); 
  88.     }
  89.     const_reverse_iterator  rbegin() const  
  90.     {   
  91.         return m_vRanges.rbegin();  
  92.     }
  93.     const_reverse_iterator  rend() const    
  94.     {   
  95.         return m_vRanges.rend();    
  96.     }
  97.     size_type size() const  
  98.     {   
  99.         return m_vRanges.size();    
  100.     }
  101.     bool    empty() const   
  102.     {   
  103.         return m_vRanges.empty();   
  104.     }
  105.     const   TRange& operator[](size_type pos)   const   
  106.     {  
  107.         return m_vRanges[pos];  
  108.     }
  109.     void    clear()
  110.     {
  111.         m_vRanges.clear();
  112.     }
  113.     // returns iterator pointing to the TRange that has ToOpen > pos
  114.     const_iterator  find(position_type pos)   const
  115.     {
  116.         return x_Find(pos);
  117.     }
  118.     position_type   GetFrom() const
  119.     {
  120.         if(! m_vRanges.empty())
  121.             return begin()->GetFrom();
  122.         else return -1;
  123.     }
  124.     position_type   GetToOpen() const
  125.     {
  126.         if(! m_vRanges.empty())
  127.             return rbegin()->GetToOpen();
  128.         else return -1;
  129.     }
  130.     position_type   GetTo() const
  131.     {
  132.         if(! m_vRanges.empty())
  133.             return rbegin()->GetToOpen();
  134.         else return -1;
  135.     }
  136.     bool            Empty() const
  137.     {
  138.         return empty();
  139.     } 
  140.     bool            NotEmpty() const
  141.     {
  142.         return ! empty();
  143.     }
  144.     position_type   GetLength (void) const
  145.     {
  146.        if(! m_vRanges.empty())  {
  147.             position_type From = begin()->GetFrom();
  148.             return rbegin()->GetToOpen() - From;
  149.        } else return 0;
  150.     }
  151.     TRange          GetLimits() const
  152.     {
  153.         if(! m_vRanges.empty())  {
  154.             position_type From = begin()->GetFrom();
  155.             position_type To = rbegin()->GetTo();
  156.             return TRange(From, To);
  157.        } else return TRange(0, -1);
  158.     }
  159.     TThisType&  IntersectWith (const TRange& r)
  160.     {
  161.          x_IntersectWith(r);
  162.          return *this;
  163.     }
  164.     TThisType &  operator &= (const TRange& r)
  165.     {
  166.          x_IntersectWith(r);
  167.          return *this;
  168.     }
  169.     bool  IntersectingWith (const TRange& r) const
  170.     {
  171.         return x_Intersects(r).second;
  172.     }
  173.     TThisType&  CombineWith (const TRange& r)
  174.     {
  175.         x_CombineWith(r);
  176.         return *this;
  177.     }
  178.     TThisType &  operator+= (const TRange& r)
  179.     {
  180.         x_CombineWith(r);
  181.         return *this;
  182.     }
  183.     TThisType&  Subtract(const TRange& r)
  184.     {
  185.         x_Subtract(r);
  186.         return *this;
  187.     }
  188.     TThisType &  operator-= (const TRange& r)
  189.     {
  190.        x_Subtract(r);
  191.        return *this;
  192.     }    
  193.     TThisType&  IntersectWith (const TThisType &c)
  194.     {
  195.         x_IntersectWith(c);
  196.         return *this;
  197.     }
  198.     TThisType &  operator&= (const TThisType &c)
  199.     {
  200.         x_IntersectWith(c);
  201.         return *this;
  202.     }
  203.     TThisType&  CombineWith (const TThisType &c)
  204.     {
  205.         x_CombineWith(c);
  206.         return *this;
  207.     }
  208.     TThisType &  operator+= (const TThisType &c)
  209.     {
  210.         x_CombineWith(c);
  211.         return *this;
  212.     }
  213.     TThisType&  Subtract(const TThisType &c)
  214.     {
  215.         x_Subtract(c);
  216.         return *this;
  217.     }
  218.     TThisType &  operator-= (const TThisType &c)
  219.     {
  220.        x_Subtract(c);
  221.        return *this;
  222.     }    
  223. protected:
  224.     typedef typename TRangeVector::iterator    iterator;
  225.     typedef typename TRangeVector::reverse_iterator    reverse_iterator;
  226.     iterator  begin()   
  227.     {   
  228.         return m_vRanges.begin();   
  229.     }
  230.     iterator  end()
  231.     {   
  232.         return m_vRanges.end(); 
  233.     }    
  234.     pair<iterator, bool>    x_Find(position_type pos)
  235.     {
  236.         PRangeLessPos<TRange, position_type>    p;
  237.         iterator it = lower_bound(begin(), end(), pos, p);
  238.         bool b_contains = it != end()  &&  it->GetFrom() >= pos;
  239.         return make_pair(it, b_contains);
  240.     }
  241.     pair<iterator, bool>    x_Intersects(const TRange& r)
  242.     {
  243.         PRangeLessPos<TRange, position_type>    p;
  244.         iterator it = lower_bound(begin(), end(), r.GetFrom(), p);
  245.         bool b_intersects = it != end()  &&  it->GetFrom() < r.GetToOpen();
  246.         return make_pair(it, b_intersects);
  247.     }
  248.    
  249.     void    x_IntersectWith(const TRange& r)
  250.     {
  251.         PRangeLessPos<TRange, position_type>    p;
  252.         position_type pos_to = r.GetTo();
  253.         iterator it_right = lower_bound(begin(), end(), pos_to, p);
  254.         if(it_right != end()) {
  255.             if(it_right->GetFrom() <= pos_to) {   //intersects
  256.                 it_right->SetTo(pos_to);
  257.                 ++it_right; // exclude from removal
  258.             }
  259.             m_vRanges.erase(it_right, end()); // erase ranges to the right
  260.         }
  261.         position_type pos_from = this->R.GetFrom();
  262.         iterator it_left = lower_bound(begin(), end(), pos_from, this->P);
  263.         if(it_left != end()) {        
  264.             if(it_left->GetFrom() < pos_from)    
  265.                 it_left->SetFrom(pos_from);
  266.             m_vRanges.erase(begin(), it_left); //erase ranges to the left
  267.         }
  268.     }
  269.     // returns iterator to the range representing result of combination
  270.     iterator    x_CombineWith(const TRange& r)
  271.     {
  272.         PRangeLessPos<TRange, position_type>    p;
  273.         position_type pos_from = r.GetFrom();
  274.         position_type pos_to_open = r.GetToOpen();                    
  275.         iterator it_begin_m = lower_bound(begin(), end(), pos_from - 1, p);        
  276.         if(it_begin_m != end() && it_begin_m->GetFrom() <= pos_to_open)  { // intersection
  277.             it_begin_m->CombineWith(r);
  278.         
  279.             iterator it_end_m = lower_bound(it_begin_m, end(), pos_to_open, p);
  280.             if(it_end_m != end()  &&  it_end_m->GetFrom() <= pos_to_open) {// subject to merge
  281.                 it_begin_m->SetToOpen(it_end_m->GetToOpen()); 
  282.                 ++it_end_m; // including it into erased set
  283.             }
  284.             m_vRanges.erase(it_begin_m + 1, it_end_m); 
  285.         } else {
  286.             m_vRanges.insert(it_begin_m, r);
  287.         }
  288.         return it_begin_m;
  289.     }
  290.     void    x_Subtract(const TRange& r)
  291.     {
  292.         PRangeLessPos<TRange, position_type>    P;
  293.         position_type pos_from = r.GetFrom();
  294.         position_type pos_to_open = r.GetToOpen();
  295.         iterator it_begin_e = lower_bound(begin(), end(), pos_from, P);
  296.         if(it_begin_e != end()) {   // possible intersection
  297.             
  298.             if(it_begin_e->GetFrom() < pos_from  &&  it_begin_e->GetToOpen() > pos_to_open)    { 
  299.                 //it_begin_e contains R, split it in two
  300.                 it_begin_e = m_vRanges.insert(it_begin_e, *it_begin_e);
  301.                 it_begin_e->SetToOpen(pos_from);
  302.                 (++it_begin_e)->SetFrom(pos_to_open);
  303.             } else  {
  304.                 if(it_begin_e->GetFrom() < pos_from) { // cut this segement , but don't erase
  305.                     it_begin_e->SetToOpen(pos_from);
  306.                     ++it_begin_e;
  307.                 }
  308.                 iterator it_end_e = lower_bound(it_begin_e, end(), pos_to_open, P);
  309.                 if(it_end_e != end()  &&  it_end_e->GetFrom() < pos_to_open)    { 
  310.                     it_end_e->SetFrom(pos_to_open); // truncate
  311.                 }
  312.                 // erase ranges fully covered by R
  313.                 m_vRanges.erase(it_begin_e, it_end_e); 
  314.             }
  315.         } 
  316.     }
  317.     void    x_IntersectWith(const TThisType &c)
  318.     {
  319.         ITERATE(typename TThisType, it, c)   {
  320.             x_IntersectWith(*it);
  321.         }
  322.     }
  323.     void    x_CombineWith(const TThisType &c)
  324.     {
  325.         ITERATE(typename TThisType, it, c)   {
  326.             x_CombineWith(*it);
  327.         }
  328.     }
  329.     void    x_Subtract(const TThisType &c)
  330.     {
  331.         ITERATE(typename TThisType, it, c)   {
  332.             x_Subtract(*it);
  333.         }
  334.     }
  335. protected:
  336.     TRangeVector    m_vRanges;  
  337. };
  338. END_NCBI_SCOPE
  339. /*
  340.  * ===========================================================================
  341.  * $Log: range_coll.hpp,v $
  342.  * Revision 1000.2  2004/06/01 19:38:30  gouriano
  343.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.4
  344.  *
  345.  * Revision 1.4  2004/04/26 14:51:43  ucko
  346.  * Add "typename" and "this->" to accommodate GCC 3.4's stricter
  347.  * treatment of templates.
  348.  *
  349.  * Revision 1.3  2004/02/12 20:51:52  yazhuk
  350.  * Fixed GetFrom()
  351.  *
  352.  * Revision 1.2  2003/12/22 19:17:49  dicuccio
  353.  * Use correct #include guard
  354.  *
  355.  * Revision 1.1  2003/12/01 16:29:45  yazhuk
  356.  * Moved from gui/widgets/aln_multiple
  357.  *
  358.  * Revision 1.7  2003/10/10 18:56:12  yazhuk
  359.  * Added GetFrom(), fixed find()
  360.  *
  361.  * Revision 1.6  2003/10/08 14:12:58  dicuccio
  362.  * Moved CGlPane into opengl
  363.  *
  364.  * Revision 1.5  2003/09/29 13:38:48  yazhuk
  365.  * Enforced coding policy
  366.  *
  367.  * Revision 1.4  2003/09/23 20:45:47  yazhuk
  368.  * Added comments
  369.  *
  370.  * Revision 1.3  2003/09/08 20:47:50  yazhuk
  371.  * Bugfixes
  372.  *
  373.  * Revision 1.2  2003/09/08 17:04:12  yazhuk
  374.  * GCC compilation fixes
  375.  *
  376.  * Revision 1.1  2003/09/08 16:34:38  yazhuk
  377.  * Initial revision
  378.  *
  379.  * ===========================================================================
  380.  */
  381. #endif  // UTIL___RANGE_COLL__HPP