library of assembled shared sources

http://lass.cocamware.com

static_vector.inl

Go to the documentation of this file.
00001 /** @file
00002  *  @author Bram de Greve (bramz@users.sourceforge.net)
00003  *  @author Tom De Muer (tomdemuer@users.sourceforge.net)
00004  *
00005  *  *** BEGIN LICENSE INFORMATION ***
00006  *  
00007  *  The contents of this file are subject to the Common Public Attribution License 
00008  *  Version 1.0 (the "License"); you may not use this file except in compliance with 
00009  *  the License. You may obtain a copy of the License at 
00010  *  http://lass.sourceforge.net/cpal-license. The License is based on the 
00011  *  Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover 
00012  *  use of software over a computer network and provide for limited attribution for 
00013  *  the Original Developer. In addition, Exhibit A has been modified to be consistent 
00014  *  with Exhibit B.
00015  *  
00016  *  Software distributed under the License is distributed on an "AS IS" basis, WITHOUT 
00017  *  WARRANTY OF ANY KIND, either express or implied. See the License for the specific 
00018  *  language governing rights and limitations under the License.
00019  *  
00020  *  The Original Code is LASS - Library of Assembled Shared Sources.
00021  *  
00022  *  The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
00023  *  The Original Developer is the Initial Developer.
00024  *  
00025  *  All portions of the code written by the Initial Developer are:
00026  *  Copyright (C) 2004-2007 the Initial Developer.
00027  *  All Rights Reserved.
00028  *  
00029  *  Contributor(s):
00030  *
00031  *  Alternatively, the contents of this file may be used under the terms of the 
00032  *  GNU General Public License Version 2 or later (the GPL), in which case the 
00033  *  provisions of GPL are applicable instead of those above.  If you wish to allow use
00034  *  of your version of this file only under the terms of the GPL and not to allow 
00035  *  others to use your version of this file under the CPAL, indicate your decision by 
00036  *  deleting the provisions above and replace them with the notice and other 
00037  *  provisions required by the GPL License. If you do not delete the provisions above,
00038  *  a recipient may use your version of this file under either the CPAL or the GPL.
00039  *  
00040  *  *** END LICENSE INFORMATION ***
00041  */
00042 
00043 #include "../meta/is_integral.h"
00044     
00045 namespace lass
00046 {
00047 namespace stde
00048 {
00049 
00050 namespace impl
00051 {
00052 
00053 /** @internal
00054  */
00055 struct static_vector_traits
00056 {
00057     template <typename Container, typename T>
00058     static void push(Container& container, const T& value)
00059     {
00060         container.push_back(value);
00061     }
00062     template <typename Container>
00063     static void temp_to_output(Container& temp, Container& output)
00064     {
00065         output.assign(temp.begin(), temp.end());
00066     }
00067 };
00068 
00069 }
00070 
00071 
00072 
00073 // --- public --------------------------------------------------------------------------------------
00074 
00075 template <typename T, size_t maxsize> inline
00076 static_vector<T, maxsize>::static_vector():
00077     size_(0)
00078 {
00079 }
00080 
00081 
00082 
00083 template <typename T, size_t maxsize> inline
00084 static_vector<T, maxsize>::static_vector(size_type n, const value_type& value):
00085     size_(0)
00086 {
00087     insert(end(), n, value, meta::Wrap<meta::True>());
00088 }
00089 
00090 
00091 
00092 template <typename T, size_t maxsize>
00093 template <typename InputIterator> inline
00094 static_vector<T, maxsize>::static_vector(InputIterator first, InputIterator last):
00095     size_(0)
00096 {
00097     insert(end(), first, last, meta::Wrap<typename meta::IsIntegral<InputIterator>::Type>());                       
00098 }
00099 
00100 
00101 
00102 template <typename T, size_t maxsize> inline
00103 void static_vector<T, maxsize>::assign(size_type n, const value_type& value)
00104 {
00105     erase(begin(), end());
00106     insert(end(), n, value, meta::Wrap<meta::True>());
00107 }
00108 
00109 
00110 
00111 template <typename T, size_t maxsize>
00112 template <typename InputIterator> inline
00113 void static_vector<T, maxsize>::assign(InputIterator first, InputIterator last)
00114 {
00115     erase(begin(), end());
00116     insert(end(), first, last, meta::Wrap<typename meta::IsIntegral<InputIterator>::Type>());
00117 }
00118 
00119 
00120 
00121 
00122 template <typename T, size_t maxsize> inline
00123 static_vector<T, maxsize>::~static_vector()
00124 {
00125     clear();
00126 }
00127 
00128 
00129 
00130 template <typename T, size_t maxsize> inline
00131 typename static_vector<T, maxsize>::iterator
00132 static_vector<T, maxsize>::begin()
00133 {
00134     return get_element(0);
00135 }
00136 
00137 
00138 
00139 template <typename T, size_t maxsize> inline
00140 typename static_vector<T, maxsize>::const_iterator
00141 static_vector<T, maxsize>::begin() const
00142 {
00143     return get_element(0);
00144 }
00145 
00146 
00147 
00148 template <typename T, size_t maxsize> inline
00149 typename static_vector<T, maxsize>::iterator
00150 static_vector<T, maxsize>::end()
00151 {
00152     return get_element(size_);
00153 }
00154 
00155 
00156 
00157 template <typename T, size_t maxsize> inline
00158 typename static_vector<T, maxsize>::const_iterator
00159 static_vector<T, maxsize>::end() const
00160 {
00161     return get_element(size_);
00162 }
00163 
00164 
00165 
00166 template <typename T, size_t maxsize> inline
00167 typename static_vector<T, maxsize>::reverse_iterator
00168 static_vector<T, maxsize>::rbegin()
00169 {
00170     return reverse_iterator(get_element(size_));
00171 }
00172 
00173 
00174 
00175 template <typename T, size_t maxsize> inline
00176 typename static_vector<T, maxsize>::const_reverse_iterator
00177 static_vector<T, maxsize>::rbegin() const
00178 {
00179     return reverse_iterator(get_element(size_));
00180 }
00181 
00182 
00183 
00184 template <typename T, size_t maxsize> inline
00185 typename static_vector<T, maxsize>::reverse_iterator
00186 static_vector<T, maxsize>::rend()
00187 {
00188     return reverse_iterator(get_element(0));
00189 }
00190 
00191 
00192 
00193 template <typename T, size_t maxsize> inline
00194 typename static_vector<T, maxsize>::const_reverse_iterator
00195 static_vector<T, maxsize>::rend() const
00196 {
00197     return reverse_iterator(get_element(0));
00198 }
00199 
00200 
00201 
00202 template <typename T, size_t maxsize> inline
00203 typename static_vector<T, maxsize>::size_type
00204 static_vector<T, maxsize>::size() const
00205 {
00206     return size_;
00207 }
00208 
00209 
00210 
00211 template <typename T, size_t maxsize> inline
00212 typename static_vector<T, maxsize>::size_type
00213 static_vector<T, maxsize>::max_size() const
00214 {
00215     return max_size_;
00216 }
00217 
00218 
00219 
00220 template <typename T, size_t maxsize>
00221 void static_vector<T, maxsize>::resize(size_type n, const value_type& value)
00222 {
00223     enforce_valid_size(n);
00224     while (size_ > n)
00225     {
00226         get_element(--size_)->~value_type();
00227     }
00228     while (size_ < n)
00229     {
00230         new (get_element(size_)) value_type(value);
00231         ++size_;
00232     }
00233 }
00234 
00235 
00236 
00237 template <typename T, size_t maxsize> inline
00238 typename static_vector<T, maxsize>::size_type
00239 static_vector<T, maxsize>::capacity() const
00240 {
00241     return max_size_;
00242 }
00243 
00244 
00245 
00246 template <typename T, size_t maxsize> inline
00247 bool static_vector<T, maxsize>::empty() const
00248 {
00249     return size_ == 0;
00250 }
00251 
00252 
00253 
00254 template <typename T, size_t maxsize> inline
00255 void static_vector<T, maxsize>::reserve(size_type n)
00256 {
00257     enforce_valid_size(n);
00258 }
00259 
00260 
00261 
00262 template <typename T, size_t maxsize> inline
00263 typename static_vector<T, maxsize>::reference
00264 static_vector<T, maxsize>::operator[](size_type i)
00265 {
00266     return *get_element(i);
00267 }
00268 
00269 
00270 
00271 template <typename T, size_t maxsize> inline
00272 typename static_vector<T, maxsize>::const_reference
00273 static_vector<T, maxsize>::operator[](size_type i) const
00274 {
00275     return *get_element(i);
00276 }
00277 
00278 
00279 
00280 template <typename T, size_t maxsize>
00281 typename static_vector<T, maxsize>::reference
00282 static_vector<T, maxsize>::at(size_type i)
00283 {
00284     if (i >= size_)
00285     {
00286         throw std::out_of_range("index out of range in lass::stde::static_vector::at");
00287     }
00288     return *get_element(i);
00289 }
00290 
00291 
00292 
00293 template <typename T, size_t maxsize>
00294 typename static_vector<T, maxsize>::const_reference
00295 static_vector<T, maxsize>::at(size_type i) const
00296 {
00297     if (i >= size_)
00298     {
00299         throw std::out_of_range("index out of range in lass::stde::static_vector::at");
00300     }
00301     return *get_element(i);
00302 }
00303 
00304 
00305 
00306 template <typename T, size_t maxsize> inline
00307 typename static_vector<T, maxsize>::reference
00308 static_vector<T, maxsize>::front()
00309 {
00310     return *get_element(0);
00311 }
00312 
00313 
00314 
00315 template <typename T, size_t maxsize> inline
00316 typename static_vector<T, maxsize>::const_reference
00317 static_vector<T, maxsize>::front() const
00318 {
00319     return *get_element(0);
00320 }
00321 
00322 
00323 
00324 template <typename T, size_t maxsize> inline
00325 typename static_vector<T, maxsize>::reference
00326 static_vector<T, maxsize>::back()
00327 {
00328     return *get_element(size_ - 1);
00329 }
00330 
00331 
00332 
00333 template <typename T, size_t maxsize> inline
00334 typename static_vector<T, maxsize>::const_reference
00335 static_vector<T, maxsize>::back() const
00336 {
00337     return *get_element(size_ - 1);
00338 }
00339 
00340 
00341 
00342 template <typename T, size_t maxsize> inline
00343 void static_vector<T, maxsize>::push_back(const value_type& value)
00344 {
00345     enforce_valid_size(size_ + 1);
00346     new (get_element(size_)) value_type(value);
00347     ++size_;
00348 }
00349 
00350 
00351 
00352 template <typename T, size_t maxsize> inline
00353 void static_vector<T, maxsize>::pop_back()
00354 {
00355     get_element(--size_)->~value_type();
00356 }
00357 
00358 
00359 
00360 template <typename T, size_t maxsize>
00361 void static_vector<T, maxsize>::insert(iterator position, const value_type& value)
00362 {
00363     enforce_valid_size(size_ + 1);
00364     move_to_back(position, end(), 1);
00365     new (position) value_type(value);
00366     ++size_;
00367 }
00368 
00369 
00370 
00371 template <typename T, size_t maxsize> inline
00372 void static_vector<T, maxsize>::insert(iterator position, size_type n, const value_type& value)
00373 {
00374     insert(position, n, value, meta::Wrap<meta::True>());
00375 }
00376 
00377 
00378 
00379 template <typename T, size_t maxsize>
00380 template <typename InputIterator> inline
00381 void static_vector<T, maxsize>::insert(iterator position, InputIterator first, InputIterator last)
00382 {
00383     insert(position, first, last, meta::Wrap<typename meta::IsIntegral<InputIterator>::Type>());
00384 }
00385 
00386 
00387 
00388 template <typename T, size_t maxsize>
00389 typename static_vector<T, maxsize>::iterator
00390 static_vector<T, maxsize>::erase(iterator position)
00391 {
00392     position->~value_type();
00393     move_to_front(position + 1, end(), 1);
00394     --size_;
00395     return position;
00396 }
00397 
00398 
00399 
00400 template <typename T, size_t maxsize>
00401 typename static_vector<T, maxsize>::iterator
00402 static_vector<T, maxsize>::erase(iterator first, iterator last)
00403 {
00404     for (iterator i = first; i != last; ++i)
00405     {
00406         i->~value_type();
00407     }
00408     const size_type n = last - first;;
00409     move_to_front(last, end(), n);
00410     size_ -= n;
00411     return first;
00412 }
00413 
00414 
00415 
00416 template <typename T, size_t maxsize>
00417 void static_vector<T, maxsize>::clear()
00418 {
00419     for (size_type i = 0; i < size_; ++i)
00420     {
00421         get_element(i)->~value_type();
00422     }
00423     size_ = 0;
00424 }
00425 
00426 template <typename T, size_t maxsize>
00427 void static_vector<T, maxsize>::swap(static_vector<T, maxsize>& iOther)
00428 {
00429     for (size_type i = 0; i < std::max(size(),iOther.size()); ++i)
00430     {
00431         std::swap(operator[](i), iOther[i]);
00432     }
00433     std::swap(size_,iOther.size_);
00434 }
00435 
00436     
00437 // --- private -------------------------------------------------------------------------------------
00438 
00439 template <typename T, size_t maxsize> inline
00440 void static_vector<T, maxsize>::move_to_back(iterator first, iterator last, size_type step)
00441 {
00442     while (last != first)
00443     {
00444         --last;
00445         new (last + step) value_type(*last);
00446         last->~value_type();
00447     }
00448 }
00449 
00450 
00451 
00452 template <typename T, size_t maxsize> inline
00453 void static_vector<T, maxsize>::move_to_front(iterator first, iterator last, size_type step)
00454 {
00455     while (first != last)
00456     {
00457         new (first - step) value_type(*first);
00458         first->~value_type();
00459         ++first;
00460     }
00461 }
00462 
00463 
00464 
00465 template <typename T, size_t maxsize>
00466 void static_vector<T, maxsize>::insert(iterator position, size_t n, value_type value,  
00467                                        meta::Wrap<meta::True>)
00468 {
00469     enforce_valid_size(size_ + n);
00470     move_to_back(position, end(), n);
00471     for (const iterator last = position + n; position != last; ++position)
00472     {
00473         new (position) value_type(value);
00474     }
00475     size_ += n;
00476 }
00477     
00478 
00479 
00480 template <typename T, size_t maxsize>
00481 template <typename InputIterator> 
00482 void static_vector<T, maxsize>::insert(iterator position, InputIterator first, InputIterator last,
00483                                         meta::Wrap<meta::False>)
00484 {
00485     const size_type n = std::distance(first, last);
00486     enforce_valid_size(size_ + n);
00487     move_to_back(position, end(), n);
00488     while (first != last)
00489     {
00490         new (position++) value_type(*first++);
00491     }
00492     size_ += n;
00493 }
00494 
00495 
00496 
00497 template <typename T, size_t maxsize>
00498 void static_vector<T, maxsize>::assign(size_t n, value_type value, meta::Wrap<meta::True>)
00499 {
00500     enforce_valid_size(n);
00501     clear();
00502     insert(begin(), n, value, meta::Wrap<meta::True>());                    
00503 }
00504     
00505 
00506 
00507 template <typename T, size_t maxsize>
00508 template <typename InputIterator> 
00509 void static_vector<T, maxsize>::assign(InputIterator first, InputIterator last,
00510                                        meta::Wrap<meta::False>)
00511 {
00512     const size_type n = std::distance(first, last);
00513     enforce_valid_size(n);
00514     clear();
00515     insert(begin(), first, last, meta::Wrap<meta::False>());                    
00516 }
00517 
00518 
00519 
00520 template <typename T, size_t maxsize> inline
00521 void static_vector<T, maxsize>::enforce_valid_size(size_type new_size) const
00522 {
00523     if (new_size > max_size_)
00524     {
00525         throw std::length_error("lass::stde::static_vector cannot reallocate to expand capacity");
00526     }
00527 }
00528 
00529 
00530 
00531 // --- free ----------------------------------------------------------------------------------------
00532 
00533 /** returns wether @a a and @a b are lexicographical idential.
00534  *  @relates static_vector
00535  *
00536  *  @param a first @c static_vector
00537  *  @param b second @c static_vector
00538  *
00539  *  returns true if <tt>a.size() == b.size()</tt> and each element of @a is considered
00540  *  equal to its corresponding element in @a b by using @c operator==
00541  *
00542  *  @complexity O(N) with N = <tt>a.size() == b.size() ? a.size() : 1</tt>
00543  */
00544 template <typename T, size_t maxsize>
00545 bool operator==(const static_vector<T, maxsize>& a, const static_vector<T, maxsize>& b)
00546 {
00547     if (a.size() != b.size())
00548     {
00549         return false;
00550     }
00551     typedef typename static_vector<T, maxsize>::const_iterator const_iterator;
00552     const const_iterator a_end = a.end();
00553     for (const_iterator i = a.begin(), j = b.begin(); i != a_end; ++i, ++j)
00554     {
00555         if (*i != *j)
00556         {
00557             return false;
00558         }
00559     }
00560     return true;
00561 }
00562 
00563 
00564 
00565 /** returns wether @a a and @a b are not lexicographical idential.
00566  *  @relates static_vector
00567  *
00568  *  @param a first @c static_vector
00569  *  @param b second @c static_vector
00570  *
00571  *  Is equivalent to <tt>!(a == b)</tt>
00572  *
00573  *  @complexity O(N) with N = <tt>a.size() == b.size() ? a.size() : 1</tt>
00574  */
00575 template <typename T, size_t maxsize>
00576 bool operator!=(const static_vector<T, maxsize>& a, const static_vector<T, maxsize>& b)
00577 {
00578     return !(a == b);
00579 }
00580 
00581 
00582 
00583 /** returns wether @a a is lexicographical less than @a b.
00584  *  @relates static_vector
00585  *
00586  *  @param a first @c static_vector
00587  *  @param b second @c static_vector
00588  *
00589  *  returns true if for the first difference between @a a and @a b the element of @a a is less
00590  *  than the corresponding one of @a b.  In case no different elements between @a and @a b can be
00591  *  found, it returns true if <tt>a.size() < b.size()</tt>
00592  *
00593  *  @complexity O(N) with N = <tt>std::min(a.size(), b.size())</tt>
00594  */
00595 template <typename T, size_t maxsize>
00596 bool operator<(const static_vector<T, maxsize>& a, const static_vector<T, maxsize>& b)
00597 {
00598     typedef typename static_vector<T, maxsize>::const_iterator const_iterator;
00599     const const_iterator a_end = a.end();
00600     const const_iterator b_end = b.end();
00601     const_iterator i = a.begin();
00602     const_iterator j = b.begin();
00603     while (i != a_end && j != b_end)
00604     {
00605         if (!(*i < *j))
00606         {
00607             return false;
00608         }
00609         ++i;
00610         ++j;
00611     }
00612     return j != b_end;
00613 }
00614 
00615 
00616 
00617 /** returns wether @a b is lexicographical less than @a a.
00618  *  @relates static_vector
00619  *
00620  *  @param a first @c static_vector
00621  *  @param b second @c static_vector
00622  *
00623  *  Is equivalent to <tt>(b < a)</tt>
00624  *
00625  *  @complexity O(N) with N = <tt>std::min(a.size(), b.size())</tt>
00626  */
00627 template <typename T, size_t maxsize>
00628 bool operator>(const static_vector<T, maxsize>& a, const static_vector<T, maxsize>& b)
00629 {
00630     return b < a;
00631 }
00632 
00633 
00634 
00635 /** returns wether @a a is lexicographical less or equal to @a b.
00636  *  @relates static_vector
00637  *
00638  *  @param a first @c static_vector
00639  *  @param b second @c static_vector
00640  *
00641  *  Is equivalent to <tt>!(b < a)</tt>
00642  *
00643  *  @complexity O(N) with N = <tt>std::min(a.size(), b.size())</tt>
00644  */
00645 template <typename T, size_t maxsize>
00646 bool operator<=(const static_vector<T, maxsize>& a, const static_vector<T, maxsize>& b)
00647 {
00648     return !(b < a);
00649 }
00650 
00651 
00652 
00653 /** returns wether @a b is lexicographical less or equal to @a a.
00654  *  @relates static_vector
00655  *
00656  *  @param a first @c static_vector
00657  *  @param b second @c static_vector
00658  *
00659  *  Is equivalent to <tt>!(a < b)</tt>
00660  *
00661  *  @complexity O(N) with N = <tt>std::min(a.size(), b.size())</tt>
00662  */
00663 template <typename T, size_t maxsize>
00664 bool operator>=(const static_vector<T, maxsize>& a, const static_vector<T, maxsize>& b)
00665 {
00666     return !(a < b);
00667 }
00668 
00669 
00670 
00671 /** @relates static_vector
00672  *  writes static_vector to output stream.
00673  *
00674  *  @param ostream should be a good stream.
00675  *  @param container @c static_vector to be written as [foo, bar, spam, ham]
00676  *
00677  *  @b complexity: O(N) with N = @c container.size()
00678  */
00679 template <typename T, size_t maxsize, typename Char, typename Traits>
00680 std::basic_ostream<Char, Traits>&
00681 operator<<(std::basic_ostream<Char, Traits>& ostream,
00682            const static_vector<T, maxsize>& container)
00683 {
00684     return impl::print_sequence(
00685         ostream, container.begin(), container.end(), "[", ", ", "]");
00686 }
00687 
00688 
00689 
00690 /** @relates static_vector
00691  *  reads list from stream.
00692  *
00693  *  @param istream should be a good stream.
00694  *  @param container @c static_vector to be read as [foo, bar, spam, ham]
00695  *
00696  *  @b complexity: O(N) with N = number of elements to be read.
00697  *
00698  *  @pre @a maxsize should be large enough to read all elements
00699  */
00700 template <typename T, size_t maxsize, typename Char, typename Traits>
00701 std::basic_istream<Char, Traits>&
00702 operator>>(std::basic_istream<Char, Traits>& istream,
00703            static_vector<T, maxsize>& container)
00704 {
00705     std::basic_istream<Char, Traits>& result =
00706         impl::read_container<impl::static_vector_traits, impl::value_traits, T, Char>(
00707             istream, container, '[', ',', 0, ']');
00708     return result;
00709 }
00710 
00711 
00712 }
00713 
00714 }
00715 
00716 // EOF

Generated on Mon Nov 10 14:21:40 2008 for Library of Assembled Shared Sources by doxygen 1.5.7.1
SourceForge.net Logo