OnixS C++ CME MDP Premium Market Data Handler 5.11.1
Users' manual and API documentation
Loading...
Searching...
No Matches
ByteSpan.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 protected by copyright law
4// and international copyright treaties.
5//
6// Access to and use of the software is governed by the terms of the applicable OnixS Software
7// Services Agreement (the Agreement) and Customer end user license agreements granting
8// a non-assignable, non-transferable and non-exclusive license to use the software
9// for it's own data processing purposes under the terms defined in the Agreement.
10//
11// Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
12// of this source code or associated reference material to any other location for further reproduction
13// or redistribution, and any amendments to this copyright notice, are expressly prohibited.
14//
15// Any reproduction or redistribution for sale or hiring of the Software not in accordance with
16// the terms of the Agreement is a violation of copyright law.
17//
18#pragma once
19
20#include <OnixS/CME/MDH/ABI.h>
21
22#if defined(ONIXS_CMEMDH_CXX20)
23#include <span>
24#endif
25
26#include <array>
27#include <cassert>
28#include <cstddef>
29#include <cstdint>
30#include <iterator>
31#include <string>
32#include <type_traits>
33#include <utility>
34
36
37#if defined(ONIXS_CMEMDH_CXX20)
38
44using ByteSpan = std::span<const std::uint8_t>;
45
46#else
47
48namespace ByteSpanDetails {
49
50template <class Value>
51constexpr Value* toAddress(Value* value) noexcept
52{
53 return value;
54}
55
56template <class Iterator>
57auto toAddress(const Iterator& value) noexcept(noexcept(value.operator->()))
58 -> decltype(value.operator->())
59{
60 return value.operator->();
61}
62
63} // namespace ByteSpanDetails
64
71class ByteSpan
72{
73public:
75 using element_type = const std::uint8_t;
76
78 using value_type = typename std::remove_cv<element_type>::type;
79
81 using size_type = std::size_t;
82
84 using difference_type = std::ptrdiff_t;
85
87 using pointer = element_type*;
88
90 using const_pointer = const element_type*;
91
93 using reference = element_type&;
94
96 using const_reference = const element_type&;
97
99 using iterator = pointer;
100
102 using reverse_iterator = std::reverse_iterator<iterator>;
103
104 enum : size_type
105 {
107 extent = static_cast<size_type>(-1)
108 };
109
111 constexpr ByteSpan() noexcept
112 : data_(nullptr)
113 , size_(0)
114 {
115 }
116
123 template <
124 class Data,
125 typename std::enable_if<
126 std::is_pointer<Data>::value && std::is_convertible<Data, pointer>::value,
127 int
128 >::type = 0
129 >
130 constexpr ByteSpan(Data data, size_type size) noexcept
131 : data_(static_cast<pointer>(data))
132 , size_(size)
133 {
134 }
135
143 template <
144 class First,
145 class End,
146 typename std::enable_if<
147 std::is_pointer<First>::value && std::is_convertible<First, pointer>::value &&
148 std::is_pointer<End>::value && std::is_convertible<End, pointer>::value,
149 int
150 >::type = 0
151 >
152 constexpr ByteSpan(First first, End last) noexcept
153 : data_(static_cast<pointer>(first))
154 , size_(first == nullptr
155 ? 0
156 : static_cast<size_type>(static_cast<pointer>(last) - static_cast<pointer>(first)))
157 {
158 }
159
167 template <
168 class Iterator,
169 typename std::enable_if<
170 !std::is_pointer<Iterator>::value &&
171 std::is_convertible<
172 decltype(ByteSpanDetails::toAddress(std::declval<const Iterator&>())),
173 pointer
174 >::value,
175 int
176 >::type = 0
177 >
178 ByteSpan(Iterator first, size_type size) noexcept(noexcept(ByteSpanDetails::toAddress(first)))
179 : data_(size == 0 ? nullptr : static_cast<pointer>(ByteSpanDetails::toAddress(first)))
180 , size_(size)
181 {
182 }
183
192 template <
193 class Iterator,
194 class End,
195 typename std::enable_if<
196 !std::is_pointer<Iterator>::value &&
197 std::is_convertible<
198 decltype(ByteSpanDetails::toAddress(std::declval<const Iterator&>())),
199 pointer
200 >::value &&
201 std::is_convertible<
202 decltype(std::declval<End>() - std::declval<Iterator>()),
203 difference_type
204 >::value,
205 int
206 >::type = 0
207 >
208 ByteSpan(Iterator first, End last)
209 noexcept(noexcept(ByteSpanDetails::toAddress(first)) && noexcept(last - first))
210 : data_(nullptr)
211 , size_(static_cast<size_type>(last - first))
212 {
213 if (size_ != 0)
214 {
215 data_ = static_cast<pointer>(ByteSpanDetails::toAddress(first));
216 }
217 }
218
223 template <size_type Count>
224 constexpr ByteSpan(const value_type (&array)[Count]) noexcept
225 : data_(array)
226 , size_(Count)
227 {
228 }
229
234 template <size_type Count>
235 ByteSpan(const std::array<value_type, Count>& array) noexcept
236 : data_(array.data())
237 , size_(Count)
238 {
239 }
240
247 template <
248 class Range,
249 typename std::enable_if<
250 !std::is_same<typename std::decay<Range>::type, ByteSpan>::value &&
251 std::is_convertible<
252 decltype(std::declval<Range>().data()),
253 pointer
254 >::value &&
255 std::is_convertible<
256 decltype(std::declval<Range>().size()),
257 size_type
258 >::value,
259 int
260 >::type = 0
261 >
262 ByteSpan(Range&& range)
263 noexcept(
264 noexcept(std::forward<Range>(range).data()) &&
265 noexcept(std::forward<Range>(range).size()))
266 : data_(static_cast<pointer>(std::forward<Range>(range).data()))
267 , size_(static_cast<size_type>(std::forward<Range>(range).size()))
268 {
269 }
270
273 constexpr iterator begin() const noexcept
274 {
275 return data_;
276 }
277
280 constexpr iterator end() const noexcept
281 {
282 return pointerAt(size_);
283 }
284
287 reverse_iterator rbegin() const noexcept
288 {
289 return reverse_iterator(end());
290 }
291
294 reverse_iterator rend() const noexcept
295 {
296 return reverse_iterator(begin());
297 }
298
303 constexpr reference operator[](size_type index) const noexcept
304 {
305 return data_[index];
306 }
307
311 reference front() const noexcept
312 {
313 assert(!empty());
314 return data_[0];
315 }
316
320 reference back() const noexcept
321 {
322 assert(!empty());
323 return data_[size_ - 1];
324 }
325
329 constexpr pointer data() const noexcept
330 {
331 return data_;
332 }
333
336 constexpr size_type size() const noexcept
337 {
338 return size_;
339 }
340
343 constexpr size_type size_bytes() const noexcept
344 {
345 return size_ * sizeof(element_type);
346 }
347
350 constexpr bool empty() const noexcept
351 {
352 return size_ == 0;
353 }
354
359 template <size_type Count>
360 ByteSpan first() const noexcept
361 {
362 assert(Count <= size_);
363 return ByteSpan(data_, Count);
364 }
365
370 ByteSpan first(size_type count) const noexcept
371 {
372 assert(count <= size_);
373 return ByteSpan(data_, count);
374 }
375
380 template <size_type Count>
381 ByteSpan last() const noexcept
382 {
383 assert(Count <= size_);
384 return ByteSpan(pointerAt(size_ - Count), Count);
385 }
386
391 ByteSpan last(size_type count) const noexcept
392 {
393 assert(count <= size_);
394 return ByteSpan(pointerAt(size_ - count), count);
395 }
396
402 template <size_type Offset, size_type Count = extent>
403 ByteSpan subspan() const noexcept
404 {
405 assert(Offset <= size_);
406 const size_type count = Count == extent ? size_ - Offset : Count;
407 assert(count <= size_ - Offset);
408 return ByteSpan(pointerAt(Offset), count);
409 }
410
416 ByteSpan subspan(size_type offset, size_type count = extent) const noexcept
417 {
418 assert(offset <= size_);
419 const size_type actualCount = count == extent ? size_ - offset : count;
420 assert(actualCount <= size_ - offset);
421 return ByteSpan(pointerAt(offset), actualCount);
422 }
423
424private:
425 constexpr pointer pointerAt(size_type offset) const noexcept
426 {
427 return data_ == nullptr ? nullptr : data_ + offset;
428 }
429
430 pointer data_;
431 size_type size_;
432};
433
434#endif
435
440void toStr(std::string& str, ByteSpan span);
441
445inline std::string toStr(ByteSpan span)
446{
447 std::string str;
448
449 toStr(str, span);
450
451 return str;
452}
453
460void toStr(std::string& str, const ByteSpan spans[], size_t spansCount);
461
467inline std::string toStr(const ByteSpan spans[], size_t spansCount)
468{
469 std::string str;
470
471 toStr(str, spans, spansCount);
472
473 return str;
474}
475
#define ONIXS_CME_MDH_TESTING_NAMESPACE_END
Definition Bootstrap.h:84
#define ONIXS_CME_MDH_TESTING_NAMESPACE_BEGIN
Definition Bootstrap.h:83
#define ONIXS_CMEMDH_EXPORTED
Definition Compiler.h:163
void toStr(std::string &str, const MessageHolder< MessageType, MaxMessageSize > &holder)
Appends the holder's capacity, prefix, and message to a string.
std::span< const std::uint8_t > ByteSpan
Provides a non-owning read-only view over contiguous byte storage.
Definition ByteSpan.h:44