vector.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. /*
  2. * Copyright 2021 Google Inc. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #ifndef FLATBUFFERS_VECTOR_H_
  17. #define FLATBUFFERS_VECTOR_H_
  18. #include "flatbuffers/base.h"
  19. #include "flatbuffers/buffer.h"
  20. #include "flatbuffers/stl_emulation.h"
  21. namespace flatbuffers {
  22. struct String;
  23. // An STL compatible iterator implementation for Vector below, effectively
  24. // calling Get() for every element.
  25. template<typename T, typename IT> struct VectorIterator {
  26. typedef std::random_access_iterator_tag iterator_category;
  27. typedef IT value_type;
  28. typedef ptrdiff_t difference_type;
  29. typedef IT *pointer;
  30. typedef IT &reference;
  31. VectorIterator(const uint8_t *data, uoffset_t i)
  32. : data_(data + IndirectHelper<T>::element_stride * i) {}
  33. VectorIterator(const VectorIterator &other) : data_(other.data_) {}
  34. VectorIterator() : data_(nullptr) {}
  35. VectorIterator &operator=(const VectorIterator &other) {
  36. data_ = other.data_;
  37. return *this;
  38. }
  39. VectorIterator &operator=(VectorIterator &&other) {
  40. data_ = other.data_;
  41. return *this;
  42. }
  43. bool operator==(const VectorIterator &other) const {
  44. return data_ == other.data_;
  45. }
  46. bool operator<(const VectorIterator &other) const {
  47. return data_ < other.data_;
  48. }
  49. bool operator!=(const VectorIterator &other) const {
  50. return data_ != other.data_;
  51. }
  52. difference_type operator-(const VectorIterator &other) const {
  53. return (data_ - other.data_) / IndirectHelper<T>::element_stride;
  54. }
  55. // Note: return type is incompatible with the standard
  56. // `reference operator*()`.
  57. IT operator*() const { return IndirectHelper<T>::Read(data_, 0); }
  58. // Note: return type is incompatible with the standard
  59. // `pointer operator->()`.
  60. IT operator->() const { return IndirectHelper<T>::Read(data_, 0); }
  61. VectorIterator &operator++() {
  62. data_ += IndirectHelper<T>::element_stride;
  63. return *this;
  64. }
  65. VectorIterator operator++(int) {
  66. VectorIterator temp(data_, 0);
  67. data_ += IndirectHelper<T>::element_stride;
  68. return temp;
  69. }
  70. VectorIterator operator+(const uoffset_t &offset) const {
  71. return VectorIterator(data_ + offset * IndirectHelper<T>::element_stride,
  72. 0);
  73. }
  74. VectorIterator &operator+=(const uoffset_t &offset) {
  75. data_ += offset * IndirectHelper<T>::element_stride;
  76. return *this;
  77. }
  78. VectorIterator &operator--() {
  79. data_ -= IndirectHelper<T>::element_stride;
  80. return *this;
  81. }
  82. VectorIterator operator--(int) {
  83. VectorIterator temp(data_, 0);
  84. data_ -= IndirectHelper<T>::element_stride;
  85. return temp;
  86. }
  87. VectorIterator operator-(const uoffset_t &offset) const {
  88. return VectorIterator(data_ - offset * IndirectHelper<T>::element_stride,
  89. 0);
  90. }
  91. VectorIterator &operator-=(const uoffset_t &offset) {
  92. data_ -= offset * IndirectHelper<T>::element_stride;
  93. return *this;
  94. }
  95. private:
  96. const uint8_t *data_;
  97. };
  98. template<typename Iterator>
  99. struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
  100. explicit VectorReverseIterator(Iterator iter)
  101. : std::reverse_iterator<Iterator>(iter) {}
  102. // Note: return type is incompatible with the standard
  103. // `reference operator*()`.
  104. typename Iterator::value_type operator*() const {
  105. auto tmp = std::reverse_iterator<Iterator>::current;
  106. return *--tmp;
  107. }
  108. // Note: return type is incompatible with the standard
  109. // `pointer operator->()`.
  110. typename Iterator::value_type operator->() const {
  111. auto tmp = std::reverse_iterator<Iterator>::current;
  112. return *--tmp;
  113. }
  114. };
  115. // This is used as a helper type for accessing vectors.
  116. // Vector::data() assumes the vector elements start after the length field.
  117. template<typename T> class Vector {
  118. public:
  119. typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type>
  120. iterator;
  121. typedef VectorIterator<T, typename IndirectHelper<T>::return_type>
  122. const_iterator;
  123. typedef VectorReverseIterator<iterator> reverse_iterator;
  124. typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
  125. typedef typename flatbuffers::bool_constant<flatbuffers::is_scalar<T>::value>
  126. scalar_tag;
  127. static FLATBUFFERS_CONSTEXPR bool is_span_observable =
  128. scalar_tag::value && (FLATBUFFERS_LITTLEENDIAN || sizeof(T) == 1);
  129. uoffset_t size() const { return EndianScalar(length_); }
  130. // Deprecated: use size(). Here for backwards compatibility.
  131. FLATBUFFERS_ATTRIBUTE([[deprecated("use size() instead")]])
  132. uoffset_t Length() const { return size(); }
  133. typedef typename IndirectHelper<T>::return_type return_type;
  134. typedef typename IndirectHelper<T>::mutable_return_type mutable_return_type;
  135. typedef return_type value_type;
  136. return_type Get(uoffset_t i) const {
  137. FLATBUFFERS_ASSERT(i < size());
  138. return IndirectHelper<T>::Read(Data(), i);
  139. }
  140. return_type operator[](uoffset_t i) const { return Get(i); }
  141. // If this is a Vector of enums, T will be its storage type, not the enum
  142. // type. This function makes it convenient to retrieve value with enum
  143. // type E.
  144. template<typename E> E GetEnum(uoffset_t i) const {
  145. return static_cast<E>(Get(i));
  146. }
  147. // If this a vector of unions, this does the cast for you. There's no check
  148. // to make sure this is the right type!
  149. template<typename U> const U *GetAs(uoffset_t i) const {
  150. return reinterpret_cast<const U *>(Get(i));
  151. }
  152. // If this a vector of unions, this does the cast for you. There's no check
  153. // to make sure this is actually a string!
  154. const String *GetAsString(uoffset_t i) const {
  155. return reinterpret_cast<const String *>(Get(i));
  156. }
  157. const void *GetStructFromOffset(size_t o) const {
  158. return reinterpret_cast<const void *>(Data() + o);
  159. }
  160. iterator begin() { return iterator(Data(), 0); }
  161. const_iterator begin() const { return const_iterator(Data(), 0); }
  162. iterator end() { return iterator(Data(), size()); }
  163. const_iterator end() const { return const_iterator(Data(), size()); }
  164. reverse_iterator rbegin() { return reverse_iterator(end()); }
  165. const_reverse_iterator rbegin() const {
  166. return const_reverse_iterator(end());
  167. }
  168. reverse_iterator rend() { return reverse_iterator(begin()); }
  169. const_reverse_iterator rend() const {
  170. return const_reverse_iterator(begin());
  171. }
  172. const_iterator cbegin() const { return begin(); }
  173. const_iterator cend() const { return end(); }
  174. const_reverse_iterator crbegin() const { return rbegin(); }
  175. const_reverse_iterator crend() const { return rend(); }
  176. // Change elements if you have a non-const pointer to this object.
  177. // Scalars only. See reflection.h, and the documentation.
  178. void Mutate(uoffset_t i, const T &val) {
  179. FLATBUFFERS_ASSERT(i < size());
  180. WriteScalar(data() + i, val);
  181. }
  182. // Change an element of a vector of tables (or strings).
  183. // "val" points to the new table/string, as you can obtain from
  184. // e.g. reflection::AddFlatBuffer().
  185. void MutateOffset(uoffset_t i, const uint8_t *val) {
  186. FLATBUFFERS_ASSERT(i < size());
  187. static_assert(sizeof(T) == sizeof(uoffset_t), "Unrelated types");
  188. WriteScalar(data() + i,
  189. static_cast<uoffset_t>(val - (Data() + i * sizeof(uoffset_t))));
  190. }
  191. // Get a mutable pointer to tables/strings inside this vector.
  192. mutable_return_type GetMutableObject(uoffset_t i) const {
  193. FLATBUFFERS_ASSERT(i < size());
  194. return const_cast<mutable_return_type>(IndirectHelper<T>::Read(Data(), i));
  195. }
  196. // The raw data in little endian format. Use with care.
  197. const uint8_t *Data() const {
  198. return reinterpret_cast<const uint8_t *>(&length_ + 1);
  199. }
  200. uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
  201. // Similarly, but typed, much like std::vector::data
  202. const T *data() const { return reinterpret_cast<const T *>(Data()); }
  203. T *data() { return reinterpret_cast<T *>(Data()); }
  204. template<typename K> return_type LookupByKey(K key) const {
  205. void *search_result = std::bsearch(
  206. &key, Data(), size(), IndirectHelper<T>::element_stride, KeyCompare<K>);
  207. if (!search_result) {
  208. return nullptr; // Key not found.
  209. }
  210. const uint8_t *element = reinterpret_cast<const uint8_t *>(search_result);
  211. return IndirectHelper<T>::Read(element, 0);
  212. }
  213. template<typename K> mutable_return_type MutableLookupByKey(K key) {
  214. return const_cast<mutable_return_type>(LookupByKey(key));
  215. }
  216. protected:
  217. // This class is only used to access pre-existing data. Don't ever
  218. // try to construct these manually.
  219. Vector();
  220. uoffset_t length_;
  221. private:
  222. // This class is a pointer. Copying will therefore create an invalid object.
  223. // Private and unimplemented copy constructor.
  224. Vector(const Vector &);
  225. Vector &operator=(const Vector &);
  226. template<typename K> static int KeyCompare(const void *ap, const void *bp) {
  227. const K *key = reinterpret_cast<const K *>(ap);
  228. const uint8_t *data = reinterpret_cast<const uint8_t *>(bp);
  229. auto table = IndirectHelper<T>::Read(data, 0);
  230. // std::bsearch compares with the operands transposed, so we negate the
  231. // result here.
  232. return -table->KeyCompareWithValue(*key);
  233. }
  234. };
  235. template<class U>
  236. FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U> &vec)
  237. FLATBUFFERS_NOEXCEPT {
  238. static_assert(Vector<U>::is_span_observable,
  239. "wrong type U, only LE-scalar, or byte types are allowed");
  240. return span<U>(vec.data(), vec.size());
  241. }
  242. template<class U>
  243. FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
  244. const Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
  245. static_assert(Vector<U>::is_span_observable,
  246. "wrong type U, only LE-scalar, or byte types are allowed");
  247. return span<const U>(vec.data(), vec.size());
  248. }
  249. template<class U>
  250. FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<uint8_t> make_bytes_span(
  251. Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
  252. static_assert(Vector<U>::scalar_tag::value,
  253. "wrong type U, only LE-scalar, or byte types are allowed");
  254. return span<uint8_t>(vec.Data(), vec.size() * sizeof(U));
  255. }
  256. template<class U>
  257. FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t> make_bytes_span(
  258. const Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
  259. static_assert(Vector<U>::scalar_tag::value,
  260. "wrong type U, only LE-scalar, or byte types are allowed");
  261. return span<const uint8_t>(vec.Data(), vec.size() * sizeof(U));
  262. }
  263. // Convenient helper functions to get a span of any vector, regardless
  264. // of whether it is null or not (the field is not set).
  265. template<class U>
  266. FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U> *ptr)
  267. FLATBUFFERS_NOEXCEPT {
  268. static_assert(Vector<U>::is_span_observable,
  269. "wrong type U, only LE-scalar, or byte types are allowed");
  270. return ptr ? make_span(*ptr) : span<U>();
  271. }
  272. template<class U>
  273. FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
  274. const Vector<U> *ptr) FLATBUFFERS_NOEXCEPT {
  275. static_assert(Vector<U>::is_span_observable,
  276. "wrong type U, only LE-scalar, or byte types are allowed");
  277. return ptr ? make_span(*ptr) : span<const U>();
  278. }
  279. // Represent a vector much like the template above, but in this case we
  280. // don't know what the element types are (used with reflection.h).
  281. class VectorOfAny {
  282. public:
  283. uoffset_t size() const { return EndianScalar(length_); }
  284. const uint8_t *Data() const {
  285. return reinterpret_cast<const uint8_t *>(&length_ + 1);
  286. }
  287. uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
  288. protected:
  289. VectorOfAny();
  290. uoffset_t length_;
  291. private:
  292. VectorOfAny(const VectorOfAny &);
  293. VectorOfAny &operator=(const VectorOfAny &);
  294. };
  295. template<typename T, typename U>
  296. Vector<Offset<T>> *VectorCast(Vector<Offset<U>> *ptr) {
  297. static_assert(std::is_base_of<T, U>::value, "Unrelated types");
  298. return reinterpret_cast<Vector<Offset<T>> *>(ptr);
  299. }
  300. template<typename T, typename U>
  301. const Vector<Offset<T>> *VectorCast(const Vector<Offset<U>> *ptr) {
  302. static_assert(std::is_base_of<T, U>::value, "Unrelated types");
  303. return reinterpret_cast<const Vector<Offset<T>> *>(ptr);
  304. }
  305. // Convenient helper function to get the length of any vector, regardless
  306. // of whether it is null or not (the field is not set).
  307. template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
  308. return v ? v->size() : 0;
  309. }
  310. } // namespace flatbuffers
  311. #endif // FLATBUFFERS_VERIFIER_H_