upgrade Filament to v1.41
This commit is contained in:
@@ -41,11 +41,13 @@ class StructureOfArraysBase {
|
||||
static constexpr const size_t kArrayCount = sizeof...(Elements);
|
||||
|
||||
public:
|
||||
using SoA = StructureOfArraysBase<Allocator, Elements ...>;
|
||||
using SoA = StructureOfArraysBase<Allocator, Elements...>;
|
||||
|
||||
using Structure = std::tuple<Elements...>;
|
||||
|
||||
// Type of the Nth array
|
||||
template<size_t N>
|
||||
using TypeAt = typename std::tuple_element_t<N, std::tuple<Elements...>>;
|
||||
using TypeAt = typename std::tuple_element_t<N, Structure>;
|
||||
|
||||
// Number of arrays
|
||||
static constexpr size_t getArrayCount() noexcept { return kArrayCount; }
|
||||
@@ -57,7 +59,7 @@ public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
class Structure;
|
||||
class IteratorValue;
|
||||
template<typename T> class Iterator;
|
||||
using iterator = Iterator<StructureOfArraysBase*>;
|
||||
using const_iterator = Iterator<StructureOfArraysBase const*>;
|
||||
@@ -69,45 +71,45 @@ public:
|
||||
* In other words, it's the return type of iterator::operator*(), and since it
|
||||
* cannot be a C++ reference (&), it's an object that acts like it.
|
||||
*/
|
||||
class StructureRef {
|
||||
friend class Structure;
|
||||
class IteratorValueRef {
|
||||
friend class IteratorValue;
|
||||
friend iterator;
|
||||
friend const_iterator;
|
||||
StructureOfArraysBase* const UTILS_RESTRICT soa;
|
||||
size_t const index;
|
||||
|
||||
StructureRef(StructureOfArraysBase* soa, size_t index) : soa(soa), index(index) { }
|
||||
IteratorValueRef(StructureOfArraysBase* soa, size_t index) : soa(soa), index(index) { }
|
||||
|
||||
// assigns a value_type to a reference (i.e. assigns to what's pointed to by the reference)
|
||||
template<size_t ... Is>
|
||||
StructureRef& assign(Structure const& rhs, std::index_sequence<Is...>);
|
||||
IteratorValueRef& assign(IteratorValue const& rhs, std::index_sequence<Is...>);
|
||||
|
||||
// assigns a value_type to a reference (i.e. assigns to what's pointed to by the reference)
|
||||
template<size_t ... Is>
|
||||
StructureRef& assign(Structure&& rhs, std::index_sequence<Is...>) noexcept;
|
||||
IteratorValueRef& assign(IteratorValue&& rhs, std::index_sequence<Is...>) noexcept;
|
||||
|
||||
// objects pointed to by reference can be swapped, so provide the special swap() function.
|
||||
friend void swap(StructureRef lhs, StructureRef rhs) {
|
||||
friend void swap(IteratorValueRef lhs, IteratorValueRef rhs) {
|
||||
lhs.soa->swap(lhs.index, rhs.index);
|
||||
}
|
||||
|
||||
public:
|
||||
// references can be created by copy-assignment only
|
||||
StructureRef(StructureRef const& rhs) noexcept : soa(rhs.soa), index(rhs.index) { }
|
||||
IteratorValueRef(IteratorValueRef const& rhs) noexcept : soa(rhs.soa), index(rhs.index) { }
|
||||
|
||||
// copy the content of a reference to the content of this one
|
||||
StructureRef& operator=(StructureRef const& rhs);
|
||||
IteratorValueRef& operator=(IteratorValueRef const& rhs);
|
||||
|
||||
// move the content of a reference to the content of this one
|
||||
StructureRef& operator=(StructureRef&& rhs) noexcept;
|
||||
IteratorValueRef& operator=(IteratorValueRef&& rhs) noexcept;
|
||||
|
||||
// copy a value_type to the content of this reference
|
||||
StructureRef& operator=(Structure const& rhs) {
|
||||
IteratorValueRef& operator=(IteratorValue const& rhs) {
|
||||
return assign(rhs, std::make_index_sequence<kArrayCount>());
|
||||
}
|
||||
|
||||
// move a value_type to the content of this reference
|
||||
StructureRef& operator=(Structure&& rhs) noexcept {
|
||||
IteratorValueRef& operator=(IteratorValue&& rhs) noexcept {
|
||||
return assign(rhs, std::make_index_sequence<kArrayCount>());
|
||||
}
|
||||
|
||||
@@ -122,36 +124,36 @@ public:
|
||||
* Internally we're using a tuple<> to store the data.
|
||||
* This object is not trivial to construct, as it copies an entry of the SoA.
|
||||
*/
|
||||
class Structure {
|
||||
friend class StructureRef;
|
||||
class IteratorValue {
|
||||
friend class IteratorValueRef;
|
||||
friend iterator;
|
||||
friend const_iterator;
|
||||
using Type = std::tuple<typename std::decay<Elements>::type...>;
|
||||
Type elements;
|
||||
|
||||
template<size_t ... Is>
|
||||
static Type init(StructureRef const& rhs, std::index_sequence<Is...>) {
|
||||
static Type init(IteratorValueRef const& rhs, std::index_sequence<Is...>) {
|
||||
return Type{ rhs.soa->template elementAt<Is>(rhs.index)... };
|
||||
}
|
||||
|
||||
template<size_t ... Is>
|
||||
static Type init(StructureRef&& rhs, std::index_sequence<Is...>) noexcept {
|
||||
static Type init(IteratorValueRef&& rhs, std::index_sequence<Is...>) noexcept {
|
||||
return Type{ std::move(rhs.soa->template elementAt<Is>(rhs.index))... };
|
||||
}
|
||||
|
||||
public:
|
||||
Structure(Structure const& rhs) = default;
|
||||
Structure(Structure&& rhs) noexcept = default;
|
||||
Structure& operator=(Structure const& rhs) = default;
|
||||
Structure& operator=(Structure&& rhs) noexcept = default;
|
||||
IteratorValue(IteratorValue const& rhs) = default;
|
||||
IteratorValue(IteratorValue&& rhs) noexcept = default;
|
||||
IteratorValue& operator=(IteratorValue const& rhs) = default;
|
||||
IteratorValue& operator=(IteratorValue&& rhs) noexcept = default;
|
||||
|
||||
// initialize and assign from a StructureRef
|
||||
Structure(StructureRef const& rhs)
|
||||
IteratorValue(IteratorValueRef const& rhs)
|
||||
: elements(init(rhs, std::make_index_sequence<kArrayCount>())) {}
|
||||
Structure(StructureRef&& rhs) noexcept
|
||||
IteratorValue(IteratorValueRef&& rhs) noexcept
|
||||
: elements(init(rhs, std::make_index_sequence<kArrayCount>())) {}
|
||||
Structure& operator=(StructureRef const& rhs) { return operator=(Structure(rhs)); }
|
||||
Structure& operator=(StructureRef&& rhs) noexcept { return operator=(Structure(rhs)); }
|
||||
IteratorValue& operator=(IteratorValueRef const& rhs) { return operator=(IteratorValue(rhs)); }
|
||||
IteratorValue& operator=(IteratorValueRef&& rhs) noexcept { return operator=(IteratorValue(rhs)); }
|
||||
|
||||
// access the elements of this value_Type (i.e. the "fields" of the structure)
|
||||
template<size_t I> TypeAt<I> const& get() const { return std::get<I>(elements); }
|
||||
@@ -174,9 +176,9 @@ public:
|
||||
Iterator(CVQualifiedSOAPointer soa, size_t index) : soa(soa), index(index) {}
|
||||
|
||||
public:
|
||||
using value_type = Structure;
|
||||
using reference = StructureRef;
|
||||
using pointer = StructureRef*; // FIXME: this should be a StructurePtr type
|
||||
using value_type = IteratorValue;
|
||||
using reference = IteratorValueRef;
|
||||
using pointer = IteratorValueRef*; // FIXME: this should be a StructurePtr type
|
||||
using difference_type = ptrdiff_t;
|
||||
using iterator_category = std::random_access_iterator_tag;
|
||||
|
||||
@@ -335,6 +337,11 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
StructureOfArraysBase& push_back(Structure&& args) noexcept {
|
||||
ensureCapacity(mSize + 1);
|
||||
return push_back_unsafe(std::forward<Structure>(args));
|
||||
}
|
||||
|
||||
StructureOfArraysBase& push_back(Elements const& ... args) noexcept {
|
||||
ensureCapacity(mSize + 1);
|
||||
return push_back_unsafe(args...);
|
||||
@@ -349,23 +356,29 @@ public:
|
||||
struct PushBackUnsafeClosure {
|
||||
size_t last;
|
||||
std::tuple<Elements...> args;
|
||||
inline explicit PushBackUnsafeClosure(size_t last, Elements&& ... args)
|
||||
: last(last), args(std::forward<Elements>(args)...) {}
|
||||
inline explicit PushBackUnsafeClosure(size_t last, Elements const& ... args)
|
||||
: last(last), args(args...) {}
|
||||
inline explicit PushBackUnsafeClosure(size_t last, Structure&& args)
|
||||
: last(last), args(std::forward<Structure>(args)) {}
|
||||
template<size_t I>
|
||||
inline void operator()(TypeAt<I>* p) {
|
||||
new(p + last) TypeAt<I>{ std::get<I>(args) };
|
||||
}
|
||||
};
|
||||
|
||||
StructureOfArraysBase& push_back_unsafe(Structure&& args) noexcept {
|
||||
for_each_index(mArrays,
|
||||
PushBackUnsafeClosure{ mSize++, std::forward<Structure>(args) });
|
||||
return *this;
|
||||
}
|
||||
|
||||
StructureOfArraysBase& push_back_unsafe(Elements const& ... args) noexcept {
|
||||
for_each_index(mArrays, PushBackUnsafeClosure{ mSize++, args... });
|
||||
for_each_index(mArrays,
|
||||
PushBackUnsafeClosure{ mSize++, { args... } });
|
||||
return *this;
|
||||
}
|
||||
|
||||
StructureOfArraysBase& push_back_unsafe(Elements&& ... args) noexcept {
|
||||
for_each_index(mArrays, PushBackUnsafeClosure{ mSize++, std::forward<Elements>(args)... });
|
||||
for_each_index(mArrays,
|
||||
PushBackUnsafeClosure{ mSize++, { std::forward<Elements>(args)... }});
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -562,8 +575,10 @@ private:
|
||||
forEach([from, to](auto p) {
|
||||
using T = typename std::decay<decltype(*p)>::type;
|
||||
// note: scalar types like int/float get initialized to zero
|
||||
for (size_t i = from; i < to; i++) {
|
||||
new(p + i) T();
|
||||
if constexpr (!std::is_trivially_default_constructible_v<T>) {
|
||||
for (size_t i = from; i < to; i++) {
|
||||
new(p + i) T();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -571,8 +586,10 @@ private:
|
||||
void destroy_each(size_t from, size_t to) noexcept {
|
||||
forEach([from, to](auto p) {
|
||||
using T = typename std::decay<decltype(*p)>::type;
|
||||
for (size_t i = from; i < to; i++) {
|
||||
p[i].~T();
|
||||
if constexpr (!std::is_trivially_destructible_v<T>) {
|
||||
for (size_t i = from; i < to; i++) {
|
||||
p[i].~T();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -592,15 +609,17 @@ private:
|
||||
reinterpret_cast<T*>(uintptr_t(b) + offsets[index]);
|
||||
|
||||
// for trivial cases, just call memcpy()
|
||||
if (std::is_trivially_copyable<T>::value &&
|
||||
std::is_trivially_destructible<T>::value) {
|
||||
if constexpr (std::is_trivially_copyable_v<T> &&
|
||||
std::is_trivially_destructible_v<T>) {
|
||||
memcpy(arrayPointer, p, size * sizeof(T));
|
||||
} else {
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
// we move an element by using the in-place move-constructor
|
||||
new(arrayPointer + i) T(std::move(p[i]));
|
||||
// and delete them by calling the destructor directly
|
||||
p[i].~T();
|
||||
if constexpr (!std::is_trivially_destructible_v<T>) {
|
||||
// and delete them by calling the destructor directly
|
||||
p[i].~T();
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
@@ -626,27 +645,27 @@ private:
|
||||
|
||||
template<typename Allocator, typename... Elements>
|
||||
inline
|
||||
typename StructureOfArraysBase<Allocator, Elements...>::StructureRef&
|
||||
StructureOfArraysBase<Allocator, Elements...>::StructureRef::operator=(
|
||||
StructureOfArraysBase::StructureRef const& rhs) {
|
||||
return operator=(Structure(rhs));
|
||||
typename StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef&
|
||||
StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef::operator=(
|
||||
StructureOfArraysBase::IteratorValueRef const& rhs) {
|
||||
return operator=(IteratorValue(rhs));
|
||||
}
|
||||
|
||||
template<typename Allocator, typename... Elements>
|
||||
inline
|
||||
typename StructureOfArraysBase<Allocator, Elements...>::StructureRef&
|
||||
StructureOfArraysBase<Allocator, Elements...>::StructureRef::operator=(
|
||||
StructureOfArraysBase::StructureRef&& rhs) noexcept {
|
||||
return operator=(Structure(rhs));
|
||||
typename StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef&
|
||||
StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef::operator=(
|
||||
StructureOfArraysBase::IteratorValueRef&& rhs) noexcept {
|
||||
return operator=(IteratorValue(rhs));
|
||||
}
|
||||
|
||||
template<typename Allocator, typename... Elements>
|
||||
template<size_t... Is>
|
||||
inline
|
||||
typename StructureOfArraysBase<Allocator, Elements...>::StructureRef&
|
||||
StructureOfArraysBase<Allocator, Elements...>::StructureRef::assign(
|
||||
StructureOfArraysBase::Structure const& rhs, std::index_sequence<Is...>) {
|
||||
// implements StructureRef& StructureRef::operator=(Structure const& rhs)
|
||||
typename StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef&
|
||||
StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef::assign(
|
||||
StructureOfArraysBase::IteratorValue const& rhs, std::index_sequence<Is...>) {
|
||||
// implements IteratorValueRef& IteratorValueRef::operator=(IteratorValue const& rhs)
|
||||
auto UTILS_UNUSED l = { (soa->elementAt<Is>(index) = std::get<Is>(rhs.elements), 0)... };
|
||||
return *this;
|
||||
}
|
||||
@@ -654,10 +673,10 @@ StructureOfArraysBase<Allocator, Elements...>::StructureRef::assign(
|
||||
template<typename Allocator, typename... Elements>
|
||||
template<size_t... Is>
|
||||
inline
|
||||
typename StructureOfArraysBase<Allocator, Elements...>::StructureRef&
|
||||
StructureOfArraysBase<Allocator, Elements...>::StructureRef::assign(
|
||||
StructureOfArraysBase::Structure&& rhs, std::index_sequence<Is...>) noexcept {
|
||||
// implements StructureRef& StructureRef::operator=(Structure&& rhs) noexcept
|
||||
typename StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef&
|
||||
StructureOfArraysBase<Allocator, Elements...>::IteratorValueRef::assign(
|
||||
StructureOfArraysBase::IteratorValue&& rhs, std::index_sequence<Is...>) noexcept {
|
||||
// implements IteratorValueRef& IteratorValueRef::operator=(IteratorValue&& rhs) noexcept
|
||||
auto UTILS_UNUSED l = {
|
||||
(soa->elementAt<Is>(index) = std::move(std::get<Is>(rhs.elements)), 0)... };
|
||||
return *this;
|
||||
|
||||
Reference in New Issue
Block a user