summaryrefslogtreecommitdiff
path: root/TAO/tao/Valuetype/Sequence_T.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/Valuetype/Sequence_T.cpp')
-rw-r--r--TAO/tao/Valuetype/Sequence_T.cpp504
1 files changed, 504 insertions, 0 deletions
diff --git a/TAO/tao/Valuetype/Sequence_T.cpp b/TAO/tao/Valuetype/Sequence_T.cpp
new file mode 100644
index 00000000000..d69116d7704
--- /dev/null
+++ b/TAO/tao/Valuetype/Sequence_T.cpp
@@ -0,0 +1,504 @@
+// $Id$
+
+#ifndef TAO_VALUETYPE_SEQUENCE_T_CPP
+#define TAO_VALUETYPE_SEQUENCE_T_CPP
+
+#include "tao/Valuetype/Sequence_T.h"
+
+#if !defined (__ACE_INLINE__)
+#include "tao/Valuetype/Sequence_T.inl"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID (Valuetype,
+ Sequence_T,
+ "$Id$")
+
+
+TAO_BEGIN_VERSIONED_NAMESPACE_DECL
+
+// *************************************************************
+// class TAO_Valuetype_Manager
+// *************************************************************
+
+template <typename T, typename T_var>
+TAO_Valuetype_Manager<T,T_var> &
+TAO_Valuetype_Manager<T,T_var>::operator= (
+ const TAO_Valuetype_Manager<T,T_var> & rhs
+ )
+{
+ if (this == &rhs)
+ {
+ return *this;
+ }
+
+ if (this->release_)
+ {
+ TAO::Value_Traits<T>::remove_ref (*this->ptr_);
+ *this->ptr_ = *rhs.ptr_;
+ TAO::Value_Traits<T>::add_ref (*this->ptr_);
+ }
+ else
+ {
+ *this->ptr_ = *rhs.ptr_;
+ }
+
+ return *this;
+}
+
+template <typename T, typename T_var>
+TAO_Valuetype_Manager<T,T_var> &
+TAO_Valuetype_Manager<T,T_var>::operator= (T * p)
+{
+ if (this->release_)
+ {
+ // The semantics of the elements of a sequence are the same as
+ // that of a var variable. Therefore we will not duplicate the
+ // user provided pointer before assigning it to the internal
+ // variable.
+ TAO::Value_Traits<T>::remove_ref (*this->ptr_);
+ *this->ptr_ = p;
+ }
+ else
+ {
+ *this->ptr_ = p;
+ }
+
+ return *this;
+}
+
+template <typename T, typename T_var>
+TAO_Valuetype_Manager<T,T_var> &
+TAO_Valuetype_Manager<T,T_var>::operator= (const T_var & p)
+{
+ if (this->release_)
+ {
+ // The semantics of the elements of a sequence are the same as
+ // that of a var variable. Therefore we duplicate p's
+ // pointer before assigning it to the internal
+ // variable.
+ if (*this->ptr_ != 0)
+ {
+ (*this->ptr_)->_remove_ref ();
+ }
+
+ TAO::Value_Traits<T>::remove_ref (*this->ptr_);
+ *this->ptr_ = p.in ();
+ TAO::Value_Traits<T>::add_ref (*this->ptr_);
+ }
+ else
+ {
+ *this->ptr_ = p.in ();
+ }
+
+ return *this;
+}
+
+// *************************************************************
+// Operations for class TAO_Unbounded_Valuetype_Sequence
+// *************************************************************
+
+template <typename T, typename T_var>
+TAO_Unbounded_Valuetype_Sequence<T,T_var>::TAO_Unbounded_Valuetype_Sequence (
+ CORBA::ULong maximum
+ )
+ : TAO_Unbounded_Base_Sequence (
+ maximum,
+ TAO_Unbounded_Valuetype_Sequence<T,T_var>::allocbuf (maximum)
+ )
+{
+}
+
+template <typename T, typename T_var>
+TAO_Unbounded_Valuetype_Sequence<T,T_var>::TAO_Unbounded_Valuetype_Sequence (
+ const TAO_Unbounded_Valuetype_Sequence<T,T_var> & rhs
+ )
+ : TAO_Unbounded_Base_Sequence (rhs)
+{
+ if (rhs.buffer_ != 0)
+ {
+ T ** tmp1 =
+ TAO_Unbounded_Valuetype_Sequence<T,T_var>::allocbuf (
+ this->maximum_
+ );
+ T ** const tmp2 =
+ reinterpret_cast<T ** ACE_CAST_CONST> (rhs.buffer_);
+
+ for (CORBA::ULong i = 0; i < rhs.length_; ++i)
+ {
+ TAO::Value_Traits<T>::add_ref (tmp2[i]);
+ tmp1[i] = tmp2[i];
+ }
+
+ this->buffer_ = tmp1;
+ }
+ else
+ {
+ this->buffer_ = 0;
+ }
+}
+
+template <typename T, typename T_var>
+TAO_Unbounded_Valuetype_Sequence<T,T_var>::~TAO_Unbounded_Valuetype_Sequence (
+ void
+ )
+{
+ this->_deallocate_buffer ();
+}
+
+template <typename T, typename T_var>
+TAO_Unbounded_Valuetype_Sequence<T,T_var> &
+TAO_Unbounded_Valuetype_Sequence<T,T_var>::operator= (
+ const TAO_Unbounded_Valuetype_Sequence<T,T_var> & rhs
+ )
+{
+ if (this == &rhs)
+ {
+ return *this;
+ }
+
+ if (this->release_)
+ {
+ T ** tmp = reinterpret_cast<T **> (this->buffer_);
+
+ for (CORBA::ULong i = 0; i < this->length_; ++i)
+ {
+ TAO::Value_Traits<T>::remove_ref (tmp[i]);
+ tmp[i] = 0;
+ }
+
+ if (this->maximum_ < rhs.maximum_)
+ {
+ TAO_Unbounded_Valuetype_Sequence<T,T_var>::freebuf (tmp);
+ this->buffer_ =
+ TAO_Unbounded_Valuetype_Sequence<T,T_var>::allocbuf (rhs.maximum_);
+ }
+ }
+ else
+ {
+ if (rhs.maximum_ == 0)
+ {
+ this->buffer_ = 0;
+ }
+ else
+ {
+ this->buffer_ =
+ TAO_Unbounded_Valuetype_Sequence<T,T_var>::allocbuf (
+ rhs.maximum_
+ );
+ }
+ }
+
+ TAO_Unbounded_Base_Sequence::operator= (rhs);
+
+ T ** tmp1 = reinterpret_cast<T **> (this->buffer_);
+ T ** const tmp2 = reinterpret_cast<T **ACE_CAST_CONST> (rhs.buffer_);
+
+ for (CORBA::ULong i = 0; i < rhs.length_; ++i)
+ {
+ TAO::Value_Traits<T>::add_ref (tmp2[i]);
+ tmp1[i] = tmp2[i];
+ }
+
+ return *this;
+}
+
+template <typename T, typename T_var>
+T **
+TAO_Unbounded_Valuetype_Sequence<T,T_var>::allocbuf (CORBA::ULong nelems)
+{
+ T ** buf = 0;
+ ACE_NEW_RETURN (buf,
+ T * [nelems],
+ 0);
+
+ for (CORBA::ULong i = 0; i < nelems; ++i)
+ {
+ buf[i] = 0;
+ }
+
+ return buf;
+}
+
+template <typename T, typename T_var>
+void
+TAO_Unbounded_Valuetype_Sequence<T,T_var>::freebuf (T ** buffer)
+{
+ if (buffer == 0)
+ {
+ return;
+ }
+
+ // {orbos/97-05-15:16.11} The freebuf function ensures that the
+ // destructor for each element is called before the buffer is
+ // destroyed, except for string elements, which are freed using
+ // string_free(), and object reference elements, which are freed
+ // using release(). The freebuf function will ignore null pointers
+ // passed to it.
+
+ // @@ How are we supposed to implement that! We don't know the
+ // length of the buffer here.
+ // Mark the length in the first four bytes? For the moment we let
+ // that be.
+
+ delete [] buffer;
+}
+
+template <typename T, typename T_var>
+void
+TAO_Unbounded_Valuetype_Sequence<T,T_var>::_allocate_buffer (
+ CORBA::ULong length
+ )
+{
+ T ** tmp =
+ TAO_Unbounded_Valuetype_Sequence<T,T_var>::allocbuf (length);
+
+ if (this->buffer_ != 0)
+ {
+ T ** old = reinterpret_cast<T **> (this->buffer_);
+
+ for (CORBA::ULong i = 0; i < this->length_; ++i)
+ // Only call duplicate when we did not own the previous
+ // buffer, since after this method we own it we must also own
+ // the objects. If we already own the objects there is no
+ // need to copy them, if we did we would also have to remove
+ // the old instances.
+ if (!this->release_)
+ {
+ TAO::Value_Traits<T>::add_ref (tmp[i]);
+ tmp[i] = old[i];
+ }
+ else
+ {
+ tmp[i] = old[i];
+ }
+
+ if (this->release_)
+ {
+ delete [] old;
+ }
+ }
+
+ this->buffer_ = tmp;
+}
+
+template <typename T, typename T_var>
+void
+TAO_Unbounded_Valuetype_Sequence<T,T_var>::_deallocate_buffer (void)
+{
+ if (this->buffer_ == 0 || this->release_ == 0)
+ {
+ return;
+ }
+
+ T ** tmp = reinterpret_cast<T **> (this->buffer_);
+
+ for (CORBA::ULong i = 0; i < this->length_; ++i)
+ {
+ TAO::Value_Traits<T>::remove_ref (tmp[i]);
+ tmp[i] = 0;
+ }
+
+ TAO_Unbounded_Valuetype_Sequence<T,T_var>::freebuf (tmp);
+ this->buffer_ = 0;
+}
+
+template <typename T, typename T_var>
+void
+TAO_Unbounded_Valuetype_Sequence<T,T_var>::_shrink_buffer (
+ CORBA::ULong nl,
+ CORBA::ULong ol
+ )
+{
+ T ** tmp = static_cast<T **> (this->buffer_);
+
+ for (CORBA::ULong i = nl; i < ol; ++i)
+ {
+ TAO::Value_Traits<T>::remove_ref (tmp[i]);
+ tmp[i] = 0;
+ }
+}
+
+// *************************************************************
+// Operations for class TAO_Bounded_Valuetype_Sequence
+// *************************************************************
+
+template <typename T, typename T_var, size_t MAX>
+TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>::TAO_Bounded_Valuetype_Sequence (
+ void
+ )
+ : TAO_Bounded_Base_Sequence (
+ MAX,
+ TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>::allocbuf (MAX)
+ )
+{
+}
+
+template <typename T, typename T_var, size_t MAX>
+TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>::TAO_Bounded_Valuetype_Sequence (
+ const TAO_Bounded_Valuetype_Sequence<T,T_var,MAX> & rhs
+ )
+ : TAO_Bounded_Base_Sequence (rhs)
+{
+ if (rhs.buffer_ != 0)
+ {
+ T ** tmp1 =
+ TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>::allocbuf (MAX);
+
+ T ** const tmp2 =
+ reinterpret_cast<T ** ACE_CAST_CONST> (rhs.buffer_);
+
+ for (CORBA::ULong i = 0; i < rhs.length_; ++i)
+ {
+ TAO::Value_Traits<T>::add_ref (tmp2[i]);
+ tmp1[i] = tmp2[i];
+ }
+
+ this->buffer_ = tmp1;
+ }
+ else
+ {
+ this->buffer_ = 0;
+ }
+}
+
+template<typename T, typename T_var, size_t MAX>
+TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>::~TAO_Bounded_Valuetype_Sequence (
+ void
+ )
+{
+ this->_deallocate_buffer ();
+}
+
+template <typename T, typename T_var, size_t MAX>
+TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>&
+TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>::operator= (
+ const TAO_Bounded_Valuetype_Sequence<T,T_var,MAX> & rhs
+ )
+{
+ if (this == &rhs)
+ {
+ return *this;
+ }
+
+ if (this->release_)
+ {
+ T ** tmp = reinterpret_cast<T **> (this->buffer_);
+
+ for (CORBA::ULong i = 0; i < this->length_; ++i)
+ {
+ TAO::Value_Traits<T>::remove_ref (tmp[i]);
+ tmp[i] = 0;
+ }
+ // No need to reallocate the buffer since it is always of size
+ // MAX
+ }
+ else
+ {
+ if (rhs.maximum_ == 0)
+ {
+ this->buffer_ = 0;
+ }
+ else
+ {
+ this->buffer_ =
+ TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>::allocbuf (
+ rhs.maximum_
+ );
+ }
+ }
+
+ TAO_Bounded_Base_Sequence::operator= (rhs);
+
+ T ** tmp1 = reinterpret_cast<T **> (this->buffer_);
+ T ** const tmp2 = reinterpret_cast<T ** ACE_CAST_CONST> (rhs.buffer_);
+
+ for (CORBA::ULong i = 0; i < rhs.length_; ++i)
+ {
+ TAO::Value_Traits<T>::add_ref (tmp2[i]);
+ tmp1[i] = tmp2[i];
+ }
+
+ return *this;
+}
+
+template <typename T, typename T_var, size_t MAX>
+T **
+TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>::allocbuf (CORBA::ULong)
+{
+ T ** buf = 0;
+ ACE_NEW_RETURN (buf,
+ T * [MAX],
+ 0);
+
+ for (CORBA::ULong i = 0; i < MAX; ++i)
+ {
+ buf[i] = 0;
+ }
+
+ return buf;
+}
+
+template <typename T, typename T_var, size_t MAX>
+void
+TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>::freebuf (T ** buffer)
+{
+ // How much do we deallocate? Easy! allocbuf() always creates MAX
+ // elements and initialize them to T::_nil(). So we can be
+ // complaint and call CORBA::release() on each one.
+ for (CORBA::ULong i = 0; i < MAX; ++i)
+ {
+ if (buffer[i] != 0)
+ {
+ TAO::Value_Traits<T>::remove_ref (buffer[i]);
+ buffer[i] = 0;
+ }
+ }
+
+ delete [] buffer;
+}
+
+template <typename T, typename T_var, size_t MAX>
+void
+TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>::_allocate_buffer (
+ CORBA::ULong length
+ )
+{
+ // For this class memory is never reallocated so the implementation
+ // is *really* simple.
+ this->buffer_ =
+ TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>::allocbuf (length);
+}
+
+template <typename T, typename T_var, size_t MAX>
+void
+TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>::_deallocate_buffer (void)
+{
+ if (this->release_ == 0)
+ {
+ return;
+ }
+
+ T ** tmp = reinterpret_cast<T **> (this->buffer_);
+ TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>::freebuf (tmp);
+ this->buffer_ = 0;
+}
+
+template <typename T, typename T_var, size_t MAX>
+void
+TAO_Bounded_Valuetype_Sequence<T,T_var,MAX>::_shrink_buffer (
+ CORBA::ULong nl,
+ CORBA::ULong ol
+ )
+{
+ T ** tmp = reinterpret_cast<T **> (this->buffer_);
+
+ for (CORBA::ULong i = nl; i < ol; ++i)
+ {
+ TAO::Value_Traits<T>::remove_ref (tmp[i]);
+ tmp[i] = 0;
+ }
+}
+
+TAO_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* TAO_VALUETYPE_SEQUENCE_T_CPP */