Skip to content

Commit

Permalink
Adapt CppBuilder<std::set<T>>::eligible
Browse files Browse the repository at this point in the history
  • Loading branch information
dubzzz committed Oct 27, 2015
1 parent 64fad0b commit 8a61399
Showing 1 changed file with 58 additions and 14 deletions.
72 changes: 58 additions & 14 deletions src/py2cpp.hpp
Expand Up @@ -533,36 +533,80 @@ template <class T> struct ToBuildable<std::vector<T>> : CppBuilder<std::vector<T
* Set builder
*/

template <class T>
struct CppBuilder<std::set<T>>
namespace
{
typedef std::set<typename ToBuildable<T>::value_type> value_type;
value_type operator() (PyObject* pyo) const
template <class T>
struct CppBuilderSetHelper
{
assert(pyo);
if (PySet_Check(pyo))
typedef std::set<typename ToBuildable<T>::value_type> value_type;

PyObject *pyo;
std::vector<PyObject*> backup;

CppBuilderSetHelper(PyObject* pyo) : pyo(pyo), backup()
{}

value_type build()
{
long size { PySet_Size(pyo) };
PyObject* backup[size];
value_type s;
for (auto& elt : backup)
long size { PySet_Size(pyo) };
for (long i { 0 } ; i != size ; ++i)
{
PyObject* popped { PySet_Pop(pyo) };
elt = popped;
backup.push_back(popped);
s.insert(ToBuildable<T>()(popped));
}
return s;
}

bool eligible()
{
long size { PySet_Size(pyo) };
for (long i { 0 } ; i != size ; ++i)
{
PyObject* popped { PySet_Pop(pyo) };
backup.push_back(popped);
if (! ToBuildable<T>().eligible(popped))
{
return false;
}
}
return true;
}

~CppBuilderSetHelper()
{
for (auto& popped : backup)
{
PySet_Add(pyo, popped);
Py_DECREF(popped);
PySet_Add(pyo, popped);
Py_DECREF(popped);
}
return s;
}
};
}

template <class T>
struct CppBuilder<std::set<T>>
{
typedef std::set<typename ToBuildable<T>::value_type> value_type;
value_type operator() (PyObject* pyo) const
{
assert(pyo);
if (PySet_Check(pyo))
{
CppBuilderSetHelper<T> helper(pyo);
return helper.build();
}
throw std::invalid_argument("Not a PySet instance");
}
bool eligible(PyObject* pyo) const
{
return PySet_Check(pyo);
if (! PySet_Check(pyo))
{
return false;
}
CppBuilderSetHelper<T> helper(pyo);
return helper.eligible();
}
};
template <class T> struct ToBuildable<std::set<T>> : CppBuilder<std::set<T>> {};
Expand Down

0 comments on commit 8a61399

Please sign in to comment.