54 _data = _allocate(_size);
56 for (
auto& v : rhs) *(dest_v++) = v;
62 Data(in_properties,
sizeof(value_type)),
63 _data(_allocate(numElements)),
64 _size(numElements) {
dirty(); }
66 Array(uint32_t numElements, value_type* data,
Properties in_properties = {}) :
67 Data(in_properties,
sizeof(value_type)),
69 _size(numElements) {
dirty(); }
71 Array(uint32_t numElements,
const value_type& value,
Properties in_properties = {}) :
72 Data(in_properties,
sizeof(value_type)),
73 _data(_allocate(numElements)),
76 for (
auto& v : *
this) v = value;
85 assign(data, offset, stride, numElements, in_properties);
88 explicit Array(std::initializer_list<value_type> l) :
89 _data(_allocate(l.size())),
90 _size(
static_cast<uint32_t
>(l.size()))
95 for (
const value_type& v : l) { (*itr++) = v; }
100 explicit Array(
ref_ptr<Data> data, uint32_t offset, uint32_t stride, std::initializer_list<value_type> l) :
104 assign(data, offset, stride, l.size());
107 for (
const value_type& v : l) { (*itr++) = v; }
112 template<
typename... Args>
133 size_t sizeofObject() const noexcept
override {
return sizeof(Array); }
134 const char* className() const noexcept
override {
return type_name<Array>(); }
135 const std::type_info&
type_info() const noexcept
override {
return typeid(*this); }
136 bool is_compatible(
const std::type_info& type)
const noexcept override {
return typeid(
Array) == type || Data::is_compatible(type); }
139 void accept(Visitor& visitor)
override;
140 void accept(ConstVisitor& visitor)
const override;
142 void read(Input& input)
override
144 size_t original_total_size = size();
148 uint32_t width_size = input.readValue<uint32_t>(
"size");
150 if (
auto data_storage = input.readObject<Data>(
"storage"))
152 uint32_t offset = input.readValue<uint32_t>(
"offset");
157 if (input.matchPropertyName(
"data"))
159 size_t new_total_size = computeValueCountIncludingMipmaps(width_size, 1, 1,
properties.maxNumMipmaps);
163 if (original_total_size != new_total_size)
167 _data = _allocate(new_total_size);
172 _data = _allocate(new_total_size);
179 if (_data) input.read(new_total_size, _data);
185 void write(Output& output)
const override
189 output.writeValue<uint32_t>(
"size", _size);
190 output.writeObject(
"storage", _storage);
193 auto offset = (
reinterpret_cast<uintptr_t
>(_data) -
reinterpret_cast<uintptr_t
>(_storage->dataPointer()));
194 output.writeValue<uint32_t>(
"offset", offset);
198 output.writePropertyName(
"data");
199 output.write(size(), _data);
200 output.writeEndOfLine();
203 size_t size()
const {
return (
properties.maxNumMipmaps <= 1) ? _size : computeValueCountIncludingMipmaps(_size, 1, 1,
properties.maxNumMipmaps); }
205 bool available()
const {
return _data !=
nullptr; }
206 bool empty()
const {
return _data ==
nullptr; }
217 Array& operator=(
const Array& rhs)
219 if (&rhs ==
this)
return *
this;
228 _data = _allocate(_size);
230 for (
auto& v : rhs) *(dest_v++) = v;
238 void assign(uint32_t numElements, value_type* data, Properties in_properties = {})
251 void assign(ref_ptr<Data> storage, uint32_t offset, uint32_t stride, uint32_t numElements, Properties in_properties = {})
258 if (_storage && _storage->dataPointer())
260 _data =
reinterpret_cast<value_type*
>(
reinterpret_cast<uint8_t*
>(_storage->dataPointer()) + offset);
274 void* dataRelease()
override
289 size_t valueSize()
const override {
return sizeof(value_type); }
290 size_t valueCount()
const override {
return size(); }
292 bool dataAvailable()
const override {
return available(); }
293 size_t dataSize()
const override {
return size() *
properties.stride; }
295 void* dataPointer()
override {
return _data; }
296 const void* dataPointer()
const override {
return _data; }
298 void* dataPointer(
size_t i)
override {
return data(i); }
299 const void* dataPointer(
size_t i)
const override {
return data(i); }
301 uint32_t dimensions()
const override {
return 1; }
303 uint32_t width()
const override {
return _size; }
304 uint32_t height()
const override {
return 1; }
305 uint32_t depth()
const override {
return 1; }
307 value_type* data() {
return _data; }
308 const value_type* data()
const {
return _data; }
310 inline value_type* data(
size_t i) {
return reinterpret_cast<value_type*
>(
reinterpret_cast<uint8_t*
>(_data) + i *
properties.stride); }
311 inline const value_type* data(
size_t i)
const {
return reinterpret_cast<const value_type*
>(
reinterpret_cast<const uint8_t*
>(_data) + i *
properties.stride); }
313 value_type& operator[](
size_t i) {
return *data(i); }
314 const value_type& operator[](
size_t i)
const {
return *data(i); }
316 value_type& at(
size_t i) {
return *data(i); }
317 const value_type& at(
size_t i)
const {
return *data(i); }
319 void set(
size_t i,
const value_type& v) { *data(i) = v; }
321 Data* storage() {
return _storage; }
322 const Data* storage()
const {
return _storage; }
324 iterator begin() {
return iterator{_data,
properties.stride}; }
325 const_iterator begin()
const {
return const_iterator{_data,
properties.stride}; }
327 iterator end() {
return iterator{data(_size),
properties.stride}; }
328 const_iterator end()
const {
return const_iterator{data(_size),
properties.stride}; }
336 value_type* _allocate(
size_t size)
const
341 return new value_type[size];
343 return new (std::malloc(
sizeof(value_type) * size)) value_type[size];
345 return new (vsg::allocate(
sizeof(value_type) * size, ALLOCATOR_AFFINITY_DATA)) value_type[size];
350 if (!_storage && _data)
357 vsg::deallocate(_data);
364 ref_ptr<Data> _storage;