src/Message/Message.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://people.web.psi.ch/adelmann/ for more details
00023  *
00024  ***************************************************************************/
00025 
00026 // include files
00027 #include "Message/Message.h"
00028 #include "Utility/Inform.h"
00029 #include "Utility/IpplInfo.h"
00030 #include "Profile/Profiler.h"
00031 
00032 #ifdef IPPL_STDSTL
00033 
00034 #include <iterator>
00035 // Rogue Wave STL for PGI compiler doesn't have iterator_traits!!
00036 
00037 // By now they have 2002 andreas 
00038 #ifdef OLD_IPPL_PGI
00039 namespace std {
00040 
00041 template <class _Iterator>
00042 struct iterator_traits {
00043   typedef typename _Iterator::iterator_category iterator_category;
00044   typedef typename _Iterator::value_type        value_type;
00045   typedef typename _Iterator::difference_type   difference_type;
00046   typedef typename _Iterator::pointer           pointer;
00047   typedef typename _Iterator::reference         reference;
00048 };
00049 
00050 template <class _Tp>
00051 struct iterator_traits<_Tp*> {
00052   typedef random_access_iterator_tag iterator_category;
00053   typedef _Tp                         value_type;
00054   typedef ptrdiff_t                   difference_type;
00055   typedef _Tp*                        pointer;
00056   typedef _Tp&                        reference;
00057 };
00058 
00059 template <class _Tp>
00060 struct iterator_traits<const _Tp*> {
00061   typedef random_access_iterator_tag iterator_category;
00062   typedef _Tp                         value_type;
00063   typedef ptrdiff_t                   difference_type;
00064   typedef const _Tp*                  pointer;
00065   typedef const _Tp&                  reference;
00066 };
00067 
00068 }
00069 #endif // IPPL_PGI
00070 using namespace std;
00071 
00072 #else
00073 
00074 #include <iterator.h>
00075 
00076 #endif 
00077 
00078 #ifdef IPPL_USE_STANDARD_HEADERS
00079 #include <new>
00080 #include <memory>
00081 using namespace std;
00082 #else
00083 #include <new.h>
00084 #include <memory.h>
00085 #endif
00086 
00087 #include <stdlib.h>
00088 #include <stddef.h>
00089 
00090 // MWERKS: moved macro definitions for MessageTypeIntrinsic to Message.h
00091 
00092 // MWERKS: moved PutSingleItem definitions to Message.h
00093 
00094 // definitions for non-templated static member functions of PutSingleItem
00095 // can remain here.  JCC
00096 
00097 // specialization to a non-built-in type, which is never assumed to be a ptr
00098 
00099 template <class T>
00100 Message&
00101 PutSingleItem<T, false, false>::put(Message& msg, const T& cvalue)
00102 {
00103   T& value = const_cast<T&>(cvalue);
00104   value.putMessage(msg);
00105   return msg;
00106 }
00107 
00108 template <class T>
00109 Message&
00110 PutSingleItem<T, false, false>::get(Message& msg, T& value)
00111 {
00112   value.getMessage(msg);
00113   return msg;
00114 }
00115 
00116 template <class T>
00117 Message&
00118 PutSingleItem<T, false, false>::put(Message& m, T beg, T end)
00119 {
00120   // get the value type using iterator traits
00121   typedef typename iterator_traits<T>::value_type T2;
00122 
00123   // make sure this is not empty ... if so, just create an empty item
00124   if (beg == end) {
00125     m.putmsg(0, sizeof(T2), 0);
00126   }
00127   else {
00128     // find the number of elements in this iterator range
00129     unsigned int d = 0;
00130     T f;
00131     for (f = beg; f != end; ++d, ++f);
00132 
00133     // if DoCopy is false, we must assume the iterators are pointers
00134     // to simple data types, and so we can just cast the pointer to
00135     // void and store it
00136     if (!m.willCopy()) {
00137 #ifdef __MWERKS__
00138       m.putmsg((void*) (&*beg), sizeof(T2), d);
00139 #else
00140   // Is this bad C++ or mwerks bug? Certain STL implems this might be wrong:
00141       m.putmsg((void*) (&*beg), sizeof(T2), d);
00142       //m.putmsg((void*) beg, sizeof(T2), d);
00143 #endif // __MWERKS__
00144     }
00145     else {
00146       // make a copy ourselves
00147       // use malloc to get block, placement new for each element
00148       T2* cpydata = static_cast<T2*>( malloc(sizeof(T2) * d) );
00149       T2* cpy = cpydata;
00150       T i;
00151       for (i = beg; i != end; ++i, ++cpy)
00152         new (cpy) T2(*i);
00153 
00154       // put data into this message
00155       m.setCopy(false);
00156       m.setDelete(true);
00157       m.putmsg( (void*) cpydata, sizeof(T2), d );
00158     }
00159   }
00160   return m;
00161 }
00162 
00163 template <class T>
00164 Message&
00165 PutSingleItem<T, false, false>::put(Message& m,
00166                                     const vector<size_t>& indices, T beg)
00167 {
00168   // get the value type using iterator traits
00169   typedef typename iterator_traits<T>::value_type T2;
00170 
00171   // make sure this is not empty ... if so, just create an empty item
00172   if (indices.begin() == indices.end()) {
00173     m.putmsg(0, sizeof(T2), 0);
00174   }
00175   else {
00176     // find the number of elements in this iterator range
00177     vector<size_t>::size_type d = indices.size();
00178 
00179     // make a copy of the data ourselves
00180     // use malloc to get block, placement new for each element
00181     T2* cpydata = static_cast<T2*>( malloc(sizeof(T2) * d) );
00182     T2* cpy = cpydata;
00183     vector<size_t>::const_iterator i, iend = indices.end();
00184     for (i = indices.begin(); i != iend; ++i, ++cpy)
00185       new (cpy) T2(beg[*i]);
00186 
00187     // put data into this message
00188     m.setCopy(false);
00189     m.setDelete(true);
00190     m.putmsg( (void*) cpydata, sizeof(T2), d );
00191   }
00192   return m;
00193 }
00194 
00195 template <class T>
00196 Message&
00197 PutSingleItem<T, false, false>::get_iter(Message& m, T o)
00198 {
00199   // get the value type using iterator traits
00200   typedef typename iterator_traits<T>::value_type T2;
00201 
00202   // check to see if there is an item
00203   if ( m.empty() ) {
00204     ERRORMSG("get_iter(): no more items in Message" << endl);
00205   }
00206   else {
00207     // get the next MsgItem off the top of the list
00208     Message::MsgItem& mitem = m.item(0);
00209 
00210     // copy the data pointer
00211     T2* data = static_cast<T2*>( mitem.data() );
00212     int i;
00213     for (i = mitem.numElems(); i > 0; i--)
00214       *o++ = *data++;
00215 
00216     // delete this MsgItem
00217     m.get();
00218   }
00219   return m;
00220 }
00221 
00222 
00223 // specialization to a built-in type that is not a pointer
00224 
00225 template <class T>
00226 Message&
00227 PutSingleItem<T, true, false>::put(Message& msg, const T& value)
00228 {
00229   T& ncval = const_cast<T&>(value);  
00230   return msg.putmsg( (void*) &ncval, sizeof(T) );
00231 }
00232 
00233 template <class T>
00234 Message&
00235 PutSingleItem<T, true, false>::get(Message& msg, T& value)
00236 {
00237   return msg.getmsg( (void*) &value );
00238 }
00239 
00240 
00241 // specialization to a pointer to a built-in type. In this class, we
00242 // know that 'T' is a pointer type.
00243 
00244 
00245 template <class T>
00246 Message&
00247 PutSingleItem<T, true, true>::put(Message& msg, T beg, T end)
00248 {
00249   typedef typename iterator_traits<T>::value_type value_type;
00250   return msg.putmsg( (void*) beg,
00251                      sizeof(value_type),
00252                      (end - beg) );
00253 }
00254 
00255 template <class T>
00256 Message&
00257 PutSingleItem<T, true, true>::get(Message& msg, T ptr)
00258 {
00259     return msg.getmsg( (void*) ptr );
00260 }
00261 
00262 template <class T>
00263 Message&
00264 PutSingleItem<T, true, true>::put(Message& m,
00265                                   const vector<size_t>& indices, T beg)
00266 {
00267   return PutSingleItem<T, false, false>::put(m, indices, beg);
00268 }
00269 
00270 template <class T>
00271 Message&
00272 PutSingleItem<T, true, true>::get_iter(Message& m, T o)
00273 {
00274   return PutSingleItem<T, false, false>::get_iter(m, o);
00275 }
00276 
00277 
00278 /***************************************************************************
00279  * $RCSfile: Message.cpp,v $   $Author: adelmann $
00280  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:28 $
00281  * IPPL_VERSION_ID: $Id: Message.cpp,v 1.1.1.1 2003/01/23 07:40:28 adelmann Exp $ 
00282  ***************************************************************************/

Generated on Mon Jan 16 13:23:52 2006 for IPPL by  doxygen 1.4.6