OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
Message.hpp
Go to the documentation of this file.
1// -*- C++ -*-
2/***************************************************************************
3 *
4 * The IPPL Framework
5 *
6 * This program was prepared by PSI.
7 * All rights in the program are reserved by PSI.
8 * Neither PSI nor the author(s)
9 * makes any warranty, express or implied, or assumes any liability or
10 * responsibility for the use of this software
11 *
12 ***************************************************************************/
13
14#include "Message/Message.h"
15#include "Utility/IpplInfo.h"
16
17#include <iterator>
18#include <new>
19#include <memory>
20#include <cstdlib>
21#include <cstddef>
22
23template <class T>
26{
27 T& value = const_cast<T&>(cvalue);
28 value.putMessage(msg);
29 return msg;
30}
31
32template <class T>
35{
36 value.getMessage(msg);
37 return msg;
38}
39
40template <class T>
43{
44 // get the value type using iterator traits
45 typedef typename std::iterator_traits<T>::value_type T2;
46
47 // make sure this is not empty ... if so, just create an empty item
48 if (beg == end)
49 {
50 m.putmsg(0, sizeof(T2), 0);
51 }
52 else
53 {
54 // find the number of elements in this iterator range
55 unsigned int d = 0;
56 T f;
57 for (f = beg; f != end; ++d, ++f);
58
59 // if DoCopy is false, we must assume the iterators are pointers
60 // to simple data types, and so we can just cast the pointer to
61 // void and store it
62 if (!m.willCopy())
63 {
64 m.putmsg((void*) (&*beg), sizeof(T2), d);
65 }
66 else
67 {
68 // make a copy ourselves
69 // use malloc to get block, placement new for each element
70 T2* cpydata = static_cast<T2*>( malloc(sizeof(T2) * d) );
71 T2* cpy = cpydata;
72 T i;
73 for (i = beg; i != end; ++i, ++cpy)
74 new (cpy) T2(*i);
75
76 // put data into this message
77 m.setCopy(false);
78 m.setDelete(true);
79 m.putmsg( (void*) cpydata, sizeof(T2), d );
80 }
81 }
82 return m;
83}
84
85template <class T>
88 const std::vector<size_t>& indices, T beg)
89{
90 // get the value type using iterator traits
91 typedef typename std::iterator_traits<T>::value_type T2;
92
93 // make sure this is not empty ... if so, just create an empty item
94 if (indices.begin() == indices.end())
95 {
96 m.putmsg(0, sizeof(T2), 0);
97 }
98 else
99 {
100 // find the number of elements in this iterator range
101 std::vector<size_t>::size_type d = indices.size();
102
103 // make a copy of the data ourselves
104 // use malloc to get block, placement new for each element
105 T2* cpydata = static_cast<T2*>( malloc(sizeof(T2) * d) );
106 T2* cpy = cpydata;
107 std::vector<size_t>::const_iterator i, iend = indices.end();
108 for (i = indices.begin(); i != iend; ++i, ++cpy)
109 new (cpy) T2(beg[*i]);
110
111 // put data into this message
112 m.setCopy(false);
113 m.setDelete(true);
114 m.putmsg( (void*) cpydata, sizeof(T2), d );
115 }
116 return m;
117}
118
119template <class T>
120Message&
122{
123 // get the value type using iterator traits
124 typedef typename std::iterator_traits<T>::value_type T2;
125
126 // check to see if there is an item
127 if ( m.empty() )
128 {
129 ERRORMSG("get_iter(): no more items in Message" << endl);
130 }
131 else
132 {
133 // get the next MsgItem off the top of the list
134 Message::MsgItem& mitem = m.item(0);
135
136 // copy the data pointer
137 T2* data = static_cast<T2*>( mitem.data() );
138 int i;
139 for (i = mitem.numElems(); i > 0; i--)
140 *o++ = *data++;
141
142 // delete this MsgItem
143 m.get();
144 }
145 return m;
146}
147
148
149// specialization to a built-in type that is not a pointer
150
151template <class T>
152Message&
154{
155 T& ncval = const_cast<T&>(value);
156 return msg.putmsg( (void*) &ncval, sizeof(T) );
157}
158
159template <class T>
160Message&
162{
163 return msg.getmsg( (void*) &value );
164}
165
166
167// specialization to a pointer to a built-in type. In this class, we
168// know that 'T' is a pointer type.
169
170
171template <class T>
172Message&
174{
176 return msg.putmsg( (void*) beg,
177 sizeof(value_type),
178 (end - beg) );
179}
180
181template <class T>
182Message&
184{
185 return msg.getmsg( (void*) ptr );
186}
187
188template <class T>
189Message&
191 const std::vector<size_t>& indices, T beg)
192{
193 return PutSingleItem<T, false, false>::put(m, indices, beg);
194}
195
196template <class T>
197Message&
199{
201}
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
T * value_type(const SliceIterator< T > &)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
size_t size() const
Definition: Message.h:292
Message & putmsg(void *, int, int=0)
Message & setCopy(const bool c)
Definition: Message.h:319
Message & getmsg(void *)
bool empty() const
Definition: Message.h:300
MsgItem & item(size_t n)
Definition: Message.h:308
Message & setDelete(const bool c)
Definition: Message.h:331
bool willCopy() const
Definition: Message.h:324
Message & get(const T &cval)
Definition: Message.h:476
unsigned int numElems() const
Definition: Message.h:222
void * data()
Definition: Message.h:244