Commit 4b853865 authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz

python: initial work on wrapping twa_graph::out(n)

* spot/twa/twagraph.hh (out): Do not hide from SWIG.
* spot/graph/graph.hh: Hide stuff that SWIG do not understand.
* wrap/python/spot_impl.i: Add some typemaps and fragment to
iterate over the result of twa_graph::out().
parent 4e040fd9
...@@ -36,6 +36,7 @@ namespace spot ...@@ -36,6 +36,7 @@ namespace spot
namespace internal namespace internal
{ {
#ifndef SWIG
template <typename Of, typename ...Args> template <typename Of, typename ...Args>
struct first_is_base_of struct first_is_base_of
{ {
...@@ -48,7 +49,7 @@ namespace spot ...@@ -48,7 +49,7 @@ namespace spot
static const bool value = static const bool value =
std::is_base_of<Of, typename std::decay<Arg1>::type>::value; std::is_base_of<Of, typename std::decay<Arg1>::type>::value;
}; };
#endif
// The boxed_label class stores Data as an attribute called // The boxed_label class stores Data as an attribute called
// "label" if boxed is true. It is an empty class if Data is // "label" if boxed is true. It is an empty class if Data is
...@@ -62,6 +63,7 @@ namespace spot ...@@ -62,6 +63,7 @@ namespace spot
typedef Data data_t; typedef Data data_t;
Data label; Data label;
#ifndef SWIG
template <typename... Args, template <typename... Args,
typename = typename std::enable_if< typename = typename std::enable_if<
!first_is_base_of<boxed_label, Args...>::value>::type> !first_is_base_of<boxed_label, Args...>::value>::type>
...@@ -70,6 +72,7 @@ namespace spot ...@@ -70,6 +72,7 @@ namespace spot
: label{std::forward<Args>(args)...} : label{std::forward<Args>(args)...}
{ {
} }
#endif
// if Data is a POD type, G++ 4.8.2 wants default values for all // if Data is a POD type, G++ 4.8.2 wants default values for all
// label fields unless we define this default constructor here. // label fields unless we define this default constructor here.
...@@ -115,6 +118,7 @@ namespace spot ...@@ -115,6 +118,7 @@ namespace spot
{ {
typedef Data data_t; typedef Data data_t;
#ifndef SWIG
template <typename... Args, template <typename... Args,
typename = typename std::enable_if< typename = typename std::enable_if<
!first_is_base_of<boxed_label, Args...>::value>::type> !first_is_base_of<boxed_label, Args...>::value>::type>
...@@ -123,6 +127,7 @@ namespace spot ...@@ -123,6 +127,7 @@ namespace spot
: Data{std::forward<Args>(args)...} : Data{std::forward<Args>(args)...}
{ {
} }
#endif
// if Data is a POD type, G++ 4.8.2 wants default values for all // if Data is a POD type, G++ 4.8.2 wants default values for all
// label fields unless we define this default constructor here. // label fields unless we define this default constructor here.
...@@ -155,7 +160,7 @@ namespace spot ...@@ -155,7 +160,7 @@ namespace spot
Edge succ = 0; // First outgoing edge (used when iterating) Edge succ = 0; // First outgoing edge (used when iterating)
Edge succ_tail = 0; // Last outgoing edge (used for Edge succ_tail = 0; // Last outgoing edge (used for
// appending new edges) // appending new edges)
#ifndef SWIG
template <typename... Args, template <typename... Args,
typename = typename std::enable_if< typename = typename std::enable_if<
!first_is_base_of<distate_storage, Args...>::value>::type> !first_is_base_of<distate_storage, Args...>::value>::type>
...@@ -164,6 +169,7 @@ namespace spot ...@@ -164,6 +169,7 @@ namespace spot
: State_Data{std::forward<Args>(args)...} : State_Data{std::forward<Args>(args)...}
{ {
} }
#endif
}; };
////////////////////////////////////////////////// //////////////////////////////////////////////////
...@@ -189,6 +195,7 @@ namespace spot ...@@ -189,6 +195,7 @@ namespace spot
{ {
} }
#ifndef SWIG
template <typename... Args> template <typename... Args>
edge_storage(StateOut dst, Edge next_succ, edge_storage(StateOut dst, Edge next_succ,
StateIn src, Args&&... args) StateIn src, Args&&... args)
...@@ -199,6 +206,7 @@ namespace spot ...@@ -199,6 +206,7 @@ namespace spot
dst(dst), next_succ(next_succ), src(src) dst(dst), next_succ(next_succ), src(src)
{ {
} }
#endif
bool operator<(const edge_storage& other) const bool operator<(const edge_storage& other) const
{ {
...@@ -231,12 +239,12 @@ namespace spot ...@@ -231,12 +239,12 @@ namespace spot
// of that list. // of that list.
template <typename Graph> template <typename Graph>
class SPOT_API edge_iterator: class SPOT_API edge_iterator: public
std::iterator<std::forward_iterator_tag, std::iterator<std::forward_iterator_tag,
typename typename
std::conditional<std::is_const<Graph>::value, std::conditional<std::is_const<Graph>::value,
const typename Graph::edge_storage_t, const typename Graph::edge_storage_t,
typename Graph::edge_storage_t>::type> typename Graph::edge_storage_t>::type>
{ {
typedef typedef
std::iterator<std::forward_iterator_tag, std::iterator<std::forward_iterator_tag,
...@@ -274,12 +282,24 @@ namespace spot ...@@ -274,12 +282,24 @@ namespace spot
return g_->edge_storage(t_); return g_->edge_storage(t_);
} }
const typename super::reference
operator*() const
{
return g_->edge_storage(t_);
}
typename super::pointer typename super::pointer
operator->() operator->()
{ {
return &g_->edge_storage(t_); return &g_->edge_storage(t_);
} }
const typename super::pointer
operator->() const
{
return &g_->edge_storage(t_);
}
edge_iterator operator++() edge_iterator operator++()
{ {
t_ = operator*().next_succ; t_ = operator*().next_succ;
...@@ -412,7 +432,7 @@ namespace spot ...@@ -412,7 +432,7 @@ namespace spot
////////////////////////////////////////////////// //////////////////////////////////////////////////
template <typename Graph> template <typename Graph>
class SPOT_API all_edge_iterator: class SPOT_API all_edge_iterator: public
std::iterator<std::forward_iterator_tag, std::iterator<std::forward_iterator_tag,
typename typename
std::conditional<std::is_const<Graph>::value, std::conditional<std::is_const<Graph>::value,
...@@ -484,11 +504,23 @@ namespace spot ...@@ -484,11 +504,23 @@ namespace spot
return tv_[t_]; return tv_[t_];
} }
typename super::pointer const typename super::reference
operator*() const
{
return tv_[t_];
}
const typename super::pointer
operator->() operator->()
{ {
return &tv_[t_]; return &tv_[t_];
} }
typename super::pointer
operator->() const
{
return &tv_[t_];
}
}; };
......
...@@ -387,11 +387,20 @@ namespace spot ...@@ -387,11 +387,20 @@ namespace spot
} }
#ifndef SWIG #ifndef SWIG
auto out(unsigned src) const internal::state_out<const graph_t>
SPOT_RETURN(g_.out(src)); out(unsigned src) const
auto out(unsigned src) {
SPOT_RETURN(g_.out(src)); return g_.out(src);
}
#endif
internal::state_out<graph_t>
out(unsigned src)
{
return g_.out(src);
}
#ifndef SWIG
auto states() const auto states() const
SPOT_RETURN(g_.states()); SPOT_RETURN(g_.states());
auto states() auto states()
......
...@@ -109,8 +109,8 @@ ...@@ -109,8 +109,8 @@
#include <spot/twa/twaproduct.hh> #include <spot/twa/twaproduct.hh>
#include <spot/twaalgos/cleanacc.hh> #include <spot/twaalgos/cleanacc.hh>
#include <spot/twaalgos/dot.hh>
#include <spot/twaalgos/degen.hh> #include <spot/twaalgos/degen.hh>
#include <spot/twaalgos/dot.hh>
#include <spot/twaalgos/copy.hh> #include <spot/twaalgos/copy.hh>
#include <spot/twaalgos/complete.hh> #include <spot/twaalgos/complete.hh>
#include <spot/twaalgos/complement.hh> #include <spot/twaalgos/complement.hh>
...@@ -153,6 +153,71 @@ using namespace spot; ...@@ -153,6 +153,71 @@ using namespace spot;
%} %}
// Swig come with iterators that implement a decrement method.
// This is not supported in our "successor" iterators.
%fragment("ForwardIterator_T","header",fragment="SwigPyIterator_T") {
namespace swig
{
template<typename OutIterator,
typename ValueType =
typename std::iterator_traits<OutIterator>::value_type,
typename FromOper = from_oper<ValueType> >
class ForwardIterator_T : public SwigPyIterator_T<OutIterator>
{
public:
FromOper from;
typedef OutIterator out_iterator;
typedef ValueType value_type;
typedef SwigPyIterator_T<out_iterator> base;
typedef ForwardIterator_T<OutIterator, ValueType, FromOper> self_type;
ForwardIterator_T(out_iterator curr, out_iterator first,
out_iterator last, PyObject *seq)
: SwigPyIterator_T<OutIterator>(curr, seq), begin(first), end(last)
{
}
PyObject *value() const {
if (base::current == end) {
throw stop_iteration();
} else {
return from(static_cast<const value_type&>(*(base::current)));
}
}
SwigPyIterator *copy() const
{
return new self_type(*this);
}
SwigPyIterator *incr(size_t n = 1)
{
while (n--) {
if (base::current == end) {
throw stop_iteration();
} else {
++base::current;
}
}
return this;
}
private:
out_iterator begin;
out_iterator end;
};
template<typename OutIter>
inline SwigPyIterator*
make_forward_iterator(const OutIter& current,
const OutIter& begin,
const OutIter& end, PyObject *seq = 0)
{
return new ForwardIterator_T<OutIter>(current, begin, end, seq);
}
}
}
%fragment("ForwardIterator_T");
// For spot::emptiness_check_instantiator::construct and any other // For spot::emptiness_check_instantiator::construct and any other
// function that return errors via a "char **err" argument. // function that return errors via a "char **err" argument.
...@@ -284,8 +349,25 @@ namespace std { ...@@ -284,8 +349,25 @@ namespace std {
%include <spot/twa/taatgba.hh> %include <spot/twa/taatgba.hh>
%include <spot/twa/twaproduct.hh> %include <spot/twa/twaproduct.hh>
%include <spot/graph/graph.hh>
%nodefaultctor spot::digraph;
%nodefaultctor spot::internal::state_out;
%traits_swigtype(spot::internal::edge_storage<unsigned int, unsigned int, unsigned int, spot::internal::boxed_label<spot::twa_graph_edge_data, false> >);
%fragment(SWIG_Traits_frag(spot::internal::edge_storage<unsigned int, unsigned int, unsigned int, spot::internal::boxed_label<spot::twa_graph_edge_data, false> >));
%typemap(out, optimal="1") spot::internal::state_out<spot::digraph<spot::twa_graph_state, spot::twa_graph_edge_data>> {
$result = SWIG_NewPointerObj(new $1_ltype($1), $&1_descriptor,
SWIG_POINTER_OWN);
}
%noexception spot::twa_graph::out;
%include <spot/twa/twagraph.hh> %include <spot/twa/twagraph.hh>
%template(twa_graph_state_out) spot::internal::state_out<spot::digraph<spot::twa_graph_state, spot::twa_graph_edge_data>>;
%template(twa_graph_edge_boxed_data) spot::internal::boxed_label<spot::twa_graph_edge_data, false>;
%template(twa_graph_edge_storage) spot::internal::edge_storage<unsigned int, unsigned int, unsigned int, spot::internal::boxed_label<spot::twa_graph_edge_data, false> >;
// Should come after the definition of twa_graph // Should come after the definition of twa_graph
%include <spot/twaalgos/cleanacc.hh> %include <spot/twaalgos/cleanacc.hh>
...@@ -303,8 +385,8 @@ namespace std { ...@@ -303,8 +385,8 @@ namespace std {
%include <spot/twaalgos/magic.hh> %include <spot/twaalgos/magic.hh>
%include <spot/twaalgos/minimize.hh> %include <spot/twaalgos/minimize.hh>
%include <spot/twaalgos/neverclaim.hh> %include <spot/twaalgos/neverclaim.hh>
%include <spot/twaalgos/strength.hh>
%include <spot/twaalgos/remfin.hh> %include <spot/twaalgos/remfin.hh>
%include <spot/twaalgos/strength.hh>
%include <spot/twaalgos/sccfilter.hh> %include <spot/twaalgos/sccfilter.hh>
%include <spot/twaalgos/stats.hh> %include <spot/twaalgos/stats.hh>
%include <spot/twaalgos/isdet.hh> %include <spot/twaalgos/isdet.hh>
...@@ -369,6 +451,15 @@ namespace std { ...@@ -369,6 +451,15 @@ namespace std {
} }
} }
%extend spot::internal::state_out<spot::digraph<spot::twa_graph_state, spot::twa_graph_edge_data>> {
swig::SwigPyIterator* __iter__(PyObject **PYTHON_SELF)
{
return swig::make_forward_iterator(self->begin(), self->begin(),
self->end(), *PYTHON_SELF);
}
}
%extend spot::acc_cond::acc_code { %extend spot::acc_cond::acc_code {
std::string __repr__() std::string __repr__()
{ {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment