Ring Daemon 16.0.0
Loading...
Searching...
No Matches
vector_ref.h
Go to the documentation of this file.
1#pragma once
2
3#include <cstring>
4#include <cassert>
5#include <type_traits>
6#include <vector>
7#include <string>
8#include <atomic>
9
10#ifdef __INTEL_COMPILER
11#pragma warning(disable : 597) // will not be called for implicit or explicit conversions
12#endif
13
14namespace dev {
15
19template<class _T>
21{
22public:
23 using value_type = _T;
24 using element_type = _T;
25 using mutable_value_type = typename std::
26 conditional<std::is_const<_T>::value, typename std::remove_const<_T>::type, _T>::type;
27
28 static_assert(std::is_pod<value_type>::value,
29 "vector_ref can only be used with PODs due to its low-level treatment of data.");
30
32 : m_data(nullptr)
33 , m_count(0)
34 {}
36 vector_ref(_T* _data, size_t _count)
37 : m_data(_data)
38 , m_count(_count)
39 {}
42 typename std::conditional<std::is_const<_T>::value, std::string const*, std::string*>::type
43 _data)
44 : m_data(reinterpret_cast<_T*>(_data->data()))
45 , m_count(_data->size() / sizeof(_T))
46 {}
48 vector_ref(typename std::conditional<std::is_const<_T>::value,
49 std::vector<typename std::remove_const<_T>::type> const*,
50 std::vector<_T>*>::type _data)
51 : m_data(_data->data())
52 , m_count(_data->size())
53 {}
56 typename std::conditional<std::is_const<_T>::value, std::string const&, std::string&>::type
57 _data)
58 : m_data(reinterpret_cast<_T*>(_data.data()))
59 , m_count(_data.size() / sizeof(_T))
60 {}
61 explicit operator bool() const { return m_data && m_count; }
62
63 bool contentsEqual(std::vector<mutable_value_type> const& _c) const
64 {
65 if (!m_data || m_count == 0)
66 return _c.empty();
67 else
68 return _c.size() == m_count && !memcmp(_c.data(), m_data, m_count * sizeof(_T));
69 }
70 std::vector<mutable_value_type> toVector() const
71 {
72 return std::vector<mutable_value_type>(m_data, m_data + m_count);
73 }
74 std::vector<unsigned char> toBytes() const
75 {
76 return std::vector<unsigned char>(reinterpret_cast<unsigned char const*>(m_data),
77 reinterpret_cast<unsigned char const*>(m_data)
78 + m_count * sizeof(_T));
79 }
80 std::string toString() const
81 {
82 return std::string((char const*) m_data, ((char const*) m_data) + m_count * sizeof(_T));
83 }
84
85 template<class _T2>
86 explicit operator vector_ref<_T2>() const
87 {
88 assert(m_count * sizeof(_T) / sizeof(_T2) * sizeof(_T2) / sizeof(_T) == m_count);
89 return vector_ref<_T2>(reinterpret_cast<_T2*>(m_data), m_count * sizeof(_T) / sizeof(_T2));
90 }
91 operator vector_ref<_T const>() const { return vector_ref<_T const>(m_data, m_count); }
92
93 _T* data() const { return m_data; }
95 size_t count() const { return m_count; }
97 size_t size() const { return m_count; }
98 bool empty() const { return !m_count; }
101 {
102 if (!m_data)
103 return *this;
104 else
105 return vector_ref<_T>(m_data + m_count, m_count);
106 }
110 vector_ref<_T> cropped(size_t _begin, size_t _count) const
111 {
112 if (m_data && _begin <= m_count && _count <= m_count && _begin + _count <= m_count)
113 return vector_ref<_T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count);
114 else
115 return vector_ref<_T>();
116 }
118 vector_ref<_T> cropped(size_t _begin) const
119 {
120 if (m_data && _begin <= m_count)
121 return vector_ref<_T>(m_data + _begin, m_count - _begin);
122 else
123 return vector_ref<_T>();
124 }
125 void retarget(_T* _d, size_t _s)
126 {
127 m_data = _d;
128 m_count = _s;
129 }
130 void retarget(std::vector<_T> const& _t)
131 {
132 m_data = _t.data();
133 m_count = _t.size();
134 }
137 void cleanse()
138 {
139 static std::atomic<unsigned char> s_cleanseCounter {0u};
140 uint8_t* p = (uint8_t*) begin();
141 size_t const len = (uint8_t*) end() - p;
142 size_t loop = len;
143 size_t count = s_cleanseCounter;
144 while (loop--) {
145 *(p++) = (uint8_t) count;
146 count += (17 + ((size_t) p & 0xf));
147 }
148 p = (uint8_t*) memchr((uint8_t*) begin(), (uint8_t) count, len);
149 if (p)
150 count += (63 + (size_t) p);
151 s_cleanseCounter = (uint8_t) count;
152 memset((uint8_t*) begin(), 0, len);
153 }
154
155 _T* begin() { return m_data; }
156 _T* end() { return m_data + m_count; }
157 _T const* begin() const { return m_data; }
158 _T const* end() const { return m_data + m_count; }
159
160 _T& operator[](size_t _i)
161 {
162 assert(m_data);
163 assert(_i < m_count);
164 return m_data[_i];
165 }
166 _T const& operator[](size_t _i) const
167 {
168 assert(m_data);
169 assert(_i < m_count);
170 return m_data[_i];
171 }
172
173 bool operator==(vector_ref<_T> const& _cmp) const
174 {
175 return m_data == _cmp.m_data && m_count == _cmp.m_count;
176 }
177 bool operator!=(vector_ref<_T> const& _cmp) const { return !operator==(_cmp); }
178
179 void reset()
180 {
181 m_data = nullptr;
182 m_count = 0;
183 }
184
185private:
186 _T* m_data;
187 size_t m_count;
188};
189
190template<class _T>
191vector_ref<_T const>
192ref(_T const& _t)
193{
194 return vector_ref<_T const>(&_t, 1);
195}
196template<class _T>
197vector_ref<_T>
198ref(_T& _t)
199{
200 return vector_ref<_T>(&_t, 1);
201}
202template<class _T>
203vector_ref<_T const>
204ref(std::vector<_T> const& _t)
205{
206 return vector_ref<_T const>(&_t);
207}
208template<class _T>
209vector_ref<_T>
210ref(std::vector<_T>& _t)
211{
212 return vector_ref<_T>(&_t);
213}
214
215} // namespace dev
A modifiable reference to an existing object or vector in memory.
Definition vector_ref.h:21
size_t count() const
Definition vector_ref.h:95
void retarget(_T *_d, size_t _s)
Definition vector_ref.h:125
std::vector< mutable_value_type > toVector() const
Definition vector_ref.h:70
vector_ref< _T > next() const
Definition vector_ref.h:100
_T * data() const
Definition vector_ref.h:93
vector_ref(_T *_data, size_t _count)
Creates a new vector_ref to point to _count elements starting at _data.
Definition vector_ref.h:36
_T const * end() const
Definition vector_ref.h:158
_T const * begin() const
Definition vector_ref.h:157
std::vector< unsigned char > toBytes() const
Definition vector_ref.h:74
void cleanse()
Securely overwrite the memory.
Definition vector_ref.h:137
_T const & operator[](size_t _i) const
Definition vector_ref.h:166
typename std::conditional< std::is_const< _T >::value, typename std::remove_const< _T >::type, _T >::type mutable_value_type
Definition vector_ref.h:26
bool operator!=(vector_ref< _T > const &_cmp) const
Definition vector_ref.h:177
bool operator==(vector_ref< _T > const &_cmp) const
Definition vector_ref.h:173
vector_ref(typename std::conditional< std::is_const< _T >::value, std::string const *, std::string * >::type _data)
Creates a new vector_ref pointing to the data part of a string (given as pointer).
Definition vector_ref.h:41
bool contentsEqual(std::vector< mutable_value_type > const &_c) const
Definition vector_ref.h:63
size_t size() const
Definition vector_ref.h:97
_T & operator[](size_t _i)
Definition vector_ref.h:160
vector_ref< _T > cropped(size_t _begin) const
Definition vector_ref.h:118
vector_ref(typename std::conditional< std::is_const< _T >::value, std::string const &, std::string & >::type _data)
Creates a new vector_ref pointing to the data part of a string (given as reference).
Definition vector_ref.h:55
vector_ref(typename std::conditional< std::is_const< _T >::value, std::vector< typename std::remove_const< _T >::type > const *, std::vector< _T > * >::type _data)
Creates a new vector_ref pointing to the data part of a vector (given as pointer).
Definition vector_ref.h:48
std::string toString() const
Definition vector_ref.h:80
bool empty() const
Definition vector_ref.h:98
vector_ref< _T > cropped(size_t _begin, size_t _count) const
Definition vector_ref.h:110
void retarget(std::vector< _T > const &_t)
Definition vector_ref.h:130
Definition Address.h:25
vector_ref< _T const > ref(_T const &_t)
Definition vector_ref.h:192