8#ifndef PXR_BASE_VT_ARRAY_EDIT_BUILDER_H
9#define PXR_BASE_VT_ARRAY_EDIT_BUILDER_H
14#include "pxr/base/vt/api.h"
18#include "pxr/base/vt/hash.h"
19#include "pxr/base/vt/streamOut.h"
24#include <unordered_map>
26PXR_NAMESPACE_OPEN_SCOPE
29class Vt_ArrayEditOpsBuilder
32 using Ops = Vt_ArrayEditOps;
35 void AddOp(Ops::Op op, int64_t a1, int64_t a2);
38 void AddOp(Ops::Op op, int64_t a1);
44 void _AddOp(Ops::Op op);
46 static void _IssueArityError(Ops::Op op,
int count);
47 static void _IssueNegativeSizeError(Ops::Op op, int64_t size);
49 static inline bool _CheckArity(Ops::Op op,
int count);
51 std::vector<int64_t> _ins;
52 int64_t _lastOpIdx = 0;
68 using Ops = Vt_ArrayEditOps;
71 using ElementType =
typename Edit::ElementType;
76 static constexpr auto EndIndex = Vt_ArrayEditOps::EndIndex;
85 Self &
Write(ElementType
const &elem, int64_t index) {
86 _opsBuilder.AddOp(Ops::OpWriteLiteral, _FindOrAddLiteral(elem), index);
95 _opsBuilder.AddOp(Ops::OpWriteRef, srcIndex, dstIndex);
105 _opsBuilder.AddOp(Ops::OpInsertLiteral, _FindOrAddLiteral(elem), index);
116 _opsBuilder.AddOp(Ops::OpInsertRef, srcIndex, dstIndex);
122 _opsBuilder.AddOp(Ops::OpInsertLiteral, _FindOrAddLiteral(elem), 0);
128 _opsBuilder.AddOp(Ops::OpInsertRef, srcIndex, 0);
135 Ops::OpInsertLiteral, _FindOrAddLiteral(elem),
EndIndex);
141 _opsBuilder.AddOp(Ops::OpInsertRef, srcIndex,
EndIndex);
150 _opsBuilder.AddOp(Ops::OpEraseRef, index);
157 _opsBuilder.AddOp(Ops::OpMinSize, size);
164 _opsBuilder.AddOp(Ops::OpMinSizeFill, size, _FindOrAddLiteral(fill));
171 _opsBuilder.AddOp(Ops::OpMaxSize, size);
179 _opsBuilder.AddOp(Ops::OpSetSize, size);
188 _opsBuilder.AddOp(Ops::OpSetSizeFill, size, _FindOrAddLiteral(fill));
197 result._literals = std::move(_literals);
198 result._ops._ins = std::move(_opsBuilder._ins);
216 std::vector<int64_t> *indexesOut) {
218 *valuesOut = edit._literals;
219 *indexesOut = edit._ops._ins;
232 result._literals = values;
233 result._ops._ins = std::vector<int64_t>(indexes.
begin(), indexes.
end());
238 int64_t _FindOrAddLiteral(ElementType
const &elem) {
239 auto iresult = _literalToIndex.emplace(elem, _literals.size());
240 if (iresult.second) {
241 _literals.push_back(elem);
243 return iresult.first->second;
247 Vt_ArrayEditOpsBuilder _opsBuilder;
248 std::unordered_map<ElementType, int64_t, TfHash> _literalToIndex;
256 if (in.IsIdentity()) {
257 return std::move(in);
263 const Array literals = std::move(in._literals);
264 const auto numLiterals = literals.size();
265 Ops ops = std::move(in._ops);
267 in._literals.clear();
270 ops.ForEach([&](Ops::Op op, int64_t a1, int64_t a2) {
272 case Ops::OpWriteLiteral:
274 if (a1 >= 0 &&
static_cast<size_t>(a1) < numLiterals) {
275 builder.
Write(literals[a1], a2);
278 case Ops::OpInsertLiteral:
280 if (a1 >= 0 &&
static_cast<size_t>(a1) < numLiterals) {
281 builder.
Insert(literals[a1], a2);
284 case Ops::OpWriteRef: builder.
WriteRef(a1, a2);
break;
285 case Ops::OpInsertRef: builder.
InsertRef(a1, a2);
break;
286 case Ops::OpEraseRef: builder.
EraseRef(a1);
break;
287 case Ops::OpMinSize: builder.
MinSize(a1);
break;
288 case Ops::OpSetSize: builder.
SetSize(a1);
break;
289 case Ops::OpMaxSize: builder.
MaxSize(a1);
break;
290 case Ops::OpMinSizeFill:
292 if (a1 >= 0 &&
static_cast<size_t>(a1) < numLiterals) {
293 builder.
MinSize(a1, literals[a2]);
296 case Ops::OpSetSizeFill:
298 if (a1 >= 0 &&
static_cast<size_t>(a1) < numLiterals) {
299 builder.
SetSize(a1, literals[a2]);
308PXR_NAMESPACE_CLOSE_SCOPE
Low-level utilities for informing users of various internal and external diagnostic conditions.
Represents a range of contiguous elements.
iterator end() const noexcept
Returns a non-const iterator to the end of the span.
iterator begin() const noexcept
Returns a non-const iterator the start of the span.
A builder type that produces instances of VtArrayEdit representing sequences of array edit operations...
Self & Prepend(ElementType const &elem)
Equivalent to Insert(elem, 0)
Self & MinSize(int64_t size)
Add an instruction that, if the array's size is less than size, appends value-initialized elements to...
Self & Append(ElementType const &elem)
Equivalent to Insert(elem, EndIndex)
Self & MinSize(int64_t size, ElementType const &fill)
Add an instruction that, if the array's size is less than size, appends copies of fill to the array u...
Self & EraseRef(int64_t index)
Add an instruction that erases the element at index.
VtArrayEdit< ELEM > FinalizeAndReset()
Return a VtArrayEdit that performs the edits as specified by prior calls to this class's other member...
Self & AppendRef(int64_t srcIndex)
Equivalent to InsertRef(srcIndex, EndIndex)
Self & SetSize(int64_t size, ElementType const &fill)
Add an instruction that, if the array's size is not equal to size, then items are either appended or ...
Self & InsertRef(int64_t srcIndex, int64_t dstIndex)
Add an instruction that inserts a copy of the element at srcIndex at dstIndex.
static VtArrayEdit< ELEM > Optimize(VtArrayEdit< ELEM > &&in)
Given a VtArrayEdit that may have been composed from several, attempt to produce a smaller,...
Self & PrependRef(int64_t srcIndex)
Equivalent to InsertRef(srcIndex, 0)
Self & SetSize(int64_t size)
Add an instruction that, if the array's size is not equal to size, then items are either appended or ...
Self & Write(ElementType const &elem, int64_t index)
Add an instruction that writes elem to index.
Self & WriteRef(int64_t srcIndex, int64_t dstIndex)
Add an instruction that writes the element at srcIndex to dstIndex.
Self & Insert(ElementType const &elem, int64_t index)
Add an instruction that inserts elem at index.
static constexpr auto EndIndex
A special index value meaning one-past-the-end of the array, for use in Insert() instructions.
Self & MaxSize(int64_t size)
Add an instruction that, if the array's size is greater than size erases trailing elements until it h...
VtArrayEditBuilder()=default
Default construct a builder with no instructions.
An array edit represents a sequence of per-element modifications to a VtArray.
VtArray< ELEM > Array
Shorthand for the corresponding VtArray type.
Represents an arbitrary dimensional rectangular container class.
#define TF_VERIFY(cond, format,...)
Checks a condition and reports an error if it evaluates false.