// -*- c++ -*- /* * MICO --- an Open Source CORBA implementation * Copyright (c) 1997-2010 by The Mico Team * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * For more information, visit the MICO Home Page at * http://www.mico.org/ */ #ifndef __mico_sequence_h__ #define __mico_sequence_h__ template class TSeqVar; /* * C++ template for unbounded sequences. The element type of the sequence * can be of any type except for arrays and recursive types (see * SequenceIndTmpl) */ template class SequenceTmpl { public: typedef T &ElementType; // Needed in TSeqVar (see var.h) typedef TSeqVar > _var_type; private: std::vector vec; public: SequenceTmpl () {} SequenceTmpl (MICO_ULong maxval) { vec.reserve (maxval); } SequenceTmpl (MICO_ULong max, MICO_ULong length, T *value, MICO_Boolean rel = FALSE); SequenceTmpl (const SequenceTmpl &s) { vec = s.vec; } ~SequenceTmpl () { } void replace (MICO_ULong max, MICO_ULong length, T *value, MICO_Boolean rel = FALSE); SequenceTmpl &operator= (const SequenceTmpl &s) { vec = s.vec; return *this; } MICO_ULong maximum () const { return vec.capacity (); } MICO_Boolean release () const { // we always own the buffer return TRUE; } T* get_buffer (MICO_Boolean orphan = FALSE); const T* get_buffer () const { assert (vec.size() > 0); return &vec[0]; } void length (MICO_ULong l); MICO_ULong length () const; T &operator[] (MICO_ULong idx); const T &operator[] (MICO_ULong idx) const; static T *allocbuf (MICO_ULong len) { return new T[len]; } static void freebuf (T *b) { delete[] b; } #if defined( __SUNPRO_CC ) && ( __SUNPRO_CC <= 0x5010 ) friend MICO_Boolean operator== (const SequenceTmpl &v1, const SequenceTmpl &v2) { if (v1.length() != v2.length()) return FALSE; for (MICO_ULong _i = 0; _i < v1.length(); ++_i) { if (!(v1[_i] == v2[_i])) return FALSE; } return TRUE; } #endif }; template SequenceTmpl::SequenceTmpl (MICO_ULong maxval, MICO_ULong lengthval, T *value, MICO_Boolean rel) { assert (lengthval <= maxval); vec.reserve (maxval); vec.insert (vec.begin(), value, value+lengthval); if (rel) freebuf (value); } template void SequenceTmpl::replace (MICO_ULong maxval, MICO_ULong lengthval, T *value, MICO_Boolean rel) { assert (lengthval <= maxval); vec.erase (vec.begin(), vec.end()); vec.reserve (maxval); vec.insert (vec.begin(), value, value+lengthval); if (rel) freebuf (value); } template void SequenceTmpl::length (MICO_ULong l) { if (l < vec.size ()) { vec.erase (vec.begin() + l, vec.end()); } else if (l > vec.size()) { T* t = new T; // the (long) cast is needed for SGI STL vec.insert (vec.end(), long(l - vec.size()), *t); delete t; } } template inline MICO_ULong SequenceTmpl::length () const { // The MICO_ULong cast is needed for Win64/VC++ 10.0 return (MICO_ULong)vec.size (); } template inline T & SequenceTmpl::operator[] (MICO_ULong idx) { return vec[idx]; } template inline const T & SequenceTmpl::operator[] (MICO_ULong idx) const { return vec[idx]; } template T * SequenceTmpl::get_buffer (MICO_Boolean orphan) { if (orphan) { // The MICO_ULong cast is needed for Win64/VC++ 10.0 T *b = allocbuf ((MICO_ULong)vec.capacity()); for (mico_vec_size_type i = 0; i < vec.size(); ++i) b[i] = vec[i]; vec.erase (vec.begin(), vec.end()); return b; } else { assert (vec.size() > 0); return &vec[0]; } } #if !defined( __SUNPRO_CC ) || ( __SUNPRO_CC > 0x5010 ) template MICO_Boolean operator== (const SequenceTmpl &v1, const SequenceTmpl &v2) { if (v1.length() != v2.length()) return FALSE; for (MICO_ULong _i = 0; _i < v1.length(); ++_i) { if (!(v1[_i] == v2[_i])) return FALSE; } return TRUE; } #endif /* * Same as SequenceTmpl except that this template is for bounded sequences. */ template class BoundedSequenceTmpl { public: typedef T &ElementType; // Needed in TSeqVar (see var.h) private: std::vector vec; public: BoundedSequenceTmpl () { vec.reserve (max); } BoundedSequenceTmpl (MICO_ULong length, T *value, MICO_Boolean rel = TRUE); BoundedSequenceTmpl (const BoundedSequenceTmpl &s) { vec = s.vec; } ~BoundedSequenceTmpl () { } void replace (MICO_ULong length, T *value, MICO_Boolean rel = TRUE); BoundedSequenceTmpl &operator= (const BoundedSequenceTmpl &s) { vec = s.vec; return *this; } MICO_ULong maximum () const { return max; } MICO_Boolean release () const { // we always own the buffer return TRUE; } T* get_buffer (MICO_Boolean orphan = FALSE); const T* get_buffer () const { assert (vec.size() > 0); return &vec[0]; } void length (MICO_ULong l); MICO_ULong length () const { // The MICO_ULong cast is needed for Win64/VC++ 10.0 return (MICO_ULong)vec.size(); } T &operator[] (MICO_ULong idx) { return vec[idx]; } const T &operator[] (MICO_ULong idx) const { return vec[idx]; } static T *allocbuf (MICO_ULong len) { return new T[len]; } static void freebuf (T *b) { delete[] b; } #if defined( __SUNPRO_CC ) && ( __SUNPRO_CC <= 0x5010 ) friend MICO_Boolean operator== (const BoundedSequenceTmpl &v1, const BoundedSequenceTmpl &v2) { if (v1.length() != v2.length()) return FALSE; for (MICO_ULong _i = 0; _i < v1.length(); ++_i) { if (!(v1[_i] == v2[_i])) return FALSE; } return TRUE; } #endif }; template BoundedSequenceTmpl::BoundedSequenceTmpl (MICO_ULong lengthval, T *value, MICO_Boolean rel) { assert (lengthval <= max); vec.reserve (max); vec.insert (vec.begin(), value, value+lengthval); if (rel) freebuf (value); } template void BoundedSequenceTmpl::replace (MICO_ULong lengthval, T *value, MICO_Boolean rel) { assert (lengthval <= max); vec.erase (vec.begin(), vec.end()); vec.reserve (max); vec.insert (vec.begin(), value, value+lengthval); if (rel) freebuf (value); } template void BoundedSequenceTmpl::length (MICO_ULong l) { assert (l <= max); if (l < vec.size ()) { vec.erase (vec.begin() + l, vec.end()); } else if (l > vec.size()) { T t; vec.insert (vec.end(), long(l - vec.size()), t); } } template T * BoundedSequenceTmpl::get_buffer (MICO_Boolean orphan) { if (orphan) { T *b = allocbuf (vec.capacity()); for (mico_vec_size_type i = 0; i < vec.size(); ++i) b[i] = vec[i]; vec.erase (vec.begin(), vec.end()); return b; } else { assert (vec.size() > 0); return &vec[0]; } } #if !defined( __SUNPRO_CC ) || ( __SUNPRO_CC > 0x5010 ) template MICO_Boolean operator== (const BoundedSequenceTmpl &v1, const BoundedSequenceTmpl &v2) { if (v1.length() != v2.length()) return FALSE; for (MICO_ULong _i = 0; _i < v1.length(); ++_i) { if (!(v1[_i] == v2[_i])) return FALSE; } return TRUE; } #endif /* * C++ template for sequences of arrays and recursive types. The difference * is, that this template maintains it members only indirectly through * pointers. This is especially necessary to break infinite recursion * for recursive types. If this template is used for arrays, then T_elem * denotes the element type of the array, T the array type itself and * n the total number of array elements. If the template is used for * recursive types then T_elem and T are the same and n should be set to 1. */ template class SequenceIndTmpl { public: typedef T &ElementType; // Needed in TSeqVar (see var.h) private: std::vector vec; public: SequenceIndTmpl () {} SequenceIndTmpl (MICO_ULong maxval) { vec.reserve (maxval); } SequenceIndTmpl (MICO_ULong max, MICO_ULong length, T* value, MICO_Boolean rel = TRUE); void replace (MICO_ULong max, MICO_ULong length, T *value, MICO_Boolean rel = TRUE); SequenceIndTmpl (const SequenceIndTmpl &s); ~SequenceIndTmpl (); SequenceIndTmpl& operator= (const SequenceIndTmpl &s); MICO_ULong maximum () const { return vec.capacity (); } void length (MICO_ULong l); MICO_ULong length () const { return vec.size (); } MICO_Boolean release () const { // we always own the buffer return TRUE; } // get_buffer() not supported ... T& operator[] (MICO_ULong idx) { return (T&) *vec[idx]; } const T& operator[] (MICO_ULong idx) const { return (T&) *vec[idx]; } static T *allocbuf (MICO_ULong len); static void freebuf( T* b ); #if defined( __SUNPRO_CC ) && ( __SUNPRO_CC <= 0x5010 ) friend MICO_Boolean operator== (const SequenceIndTmpl &v1, const SequenceIndTmpl &v2) { if( v1.length() != v2.length() ) return FALSE; for( MICO_ULong i = 0; i < v1.length(); i++ ) { for( MICO_ULong j = 0; j < n; j++ ) { T_elem e1 = ((T_elem*) v1[ i ])[ j ]; T_elem e2 = ((T_elem*) v2[ i ])[ j ]; if( !(e1 == e2) ) return FALSE; } } return TRUE; } #endif }; #if !defined( __SUNPRO_CC ) || ( __SUNPRO_CC > 0x5010 ) template MICO_Boolean operator== (const SequenceIndTmpl &v1, const SequenceIndTmpl &v2) { if( v1.length() != v2.length() ) return FALSE; for( MICO_ULong i = 0; i < v1.length(); i++ ) { for( MICO_ULong j = 0; j < n; j++ ) { T_elem e1 = ((T_elem*) v1[ i ])[ j ]; T_elem e2 = ((T_elem*) v2[ i ])[ j ]; if( !(e1 == e2) ) return FALSE; } } return TRUE; } #endif /* * Same as SequenceIndTmpl except that this one is for bounded sequences. */ template class BoundedSequenceIndTmpl { public: typedef T &ElementType; // Needed in TSeqVar (see var.h) private: std::vector vec; public: BoundedSequenceIndTmpl () { vec.reserve (max); } BoundedSequenceIndTmpl (MICO_ULong length, T *value, MICO_Boolean rel = TRUE); BoundedSequenceIndTmpl (const BoundedSequenceIndTmpl &s); ~BoundedSequenceIndTmpl (); BoundedSequenceIndTmpl &operator= (const BoundedSequenceIndTmpl &s); void replace (MICO_ULong length, T *value, MICO_Boolean rel = TRUE); MICO_ULong maximum () const { return max; } void length (MICO_ULong l); MICO_ULong length () const { return vec.size (); } MICO_Boolean release () const { // we always own the buffer return TRUE; } // get_buffer() not supported ... T &operator[] (MICO_ULong idx) { return (T&) *vec[idx]; } const T &operator[] (MICO_ULong idx) const { return (T&) *vec[idx]; } static T *allocbuf (MICO_ULong len); static void freebuf (T *b); #if defined( __SUNPRO_CC ) && ( __SUNPRO_CC <= 0x5010 ) friend MICO_Boolean operator== (const BoundedSequenceIndTmpl &v1, const BoundedSequenceIndTmpl &v2) { if( v1.length() != v2.length() ) return FALSE; for( MICO_ULong i = 0; i < v1.length(); i++ ) { for( MICO_ULong j = 0; j < n; j++ ) { T_elem e1 = ((T_elem*) v1[ i ])[ j ]; T_elem e2 = ((T_elem*) v2[ i ])[ j ]; if( !(e1 == e2) ) return FALSE; } } return TRUE; } #endif }; #if !defined( __SUNPRO_CC ) || ( __SUNPRO_CC > 0x5010 ) template MICO_Boolean operator== (const BoundedSequenceIndTmpl &v1, const BoundedSequenceIndTmpl &v2) { if( v1.length() != v2.length() ) return FALSE; for( MICO_ULong i = 0; i < v1.length(); i++ ) { for( MICO_ULong j = 0; j < n; j++ ) { T_elem e1 = ((T_elem*) v1[ i ])[ j ]; T_elem e2 = ((T_elem*) v2[ i ])[ j ]; if( !(e1 == e2) ) return FALSE; } } return TRUE; } #endif #endif // __mico_sequence_h__