OnixS C++ B3 BOE Binary Order Entry  1.2.0
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 
23 #include <OnixS/B3/BOE/Compiler.h>
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_B3_BOE_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_B3_BOE_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_B3_BOE_NOTHROW
201 {
202  assert(location);
203 
204  // [VG] The following line must be commented to enable composite reading, though I not sure that is right:
205  // CHECK_TYPE_INTEGRAL(Value);
206 
207  Value result;
208 
209  std::memcpy(
210  &result,
211  location,
212  sizeof(Value));
213 
214  return result;
215 }
216 
217 /// \private
218 template <unsigned ArgsCount>
219 struct CompositeExtractor;
220 
221 /// \private
222 template <>
223 struct CompositeExtractor<1>
224 {
225  template <class Value>
226  static
227  Value extract(const void* location) ONIXS_B3_BOE_NOTHROW
228  {
229 
230 #if defined (ONIXS_B3_BOE_CXX11)
231  static_assert(
232  noexcept(
233  Value(
234  std::declval<typename Value::MemberTraits::FirstArgType>()
235  )
236  ) ,
237  "must be noexcept");
238 #endif
239 
240  assert(location);
241 
242  return
243  Value(
244  extractValue<typename Value::MemberTraits::FirstArgType>(location)
245  );
246  }
247 };
248 
249 /// \private
250 template <>
251 struct CompositeExtractor<2>
252 {
253  template <class Value>
254  static
255  Value extract(const void* location) ONIXS_B3_BOE_NOTHROW
256  {
257  typedef typename Value::MemberTraits::FirstArgType FirstArgType;
258  typedef typename Value::MemberTraits::SecondArgType SecondArgType;
259 
260 #if defined (ONIXS_B3_BOE_CXX11)
261  static_assert(
262  noexcept(
263  Value(
264  std::declval<FirstArgType>(),
265  std::declval<SecondArgType>()
266  )
267  ) ,
268  "must be noexcept");
269 #endif
270 
271  assert(location);
272 
273  return
274  Value(
275  extractValue<FirstArgType>(location),
276  extractValue<SecondArgType>(
277  advanceByBytes(location, sizeof(FirstArgType)))
278  );
279  }
280 };
281 
282 /// \private
283 template <>
284 struct CompositeExtractor<4>
285 {
286  template <class Value>
287  static
288  Value extract(const void* location) ONIXS_B3_BOE_NOTHROW
289  {
290  typedef typename Value::MemberTraits::FirstArgType FirstArgType;
291  typedef typename Value::MemberTraits::SecondArgType SecondArgType;
292  typedef typename Value::MemberTraits::ThirdArgType ThirdArgType;
293  typedef typename Value::MemberTraits::FourthArgType FourthArgType;
294 
295 #if defined (ONIXS_B3_BOE_CXX11)
296  static_assert(
297  noexcept(
298  Value(
299  std::declval<FirstArgType>(),
300  std::declval<SecondArgType>(),
301  std::declval<ThirdArgType>(),
302  std::declval<FourthArgType>()
303  )
304  ) ,
305  "must be noexcept");
306 #endif
307 
308  assert(location);
309 
310  return
311  Value(
312  extractValue<FirstArgType>(location),
313  extractValue<SecondArgType>(
314  advanceByBytes(location, sizeof(FirstArgType))),
315  extractValue<ThirdArgType>(
316  advanceByBytes(location, sizeof(FirstArgType) + sizeof(SecondArgType))),
317  extractValue<FourthArgType>(
318  advanceByBytes(location, sizeof(FirstArgType) + sizeof(SecondArgType) + sizeof(ThirdArgType)))
319  );
320  }
321 };
322 
323 /// \private
324 template
325 <
326  class Value
327 >
329 typename EnableIf<details::HasMemberTraits<Value>::value, Value>::type
330 getValue(const void* location) ONIXS_B3_BOE_NOTHROW
331 {
332  assert(location);
333  return CompositeExtractor<Value::MemberTraits::Count>:: template extract<Value>(location);
334 }
335 
336 /// \private
337 template
338 <
339  class Value
340 >
342 typename EnableIf<!details::HasMemberTraits<Value>::value, Value>::type
343 getValue(const void* location) ONIXS_B3_BOE_NOTHROW
344 {
345  assert(location);
346  return extractValue<Value>(location);
347 }
348 
349 /// \private
350 template
351 <
352  class Value
353 >
355 typename EnableIf<!details::HasMemberTraits<Value>::value, size_t>::type
357 {
358  return sizeof(Value);
359 }
360 
361 /// \private
362 template
363 <
364  class Value
365 >
367 typename EnableIf<details::HasMemberTraits<Value>::value, size_t>::type
369 {
370  return Value::Size;
371 }
372 
373 /// \private
374 template
375 <
376  class Value
377 >
379 typename EnableIf<!details::HasSerializeMember<Value>::value>::type
380 commitValue(void* location, Value value)
382 {
383  assert(location);
384  std::memcpy(
385  location,
386  &value,
387  sizeof(Value));
388 }
389 
390 /// \private
391 template
392 <
393  class Value
394 >
396 typename EnableIf<details::HasSerializeMember<Value>::value>::type
397 commitValue(void* location, Value value)
399 {
400  assert(location);
401  value.serialize(location);
402 }
403 
404 /// \private
405 template
406 <
407  class Value
408 >
410 typename EnableIf<!details::HasValueStaticMember<Value>::value>::type
411 setValue(void* location, Value value)
413 {
414  assert(location);
415  commitValue(location, value);
416 }
417 
418 /// \private
419 template
420 <
421  class Value
422 >
424 typename EnableIf<details::HasValueStaticMember<Value>::value>::type
425 setValue(void* location, Value)
427 {
428  assert(location);
429  commitValue(location, Value::value());
430 }
431 
UInt64 QWord
Alias for Quad Word.
Definition: Memory.h:43
#define ONIXS_B3_BOE_MESSAGING_NAMESPACE_END
Definition: ABI.h:144
#define ONIXS_B3_BOE_NOTHROW
Definition: Compiler.h:182
#define ONIXS_B3_BOE_HOTPATH
Definition: Compiler.h:193
UInt32 DWord
Alias for Double Word.
Definition: Memory.h:40
#define ONIXS_B3_BOE_CONSTEXPR
Definition: Compiler.h:185
#define ONIXS_B3_BOE_MESSAGING_NAMESPACE_BEGIN
Definition: ABI.h:140
#define ONIXS_B3_BOE_PURE
Definition: Compiler.h:195
UInt8 Byte
Alias for Byte.
Definition: Memory.h:34
UInt16 Word
Alias for Word.
Definition: Memory.h:37