forked from BigfootDev/flatbuffers
[C++] Split flatbuffers.h into separate files (#6868)
* split flatbuffers.h into separate files * wrong variable in cmakelists for android * readded two accidentally deleted includes * created buffer.h and moved buffer related things over
This commit is contained in:
376
include/flatbuffers/vector.h
Normal file
376
include/flatbuffers/vector.h
Normal file
@@ -0,0 +1,376 @@
|
||||
/*
|
||||
* Copyright 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FLATBUFFERS_VECTOR_H_
|
||||
#define FLATBUFFERS_VECTOR_H_
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/buffer.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
struct String;
|
||||
|
||||
// An STL compatible iterator implementation for Vector below, effectively
|
||||
// calling Get() for every element.
|
||||
template<typename T, typename IT> struct VectorIterator {
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef IT value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef IT *pointer;
|
||||
typedef IT &reference;
|
||||
|
||||
VectorIterator(const uint8_t *data, uoffset_t i)
|
||||
: data_(data + IndirectHelper<T>::element_stride * i) {}
|
||||
VectorIterator(const VectorIterator &other) : data_(other.data_) {}
|
||||
VectorIterator() : data_(nullptr) {}
|
||||
|
||||
VectorIterator &operator=(const VectorIterator &other) {
|
||||
data_ = other.data_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
#if !defined(FLATBUFFERS_CPP98_STL)
|
||||
VectorIterator &operator=(VectorIterator &&other) {
|
||||
data_ = other.data_;
|
||||
return *this;
|
||||
}
|
||||
#endif // !defined(FLATBUFFERS_CPP98_STL)
|
||||
// clang-format on
|
||||
|
||||
bool operator==(const VectorIterator &other) const {
|
||||
return data_ == other.data_;
|
||||
}
|
||||
|
||||
bool operator<(const VectorIterator &other) const {
|
||||
return data_ < other.data_;
|
||||
}
|
||||
|
||||
bool operator!=(const VectorIterator &other) const {
|
||||
return data_ != other.data_;
|
||||
}
|
||||
|
||||
difference_type operator-(const VectorIterator &other) const {
|
||||
return (data_ - other.data_) / IndirectHelper<T>::element_stride;
|
||||
}
|
||||
|
||||
// Note: return type is incompatible with the standard
|
||||
// `reference operator*()`.
|
||||
IT operator*() const { return IndirectHelper<T>::Read(data_, 0); }
|
||||
|
||||
// Note: return type is incompatible with the standard
|
||||
// `pointer operator->()`.
|
||||
IT operator->() const { return IndirectHelper<T>::Read(data_, 0); }
|
||||
|
||||
VectorIterator &operator++() {
|
||||
data_ += IndirectHelper<T>::element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator operator++(int) {
|
||||
VectorIterator temp(data_, 0);
|
||||
data_ += IndirectHelper<T>::element_stride;
|
||||
return temp;
|
||||
}
|
||||
|
||||
VectorIterator operator+(const uoffset_t &offset) const {
|
||||
return VectorIterator(data_ + offset * IndirectHelper<T>::element_stride,
|
||||
0);
|
||||
}
|
||||
|
||||
VectorIterator &operator+=(const uoffset_t &offset) {
|
||||
data_ += offset * IndirectHelper<T>::element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator &operator--() {
|
||||
data_ -= IndirectHelper<T>::element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator operator--(int) {
|
||||
VectorIterator temp(data_, 0);
|
||||
data_ -= IndirectHelper<T>::element_stride;
|
||||
return temp;
|
||||
}
|
||||
|
||||
VectorIterator operator-(const uoffset_t &offset) const {
|
||||
return VectorIterator(data_ - offset * IndirectHelper<T>::element_stride,
|
||||
0);
|
||||
}
|
||||
|
||||
VectorIterator &operator-=(const uoffset_t &offset) {
|
||||
data_ -= offset * IndirectHelper<T>::element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
const uint8_t *data_;
|
||||
};
|
||||
|
||||
template<typename Iterator>
|
||||
struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
|
||||
explicit VectorReverseIterator(Iterator iter)
|
||||
: std::reverse_iterator<Iterator>(iter) {}
|
||||
|
||||
// Note: return type is incompatible with the standard
|
||||
// `reference operator*()`.
|
||||
typename Iterator::value_type operator*() const {
|
||||
auto tmp = std::reverse_iterator<Iterator>::current;
|
||||
return *--tmp;
|
||||
}
|
||||
|
||||
// Note: return type is incompatible with the standard
|
||||
// `pointer operator->()`.
|
||||
typename Iterator::value_type operator->() const {
|
||||
auto tmp = std::reverse_iterator<Iterator>::current;
|
||||
return *--tmp;
|
||||
}
|
||||
};
|
||||
|
||||
// This is used as a helper type for accessing vectors.
|
||||
// Vector::data() assumes the vector elements start after the length field.
|
||||
template<typename T> class Vector {
|
||||
public:
|
||||
typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type>
|
||||
iterator;
|
||||
typedef VectorIterator<T, typename IndirectHelper<T>::return_type>
|
||||
const_iterator;
|
||||
typedef VectorReverseIterator<iterator> reverse_iterator;
|
||||
typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
typedef typename flatbuffers::bool_constant<flatbuffers::is_scalar<T>::value>
|
||||
scalar_tag;
|
||||
|
||||
static FLATBUFFERS_CONSTEXPR bool is_span_observable =
|
||||
scalar_tag::value && (FLATBUFFERS_LITTLEENDIAN || sizeof(T) == 1);
|
||||
|
||||
uoffset_t size() const { return EndianScalar(length_); }
|
||||
|
||||
// Deprecated: use size(). Here for backwards compatibility.
|
||||
FLATBUFFERS_ATTRIBUTE(deprecated("use size() instead"))
|
||||
uoffset_t Length() const { return size(); }
|
||||
|
||||
typedef typename IndirectHelper<T>::return_type return_type;
|
||||
typedef typename IndirectHelper<T>::mutable_return_type mutable_return_type;
|
||||
typedef return_type value_type;
|
||||
|
||||
return_type Get(uoffset_t i) const {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
return IndirectHelper<T>::Read(Data(), i);
|
||||
}
|
||||
|
||||
return_type operator[](uoffset_t i) const { return Get(i); }
|
||||
|
||||
// If this is a Vector of enums, T will be its storage type, not the enum
|
||||
// type. This function makes it convenient to retrieve value with enum
|
||||
// type E.
|
||||
template<typename E> E GetEnum(uoffset_t i) const {
|
||||
return static_cast<E>(Get(i));
|
||||
}
|
||||
|
||||
// If this a vector of unions, this does the cast for you. There's no check
|
||||
// to make sure this is the right type!
|
||||
template<typename U> const U *GetAs(uoffset_t i) const {
|
||||
return reinterpret_cast<const U *>(Get(i));
|
||||
}
|
||||
|
||||
// If this a vector of unions, this does the cast for you. There's no check
|
||||
// to make sure this is actually a string!
|
||||
const String *GetAsString(uoffset_t i) const {
|
||||
return reinterpret_cast<const String *>(Get(i));
|
||||
}
|
||||
|
||||
const void *GetStructFromOffset(size_t o) const {
|
||||
return reinterpret_cast<const void *>(Data() + o);
|
||||
}
|
||||
|
||||
iterator begin() { return iterator(Data(), 0); }
|
||||
const_iterator begin() const { return const_iterator(Data(), 0); }
|
||||
|
||||
iterator end() { return iterator(Data(), size()); }
|
||||
const_iterator end() const { return const_iterator(Data(), size()); }
|
||||
|
||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||
const_reverse_iterator rbegin() const {
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
|
||||
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||
const_reverse_iterator rend() const {
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
const_iterator cbegin() const { return begin(); }
|
||||
|
||||
const_iterator cend() const { return end(); }
|
||||
|
||||
const_reverse_iterator crbegin() const { return rbegin(); }
|
||||
|
||||
const_reverse_iterator crend() const { return rend(); }
|
||||
|
||||
// Change elements if you have a non-const pointer to this object.
|
||||
// Scalars only. See reflection.h, and the documentation.
|
||||
void Mutate(uoffset_t i, const T &val) {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
WriteScalar(data() + i, val);
|
||||
}
|
||||
|
||||
// Change an element of a vector of tables (or strings).
|
||||
// "val" points to the new table/string, as you can obtain from
|
||||
// e.g. reflection::AddFlatBuffer().
|
||||
void MutateOffset(uoffset_t i, const uint8_t *val) {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
static_assert(sizeof(T) == sizeof(uoffset_t), "Unrelated types");
|
||||
WriteScalar(data() + i,
|
||||
static_cast<uoffset_t>(val - (Data() + i * sizeof(uoffset_t))));
|
||||
}
|
||||
|
||||
// Get a mutable pointer to tables/strings inside this vector.
|
||||
mutable_return_type GetMutableObject(uoffset_t i) const {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
return const_cast<mutable_return_type>(IndirectHelper<T>::Read(Data(), i));
|
||||
}
|
||||
|
||||
// The raw data in little endian format. Use with care.
|
||||
const uint8_t *Data() const {
|
||||
return reinterpret_cast<const uint8_t *>(&length_ + 1);
|
||||
}
|
||||
|
||||
uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
|
||||
|
||||
// Similarly, but typed, much like std::vector::data
|
||||
const T *data() const { return reinterpret_cast<const T *>(Data()); }
|
||||
T *data() { return reinterpret_cast<T *>(Data()); }
|
||||
|
||||
template<typename K> return_type LookupByKey(K key) const {
|
||||
void *search_result = std::bsearch(
|
||||
&key, Data(), size(), IndirectHelper<T>::element_stride, KeyCompare<K>);
|
||||
|
||||
if (!search_result) {
|
||||
return nullptr; // Key not found.
|
||||
}
|
||||
|
||||
const uint8_t *element = reinterpret_cast<const uint8_t *>(search_result);
|
||||
|
||||
return IndirectHelper<T>::Read(element, 0);
|
||||
}
|
||||
|
||||
template<typename K> mutable_return_type MutableLookupByKey(K key) {
|
||||
return const_cast<mutable_return_type>(LookupByKey(key));
|
||||
}
|
||||
|
||||
protected:
|
||||
// This class is only used to access pre-existing data. Don't ever
|
||||
// try to construct these manually.
|
||||
Vector();
|
||||
|
||||
uoffset_t length_;
|
||||
|
||||
private:
|
||||
// This class is a pointer. Copying will therefore create an invalid object.
|
||||
// Private and unimplemented copy constructor.
|
||||
Vector(const Vector &);
|
||||
Vector &operator=(const Vector &);
|
||||
|
||||
template<typename K> static int KeyCompare(const void *ap, const void *bp) {
|
||||
const K *key = reinterpret_cast<const K *>(ap);
|
||||
const uint8_t *data = reinterpret_cast<const uint8_t *>(bp);
|
||||
auto table = IndirectHelper<T>::Read(data, 0);
|
||||
|
||||
// std::bsearch compares with the operands transposed, so we negate the
|
||||
// result here.
|
||||
return -table->KeyCompareWithValue(*key);
|
||||
}
|
||||
};
|
||||
|
||||
template<class U>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U> &vec)
|
||||
FLATBUFFERS_NOEXCEPT {
|
||||
static_assert(Vector<U>::is_span_observable,
|
||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||
return span<U>(vec.data(), vec.size());
|
||||
}
|
||||
|
||||
template<class U>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
|
||||
const Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
|
||||
static_assert(Vector<U>::is_span_observable,
|
||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||
return span<const U>(vec.data(), vec.size());
|
||||
}
|
||||
|
||||
template<class U>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<uint8_t> make_bytes_span(
|
||||
Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
|
||||
static_assert(Vector<U>::scalar_tag::value,
|
||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||
return span<uint8_t>(vec.Data(), vec.size() * sizeof(U));
|
||||
}
|
||||
|
||||
template<class U>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t> make_bytes_span(
|
||||
const Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
|
||||
static_assert(Vector<U>::scalar_tag::value,
|
||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||
return span<const uint8_t>(vec.Data(), vec.size() * sizeof(U));
|
||||
}
|
||||
|
||||
// Represent a vector much like the template above, but in this case we
|
||||
// don't know what the element types are (used with reflection.h).
|
||||
class VectorOfAny {
|
||||
public:
|
||||
uoffset_t size() const { return EndianScalar(length_); }
|
||||
|
||||
const uint8_t *Data() const {
|
||||
return reinterpret_cast<const uint8_t *>(&length_ + 1);
|
||||
}
|
||||
uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
|
||||
|
||||
protected:
|
||||
VectorOfAny();
|
||||
|
||||
uoffset_t length_;
|
||||
|
||||
private:
|
||||
VectorOfAny(const VectorOfAny &);
|
||||
VectorOfAny &operator=(const VectorOfAny &);
|
||||
};
|
||||
|
||||
#ifndef FLATBUFFERS_CPP98_STL
|
||||
template<typename T, typename U>
|
||||
Vector<Offset<T>> *VectorCast(Vector<Offset<U>> *ptr) {
|
||||
static_assert(std::is_base_of<T, U>::value, "Unrelated types");
|
||||
return reinterpret_cast<Vector<Offset<T>> *>(ptr);
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
const Vector<Offset<T>> *VectorCast(const Vector<Offset<U>> *ptr) {
|
||||
static_assert(std::is_base_of<T, U>::value, "Unrelated types");
|
||||
return reinterpret_cast<const Vector<Offset<T>> *>(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Convenient helper function to get the length of any vector, regardless
|
||||
// of whether it is null or not (the field is not set).
|
||||
template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
|
||||
return v ? v->size() : 0;
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_VERIFIER_H_
|
||||
Reference in New Issue
Block a user