[转]An STL compliant sorted vector-源码示例
原文地址:http://www.codeproject.com/Articles/3217/An-STL-compliant-sorted-vector
最近在看sorted vectored的一些东西,自己封装了一个sorted vector类型,后来找到了codeproject上的一个源码示例,感觉写的不错,可以借鉴一下。
sorted_vector
adapts a std::vector
to the interface required by std::set/std::multiset
, thereby providing set/multiset and vector functionality (random access) in one container.
1 /* STL-conforming "sorted vector" container 2 * 3 * (C) 2002 Martin Holzherr (holzherr@infobrain.com). All rights reserved. 4 * 5 * Permission is granted to use, distribute and modify this code provided that: 6 * ? this copyright notice appears, 7 * ? 8 * The author welcomes any suggestions on the code or reportings of actual 9 * use of the code. Please send your comments to holzherr@infobrain.com. 10 * 11 * The author makes NO WARRANTY or representation, either express or implied, 12 * with respect to this code, its quality, accuracy, merchantability, or 13 * fitness for a particular purpose. This software is provided "AS IS", and 14 * you, its user, assume the entire risk as to its quality and accuracy. 15 * 16 * Created: November 19th, 2002 17 * Last modified: November 27th, 2002 18 (changed namespace from std to codeproject; 19 uses template member functions for MSCVER>=1300) 20 21 */ 22 23 #ifndef SORTED_VECTOR_ 24 #define SORTED_VECTOR_ 25 #define VERSION_SORTED_VECTOR_ 0x00010010 26 27 28 #include <algorithm> 29 #include <vector> 30 #include <utility> 31 #include <functional> 32 33 #pragma pack(push,8) 34 #pragma warning(push,3) 35 36 37 namespace codeproject{ 38 // TEMPLATE CLASS sorted_vector 39 40 template<class K, bool bNoDuplicates= false,class Pr = std::less<K>, class A = std::allocator<K> > 41 class sorted_vector { 42 public: 43 typedef sorted_vector<K,bNoDuplicates,Pr,A> Myt_; 44 typedef std::vector<K,A> Cont; 45 typedef typename Cont::allocator_type allocator_type; 46 typedef typename Cont::size_type size_type; 47 typedef typename Cont::difference_type difference_type; 48 typedef typename Cont::reference reference; 49 typedef typename Cont::const_reference const_reference; 50 typedef typename Cont::value_type value_type; 51 typedef K key_type; 52 typedef typename Cont::iterator iterator; 53 typedef typename Cont::const_iterator const_iterator; 54 typedef Pr key_compare; 55 typedef Pr value_compare; 56 57 typedef typename Cont::const_reverse_iterator 58 const_reverse_iterator; 59 typedef typename Cont::reverse_iterator reverse_iterator; 60 61 typedef std::pair<iterator, iterator> Pairii_; 62 typedef std::pair<const_iterator, const_iterator> Paircc_; 63 typedef std::pair<iterator, bool> Pairib_; 64 explicit sorted_vector(const Pr& pred = Pr(),const A& al = A()) 65 :key_compare_(pred),vec_(al){} 66 67 //#if (_MSC_VER >= 1300) //_MSC_VER 定义编译器的版本,MS VC++ 68 template<class It> 69 sorted_vector(It first, It beyond, 70 const Pr& pred = Pr(),const A& al = A()) 71 :key_compare_(pred),vec_(first,beyond,al) 72 {stable_sort();} 73 //#else 74 // sorted_vector(const_iterator first, const_iterator beyond, 75 // const Pr& pred = Pr(),const A& al = A()) 76 // :key_compare_(pred),vec_(first,beyond,al) 77 // {stable_sort();} 78 //#endif 79 80 sorted_vector(const Myt_& x) 81 : vec_(x.vec_),key_compare_(x.key_compare_) 82 {} 83 84 ~sorted_vector() {} 85 Myt_& operator=(const Myt_& x) {vec_.operator=(x.vec_); 86 key_compare_= x.key_compare_; 87 return *this;} 88 Myt_& operator=(const Cont& x){vec_.operator=(x); 89 sort();return *this;} 90 91 void reserve(size_type n) {vec_.reserve(n);} 92 iterator begin() {return vec_.begin(); } 93 const_iterator begin() const {return vec_.begin(); } 94 iterator end() {return vec_.end();} 95 const_iterator end() const {return vec_.end();} 96 reverse_iterator rbegin() {return vec_.rbegin();} 97 const_reverse_iterator rbegin() const 98 {return vec_.rbegin();} 99 100 reverse_iterator rend() {return vec_.rend();} 101 const_reverse_iterator rend() const 102 {return vec_.rend();} 103 104 105 size_type size() const {return vec_.size();} 106 size_type max_size() const {return vec_.max_size();} 107 bool empty() const {return vec_.empty();} 108 A get_allocator() const {return vec_.get_allocator();} 109 const_reference at(size_type p) const {return vec_.at(p);} 110 reference at(size_type p) {return vec_.at(p);} 111 const_reference operator[](size_type p) const 112 {return vec_.operator[](p);} 113 114 reference operator[](size_type p) {return vec_.operator[](p);} 115 reference front() {return vec_.front();} 116 const_reference front() const {return vec_.front();} 117 reference back() {return vec_.back();} 118 const_reference back() const {return vec_.back();} 119 void pop_back() {vec_.pop_back();} 120 121 void assign(const_iterator first, const_iterator beyond) 122 {vec_.assign(first,beyond);} 123 void assign(size_type n, const K& x = K()) 124 {vec_.assign(n,x);} 125 /*insert members*/ 126 Pairib_ insert(const value_type& x) 127 { 128 if(bNoDuplicates){ 129 iterator p= lower_bound(x); 130 if(p==end()||key_compare_(x,*p)){ 131 return Pairib_(InsertImpl_(p,x),true); 132 }else{ 133 return Pairib_(p,false); 134 } 135 }else{ 136 iterator p= upper_bound(x); 137 return Pairib_(InsertImpl_(p,x),true); 138 } 139 } 140 iterator insert(iterator it, const value_type& x)//it is the hint 141 { 142 if(it!=end() ){ 143 if(bNoDuplicates){ 144 if(key_compare_(*it,x)){ 145 if((it+1)==end()||KeyCompare_Gt_(*(it+1),x)){//use hint 146 return InsertImpl_(it+1,x); 147 }else if(KeyCompare_Geq_(*(it+1),x)){ 148 return end(); 149 } 150 } 151 }else{ 152 if( KeyCompare_Leq_(*it,x) 153 &&((it+1)==end()||KeyCompare_Geq_(*(it+1),x))){ 154 return InsertImpl_(it+1,x); 155 } 156 } 157 } 158 return insert(x).first; 159 } 160 //#if (_MSC_VER >= 1300) //_MSC_VER 定义编译器的版本,MS VC++ 161 template<class It> 162 void insert(It first, It beyond) 163 { 164 size_type n= std::distance(first,beyond); 165 reserve(size()+n); 166 for( ;first!=beyond;++first){ 167 insert(*first); 168 } 169 } 170 //#else 171 // void insert(const_iterator first, const_iterator beyond) 172 // { 173 // size_type n= std::distance(first,beyond); 174 // reserve(size()+n); 175 // for( ;first!=beyond;++first){ 176 // insert(*first); 177 // } 178 // } 179 //#endif 180 iterator erase(iterator p) {return vec_.erase(p);} 181 iterator erase(iterator first, iterator beyond) 182 {return vec_.erase(first,beyond);} 183 size_type erase(const K& key) 184 { 185 Pairii_ begEnd= equal_range(key); 186 size_type n= std::distance(begEnd.first,begEnd.second); 187 erase(begEnd.first,begEnd.second); 188 return n; 189 } 190 void clear() {return vec_.clear();} 191 192 bool Eq_(const Myt_& x) const 193 {return (size() == x.size() 194 && std::equal(begin(), end(), x.begin())); } 195 bool Lt_(const Myt_& x) const 196 {return (std::lexicographical_compare(begin(), end(), 197 x.begin(), x.end()));} 198 void swap(Myt_& x) 199 {vec_.swap(x.vec_);std::swap(key_compare_,x.key_compare_);} 200 201 friend void swap(Myt_& x, Myt_& Y_) 202 {x.swap(Y_); } 203 204 key_compare key_comp() const {return key_compare_; } 205 value_compare value_comp() const {return (key_comp()); } 206 207 //针对多维索引的属性值查找,需提供自定义的比较方法。只能查找排序的属性值。 208 template <typename _Tp, class _Compare> 209 const_iterator find(const _Tp& k, _Compare cmp) { 210 const_iterator p = lower_bound(k, cmp); 211 return (p == end() || cmp(k, *p)) ? end() : p; 212 } 213 214 template <typename _Tp, typename _Compare> 215 iterator lower_bound (const _Tp& val, _Compare cmp) { 216 return std::lower_bound(begin(), end(), val, cmp); 217 } 218 219 220 iterator find(const K& k) 221 { iterator p = lower_bound(k); 222 return (p==end()||key_compare_(k, *p))? end():p; 223 } 224 const_iterator find(const K& k) const 225 {const_iterator p = lower_bound(k); 226 return (p==end()||key_compare_(k,*p))?end():p;} 227 size_type count(const K& k) const 228 {Paircc_ Ans_ = equal_range(k); 229 size_type n = std::distance(Ans_.first, Ans_.second); 230 return (n); } 231 iterator lower_bound(const K& k) 232 {return std::lower_bound(begin(), end(), k, key_compare_); } 233 const_iterator lower_bound(const K& k) const 234 {return std::lower_bound(begin(), end(), k, key_compare_); } 235 iterator upper_bound(const K& k) 236 {return std::upper_bound(begin(), end(), k, key_compare_); } 237 const_iterator upper_bound(const K& k) const 238 {return std::upper_bound(begin(), end(), k, key_compare_); } 239 Pairii_ equal_range(const K& k) 240 {return std::equal_range(begin(), end(), k, key_compare_); } 241 Paircc_ equal_range(const K& k) const 242 {return std::equal_range(begin(), end(), k, key_compare_); } 243 244 /*functions for use with direct std::vector-access*/ 245 Cont& get_container() 246 {return vec_;} 247 void sort()//restore sorted order after low level access 248 { std::sort(vec_.begin(),vec_.end(),key_compare_); 249 if( bNoDuplicates ){ 250 vec_.erase(Unique_(),vec_.end()); 251 } 252 } 253 void stable_sort()//restore sorted order after low level access 254 { std::stable_sort(vec_.begin(),vec_.end(),key_compare_); 255 if( bNoDuplicates ){ 256 erase(Unique_(),end()); 257 } 258 } 259 protected: 260 iterator Unique_() 261 { iterator front_= vec_.begin(),out_= vec_.end(),end_=vec_.end(); 262 bool bCopy_= false; 263 for(iterator prev_; (prev_=front_)!=end_ && ++front_!=end_; ){ 264 if( key_compare_(*prev_,*front_)){ 265 if(bCopy_){ 266 *out_= *front_; 267 out_++; 268 } 269 }else{ 270 if(!bCopy_){out_=front_;bCopy_=true;} 271 } 272 } 273 return out_; 274 } 275 iterator InsertImpl_(iterator p,const value_type& x) 276 {return vec_.insert(p,x);} 277 bool KeyCompare_Leq_(const K& ty0,const K& ty1) 278 {return !key_compare_(ty1,ty0);} 279 bool KeyCompare_Geq_(const K& ty0,const K& ty1) 280 {return !key_compare_(ty0,ty1);} 281 bool KeyCompare_Gt_(const K& ty0,const K& ty1) 282 {return key_compare_(ty1,ty0);} 283 284 key_compare key_compare_; 285 Cont vec_; 286 }; 287 288 289 template<class K,bool bNoDuplicates,class Pr, class A> inline 290 bool operator==(const sorted_vector<K, bNoDuplicates,Pr,A>& x, 291 const sorted_vector<K, bNoDuplicates,Pr,A>& Y_) 292 {return x.Eq_(Y_); } 293 template<class K,bool bNoDuplicates,class Pr, class A> inline 294 bool operator!=(const sorted_vector<K, bNoDuplicates,Pr,A>& x, 295 const sorted_vector<K, bNoDuplicates,Pr,A>& Y_) 296 {return !(x == Y_); } 297 template<class K,bool bNoDuplicates,class Pr, class A> inline 298 bool operator<(const sorted_vector<K, bNoDuplicates,Pr,A>& x, 299 const sorted_vector<K, bNoDuplicates,Pr,A>& Y_) 300 {return x.Lt_(Y_);} 301 template<class K,bool bNoDuplicates,class Pr,class A> inline 302 bool operator>(const sorted_vector<K, bNoDuplicates,Pr,A>& x, 303 const sorted_vector<K, bNoDuplicates,Pr,A>& Y_) 304 {return Y_ < x; } 305 template<class K,bool bNoDuplicates,class Pr, class A> inline 306 bool operator<=(const sorted_vector<K, bNoDuplicates,Pr,A>& x, 307 const sorted_vector<K, bNoDuplicates,Pr,A>& Y_) 308 {return !(Y_ < x); } 309 template<class K, bool bNoDuplicates,class Pr,class A> inline 310 bool operator>=(const sorted_vector<K, bNoDuplicates,Pr,A>& x, 311 const sorted_vector<K, bNoDuplicates,Pr,A>& Y_) 312 {return (!(x < Y_)); } 313 } 314 #pragma warning(pop) 315 #pragma pack(pop) 316 #elif VERSION_SORTED_VECTOR_ != 0x00010010 317 #error You have included two sorted_vector.h with different version numbers 318 #endif