Array_Base.cpp

Go to the documentation of this file.
00001 // $Id: Array_Base.cpp 80826 2008-03-04 14:51:23Z wotte $
00002 
00003 #ifndef ACE_ARRAY_BASE_CPP
00004 #define ACE_ARRAY_BASE_CPP
00005 
00006 #include "ace/Array_Base.h"
00007 
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif /* ACE_LACKS_PRAGMA_ONCE */
00011 
00012 #if !defined (__ACE_INLINE__)
00013 #include "ace/Array_Base.inl"
00014 #endif /* __ACE_INLINE__ */
00015 
00016 #include "ace/Malloc_Base.h"
00017 #include "ace/os_include/os_errno.h"
00018 
00019 #include <algorithm>
00020 
00021 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00022 
00023 // Dynamically initialize an array.
00024 template <class T>
00025 ACE_Array_Base<T>::ACE_Array_Base (typename ACE_Array_Base<T>::size_type size,
00026                                    ACE_Allocator *alloc)
00027   : max_size_ (size),
00028     cur_size_ (size),
00029     allocator_ (alloc)
00030 {
00031   if (this->allocator_ == 0)
00032     this->allocator_ = ACE_Allocator::instance ();
00033 
00034   if (size != 0)
00035     {
00036       ACE_ALLOCATOR (this->array_,
00037                      (T *) this->allocator_->malloc (size * sizeof (T)));
00038       for (size_type i = 0; i < size; ++i)
00039         new (&array_[i]) T;
00040     }
00041   else
00042     this->array_ = 0;
00043 }
00044 
00045 template <class T>
00046 ACE_Array_Base<T>::ACE_Array_Base (typename ACE_Array_Base<T>::size_type size,
00047                                    const T &default_value,
00048                                    ACE_Allocator *alloc)
00049   : max_size_ (size),
00050     cur_size_ (size),
00051     allocator_ (alloc)
00052 {
00053   if (this->allocator_ == 0)
00054     this->allocator_ = ACE_Allocator::instance ();
00055 
00056   if (size != 0)
00057     {
00058       ACE_ALLOCATOR (this->array_,
00059                      (T *) this->allocator_->malloc (size * sizeof (T)));
00060       for (size_type i = 0; i < size; ++i)
00061         new (&array_[i]) T (default_value);
00062     }
00063   else
00064     this->array_ = 0;
00065 }
00066 
00067 // The copy constructor (performs initialization).
00068 
00069 template <class T>
00070 ACE_Array_Base<T>::ACE_Array_Base (const ACE_Array_Base<T> &s)
00071   : max_size_ (s.size ()),
00072     cur_size_ (s.size ()),
00073     allocator_ (s.allocator_)
00074 {
00075   if (this->allocator_ == 0)
00076     this->allocator_ = ACE_Allocator::instance ();
00077 
00078   ACE_ALLOCATOR (this->array_,
00079                  (T *) this->allocator_->malloc (s.size () * sizeof (T)));
00080   for (size_type i = 0; i < this->size (); ++i)
00081     new (&this->array_[i]) T (s.array_[i]);
00082 }
00083 
00084 // Assignment operator (performs assignment).
00085 
00086 template <class T> void
00087 ACE_Array_Base<T>::operator= (const ACE_Array_Base<T> &s)
00088 {
00089   // Check for "self-assignment".
00090 
00091   if (this != &s)
00092     {
00093       if (this->max_size_ < s.size ())
00094         {
00095           // Need to reallocate memory.
00096 
00097           // Strongly exception-safe assignment.
00098           //
00099           // Note that we're swapping the allocators here, too.
00100           // Should we?  Probably.  "*this" should be a duplicate of
00101           // the "right hand side".
00102           ACE_Array_Base<T> tmp (s);
00103           this->swap (tmp);
00104         }
00105       else
00106         {
00107           // Underlying array is large enough.  No need to reallocate
00108           // memory.
00109           //
00110           // "*this" still owns the memory for the underlying array.
00111           // Do not swap out the allocator.
00112           //
00113           // @@ Why don't we just drop the explicit destructor and
00114           //    placement operator new() calls with a straight
00115           //    element-by-element assignment?  Is the existing
00116           //    approach more efficient?
00117           //        -Ossama
00118 
00119           ACE_DES_ARRAY_NOFREE (this->array_,
00120                                 s.size (),
00121                                 T);
00122 
00123           this->cur_size_ = s.size ();
00124 
00125           for (size_type i = 0; i < this->size (); ++i)
00126             new (&this->array_[i]) T (s.array_[i]);
00127         }
00128     }
00129 }
00130 
00131 // Set an item in the array at location slot.
00132 
00133 template <class T> int
00134 ACE_Array_Base<T>::set (const T &new_item,
00135                         typename ACE_Array_Base<T>::size_type slot)
00136 {
00137   if (this->in_range (slot))
00138     {
00139       this->array_[slot] = new_item;
00140       return 0;
00141     }
00142   else
00143     return -1;
00144 }
00145 
00146 // Get an item in the array at location slot.
00147 
00148 template <class T> int
00149 ACE_Array_Base<T>::get (T &item,
00150                         typename ACE_Array_Base<T>::size_type slot) const
00151 {
00152   if (this->in_range (slot))
00153     {
00154       // Copies the item.  If you don't want to copy, use operator []
00155       // instead (but then you'll be responsible for range checking).
00156       item = this->array_[slot];
00157       return 0;
00158     }
00159   else
00160     return -1;
00161 }
00162 
00163 template<class T> int
00164 ACE_Array_Base<T>::max_size (typename ACE_Array_Base<T>::size_type new_size)
00165 {
00166   if (new_size > this->max_size_)
00167     {
00168       T *tmp = 0;
00169 
00170       ACE_ALLOCATOR_RETURN (tmp,
00171                             (T *) this->allocator_->malloc (new_size * sizeof (T)),
00172                             -1);
00173       for (size_type i = 0; i < this->cur_size_; ++i)
00174         new (&tmp[i]) T (this->array_[i]);
00175 
00176       // Initialize the new portion of the array that exceeds the
00177       // previously allocated section.
00178       for (size_type j = this->cur_size_; j < new_size; ++j)
00179         new (&tmp[j]) T;
00180 
00181       ACE_DES_ARRAY_FREE (this->array_,
00182                           this->max_size_,
00183                           this->allocator_->free,
00184                           T);
00185       this->array_ = tmp;
00186       this->max_size_ = new_size;
00187       this->cur_size_ = new_size;
00188     }
00189 
00190   return 0;
00191 }
00192 
00193 template<class T> int
00194 ACE_Array_Base<T>::size (typename ACE_Array_Base<T>::size_type new_size)
00195 {
00196   int const r = this->max_size (new_size);
00197 
00198   if (r == 0)
00199     this->cur_size_ = new_size;
00200 
00201   return r;
00202 }
00203 
00204 template<class T>
00205 void
00206 ACE_Array_Base<T>::swap (ACE_Array_Base<T> & rhs)
00207 {
00208   std::swap (this->max_size_ , rhs.max_size_);
00209   std::swap (this->cur_size_ , rhs.cur_size_);
00210   std::swap (this->array_    , rhs.array_);
00211   std::swap (this->allocator_, rhs.allocator_);
00212 }
00213 
00214 // ****************************************************************
00215 
00216 template <class T> int
00217 ACE_Array_Iterator<T>::next (T *&item)
00218 {
00219   // ACE_TRACE ("ACE_Array_Iterator<T>::next");
00220 
00221   if (this->done ())
00222     {
00223       item = 0;
00224       return 0;
00225     }
00226   else
00227     {
00228       item = &array_[current_];
00229       return 1;
00230     }
00231 }
00232 
00233 ACE_END_VERSIONED_NAMESPACE_DECL
00234 
00235 #endif /* ACE_ARRAY_BASE_CPP */

Generated on Tue Feb 2 17:18:38 2010 for ACE by  doxygen 1.4.7