blob: 2f0df8947f303bae75a792eda2d0e3ba0f06a617 [file] [log] [blame]
// 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