24#ifndef PXR_USD_SDF_PY_LIST_PROXY_H
25#define PXR_USD_SDF_PY_LIST_PROXY_H
30#include "pxr/usd/sdf/changeBlock.h"
33#include "pxr/base/tf/pyLock.h"
35#include "pxr/base/tf/pyResultConversions.h"
38#include <boost/python.hpp>
39#include <boost/python/slice.hpp>
41PXR_NAMESPACE_OPEN_SCOPE
44class SdfPyWrapListProxy {
47 typedef typename Type::TypePolicy TypePolicy;
48 typedef typename Type::value_type value_type;
49 typedef typename Type::value_vector_type value_vector_type;
50 typedef SdfPyWrapListProxy<Type> This;
54 TfPyWrapOnce<Type>(&This::_Wrap);
60 using namespace boost::python;
62 class_<Type>(_GetName().c_str(), no_init)
63 .def(
"__str__", &This::_GetStr)
64 .def(
"__len__", &Type::size)
65 .def(
"__getitem__", &This::_GetItemIndex)
66 .def(
"__getitem__", &This::_GetItemSlice)
67 .def(
"__setitem__", &This::_SetItemIndex)
68 .def(
"__setitem__", &This::_SetItemSlice)
69 .def(
"__delitem__", &This::_DelItemIndex)
70 .def(
"__delitem__", &This::_DelItemSlice)
71 .def(
"__delitem__", &Type::Remove)
72 .def(
"count", &Type::Count)
73 .def(
"copy", &Type::operator value_vector_type,
74 return_value_policy<TfPySequenceToList>())
75 .def(
"index", &This::_FindIndex)
76 .def(
"clear", &Type::clear)
77 .def(
"insert", &This::_Insert)
78 .def(
"append", &Type::push_back)
79 .def(
"remove", &Type::Remove)
80 .def(
"replace", &Type::Replace)
81 .def(
"ApplyList", &Type::ApplyList)
82 .def(
"ApplyEditsToList", &This::_ApplyEditsToList)
83 .add_property(
"expired", &This::_IsExpired)
84 .add_static_property(
"invalidIndex", &This::_GetInvalidIndex)
91 .def(self == other<value_vector_type>())
92 .def(self != other<value_vector_type>())
93 .def(self < other<value_vector_type>())
94 .def(self <= other<value_vector_type>())
95 .def(self > other<value_vector_type>())
96 .def(self >= other<value_vector_type>())
100 static std::string _GetName()
102 std::string name =
"ListProxy_" +
103 ArchGetDemangled<TypePolicy>();
112 static std::string _GetStr(
const Type& x)
114 return TfPyRepr(
static_cast<value_vector_type
>(x));
117 static value_type _GetItemIndex(
const Type& x,
int index)
122 static boost::python::list _GetItemSlice(
const Type& x,
123 const boost::python::slice& index)
125 using namespace boost::python;
131 slice::range<typename Type::const_iterator> range =
132 index.get_indicies(x.begin(), x.end());
133 for (; range.start != range.stop; range.start += range.step) {
134 result.append(*range.start);
136 result.append(*range.start);
138 catch (
const std::invalid_argument&) {
146 static void _SetItemIndex(Type& x,
int index,
const value_type& value)
151 static void _SetItemSlice(Type& x,
const boost::python::slice& index,
152 const value_vector_type& values)
154 using namespace boost::python;
156 if (! x._Validate()) {
161 size_t start, step, count;
163 slice::range<typename Type::iterator> range =
164 index.get_indicies(x.begin(), x.end());
165 start = range.start - x.begin();
167 count = 1 + (range.stop - range.start) / range.step;
169 catch (
const std::invalid_argument&) {
171 extract<int> e(index.start());
179 x._Edit(start, count, values);
183 if (count != values.size()) {
186 "to extended slice of size %zd",
187 values.size(), count).c_str());
189 else if (step == 1) {
190 x._Edit(start, count, values);
194 for (
size_t i = 0, j = start; i != count; j += step, ++i) {
195 x._Edit(j, 1, value_vector_type(1, values[i]));
201 static void _DelItemIndex(Type& x,
int i)
204 1, value_vector_type());
207 static void _DelItemSlice(Type& x,
const boost::python::slice& index)
209 using namespace boost::python;
214 slice::range<typename Type::iterator> range =
215 index.get_indicies(x.begin(), x.end());
216 size_t start = range.start - x.begin();
217 size_t step = range.step;
218 size_t count = 1 + (range.stop - range.start) / range.step;
222 x._Edit(start, count, value_vector_type());
226 value_vector_type empty;
227 for (
size_t j = start; count > 0; j += step - 1, --count) {
228 x._Edit(j, 1, empty);
232 catch (
const std::invalid_argument&) {
238 static int _GetInvalidIndex()
246 static int _FindIndex(
const Type& x,
const value_type& value)
249 const size_t index = x.Find(value);
250 return index == Type::invalidIndex
252 : static_cast<int>(index);
255 return _GetInvalidIndex();
259 static void _Insert(Type& x,
int index,
const value_type& value)
262 index += x._GetSize();
264 if (index < 0 || index >
static_cast<int>(x._GetSize())) {
267 x._Edit(index, 0, value_vector_type(1, value));
270 static bool _IsExpired(
const Type& x)
272 return x.IsExpired();
275 static value_vector_type _ApplyEditsToList(Type& x,
276 const value_vector_type& values)
278 value_vector_type newValues = values;
279 x.ApplyEditsToList(&newValues);
284PXR_NAMESPACE_CLOSE_SCOPE
Miscellaneous Utilities for dealing with script.
TF_API void TfPyThrowIndexError(const char *msg)
Raises a Python IndexError with the given error msg and throws a boost::python::error_already_set exc...
TF_API bool TfPyIsNone(boost::python::object const &obj)
Return true iff obj is None.
TF_API void TfPyThrowValueError(const char *msg)
Raises a Python ValueError with the given error msg and throws a boost::python::error_already_set exc...
TF_API int64_t TfPyNormalizeIndex(int64_t index, uint64_t size, bool throwError=false)
Return a positive index in the range [0,size).
std::string TfPyRepr(T const &t)
Return repr(t).
Demangle C++ typenames generated by the typeid() facility.
TF_API std::string TfStringReplace(const std::string &source, const std::string &from, const std::string &to)
Replaces all occurrences of string from with to in source.
TF_API std::string TfStringPrintf(const char *fmt,...)
Returns a string formed by a printf()-like specification.
Definitions of basic string utilities in tf.