1 // 2 // Copyright 2016 Pixar 3 // 4 // Licensed under the Apache License, Version 2.0 (the "Apache License") 5 // with the following modification; you may not use this file except in 6 // compliance with the Apache License and the following modification to it: 7 // Section 6. Trademarks. is deleted and replaced with: 8 // 9 // 6. Trademarks. This License does not grant permission to use the trade 10 // names, trademarks, service marks, or product names of the Licensor 11 // and its affiliates, except as required to comply with Section 4(c) of 12 // the License and to reproduce the content of the NOTICE file. 13 // 14 // You may obtain a copy of the Apache License at 15 // 16 // http://www.apache.org/licenses/LICENSE-2.0 17 // 18 // Unless required by applicable law or agreed to in writing, software 19 // distributed under the Apache License with the above modification is 20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 21 // KIND, either express or implied. See the Apache License for the specific 22 // language governing permissions and limitations under the Apache License. 23 // 24 #ifndef PXR_BASE_TF_PY_RESULT_CONVERSIONS_H 25 #define PXR_BASE_TF_PY_RESULT_CONVERSIONS_H 26 27 #include "pxr/pxr.h" 28 29 #include "pxr/base/tf/pyUtils.h" 30 31 #include <boost/python/tuple.hpp> 32 #include <boost/python/list.hpp> 33 #include <boost/python/dict.hpp> 34 35 #include <boost/type_traits/add_reference.hpp> 36 #include <boost/type_traits/remove_reference.hpp> 37 38 #include <type_traits> 39 40 PXR_NAMESPACE_OPEN_SCOPE 41 42 template <typename T> struct Tf_PySequenceToListConverter; 43 template <typename T> struct Tf_PySequenceToSetConverter; 44 template <typename T> struct Tf_PyMapToDictionaryConverter; 45 template <typename T> struct Tf_PySequenceToTupleConverter; 46 template <typename First, typename Second> struct Tf_PyPairToTupleConverter; 47 48 /// \class TfPySequenceToList 49 /// 50 /// A \c boost::python result converter generator which converts standard 51 /// library sequences to lists. 52 /// 53 /// The way to use this is as a return value policy for a function which 54 /// returns a sequence or a const reference to a sequence. For example this 55 /// function: 56 /// \code 57 /// vector<double> getDoubles() { 58 /// vector<double> ret; 59 /// ret.push_back(1.0); 60 /// ret.push_back(2.0); 61 /// ret.push_back(3.0); 62 /// return ret; 63 /// } 64 /// \endcode 65 /// 66 /// May be wrapped as: 67 /// \code 68 /// def("getDoubles", &getDoubles, return_value_policy<TfPySequenceToList>()) 69 /// \endcode 70 struct TfPySequenceToList { 71 template <typename T> 72 struct apply { 73 typedef Tf_PySequenceToListConverter<T> type; 74 }; 75 }; 76 77 /// \class TfPySequenceToSet 78 /// 79 /// A \c boost::python result converter generator which converts standard 80 /// library sequences to sets. 81 /// 82 /// The way to use this is as a return value policy for a function which 83 /// returns a sequence or a const reference to a sequence. For example this 84 /// function: 85 /// \code 86 /// unordered_set<double> getDoubles() { 87 /// unordered_set<double> ret; 88 /// ret.insert(1.0); 89 /// ret.insert(2.0); 90 /// ret.insert(3.0); 91 /// return ret; 92 /// } 93 /// \endcode 94 /// 95 /// May be wrapped as: 96 /// \code 97 /// def("getDoubles", &getDoubles, return_value_policy<TfPySequenceToSet>()) 98 /// \endcode 99 struct TfPySequenceToSet { 100 template <typename T> 101 struct apply { 102 typedef Tf_PySequenceToSetConverter<T> type; 103 }; 104 }; 105 106 /// \class TfPyMapToDictionary 107 /// 108 /// A \c boost::python result converter generator which converts standard 109 /// library maps to dictionaries. 110 struct TfPyMapToDictionary { 111 template <typename T> 112 struct apply { 113 typedef Tf_PyMapToDictionaryConverter<T> type; 114 }; 115 }; 116 117 /// \class TfPySequenceToTuple 118 /// 119 /// A \c boost::python result converter generator which converts standard 120 /// library sequences to tuples. 121 /// \see TfPySequenceToList. 122 struct TfPySequenceToTuple { 123 template <typename T> 124 struct apply { 125 typedef Tf_PySequenceToTupleConverter<T> type; 126 }; 127 }; 128 129 /// A \c boost::python result converter generator which converts standard 130 /// library pairs to tuples. 131 struct TfPyPairToTuple { 132 template <typename T> 133 struct apply { 134 typedef Tf_PyPairToTupleConverter<typename T::first_type, 135 typename T::second_type> type; 136 }; 137 }; 138 139 template <typename T> 140 struct Tf_PySequenceToListConverter { 141 typedef typename boost::remove_reference<T>::type SeqType; convertibleTf_PySequenceToListConverter142 bool convertible() const { 143 return true; 144 } operatorTf_PySequenceToListConverter145 PyObject *operator()(T seq) const { 146 return boost::python::incref(TfPyCopySequenceToList(seq).ptr()); 147 } get_pytypeTf_PySequenceToListConverter148 PyTypeObject *get_pytype() { 149 return &PyList_Type; 150 } 151 }; 152 153 template <typename T> 154 struct Tf_PySequenceToSetConverter { 155 typedef typename std::remove_reference<T>::type SeqType; convertibleTf_PySequenceToSetConverter156 bool convertible() const { 157 return true; 158 } operatorTf_PySequenceToSetConverter159 PyObject *operator()(T seq) const { 160 return boost::python::incref(TfPyCopySequenceToSet(seq).ptr()); 161 } get_pytypeTf_PySequenceToSetConverter162 PyTypeObject *get_pytype() { 163 return &PySet_Type; 164 } 165 }; 166 167 template <typename T> 168 struct Tf_PyMapToDictionaryConverter { 169 typedef typename boost::remove_reference<T>::type SeqType; 170 // TODO: convertible() should be made more robust by checking that the 171 // value_type of the container is pair<const key_type, data_type> convertibleTf_PyMapToDictionaryConverter172 bool convertible() const { 173 return true; 174 } operatorTf_PyMapToDictionaryConverter175 PyObject *operator()(T seq) const { 176 return boost::python::incref(TfPyCopyMapToDictionary(seq).ptr()); 177 } get_pytypeTf_PyMapToDictionaryConverter178 PyTypeObject *get_pytype() { 179 return &PyDict_Type; 180 } 181 }; 182 183 template <typename T> 184 struct Tf_PySequenceToTupleConverter { 185 typedef typename boost::remove_reference<T>::type SeqType; convertibleTf_PySequenceToTupleConverter186 bool convertible() const { 187 return true; 188 } operatorTf_PySequenceToTupleConverter189 PyObject *operator()(T seq) const { 190 return boost::python::incref(TfPyCopySequenceToTuple(seq).ptr()); 191 } get_pytypeTf_PySequenceToTupleConverter192 PyTypeObject *get_pytype() { 193 return &PyTuple_Type; 194 } 195 }; 196 197 template <typename First, typename Second> 198 struct Tf_PyPairToTupleConverter { 199 typedef std::pair<First, Second> PairType; convertibleTf_PyPairToTupleConverter200 bool convertible() const { 201 return true; 202 } operatorTf_PyPairToTupleConverter203 PyObject *operator()(PairType const& a) const { 204 boost::python::tuple result = 205 boost::python::make_tuple(a.first, a.second); 206 return boost::python::incref(result.ptr()); 207 } get_pytypeTf_PyPairToTupleConverter208 PyTypeObject *get_pytype() { 209 return &PyTuple_Type; 210 } 211 }; 212 213 PXR_NAMESPACE_CLOSE_SCOPE 214 215 #endif // TF_RESULT_CONVERSIONS_H 216