-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbyte_vector.hpp
84 lines (74 loc) · 2.25 KB
/
byte_vector.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#pragma once
#include <vector>
#include <cstdint>
// using byte_vector = std::vector<uint8_t>;
struct byte_vector : std::vector<uint8_t> {
using strsize_t = uint16_t;
// using std::vector<uint8_t>::std::vector<uint8_t>;
};
template<typename T>
inline auto operator<<(byte_vector&bv, T const& v) ->std::enable_if_t<std::is_integral_v<T>, byte_vector& >
{
static_assert(std::is_integral_v<T>,"operator<<(byte_vector&,T) implemented for integral types only");
//ToDo C++20 if constexpr (std::endian::native == std::endian::little)
#if BYTE_ORDER == LITTLE_ENDIAN
std::reverse_iterator<uint8_t*> first{(uint8_t *) (&v + 1)}, last{(uint8_t *) (&v)};
#else
uint8_t *first=(uint8_t*)&v, *last=(uint8_t*)(&v+1);
#endif
bv.insert(end(bv), first, last);
return bv;
}
inline auto operator<<(byte_vector&vec, byte_vector const& bv) ->byte_vector&
{
vec.insert(vec.end(), bv.begin(), bv.end());
return vec;
}
#include <string_view>
inline auto operator<<(byte_vector&vec, std::string_view const& sv) ->byte_vector&
{
vec<<byte_vector::strsize_t(sv.size());
vec.insert(vec.end(), sv.begin(), sv.end()); // Alternative way: vec.reserve(vec.size()+sv.size()); for(auto&c:sv) vec<<c;
return vec;
}
inline auto operator<<(byte_vector&vec, char const* str) ->byte_vector&
{
//ToDo optimization wanted
// while(*str!='\0')
// vec<<*str++;
// return vec;
return vec<<std::string_view(str);
}
template<size_t N>
inline auto operator<<(byte_vector&vec, char const str[N]) ->byte_vector&
{
return vec<<std::string_view(str,N-1);
}
#include <optional>
template<typename T>
inline auto operator<<(byte_vector&vec, std::optional<T> const& arg) ->byte_vector&
{
if(arg)
vec << *arg;
return vec;
//return arg ? vec << arg->value : vec;
}
#include <tuple>
template<typename... Ts>
inline auto operator<<(byte_vector&vec, std::tuple<Ts...> const& theTuple) ->byte_vector&
{
std::apply(
[&](Ts const &... tupleArgs) {
((vec << tupleArgs), ...);
}, theTuple
);
return vec;
}
#if 0
#include <iostream>
#include "byte_range_ascii.hpp"
template <typename T>
std::basic_ostream<T>& operator<<(std::basic_ostream<T> &os, byte_vector const& bv){
return os << byte_range_ascii(bv);
}
#endif