vector.h 12 KB

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