Vector.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Palmsource, Inc.
00003  * 
00004  * This software is licensed as described in the file LICENSE, which
00005  * you should have received as part of this distribution. The terms
00006  * are also available at http://www.openbinder.org/license.html.
00007  * 
00008  * This software consists of voluntary contributions made by many
00009  * individuals. For the exact contribution history, see the revision
00010  * history and logs, available at http://www.openbinder.org
00011  */
00012 
00013 #ifndef _SUPPORT_VECTOR_H
00014 #define _SUPPORT_VECTOR_H
00015 
00025 #include <support/SupportDefs.h>
00026 #include <support/Value.h>
00027 #include <support/TypeFuncs.h>
00028 #include <support/Debug.h>
00029 #include <support/Flattenable.h>
00030 
00031 #include <ErrorMgr.h>
00032 
00033 #if _SUPPORTS_NAMESPACE
00034 namespace palmos {
00035 namespace support {
00036 #endif
00037 
00042 /*--------------------------------------------------------*/
00043 /*----- SAbstractVector abstract base class --------------*/
00044 
00046 class SAbstractVector
00047 {
00048 public:
00049                             SAbstractVector(size_t element_size);
00050                             SAbstractVector(const SAbstractVector& o);
00052     virtual                 ~SAbstractVector();
00053     
00054             SAbstractVector&operator=(const SAbstractVector& o);
00055     
00056     /* Size stats */
00057     
00058             void            SetCapacity(size_t total_space);
00059             void            SetExtraCapacity(size_t extra_space);
00060             size_t          Capacity() const;
00061             
00062             size_t          ItemSize() const;
00063             
00064             size_t          CountItems() const;
00065             
00066     /* Data access */
00067 
00068             const void*     At(size_t index) const;
00069             void*           EditAt(size_t index);
00070             
00071             const void*     Array() const;
00072             void*           EditArray();
00073             
00074     /* Array modification */
00075     
00076             ssize_t         Add(const void* newElement);
00077             ssize_t         AddAt(const void* newElement, size_t index);
00078             status_t        SetSize(size_t total_count, const void *protoElement);
00079             
00080             ssize_t         AddVector(const SAbstractVector& o);
00081             ssize_t         AddVectorAt(const SAbstractVector& o, size_t index = SSIZE_MAX);
00082             ssize_t         AddArray(const void* array, size_t count);
00083             ssize_t         AddArrayAt(const void* array, size_t count, size_t index = SSIZE_MAX);
00084 
00085             ssize_t         ReplaceAt(const void* newItem, size_t index);
00086 
00087             void            MakeEmpty();
00088             void            RemoveItemsAt(size_t index, size_t count = 1);
00089             status_t        MoveItems(size_t newIndex, size_t oldIndex, size_t count = 1);
00090             
00091     static  void            MoveBefore(SAbstractVector* to, SAbstractVector* from, size_t count);
00092     static  void            MoveAfter(SAbstractVector* to, SAbstractVector* from, size_t count);
00093             void            Swap(SAbstractVector& o);
00094     
00095     /* To/From SValue */
00096             SValue          AsValue() const;
00097             status_t        SetFromValue(const SValue& value);
00098 
00099 protected:
00100     virtual void            PerformConstruct(void* base, size_t count) const = 0;
00101     virtual void            PerformCopy(void* to, const void* from, size_t count) const = 0;
00102     virtual void            PerformReplicate(void *to, const void* protoElement, size_t count) const = 0;
00103     virtual void            PerformDestroy(void* base, size_t count) const = 0;
00104     
00105     virtual void            PerformMoveBefore(void* to, void* from, size_t count) const = 0;
00106     virtual void            PerformMoveAfter(void* to, void* from, size_t count) const = 0;
00107     
00108     virtual void            PerformAssign(void* to, const void* from, size_t count) const = 0;
00109 
00110     virtual SValue          PerformAsValue(const void* from, size_t count) const = 0;
00111     virtual status_t        PerformSetFromValue(void* to, const SValue& value, size_t count) = 0;
00112 
00113 private:
00114     
00115     virtual status_t        _ReservedUntypedVector1();
00116     virtual status_t        _ReservedUntypedVector2();
00117     virtual status_t        _ReservedUntypedVector3();
00118     virtual status_t        _ReservedUntypedVector4();
00119     virtual status_t        _ReservedUntypedVector5();
00120     virtual status_t        _ReservedUntypedVector6();
00121     virtual status_t        _ReservedUntypedVector7();
00122     virtual status_t        _ReservedUntypedVector8();
00123     virtual status_t        _ReservedUntypedVector9();
00124     virtual status_t        _ReservedUntypedVector10();
00125     
00126             uint8_t*        grow(size_t amount, size_t factor=3, size_t pos=0xFFFFFFFF);
00127             uint8_t*        shrink(size_t amount, size_t factor=4, size_t pos=0xFFFFFFFF);
00128             const uint8_t*  data() const;
00129             uint8_t*        edit_data();
00130 
00131             const size_t    m_elementSize;
00132             size_t          m_size;
00133             uint8_t*        m_base;
00134             
00135             const size_t    m_localSpace;
00136             size_t          m_avail;
00137             
00138             union {
00139                 uint8_t*    heap;
00140                 uint8_t     local[8];
00141             } m_data;
00142             
00143             int32_t         _reserved[2];
00144 };
00145 
00146 // Type optimizations.
00147 #if !defined(_MSC_VER)
00148 void BMoveBefore(SAbstractVector* to, SAbstractVector* from, size_t count);
00149 void BMoveAfter(SAbstractVector* to, SAbstractVector* from, size_t count);
00150 void BSwap(SAbstractVector& v1, SAbstractVector& v2);
00151 #endif
00152 
00153 /*--------------------------------------------------------*/
00154 /*----- SVector concrete class ---------------------------*/
00155 
00157 
00169 template<class TYPE>
00170 class SVector : private SAbstractVector
00171 {
00172 public:
00173             typedef TYPE    value_type;
00174 
00175 public:
00176                             SVector();
00177                             SVector(const SVector<TYPE>& o);
00178     virtual                 ~SVector();
00179     
00180             SVector<TYPE>&  operator=(const SVector<TYPE>& o);
00181     
00182     /* Size stats */
00183     
00184             void            SetCapacity(size_t total_space);
00185             void            SetExtraCapacity(size_t extra_space);
00186             size_t          Capacity() const;
00187             
00188             size_t          CountItems() const;
00189     
00190     /* Data access */
00191 
00192             const TYPE&     operator[](size_t i) const;
00193             const TYPE&     ItemAt(size_t i) const;
00194             TYPE&           EditItemAt(size_t i);
00195     
00196             const TYPE*     Array() const;
00197             TYPE*           EditArray();
00198     
00199     /* Array modification */
00200     
00201             ssize_t         AddItem();
00202             ssize_t         AddItem(const TYPE& item);
00203 #if !(__CC_ARM)
00204             ssize_t         AddItemAt(size_t index);
00205 #endif
00206             ssize_t         AddItemAt(const TYPE& item, size_t index);
00207             status_t        SetSize(size_t total_count);
00208             status_t        SetSize(size_t total_count, const TYPE& protoElement);
00209             
00210             ssize_t         ReplaceItemAt(const TYPE& item, size_t index);
00211     
00212             ssize_t         AddVector(const SVector<TYPE>& o);
00213             ssize_t         AddVectorAt(const SVector<TYPE>& o, size_t index);
00214             ssize_t         AddArray(const TYPE *array, size_t count);
00215             ssize_t         AddArrayAt(const TYPE *array, size_t count, size_t index);
00216             
00217             void            MakeEmpty();
00218             void            RemoveItemsAt(size_t index, size_t count = 1);
00219             status_t        MoveItems(size_t newIndex, size_t oldIndex, size_t count = 1);
00220     
00221     static  void            MoveBefore(SVector<TYPE>& to, SVector<TYPE>& from, size_t count);
00222     static  void            MoveAfter(SVector<TYPE>& to, SVector<TYPE>& from, size_t count);
00223             void            Swap(SVector<TYPE>& o);
00224             
00225     /* Use as a stack */
00226     
00227             void            Push();
00228             void            Push(const TYPE& item);
00229             TYPE &          EditTop();
00230             const TYPE &    Top() const;
00231             void            Pop();
00232 
00233     /* To/From SValue */
00234             SValue          AsValue() const;
00235             status_t        SetFromValue(const SValue& value);
00236 
00237 protected:
00238     virtual void            PerformConstruct(void* base, size_t count) const;
00239     virtual void            PerformCopy(void* to, const void* from, size_t count) const;
00240     virtual void            PerformReplicate(void* to, const void* protoElement, size_t count) const;
00241     virtual void            PerformDestroy(void* base, size_t count) const;
00242     
00243     virtual void            PerformMoveBefore(void* to, void* from, size_t count) const;
00244     virtual void            PerformMoveAfter(void* to, void* from, size_t count) const;
00245     
00246     virtual void            PerformAssign(void* to, const void* from, size_t count) const;
00247 
00248     virtual SValue          PerformAsValue(const void* from, size_t count) const;
00249     virtual status_t        PerformSetFromValue(void* to, const SValue& value, size_t count);
00250 
00251     SAbstractVector&        AbstractVector() { return *this; }
00252 };
00253 
00254 #if !defined(_MSC_VER)
00255 // Type optimizations.
00256 template<class TYPE>
00257 void BMoveBefore(SVector<TYPE>* to, SVector<TYPE>* from, size_t count = 1);
00258 template<class TYPE>
00259 void BMoveAfter(SVector<TYPE>* to, SVector<TYPE>* from, size_t count = 1);
00260 template<class TYPE>
00261 void BSwap(SVector<TYPE>& v1, SVector<TYPE>& v2);
00262 #endif // _MSC_VER
00263 
00264 /*-------------------------------------------------------------*/
00265 // BArrayAsValue and BArrayConstruct 
00266 // (called by PerformAsValue and PerformSetFromValue)
00267 // have default implementations that just return errors.  
00268 // These two functions have been specialized for plain old data 
00269 // types, but to marshal an SVector of a user type, you must
00270 // use one of the implement macros (or write your own).
00271 // B_IMPLEMENT_SIMPLE_TYPE_FLATTEN_FUNCS
00272 // - If you can treat your type as a stream of bits
00273 // B_IMPLEMENT_SFLATTENABLE_FLATTEN_FUNCS
00274 // - If your type is derived from SFlattenable
00275 // B_IMPLEMENT_FLATTEN_FUNCS
00276 // - If your type implements
00277 // - SValue TYPE::AsValue() and TYPE::TYPE(const SValue&)
00278 // These macros are defined in TypeFuncs.h
00279 /*-------------------------------------------------------------*/
00280 
00283 /*-------------------------------------------------------------*/
00284 /*---- No user serviceable parts after this -------------------*/
00285 
00286 inline size_t SAbstractVector::ItemSize() const
00287 {
00288     return m_elementSize;
00289 }
00290 
00291 inline size_t SAbstractVector::CountItems() const
00292 {
00293     return m_size;
00294 }
00295 
00296 inline const void* SAbstractVector::At(size_t index) const
00297 {
00298     DbgOnlyFatalErrorIf(index >= m_size || m_base == NULL, "Vector index out of range");
00299     return m_base + (index*m_elementSize);
00300 }
00301 
00302 inline const void* SAbstractVector::Array() const
00303 {
00304     return m_base;
00305 }
00306 
00307 #if !defined(_MSC_VER)
00308 
00309 inline void BMoveBefore(SAbstractVector* to, SAbstractVector* from, size_t count)
00310 {
00311     SAbstractVector::MoveBefore(to, from, count);
00312 }
00313 
00314 inline void BMoveAfter(SAbstractVector* to, SAbstractVector* from, size_t count)
00315 {
00316     SAbstractVector::MoveAfter(to, from, count);
00317 }
00318 
00319 inline void BSwap(SAbstractVector& v1, SAbstractVector& v2)
00320 {
00321     v1.Swap(v2);
00322 }
00323 
00324 #endif // _MSC_VER
00325 
00326 /*-------------------------------------------------------------*/
00327 
00328 template<class TYPE> inline
00329 SVector<TYPE>::SVector()
00330     :   SAbstractVector(sizeof(TYPE[2])/2)
00331 {
00332 }
00333 
00334 template<class TYPE> inline
00335 SVector<TYPE>::SVector(const SVector<TYPE>& o)
00336     :   SAbstractVector(o)
00337 {
00338 }
00339 
00340 template<class TYPE> inline
00341 SVector<TYPE>::~SVector()
00342 {
00343     MakeEmpty();
00344 }
00345 
00346 template<class TYPE> inline
00347 SVector<TYPE>& SVector<TYPE>::operator=(const SVector<TYPE>& o)
00348 {
00349     SAbstractVector::operator=(o);
00350     return *this;
00351 }
00352 
00353 template<class TYPE> inline
00354 void SVector<TYPE>::SetCapacity(size_t total_space)
00355 {
00356     SAbstractVector::SetCapacity(total_space);
00357 }
00358 
00359 template<class TYPE> inline
00360 void SVector<TYPE>::SetExtraCapacity(size_t extra_space)
00361 {
00362     SAbstractVector::SetExtraCapacity(extra_space);
00363 }
00364 
00365 template<class TYPE> inline
00366 size_t SVector<TYPE>::Capacity() const
00367 {
00368     return SAbstractVector::Capacity();
00369 }
00370 
00371 template<class TYPE> inline
00372 size_t SVector<TYPE>::CountItems() const
00373 {
00374     return SAbstractVector::CountItems();
00375 }
00376 
00377 template<class TYPE> inline
00378 const TYPE& SVector<TYPE>::operator[](size_t i) const
00379 {
00380     // Don't use SAbstractVector::At() here, because we know
00381     // the item size so can do it slightly more efficiently.
00382     DbgOnlyFatalErrorIf(i >= CountItems() || Array() == NULL, "Vector index out of range");
00383     return *( static_cast<const TYPE*>(SAbstractVector::Array()) + i );
00384 }
00385 
00386 template<class TYPE> inline
00387 const TYPE& SVector<TYPE>::ItemAt(size_t i) const
00388 {
00389     // Don't use SAbstractVector::At() here, because we know
00390     // the item size so can do it slightly more efficiently.
00391     DbgOnlyFatalErrorIf(i >= CountItems() || Array() == NULL, "Vector index out of range");
00392     return *( static_cast<const TYPE*>(SAbstractVector::Array()) + i );
00393 }
00394 
00395 template<class TYPE> inline
00396 TYPE& SVector<TYPE>::EditItemAt(size_t i)
00397 {
00398     DbgOnlyFatalErrorIf(i >= CountItems() || Array() == NULL, "Vector index out of range");
00399     return *static_cast<TYPE*>(EditAt(i));
00400 }
00401 
00402 template<class TYPE> inline
00403 const TYPE* SVector<TYPE>::Array() const
00404 {
00405     return static_cast<const TYPE*>(SAbstractVector::Array());
00406 }
00407 
00408 template<class TYPE> inline
00409 TYPE* SVector<TYPE>::EditArray()
00410 {
00411     return static_cast<TYPE*>(SAbstractVector::EditArray());
00412 }
00413 
00414 template<class TYPE> inline
00415 ssize_t SVector<TYPE>::AddItem()
00416 {
00417     return Add(NULL);
00418 }
00419 
00420 template<class TYPE> inline
00421 ssize_t SVector<TYPE>::AddItem(const TYPE &item)
00422 {
00423     return Add(&item);
00424 }
00425 
00426 #if !(__CC_ARM)
00427 template<class TYPE> inline
00428 ssize_t SVector<TYPE>::AddItemAt(size_t index)
00429 {
00430     return AddAt(NULL, index);
00431 }
00432 #endif
00433 
00434 template<class TYPE> inline
00435 ssize_t SVector<TYPE>::AddItemAt(const TYPE &item, size_t index)
00436 {
00437     return AddAt(&item, index);
00438 }
00439 
00440 template<class TYPE> inline
00441 status_t SVector<TYPE>::SetSize(size_t total_count)
00442 {
00443     return SAbstractVector::SetSize(total_count, NULL);
00444 }
00445 
00446 template<class TYPE> inline
00447 status_t SVector<TYPE>::SetSize(size_t total_count, const TYPE& protoElement)
00448 {
00449     return SAbstractVector::SetSize(total_count, &protoElement);
00450 }
00451 
00452 template<class TYPE> inline
00453 ssize_t SVector<TYPE>::ReplaceItemAt(const TYPE& item, size_t index)
00454 {
00455     return ReplaceAt(&item, index);
00456 }
00457 
00458 template<class TYPE> inline
00459 ssize_t SVector<TYPE>::AddVector(const SVector<TYPE>& o)
00460 {
00461     return SAbstractVector::AddVector(o);
00462 }
00463 
00464 template<class TYPE> inline
00465 ssize_t SVector<TYPE>::AddVectorAt(const SVector<TYPE>& o, size_t index)
00466 {
00467     return SAbstractVector::AddVectorAt(o, index);
00468 }
00469 
00470 template<class TYPE> inline
00471 ssize_t SVector<TYPE>::AddArray(const TYPE *array, size_t count)
00472 {
00473     return SAbstractVector::AddArray(array, count);
00474 }
00475 
00476 template<class TYPE> inline
00477 ssize_t SVector<TYPE>::AddArrayAt(const TYPE *array, size_t count, size_t index)
00478 {
00479     return SAbstractVector::AddArrayAt(array, count, index);
00480 }
00481 
00482 template<class TYPE> inline
00483 void SVector<TYPE>::MakeEmpty()
00484 {
00485     SAbstractVector::MakeEmpty();
00486 }
00487 
00488 template<class TYPE> inline
00489 void SVector<TYPE>::RemoveItemsAt(size_t index, size_t count)
00490 {
00491     SAbstractVector::RemoveItemsAt(index, count);
00492 }
00493 
00494 template<class TYPE> inline
00495 status_t SVector<TYPE>::MoveItems(size_t newIndex, size_t oldIndex, size_t count)
00496 {
00497     return SAbstractVector::MoveItems(newIndex, oldIndex, count);
00498 }
00499 
00500 template<class TYPE> inline
00501 void SVector<TYPE>::Swap(SVector<TYPE>& o)
00502 {
00503     SAbstractVector::Swap(o);
00504 }
00505 
00506 template<class TYPE> inline
00507 void SVector<TYPE>::Push()
00508 {
00509     AddItem();
00510 }
00511 
00512 template<class TYPE> inline
00513 void SVector<TYPE>::Push(const TYPE& item)
00514 {
00515     AddItem(item);
00516 }
00517 
00518 template<class TYPE> inline
00519 TYPE& SVector<TYPE>::EditTop()
00520 {
00521     DbgOnlyFatalErrorIf(CountItems() == 0, "EditTop: Stack empty");
00522     return EditItemAt(CountItems()-1);
00523 }
00524 
00525 template<class TYPE> inline
00526 const TYPE& SVector<TYPE>::Top() const
00527 {
00528     DbgOnlyFatalErrorIf(CountItems() == 0, "Top: Stack empty");
00529     return ItemAt(CountItems()-1);
00530 }
00531 
00532 template<class TYPE> inline
00533 void SVector<TYPE>::Pop()
00534 {
00535     DbgOnlyFatalErrorIf(CountItems() == 0, "Pop: Stack empty");
00536     RemoveItemsAt(CountItems()-1);
00537 }
00538 
00539 template<class TYPE> inline
00540 SValue SVector<TYPE>::AsValue() const
00541 {
00542     return SAbstractVector::AsValue();
00543 }
00544 
00545 template<class TYPE> inline
00546 status_t SVector<TYPE>::SetFromValue(const SValue& value)
00547 {
00548     return SAbstractVector::SetFromValue(value);
00549 }
00550 
00551 template<class TYPE>
00552 void SVector<TYPE>::PerformConstruct(void* base, size_t count) const
00553 {
00554     BConstruct((TYPE*)(base), count);
00555 }
00556 
00557 template<class TYPE>
00558 void SVector<TYPE>::PerformCopy(void* to, const void* from, size_t count) const
00559 {
00560     BCopy((TYPE*)(to), (const TYPE*)(from), count);
00561 }
00562 
00563 template<class TYPE>
00564 void SVector<TYPE>::PerformReplicate(void *to, const void* protoElement, size_t count) const
00565 {
00566     BReplicate((TYPE*)(to), (const TYPE*)(protoElement), count);
00567 }
00568 
00569 template<class TYPE>
00570 void SVector<TYPE>::PerformDestroy(void* base, size_t count) const
00571 {
00572     BDestroy((TYPE*)(base), count);
00573 }
00574 
00575 template<class TYPE>
00576 void SVector<TYPE>::PerformMoveBefore(  void* to, void* from, size_t count) const
00577 {
00578     BMoveBefore((TYPE*)(to), (TYPE*)(from), count);
00579 }
00580 
00581 template<class TYPE>
00582 void SVector<TYPE>::PerformMoveAfter(   void* to, void* from, size_t count) const
00583 {
00584     BMoveAfter((TYPE*)(to), (TYPE*)(from), count);
00585 }
00586 
00587 template<class TYPE>
00588 void SVector<TYPE>::PerformAssign(  void* to, const void* from, size_t count) const
00589 {
00590     BAssign((TYPE*)(to), (const TYPE*)(from), count);
00591 }
00592 
00593 // -----------------------------------------------------------------
00594 // Some higher level TypeFuncs that need to know about SValue
00595 // -----------------------------------------------------------------
00596 
00597 // Default implementation of BArrayAsValue and BArrayConstruct
00598 // (called by PerformAsValue and PerformSetFromValue)
00599 // return an error ... the user must specialize for user types
00600 
00601 template<class TYPE>
00602 inline SValue BArrayAsValue(const TYPE*, size_t)
00603 {
00604     DbgOnlyFatalError("You need to implement your type specific BArrayAsValue");
00605     return SValue();
00606 }
00607 
00608 template<class TYPE>
00609 inline status_t BArrayConstruct(TYPE*, const SValue&, size_t)
00610 {
00611     DbgOnlyFatalError("You need to implement your type specific BArrayConstruct");
00612     return B_UNSUPPORTED;
00613 }
00614 
00615 template<class TYPE>
00616 SValue SVector<TYPE>::PerformAsValue(const void* from, size_t count) const
00617 {
00618     return BArrayAsValue((const TYPE*)(from), count);
00619 }
00620 
00621 template<class TYPE>
00622 status_t SVector<TYPE>::PerformSetFromValue(void* to, const SValue& value, size_t count)
00623 {
00624     return BArrayConstruct((TYPE*)(to), value, count);
00625 }
00626 
00627 /*-------------------------------------------------------------*/
00628 
00629 #if !defined(_MSC_VER)
00630 
00631 template<class TYPE> inline
00632 void BMoveBefore(SVector<TYPE>* to, SVector<TYPE>* from, size_t count)
00633 {
00634     BMoveBefore((SAbstractVector*)(to), (SAbstractVector*)(from), count);
00635 }
00636 
00637 template<class TYPE> inline
00638 void BMoveAfter(SVector<TYPE>* to, SVector<TYPE>* from, size_t count)
00639 {
00640     BMoveAfter((SAbstractVector*)(to), (SAbstractVector*)(from), count);
00641 }
00642 
00643 template<class TYPE> inline
00644 void BSwap(SVector<TYPE>& v1, SVector<TYPE>& v2)
00645 {
00646     v1.Swap(v2);
00647 }
00648 
00649 #endif // _MSC_VER
00650 
00651 #if _SUPPORTS_NAMESPACE
00652 } } // namespace palmos::support
00653 #endif
00654 
00655 #endif