6 #ifndef ZEROBUF_VECTOR_H 7 #define ZEROBUF_VECTOR_H 9 #include <zerobuf/DynamicSubAllocator.h> 10 #include <zerobuf/Zerobuf.h> 11 #include <zerobuf/json.h> 30 class Iterator :
public std::iterator<std::forward_iterator_tag, U>
33 Iterator(U& vector,
const size_t index)
39 bool operator==(
const Iterator& rhs)
const 41 return _index == rhs._index;
43 bool operator!=(
const Iterator& rhs)
const 45 return _index != rhs._index;
54 const typename U::element_type& operator*()
const 56 return _vector[_index];
59 template <
class Q = U,
typename =
typename std::enable_if<
60 !std::is_const<Q>::value>::type>
61 typename U::element_type& operator*()
63 return _vector[_index];
71 using element_type = T;
82 bool empty()
const {
return _getSize() == 0; }
84 uint64_t
size()
const {
return _getSize() / _getElementSize<T>(); }
89 T*
data() {
return _alloc->template getDynamic<T>(_index); }
93 return const_cast<const Allocator*
>(_alloc)->
template getDynamic<T>(
101 bool operator==(
const Vector& rhs)
const;
103 bool operator!=(
const Vector& rhs)
const;
118 template <
class Q = T>
119 const typename std::enable_if<!std::is_base_of<Zerobuf, Q>::value, Q>::type&
123 template <
class Q = T>
124 typename std::enable_if<!std::is_base_of<Zerobuf, Q>::value, Q>::type&
128 template <
class Q = T>
129 const typename std::enable_if<std::is_base_of<Zerobuf, Q>::value, Q>::type&
133 template <
class Q = T>
134 typename std::enable_if<std::is_base_of<Zerobuf, Q>::value, Q>::type&
138 template <
class Q = T>
139 void push_back(
const typename std::enable_if<
140 !std::is_base_of<Zerobuf, Q>::value, Q>::type&);
143 template <
class Q = T>
144 void push_back(
const typename std::enable_if<
145 std::is_base_of<Zerobuf, Q>::value, Q>::type&);
158 template <
class Q = T>
159 void fromJSON(
const Json::Value& json,
160 const typename std::enable_if<
161 std::is_base_of<Zerobuf, Q>::value, Q>::type* =
nullptr);
164 template <
class Q = T>
165 void fromJSON(
const Json::Value& json,
166 const typename std::enable_if<std::is_enum<Q>::value,
167 Q>::type* =
nullptr);
170 template <
class Q = T>
171 void fromJSON(
const Json::Value& json,
172 const typename std::enable_if<std::is_arithmetic<Q>::value,
173 Q>::type* =
nullptr);
176 template <
class Q = T>
178 const Json::Value& json,
179 const typename std::enable_if<std::is_same<Q, servus::uint128_t>::value,
180 Q>::type* =
nullptr);
183 template <
class Q = T>
186 const typename std::enable_if<std::is_base_of<Zerobuf, Q>::value,
187 Q>::type* =
nullptr)
const;
190 template <
class Q = T>
191 void toJSON(Json::Value& json,
192 const typename std::enable_if<std::is_enum<Q>::value,
193 Q>::type* =
nullptr)
const;
196 template <
class Q = T>
197 void toJSON(Json::Value& json,
198 const typename std::enable_if<std::is_arithmetic<Q>::value,
199 Q>::type* =
nullptr)
const;
202 template <
class Q = T>
205 const typename std::enable_if<std::is_same<Q, servus::uint128_t>::value,
206 Q>::type* =
nullptr)
const;
209 template <
class Q = T>
211 const typename std::enable_if<std::is_pod<Q>::value,
212 Q>::type* =
nullptr);
215 template <
class Q = T>
217 const typename std::enable_if<std::is_pod<Q>::value,
218 Q>::type* =
nullptr)
const;
223 mutable std::vector<T> _zerobufs;
229 size_t _getSize()
const {
return _alloc->getDynamicSize(_index); }
230 void copyBuffer(uint8_t*
data,
size_t size);
232 template <
class Q = T>
233 size_t _getElementSize(
234 typename std::enable_if<std::is_base_of<Zerobuf, Q>::value, Q>::type* =
237 return Q::ZEROBUF_STATIC_SIZE();
240 template <
class Q = T>
241 size_t _getElementSize(
242 typename std::enable_if<!std::is_base_of<Zerobuf, Q>::value, Q>::type* =
260 _alloc->updateAllocation(_index,
false, 0);
267 _alloc->updateAllocation(_index,
true ,
268 size_ * _getElementSize<T>());
300 const size_t size_ = _getSize();
301 if (size_ != rhs._getSize())
308 return ::memcmp(static_cast<const void*>(
data()),
309 static_cast<const void*>(rhs.data()), size_) == 0;
315 return !(operator==(rhs));
320 inline const typename std::enable_if<!std::is_base_of<Zerobuf, Q>::value,
325 throw std::runtime_error(
"Vector out of bounds read");
327 return data()[index];
332 inline typename std::enable_if<!std::is_base_of<Zerobuf, Q>::value, Q>::type&
336 throw std::runtime_error(
"Vector out of bounds read");
338 return data()[index];
343 inline const typename std::enable_if<std::is_base_of<Zerobuf, Q>::value,
348 throw std::runtime_error(
"Vector out of bounds read");
350 while (_zerobufs.size() < index + 1)
351 _zerobufs.emplace_back(AllocatorPtr(
353 _getElementSize<T>())));
354 return _zerobufs[index];
359 inline typename std::enable_if<std::is_base_of<Zerobuf, Q>::value, Q>::type&
363 throw std::runtime_error(
"Vector out of bounds read");
365 while (_zerobufs.size() < index + 1)
366 _zerobufs.emplace_back(AllocatorPtr(
368 _getElementSize<T>())));
369 return _zerobufs[index];
375 const typename std::enable_if<!std::is_base_of<Zerobuf, Q>::value, Q>::type&
378 const size_t size_ = _getSize();
379 T* newPtr =
reinterpret_cast<T*
>(
380 _alloc->updateAllocation(_index,
true , size_ +
sizeof(T)));
381 newPtr[size_ / _getElementSize<T>()] = value;
387 const typename std::enable_if<std::is_base_of<Zerobuf, Q>::value, Q>::type&
390 const size_t size_ = _getSize();
391 const zerobuf::Data&
zerobuf = value.toBinary();
393 _alloc->updateAllocation(_index,
true , size_ + zerobuf.size);
394 ::memcpy(newPtr + size_, zerobuf.ptr.get(), zerobuf.size);
400 const Json::Value& json,
401 const typename std::enable_if<std::is_base_of<Zerobuf, Q>::value, Q>::type*)
403 const size_t size_ = getJSONSize(json);
404 _alloc->updateAllocation(_index,
false, size_ * _getElementSize<T>());
405 for (
size_t i = 0; i < size_; ++i)
406 zerobuf::fromJSON(getJSONField(json, i), (*
this)[i]);
412 const Json::Value& json,
413 const typename std::enable_if<std::is_enum<Q>::value, Q>::type*)
415 const size_t size_ = getJSONSize(json);
416 T* array =
reinterpret_cast<T*
>(
417 _alloc->updateAllocation(_index,
false , size_ *
sizeof(T)));
419 for (
size_t i = 0; i < size_; ++i)
420 array[i] = string_to_enum<T>(
421 zerobuf::fromJSON<std::string>(getJSONField(json, i)));
427 const Json::Value& json,
428 const typename std::enable_if<std::is_arithmetic<Q>::value, Q>::type*)
430 const size_t size_ = getJSONSize(json);
431 T* array =
reinterpret_cast<T*
>(
432 _alloc->updateAllocation(_index,
false , size_ *
sizeof(T)));
434 for (
size_t i = 0; i < size_; ++i)
435 array[i] = zerobuf::fromJSON<T>(getJSONField(json, i));
441 const Json::Value& json,
442 const typename std::enable_if<std::is_same<Q, servus::uint128_t>::value,
445 const size_t size_ = getJSONSize(json);
446 T* array =
reinterpret_cast<T*
>(
447 _alloc->updateAllocation(_index,
false , size_ *
sizeof(T)));
449 for (
size_t i = 0; i < size_; ++i)
450 array[i] = zerobuf::fromJSON<T>(getJSONField(json, i));
457 const typename std::enable_if<std::is_base_of<Zerobuf, Q>::value, Q>::type*)
460 const size_t size_ =
size();
461 zerobuf::emptyJSONArray(
463 for (
size_t i = 0; i < size_; ++i)
464 zerobuf::toJSON(static_cast<const Zerobuf&>((*
this)[i]),
465 getJSONField(json, i));
472 const typename std::enable_if<std::is_enum<Q>::value, Q>::type*)
const 474 const size_t size_ =
size();
475 zerobuf::emptyJSONArray(
477 for (
size_t i = 0; i < size_; ++i)
478 zerobuf::toJSON(enum_to_string<T>((*
this)[i]), getJSONField(json, i));
485 const typename std::enable_if<std::is_arithmetic<Q>::value, Q>::type*)
const 487 const size_t size_ =
size();
488 zerobuf::emptyJSONArray(
490 for (
size_t i = 0; i < size_; ++i)
491 zerobuf::toJSON((*
this)[i], getJSONField(json, i));
498 const typename std::enable_if<std::is_same<Q, servus::uint128_t>::value,
501 const size_t size_ =
size();
502 zerobuf::emptyJSONArray(
504 for (
size_t i = 0; i < size_; ++i)
505 zerobuf::toJSON((*
this)[i], getJSONField(json, i));
511 const Json::Value& json,
512 const typename std::enable_if<std::is_pod<Q>::value, Q>::type*)
514 const std::string& decoded = zerobuf::fromJSONBinary(json);
515 copyBuffer((uint8_t*)decoded.data(), decoded.length());
522 const typename std::enable_if<std::is_pod<Q>::value, Q>::type*)
const 524 zerobuf::toJSONBinary(
data(), _getSize(), json);
530 void* to = _alloc->updateAllocation(_index,
false , size_);
531 ::memcpy(to, data_, size_);
535 inline std::ostream& operator<<(std::ostream& os, const Vector<T>& vector)
537 return os <<
typeid(vector).name() <<
" of size " << vector.size();
541 inline std::ostream& operator<<(std::ostream& os, const Vector<char>& string)
543 return os <<
string.data();
void compact(float)
Remove unused memory from vector and all members.
const_iterator end() const
bool operator==(const Vector &rhs) const
bool operator!=(const Vector &rhs) const
void fromJSON(const Json::Value &json, const typename std::enable_if< std::is_base_of< Zerobuf, Q >::value, Q >::type *=nullptr)
Update this vector of ZeroBufs from its JSON representation.
void resize(size_t size)
Resize the vector to new size; keeps elements untouched.
Zero-copy, zero-serialize, zero-hassle protocol buffers.
const_iterator begin() const
Forward iterator for Vector< T >
const std::enable_if<!std::is_base_of< Zerobuf, Q >::value, Q >::type & operator[](const size_t index) const
void push_back(const typename std::enable_if< !std::is_base_of< Zerobuf, Q >::value, Q >::type &)
Insert a builtin element at the end of the vector.
void fromJSONBinary(const Json::Value &json, const typename std::enable_if< std::is_pod< Q >::value, Q >::type *=nullptr)
Update this vector from its JSON, base64-encoded representation.
void toJSONBinary(Json::Value &json, const typename std::enable_if< std::is_pod< Q >::value, Q >::type *=nullptr) const
Allocator base class and interface.
void clear()
Empty the vector.
A zerobuf child allocator which manages a dynamic allocation of statically-sized members.
void toJSON(Json::Value &json, const typename std::enable_if< std::is_base_of< Zerobuf, Q >::value, Q >::type *=nullptr) const
STL-like vector abstraction for dynamic arrays in a zerobuf.