OnixS C++ CME iLink 3 Binary Order Entry Handler  1.18.9
API Documentation
Memory.h
Go to the documentation of this file.
1 // Copyright Onix Solutions Limited [OnixS]. All rights reserved.
2 //
3 // This software owned by Onix Solutions Limited [OnixS] and is
4 // protected by copyright law and international copyright treaties.
5 //
6 // Access to and use of the software is governed by the terms of the applicable
7 // OnixS Software Services Agreement (the Agreement) and Customer end user license
8 // agreements granting a non-assignable, non-transferable and non-exclusive license
9 // to use the software for it's own data processing purposes under the terms defined
10 // in the Agreement.
11 //
12 // Except as otherwise granted within the terms of the Agreement, copying or
13 // reproduction of any part of this source code or associated reference material
14 // to any other location for further reproduction or redistribution, and any
15 // amendments to this copyright notice, are expressly prohibited.
16 //
17 // Any reproduction or redistribution for sale or hiring of the Software not in
18 // accordance with the terms of the Agreement is a violation of copyright law.
19 //
20 
21 #pragma once
22 
26 
27 #include <cstddef>
28 #include <cstring>
29 #include <cassert>
30 
32 
33 /// Alias for Byte.
34 typedef UInt8 Byte;
35 
36 /// Alias for Word.
37 typedef UInt16 Word;
38 
39 /// Alias for Double Word.
40 typedef UInt32 DWord;
41 
42 /// Alias for Quad Word.
43 typedef UInt64 QWord;
44 
45 /// Makes the pointer an opaque one.
46 /// \private
47 template
48 <
49  typename Type
50 >
53 void*
54 toOpaquePtr(Type* ptr)
56 {
57  assert(ptr);
58  return static_cast<void*>(ptr);
59 }
60 
61 /// Makes the pointer an opaque one.
62 /// \private
63 template
64 <
65  typename Type
66 >
69 const void*
70 toOpaquePtr(const Type* ptr)
72 {
73  assert(ptr);
74  return static_cast<const void*>(ptr);
75 }
76 
77 /// \private
78 template
79 <
80  typename Type
81 >
84 void* toMutable(const Type* ptr) ONIXS_ILINK3_NOTHROW
85 {
86  assert(ptr);
87  return const_cast<void*>(static_cast<const void*>(ptr));
88 }
89 
90 /// Reinterprets the pointer as a byte block one.
91 /// \private
92 template
93 <
94  typename Type
95 >
98 Byte*
99 toByteBlock(Type* ptr)
101 {
102  assert(ptr);
103 
104  return
105  static_cast
106  <Byte*>
107  (toOpaquePtr(ptr));
108 }
109 
110 /// Reinterprets the pointer as a byte block one.
111 /// \private
112 template
113 <
114  typename Type
115 >
118 const Byte*
119 toByteBlock(const Type* ptr)
121 {
122  assert(ptr);
123 
124  return
125  static_cast
126  <const Byte*>
127  (toOpaquePtr(ptr));
128 }
129 
130 /// Advances the pointer to a given offset (distance) in bytes.
131 /// \private
132 template
133 <
134  typename Type
135 >
138 Type* advanceByBytes(Type* pointer, ptrdiff_t distance) ONIXS_ILINK3_NOTHROW
139 {
140  assert(pointer);
141 
142  return reinterpret_cast<Type*>(toByteBlock(pointer) + distance);
143 }
144 
145 /// \return a pointer that is lower than
146 /// the given one by a given number of bytes.
147 /// \private
148 template
149 <
150  typename Type
151 >
154 Type*
155 advanceBackByBytes(
156  Type* pointer,
157  ptrdiff_t distance)
159 {
160  assert(pointer);
161 
162  return
163  reinterpret_cast<Type*>
164  (
165  toByteBlock(pointer) - distance
166  );
167 }
168 
169 /// \return the distance in bytes between two pointers.
170 /// \private
171 template
172 <
173  typename Left,
174  typename Right
175 >
178 ptrdiff_t
179 byteDistance(
180  Left* left,
181  Right* right)
183 {
184  assert(left);
185  assert(right);
186 
187  return (
188  toByteBlock(left) -
189  toByteBlock(right)
190  );
191 }
192 
193 /// \private
194 template
195 <
196  class Value
197 >
199 Value
200 extractValue(const void* location) ONIXS_ILINK3_NOTHROW
201 {
202  assert(location);
203 
204  CHECK_TYPE_INTEGRAL(Value);
205 
206  Value result;
207 
208  std::memcpy(
209  &result,
210  location,
211  sizeof(Value));
212 
213  return result;
214 }
215 
216 /// \private
217 template <unsigned ArgsCount>
218 struct CompositeExtractor;
219 
220 /// \private
221 template <>
222 struct CompositeExtractor<1>
223 {
224  template <class Value>
225  static
226  Value extract(const void* location) ONIXS_ILINK3_NOTHROW
227  {
228 
229 #if defined (ONIXS_ILINK3_CXX11)
230  static_assert(
231  noexcept(
232  Value(
233  std::declval<typename Value::MemberTraits::FirstArgType>()
234  )
235  ) ,
236  "must be noexcept");
237 #endif
238 
239  assert(location);
240 
241  return
242  Value(
243  extractValue<typename Value::MemberTraits::FirstArgType>(location)
244  );
245  }
246 };
247 
248 /// \private
249 template <>
250 struct CompositeExtractor<2>
251 {
252  template <class Value>
253  static
254  Value extract(const void* location) ONIXS_ILINK3_NOTHROW
255  {
256  typedef typename Value::MemberTraits::FirstArgType FirstArgType;
257  typedef typename Value::MemberTraits::SecondArgType SecondArgType;
258 
259 #if defined (ONIXS_ILINK3_CXX11)
260  static_assert(
261  noexcept(
262  Value(
263  std::declval<FirstArgType>(),
264  std::declval<SecondArgType>()
265  )
266  ) ,
267  "must be noexcept");
268 #endif
269 
270  assert(location);
271 
272  return
273  Value(
274  extractValue<FirstArgType>(location),
275  extractValue<SecondArgType>(
276  advanceByBytes(location, sizeof(FirstArgType)))
277  );
278  }
279 };
280 
281 /// \private
282 template <>
283 struct CompositeExtractor<4>
284 {
285  template <class Value>
286  static
287  Value extract(const void* location) ONIXS_ILINK3_NOTHROW
288  {
289  typedef typename Value::MemberTraits::FirstArgType FirstArgType;
290  typedef typename Value::MemberTraits::SecondArgType SecondArgType;
291  typedef typename Value::MemberTraits::ThirdArgType ThirdArgType;
292  typedef typename Value::MemberTraits::FourthArgType FourthArgType;
293 
294 #if defined (ONIXS_ILINK3_CXX11)
295  static_assert(
296  noexcept(
297  Value(
298  std::declval<FirstArgType>(),
299  std::declval<SecondArgType>(),
300  std::declval<ThirdArgType>(),
301  std::declval<FourthArgType>()
302  )
303  ) ,
304  "must be noexcept");
305 #endif
306 
307  assert(location);
308 
309  return
310  Value(
311  extractValue<FirstArgType>(location),
312  extractValue<SecondArgType>(
313  advanceByBytes(location, sizeof(FirstArgType))),
314  extractValue<ThirdArgType>(
315  advanceByBytes(location, sizeof(FirstArgType) + sizeof(SecondArgType))),
316  extractValue<FourthArgType>(
317  advanceByBytes(location, sizeof(FirstArgType) + sizeof(SecondArgType) + sizeof(ThirdArgType)))
318  );
319  }
320 };
321 
322 /// \private
323 template
324 <
325  class Value
326 >
328 typename EnableIf<details::HasMemberTraits<Value>::value, Value>::type
329 getValue(const void* location) ONIXS_ILINK3_NOTHROW
330 {
331  assert(location);
332  return CompositeExtractor<Value::MemberTraits::Count>:: template extract<Value>(location);
333 }
334 
335 /// \private
336 template
337 <
338  class Value
339 >
341 typename EnableIf<!details::HasMemberTraits<Value>::value, Value>::type
342 getValue(const void* location) ONIXS_ILINK3_NOTHROW
343 {
344  assert(location);
345  return extractValue<Value>(location);
346 }
347 
348 /// \private
349 template
350 <
351  class Value
352 >
354 typename EnableIf<!details::HasMemberTraits<Value>::value, size_t>::type
356 {
357  return sizeof(Value);
358 }
359 
360 /// \private
361 template
362 <
363  class Value
364 >
366 typename EnableIf<details::HasMemberTraits<Value>::value, size_t>::type
368 {
369  return Value::Size;
370 }
371 
372 /// \private
373 template
374 <
375  class Value
376 >
378 typename EnableIf<!details::HasSerializeMember<Value>::value>::type
379 commitValue(void* location, Value value)
381 {
382  assert(location);
383  std::memcpy(
384  location,
385  &value,
386  sizeof(Value));
387 }
388 
389 /// \private
390 template
391 <
392  class Value
393 >
395 typename EnableIf<details::HasSerializeMember<Value>::value>::type
396 commitValue(void* location, Value value)
398 {
399  assert(location);
400  value.serialize(location);
401 }
402 
403 /// \private
404 template
405 <
406  class Value
407 >
409 typename EnableIf<!details::HasValueStaticMember<Value>::value>::type
410 setValue(void* location, Value value)
412 {
413  assert(location);
414  commitValue(location, value);
415 }
416 
417 /// \private
418 template
419 <
420  class Value
421 >
423 typename EnableIf<details::HasValueStaticMember<Value>::value>::type
424 setValue(void* location, Value)
426 {
427  assert(location);
428  commitValue(location, Value::value());
429 }
430 
#define ONIXS_ILINK3_CONSTEXPR
Definition: Compiler.h:179
UInt8 Byte
Alias for Byte.
Definition: Memory.h:34
#define ONIXS_ILINK3_PURE
Definition: Compiler.h:189
UInt64 QWord
Alias for Quad Word.
Definition: Memory.h:43
UInt16 UInt16
uInt16.
Definition: Fields.h:296
UInt16 Word
Alias for Word.
Definition: Memory.h:37
#define ONIXS_ILINK3_MESSAGING_NAMESPACE_END
Definition: ABI.h:144
UInt32 DWord
Alias for Double Word.
Definition: Memory.h:40
UInt64 UInt64
uInt64.
Definition: Fields.h:308
UInt32 UInt32
uInt32.
Definition: Fields.h:302
#define ONIXS_ILINK3_MESSAGING_NAMESPACE_BEGIN
Definition: ABI.h:140
#define ONIXS_ILINK3_HOTPATH
Definition: Compiler.h:187
#define ONIXS_ILINK3_NOTHROW
Definition: Compiler.h:176
#define CHECK_TYPE_INTEGRAL(Type)
Definition: Utils.h:47