| // Copyright (c) Microsoft. All rights reserved. |
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. |
| |
| #pragma once |
| |
| #include "list_indexing_suite.h" |
| |
| namespace bond |
| { |
| namespace python |
| { |
| |
| // Indexing suite for std::set |
| |
| template <typename T, bool NoProxy, typename DerivedPolicies> |
| class set_indexing_suite; |
| |
| namespace detail |
| { |
| template <typename T, bool NoProxy> |
| class final_set_derived_policies |
| : public bond::python::set_indexing_suite< |
| T, |
| NoProxy, |
| final_set_derived_policies<T, NoProxy> > |
| {}; |
| } |
| |
| template < |
| typename T, |
| bool NoProxy = false, |
| typename DerivedPolicies = detail::final_set_derived_policies<T, NoProxy> |
| > |
| class set_indexing_suite |
| : public list_indexing_suite<T, NoProxy, DerivedPolicies> |
| { |
| typedef list_indexing_suite<T, NoProxy, DerivedPolicies> base; |
| public: |
| typedef typename base::data_type data_type; |
| typedef typename base::index_type index_type; |
| typedef typename base::key_type key_type; |
| |
| template <class Class> |
| static void |
| extension_def(Class& class_) |
| { |
| class_ |
| .def("add", &function<DerivedPolicies::add>) |
| .def("remove", &function<DerivedPolicies::remove>) |
| .def("discard", &function<DerivedPolicies::discard>) |
| .def("clear", &DerivedPolicies::clear) |
| ; |
| } |
| |
| static bool |
| contains(T& set, key_type const& key) |
| { |
| return set.find(key) != set.end(); |
| } |
| |
| static void |
| add(T& set, data_type const& v) |
| { |
| set.insert(v); |
| } |
| |
| static void |
| discard(T& set, data_type const& v) |
| { |
| set.erase(v); |
| } |
| |
| static void |
| remove(T& set, data_type const& v) |
| { |
| if (!set.erase(v)) |
| { |
| PyErr_SetString(PyExc_KeyError, "Element doesn't exist"); |
| boost::python::throw_error_already_set(); |
| } |
| } |
| |
| static void |
| clear(T& set) |
| { |
| set.clear(); |
| } |
| |
| static data_type |
| get_item(T&, index_type) |
| { |
| not_supported(); |
| return data_type(); |
| } |
| |
| static void |
| set_item(T&, index_type, data_type const&) |
| { |
| not_supported(); |
| } |
| |
| static void |
| set_slice(T&, index_type, index_type, data_type const&) |
| { |
| not_supported(); |
| } |
| |
| template <typename Iter> |
| static void |
| set_slice(T&, index_type, index_type, Iter, Iter) |
| { |
| not_supported(); |
| } |
| |
| private: |
| template <void (*fn)(T&, data_type const&)> |
| static void |
| function(T& set, const boost::python::object v) |
| { |
| using namespace boost::python; |
| |
| extract<data_type&> elemRef(v); |
| |
| if (elemRef.check()) |
| { |
| fn(set, elemRef()); |
| } |
| else |
| { |
| extract<data_type> elem(v); |
| |
| if (elem.check()) |
| { |
| fn(set, elem()); |
| } |
| else |
| { |
| PyErr_SetString(PyExc_TypeError, "Invalid type"); |
| throw_error_already_set(); |
| } |
| } |
| } |
| |
| static void |
| not_supported() |
| { |
| PyErr_SetString(PyExc_TypeError, "__getitem__ and __setitem__ not supported for set object"); |
| boost::python::throw_error_already_set(); |
| } |
| }; |
| |
| } // namespace python |
| |
| } // namespace bond |