35 class VSG_TEMPLATE_DECLSPEC Array :
public Data
46 Array(
const Array& rhs,
const CopyOp copyop = {}) :
53 _data = _allocate(_size);
55 for (
const auto& v : rhs) *(dest_v++) = v;
60 explicit Array(uint32_t numElements,
Properties in_properties = {}) :
61 Data(in_properties,
sizeof(value_type)),
62 _data(_allocate(numElements)),
63 _size(numElements) {
dirty(); }
65 Array(uint32_t numElements, value_type* data,
Properties in_properties = {},
MipmapLayout* mipmapLayout =
nullptr) :
66 Data(in_properties,
sizeof(value_type)),
74 Array(uint32_t numElements,
const value_type& value,
Properties in_properties = {}) :
75 Data(in_properties,
sizeof(value_type)),
76 _data(_allocate(numElements)),
79 for (
auto& v : *
this) v = value;
88 assign(data, offset, stride, numElements, in_properties, mipmapLayout);
91 explicit Array(std::initializer_list<value_type> l) :
92 _data(_allocate(l.size())),
93 _size(
static_cast<uint32_t
>(l.size()))
97 iterator itr = begin();
98 for (
const value_type& v : l) { (*itr++) = v; }
103 explicit Array(
ref_ptr<Data> data, uint32_t offset, uint32_t stride, std::initializer_list<value_type> l) :
107 assign(data, offset, stride,
static_cast<uint32_t
>(l.size()));
109 iterator itr = begin();
110 for (
const value_type& v : l) { (*itr++) = v; }
115 template<
typename... Args>
121 template<
typename... Args>
145 size_t sizeofObject() const noexcept
override {
return sizeof(Array); }
146 const char* className() const noexcept
override {
return type_name<Array>(); }
147 const std::type_info&
type_info() const noexcept
override {
return typeid(*this); }
148 bool is_compatible(
const std::type_info& type)
const noexcept override {
return typeid(
Array) == type || Data::is_compatible(type); }
151 void accept(Visitor& visitor)
override;
152 void accept(ConstVisitor& visitor)
const override;
154 void read(Input& input)
override
156 size_t original_total_size = size();
160 uint32_t width_size = input.readValue<uint32_t>(
"size");
162 if (
auto data_storage = input.readObject<Data>(
"storage"))
164 uint32_t offset = input.readValue<uint32_t>(
"offset");
165 assign(data_storage, offset, properties.stride, width_size, properties);
169 if (input.matchPropertyName(
"data"))
171 properties.stride =
sizeof(value_type);
174 size_t new_total_size = computeValueCountIncludingMipmaps();
178 if (original_total_size != new_total_size)
182 _data = _allocate(new_total_size);
187 _data = _allocate(new_total_size);
190 if (_data) input.read(new_total_size, _data);
196 void write(Output& output)
const override
200 output.writeValue<uint32_t>(
"size", _size);
201 output.writeObject(
"storage", _storage);
204 auto offset = (
reinterpret_cast<uintptr_t
>(_data) -
reinterpret_cast<uintptr_t
>(_storage->dataPointer()));
205 output.writeValue<uint32_t>(
"offset", offset);
209 output.writePropertyName(
"data");
210 output.write(size(), _data);
211 output.writeEndOfLine();
214 size_t size()
const {
return (properties.mipLevels <= 1) ? _size : computeValueCountIncludingMipmaps(); }
216 bool available()
const {
return _data !=
nullptr; }
217 bool empty()
const {
return _data ==
nullptr; }
228 Array& operator=(
const Array& rhs)
230 if (&rhs ==
this)
return *
this;
240 _data = _allocate(_size);
242 for (
const auto& v : rhs) *(dest_v++) = v;
250 void assign(uint32_t numElements, value_type* data, Properties in_properties = {}, MipmapLayout* mipmapLayout =
nullptr)
254 properties = in_properties;
255 properties.stride =
sizeof(value_type);
260 setMipmapLayout(mipmapLayout);
265 void assign(ref_ptr<Data> storage, uint32_t offset, uint32_t stride, uint32_t numElements, Properties in_properties = {}, MipmapLayout* mipmapLayout =
nullptr)
270 properties = in_properties;
271 properties.stride = stride;
272 if (_storage && _storage->dataPointer())
274 _data =
reinterpret_cast<value_type*
>(
reinterpret_cast<uint8_t*
>(_storage->dataPointer()) + offset);
283 setMipmapLayout(mipmapLayout);
290 void* dataRelease()
override
305 size_t valueSize()
const override {
return sizeof(value_type); }
306 size_t valueCount()
const override {
return size(); }
308 bool dataAvailable()
const override {
return available(); }
309 size_t dataSize()
const override {
return size() * properties.stride; }
311 void* dataPointer()
override {
return _data; }
312 const void* dataPointer()
const override {
return _data; }
314 void* dataPointer(
size_t i)
override {
return data(i); }
315 const void* dataPointer(
size_t i)
const override {
return data(i); }
317 uint32_t dimensions()
const override {
return 1; }
319 uint32_t width()
const override {
return _size; }
320 uint32_t height()
const override {
return 1; }
321 uint32_t depth()
const override {
return 1; }
323 value_type* data() {
return _data; }
324 const value_type* data()
const {
return _data; }
326 inline value_type* data(
size_t i) {
return reinterpret_cast<value_type*
>(
reinterpret_cast<uint8_t*
>(_data) + i *
static_cast<size_t>(properties.stride)); }
327 inline const value_type* data(
size_t i)
const {
return reinterpret_cast<const value_type*
>(
reinterpret_cast<const uint8_t*
>(_data) + i *
static_cast<size_t>(properties.stride)); }
329 value_type& operator[](
size_t i) {
return *data(i); }
330 const value_type& operator[](
size_t i)
const {
return *data(i); }
332 value_type& at(
size_t i) {
return *data(i); }
333 const value_type& at(
size_t i)
const {
return *data(i); }
335 void set(
size_t i,
const value_type& v) { *data(i) = v; }
337 Data* storage() {
return _storage; }
338 const Data* storage()
const {
return _storage; }
340 iterator begin() {
return iterator{_data, properties.stride}; }
341 const_iterator begin()
const {
return const_iterator{_data, properties.stride}; }
343 iterator end() {
return iterator{data(_size), properties.stride}; }
344 const_iterator end()
const {
return const_iterator{data(_size), properties.stride}; }
352 value_type* _allocate(
size_t size)
const
356 else if (properties.allocatorType == ALLOCATOR_TYPE_NEW_DELETE)
357 return new value_type[size];
358 else if (properties.allocatorType == ALLOCATOR_TYPE_MALLOC_FREE)
359 return new (std::malloc(
sizeof(value_type) * size)) value_type[size];
361 return new (vsg::allocate(
sizeof(value_type) * size, ALLOCATOR_AFFINITY_DATA)) value_type[size];
366 if (!_storage && _data)
368 if (properties.allocatorType == ALLOCATOR_TYPE_NEW_DELETE)
370 else if (properties.allocatorType == ALLOCATOR_TYPE_MALLOC_FREE)
372 else if (properties.allocatorType != 0)
373 vsg::deallocate(_data);
382 ref_ptr<Data> _storage;