HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
listOp.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_USD_SDF_LIST_OP_H
8 #define PXR_USD_SDF_LIST_OP_H
9 
10 #include "pxr/pxr.h"
11 #include "pxr/usd/sdf/api.h"
12 #include "pxr/base/tf/token.h"
13 #include "pxr/base/tf/hash.h"
14 #include "pxr/base/vt/traits.h"
15 
16 #include <functional>
17 #include <iosfwd>
18 #include <list>
19 #include <map>
20 #include <optional>
21 #include <string>
22 #include <vector>
23 
25 
26 /// \enum SdfListOpType
27 ///
28 /// Enum for specifying one of the list editing operation types.
29 ///
37 };
38 
39 /// \struct Sdf_ListOpTraits
40 ///
41 /// Trait classes for specializing behaviors of SdfListOp for a given item
42 /// type.
43 ///
44 template <class T>
46 {
47  typedef std::less<T> ItemComparator;
48 };
49 
50 /// \class SdfListOp
51 ///
52 /// SdfListOp is a value type representing an operation that edits a list.
53 /// It may append or prepend items, delete them, or replace the list entirely.
54 ///
55 /// SdfListOp maintains lists of items to be prepended, appended, deleted, or
56 /// used explicitly. If used in explicit mode, the ApplyOperations method replaces the given list
57 /// with the set explicit items. Otherwise, the ApplyOperations
58 /// method is used to apply the list-editing options in the input list in the
59 /// following order:
60 /// - Delete
61 /// - Prepend
62 /// - Append
63 ///
64 /// Lists are meant to contain unique values, and all list operations
65 /// will remove duplicates if encountered. Prepending items and using
66 /// explicit mode will preserve the position of the first of the duplicates
67 /// to be encountered, while appending items will preserve the last.
68 
69 template <typename T>
70 class SdfListOp {
71 public:
72  typedef T ItemType;
73  typedef std::vector<ItemType> ItemVector;
76 
77  /// Create a ListOp in explicit mode with the given \p explicitItems.
78  SDF_API
80  const ItemVector& explicitItems = ItemVector());
81 
82  /// Create a ListOp in non-explicit mode with the given
83  /// \p prependedItems, \p appendedItems, and \p deletedItems
84  SDF_API
85  static SdfListOp Create(
86  const ItemVector& prependedItems = ItemVector(),
87  const ItemVector& appendedItems = ItemVector(),
88  const ItemVector& deletedItems = ItemVector());
89 
90  /// Create an empty ListOp in non-explicit mode.
92 
93  SDF_API void Swap(SdfListOp<T>& rhs);
94 
95  /// Returns \c true if the editor has an explicit list (even if it's
96  /// empty) or it has any added, prepended, appended, deleted,
97  /// or ordered keys.
98  bool HasKeys() const
99  {
100  if (IsExplicit()) {
101  return true;
102  }
103  if (_addedItems.size() != 0 ||
104  _prependedItems.size() != 0 ||
105  _appendedItems.size() != 0 ||
106  _deletedItems.size() != 0) {
107  return true;
108  }
109  return _orderedItems.size() != 0;
110  }
111 
112  /// Returns \c true if the given item is in any of the item lists.
113  SDF_API bool HasItem(const T& item) const;
114 
115  /// Returns \c true if the list is explicit.
116  bool IsExplicit() const
117  {
118  return _isExplicit;
119  }
120 
121  /// Returns the explicit items.
123  {
124  return _explicitItems;
125  }
126 
127  /// Returns the explicit items.
129  {
130  return _prependedItems;
131  }
132 
133  /// Returns the explicit items.
135  {
136  return _appendedItems;
137  }
138 
139  /// Returns the deleted items.
141  {
142  return _deletedItems;
143  }
144 
145  /// Return the item vector identified by \p type.
147 
148  /// Returns the effective list of items represented by the operations in
149  /// this list op. This function should be used to determine the final list
150  /// of items added instead of looking at the individual explicit, prepended,
151  /// and appended item lists.
152  ///
153  /// This is equivalent to calling ApplyOperations on an empty item vector.
155 
156  /// Sets the explicit items. If duplicates are present in \p items,
157  /// preserves the first occurence.
158  /// Returns true if no duplicates were present, false otherwise. If
159  /// duplicates were present, errMsg is set to indicate which item was duplicated.
160  SDF_API bool SetExplicitItems(const ItemVector &items, std::string* errMsg = nullptr);
161 
162  /// Sets the prepended items. If duplicates are present in \p items,
163  /// preserves the first occurence.
164  /// Returns true if no duplicates were present, false otherwise. If
165  /// duplicates were present, errMsg is set to indicate which item was duplicated.
166  SDF_API bool SetPrependedItems(const ItemVector &items, std::string* errMsg = nullptr);
167 
168  /// Sets the appended items. If duplicates are present in \p items,
169  /// preserves the last occurence.
170  /// Returns true if no duplicates were present, false otherwise. If
171  /// duplicates were present, errMsg is set to indicate which item was duplicated.
172  SDF_API bool SetAppendedItems(const ItemVector &items, std::string* errMsg = nullptr);
173 
174  /// Sets the deleted items. If duplicates are present in \p items,
175  /// preserves the first occurence.
176  /// Returns true if no duplicates were present, false otherwise. If
177  /// duplicates were present, errMsg is set to indicate which item was duplicated.
178  SDF_API bool SetDeletedItems(const ItemVector &items, std::string* errMsg = nullptr);
179 
180  /// Sets the item vector for the given operation \p type.
181  /// Removes duplicates in \p items if present.
182  /// Returns true if no duplicates were present, false otherwise. If
183  /// duplicates were present, errMsg is set to indicate which item was duplicated.
184  SDF_API bool SetItems(const ItemVector &items, SdfListOpType type,
185  std::string* errMsg = nullptr);
186 
187  /// Removes all items and changes the list to be non-explicit.
188  SDF_API void Clear();
189 
190  /// Removes all items and changes the list to be explicit.
192 
193  /// Callback type for ApplyOperations.
194  typedef std::function<
195  std::optional<ItemType>(SdfListOpType, const ItemType&)
197 
198  /// Applies edit operations to the given ItemVector.
199  /// If supplied, \p cb will be called on each item in the operation vectors
200  /// before they are applied to \p vec. Consumers can use this to transform
201  /// the items stored in the operation vectors to match what's stored in
202  /// \p vec.
203  SDF_API
204  void ApplyOperations(ItemVector* vec,
205  const ApplyCallback& cb = ApplyCallback()) const;
206 
207  /// Applies edit operations to the given ListOp.
208  ///
209  /// The result is a ListOp that, when applied to a list, has the same
210  /// effect as applying \p inner and then \p this in sequence.
211  ///
212  /// The result will be empty if the result is not well defined.
213  /// The result is well-defined when \p inner and \p this do not
214  /// use the 'ordered' or 'added' item lists. In other words, only
215  /// the explicit, prepended, appended, and deleted portions of
216  /// SdfListOp are closed under composition with ApplyOperations().
217  SDF_API
218  std::optional<SdfListOp<T>>
219  ApplyOperations(const SdfListOp<T> &inner) const;
220 
221  /// Callback type for ModifyOperations.
222  typedef std::function<
223  std::optional<ItemType>(const ItemType&)
225 
226  /// Modifies operations specified in this object.
227  /// \p callback is called for every item in all operation vectors. If the
228  /// returned key is empty then the key is removed, otherwise it's replaced
229  /// with the returned key.
230  ///
231  /// If \p callback returns a key that was previously returned for the
232  /// current operation vector being processed, the returned key will be
233  /// removed.
234  ///
235  /// Returns true if a change was made, false otherwise.
236  SDF_API
237  bool ModifyOperations(const ModifyCallback& callback);
238 
239  /// \deprecated Please use ModifyOperations(const ModifyCallback& callback)
240  /// instead.
241  SDF_API
242  bool ModifyOperations(const ModifyCallback& callback,
243  bool unusedRemoveDuplicates);
244 
245  /// Replaces the items in the specified operation vector in the range
246  /// (index, index + n] with the given \p newItems. If \p newItems is empty
247  /// the items in the range will simply be removed.
248  SDF_API
249  bool ReplaceOperations(const SdfListOpType op, size_t index, size_t n,
250  const ItemVector& newItems);
251 
252  /// Composes a stronger SdfListOp's opinions for a given operation list
253  /// over this one.
254  SDF_API
255  void ComposeOperations(const SdfListOp<T>& stronger, SdfListOpType op);
256 
257  /// \deprecated The add and reorder operations have been deprecated in favor
258  /// of the append and prepend operations.
259  const ItemVector& GetAddedItems() const
260  {
261  return _addedItems;
262  }
263 
264  /// \deprecated The add and reorder operations have been deprecated in favor
265  /// of the append and prepend operations.
267  {
268  return _orderedItems;
269  }
270  /// \deprecated The add and reorder operations have been deprecated in favor
271  /// of the append and prepend operations.
272  SDF_API void SetAddedItems(const ItemVector &items);
273 
274  /// \deprecated The add and reorder operations have been deprecated in favor
275  /// of the append and prepend operations.
276  SDF_API void SetOrderedItems(const ItemVector &items);
277 
278  friend inline size_t hash_value(const SdfListOp &op) {
279  return TfHash::Combine(
280  op._isExplicit,
281  op._explicitItems,
282  op._addedItems,
283  op._prependedItems,
284  op._appendedItems,
285  op._deletedItems,
286  op._orderedItems
287  );
288  }
289 
290  bool operator==(const SdfListOp<T> &rhs) const {
291  return _isExplicit == rhs._isExplicit &&
292  _explicitItems == rhs._explicitItems &&
293  _addedItems == rhs._addedItems &&
294  _prependedItems == rhs._prependedItems &&
295  _appendedItems == rhs._appendedItems &&
296  _deletedItems == rhs._deletedItems &&
297  _orderedItems == rhs._orderedItems;
298  };
299 
300  bool operator!=(const SdfListOp<T> &rhs) const {
301  return !(*this == rhs);
302  };
303 
304 private:
305  void _SetExplicit(bool isExplicit);
306 
307  typedef typename Sdf_ListOpTraits<T>::ItemComparator _ItemComparator;
308  typedef std::list<ItemType> _ApplyList;
309  typedef std::map<ItemType, typename _ApplyList::iterator, _ItemComparator>
310  _ApplyMap;
311 
312  void _PrependKeys(const ApplyCallback& cb,
313  _ApplyList* result, _ApplyMap* search) const;
314  void _AppendKeys(const ApplyCallback& cb,
315  _ApplyList* result, _ApplyMap* search) const;
316  void _DeleteKeys(const ApplyCallback& cb,
317  _ApplyList* result, _ApplyMap* search) const;
318 
319  /// \deprecated
320  /// Use _PrependKeys or _AppendKeys instead.
321  void _AddKeys(SdfListOpType, const ApplyCallback& cb,
322  _ApplyList* result, _ApplyMap* search) const;
323 
324  /// \deprecated
325  /// Use _PrependKeys or _AppendKeys instead.
326  void _ReorderKeys(const ApplyCallback& cb,
327  _ApplyList* result, _ApplyMap* search) const;
328  static void _ReorderKeysHelper(ItemVector order, const ApplyCallback& cb,
329  _ApplyList *result, _ApplyMap *search);
330  template <class ItemType>
331  friend void SdfApplyListOrdering(std::vector<ItemType> *v,
332  const std::vector<ItemType> &order);
333  bool _MakeUnique(std::vector<T>& items, bool reverse=false,
334  std::string* errMsg = nullptr);
335 
336 private:
337  bool _isExplicit;
338  ItemVector _explicitItems;
339  ItemVector _addedItems;
340  ItemVector _prependedItems;
341  ItemVector _appendedItems;
342  ItemVector _deletedItems;
343  ItemVector _orderedItems;
344 };
345 
346 // SdfListOps can VtValue-compose.
347 template <class T>
348 struct VtValueTypeCanCompose<SdfListOp<T>> : std::true_type {};
349 
350 // ADL swap.
351 template <class T>
353 {
354  x.Swap(y);
355 }
356 
357 // Helper function for applying an ordering operation described by \p orderVector
358 // to vector \p v.
359 template <class ItemType>
360 SDF_API
361 void SdfApplyListOrdering(std::vector<ItemType>* v,
362  const std::vector<ItemType>& order);
363 
364 // Ostream output methods for list values (useful for debugging and required
365 // for storing a list value in a VtValue).
366 template <typename T>
367 SDF_API
368 std::ostream & operator<<( std::ostream &, const SdfListOp<T> & );
369 
370 // Concrete, instantiated listop types.
371 typedef class SdfListOp<int> SdfIntListOp;
372 typedef class SdfListOp<unsigned int> SdfUIntListOp;
373 typedef class SdfListOp<int64_t> SdfInt64ListOp;
374 typedef class SdfListOp<uint64_t> SdfUInt64ListOp;
376 typedef class SdfListOp<std::string> SdfStringListOp;
377 typedef class SdfListOp<class SdfPath> SdfPathListOp;
378 typedef class SdfListOp<class SdfReference> SdfReferenceListOp;
379 typedef class SdfListOp<class SdfPayload> SdfPayloadListOp;
380 typedef class SdfListOp<class SdfUnregisteredValue> SdfUnregisteredValueListOp;
381 
383 
384 #endif // PXR_USD_SDF_LIST_OP_H
SDF_API bool SetItems(const ItemVector &items, SdfListOpType type, std::string *errMsg=nullptr)
void swap(ArAssetInfo &lhs, ArAssetInfo &rhs)
Definition: assetInfo.h:57
SDF_API bool SetAppendedItems(const ItemVector &items, std::string *errMsg=nullptr)
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
ItemVector value_vector_type
Definition: listOp.h:75
const ItemVector & GetPrependedItems() const
Returns the explicit items.
Definition: listOp.h:128
SDF_API void ComposeOperations(const SdfListOp< T > &stronger, SdfListOpType op)
const ItemVector & GetExplicitItems() const
Returns the explicit items.
Definition: listOp.h:122
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the and then *wait for them to all complete We provide a helper class
Definition: thread.h:632
const ItemVector & GetAppendedItems() const
Returns the explicit items.
Definition: listOp.h:134
const GLdouble * v
Definition: glcorearb.h:837
SDF_API const ItemVector & GetItems(SdfListOpType type) const
Return the item vector identified by type.
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
SDF_API bool ReplaceOperations(const SdfListOpType op, size_t index, size_t n, const ItemVector &newItems)
class SdfListOp< class SdfReference > SdfReferenceListOp
Definition: listOp.h:378
SDF_API void ClearAndMakeExplicit()
Removes all items and changes the list to be explicit.
PUGI__FN void reverse(I begin, I end)
Definition: pugixml.cpp:7458
friend void SdfApplyListOrdering(std::vector< ItemType > *v, const std::vector< ItemType > &order)
GLint y
Definition: glcorearb.h:103
**But if you need a result
Definition: thread.h:622
class SdfListOp< uint64_t > SdfUInt64ListOp
Definition: listOp.h:374
SDF_API void Swap(SdfListOp< T > &rhs)
class SdfListOp< class SdfPayload > SdfPayloadListOp
Definition: listOp.h:379
class SdfListOp< class SdfUnregisteredValue > SdfUnregisteredValueListOp
Definition: listOp.h:380
std::function< std::optional< ItemType >const ItemType &) > ModifyCallback
Callback type for ModifyOperations.
Definition: listOp.h:224
class SdfListOp< class SdfPath > SdfPathListOp
Definition: listOp.h:377
GLdouble n
Definition: glcorearb.h:2008
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
Definition: token.h:70
SDF_API bool ModifyOperations(const ModifyCallback &callback)
T ItemType
Definition: listOp.h:72
class SdfListOp< int > SdfIntListOp
Definition: listOp.h:371
const ItemVector & GetOrderedItems() const
Definition: listOp.h:266
const ItemVector & GetAddedItems() const
Definition: listOp.h:259
SdfListOpType
Definition: listOp.h:30
bool HasKeys() const
Definition: listOp.h:98
SDF_API bool SetExplicitItems(const ItemVector &items, std::string *errMsg=nullptr)
const ItemVector & GetDeletedItems() const
Returns the deleted items.
Definition: listOp.h:140
SDF_API ItemVector GetAppliedItems() const
GLdouble GLdouble GLint GLint order
Definition: glad.h:2676
class SdfListOp< std::string > SdfStringListOp
Definition: listOp.h:376
SDF_API bool SetDeletedItems(const ItemVector &items, std::string *errMsg=nullptr)
SDF_API bool SetPrependedItems(const ItemVector &items, std::string *errMsg=nullptr)
SDF_API void SetOrderedItems(const ItemVector &items)
SDF_API void Clear()
Removes all items and changes the list to be non-explicit.
class SdfListOp< int64_t > SdfInt64ListOp
Definition: listOp.h:373
class SdfListOp< TfToken > SdfTokenListOp
Definition: listOp.h:375
GLint GLenum GLint x
Definition: glcorearb.h:409
auto search(const T &set, const V &val) -> std::pair< bool, decltype(std::begin(detail::smart_deref(set)))>
A search function.
Definition: CLI11.h:3170
class SdfListOp< unsigned int > SdfUIntListOp
Definition: listOp.h:372
SDF_API SdfListOp()
Create an empty ListOp in non-explicit mode.
bool operator!=(const SdfListOp< T > &rhs) const
Definition: listOp.h:300
#define SDF_API
Definition: api.h:23
static size_t Combine(Args &&...args)
Produce a hash code by combining the hash codes of several objects.
Definition: hash.h:487
SDF_API void SetAddedItems(const ItemVector &items)
SDF_API void ApplyOperations(ItemVector *vec, const ApplyCallback &cb=ApplyCallback()) const
static SDF_API SdfListOp CreateExplicit(const ItemVector &explicitItems=ItemVector())
Create a ListOp in explicit mode with the given explicitItems.
SDF_API void SdfApplyListOrdering(std::vector< ItemType > *v, const std::vector< ItemType > &order)
GLuint index
Definition: glcorearb.h:786
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
std::vector< ItemType > ItemVector
Definition: listOp.h:73
static SDF_API SdfListOp Create(const ItemVector &prependedItems=ItemVector(), const ItemVector &appendedItems=ItemVector(), const ItemVector &deletedItems=ItemVector())
bool operator==(const SdfListOp< T > &rhs) const
Definition: listOp.h:290
std::function< std::optional< ItemType >SdfListOpType, const ItemType &) > ApplyCallback
Callback type for ApplyOperations.
Definition: listOp.h:196
std::less< T > ItemComparator
Definition: listOp.h:47
ItemType value_type
Definition: listOp.h:74
SDF_API bool HasItem(const T &item) const
Returns true if the given item is in any of the item lists.
bool IsExplicit() const
Returns true if the list is explicit.
Definition: listOp.h:116
friend size_t hash_value(const SdfListOp &op)
Definition: listOp.h:278