36 #ifndef VIGRA_NUMPY_ARRAY_CONVERTERS_HXX 37 #define VIGRA_NUMPY_ARRAY_CONVERTERS_HXX 39 #include "numpy_array.hxx" 40 #include "metaprogramming.hxx" 41 #include <boost/python.hpp> 42 #include <boost/python/to_python_converter.hpp> 43 #include <boost/python/raw_function.hpp> 45 #include <type_traits> 49 template <
class Array>
50 PyObject * returnNumpyArray(Array
const & a)
52 PyObject * pa = a.pyObject();
54 PyErr_SetString(PyExc_ValueError,
"returnNumpyArray(): Conversion to Python failed, array has no data.");
60 VIGRA_EXPORT std::set<std::string> & exportedArrayKeys();
62 template <
class ArrayType>
63 struct NumpyArrayConverter {};
65 template <
unsigned int N,
class T,
class Str
ide>
66 struct NumpyArrayConverter<NumpyArray<N, T, Stride> >
68 typedef NumpyArray<N, T, Stride> ArrayType;
69 typedef typename ArrayType::ArrayTraits ArrayTraits;
71 NumpyArrayConverter();
73 static void* convertible(PyObject* obj);
76 static void construct(PyObject* obj,
77 boost::python::converter::rvalue_from_python_stage1_data* data);
80 static PyObject* convert(ArrayType
const& a)
82 return returnNumpyArray(a);
86 template <
unsigned int N,
class T,
class Str
ide>
87 NumpyArrayConverter<NumpyArray<N, T, Stride> >::NumpyArrayConverter()
91 converter::registration
const * reg = converter::registry::query(type_id<ArrayType>());
95 if(!reg || !reg->rvalue_chain)
97 to_python_converter<ArrayType, NumpyArrayConverter>();
99 converter::registry::insert(&convertible, &construct, type_id<ArrayType>());
102 template <
unsigned int N,
class T,
class Str
ide>
103 void * NumpyArrayConverter<NumpyArray<N, T, Stride> >::convertible(PyObject* obj)
105 bool isCompatible = obj == Py_None || ArrayType::isStrictlyCompatible(obj);
113 template <
unsigned int N,
class T,
class Str
ide>
114 void NumpyArrayConverter<NumpyArray<N, T, Stride> >::construct(PyObject* obj,
115 boost::python::converter::rvalue_from_python_stage1_data* data)
117 void*
const storage =
118 ((boost::python::converter::rvalue_from_python_storage<ArrayType>* ) data)->storage.bytes;
120 ArrayType * array =
new (storage) ArrayType();
122 array->makeReferenceUnchecked(obj);
124 data->convertible = storage;
127 template <
unsigned int N,
class T,
class Str
ide>
128 struct NumpyArrayConverter<MultiArrayView<N, T, Stride> >
129 :
public NumpyArrayConverter<NumpyArray<N, T, Stride> >
131 typedef NumpyArrayConverter<NumpyArray<N, T, Stride> > BaseType;
132 typedef MultiArrayView<N, T, Stride> ArrayType;
134 NumpyArrayConverter()
137 converter::registry::insert(&BaseType::convertible, &BaseType::construct,
138 type_id<ArrayType>());
142 template <
class Iter,
class End>
143 struct RegisterNumpyArrayConverters
147 typedef typename UnqualifiedType<typename boost::mpl::deref<Iter>::type>::type Type;
148 NumpyArrayConverter<Type>();
149 RegisterNumpyArrayConverters<typename boost::mpl::next<Iter>::type, End>::exec();
154 struct RegisterNumpyArrayConverters<End, End>
160 template <
class Typelist>
161 void registerNumpyArrayConverters(Typelist)
163 RegisterNumpyArrayConverters<typename boost::mpl::begin<Typelist>::type,
164 typename boost::mpl::end<Typelist>::type >::exec();
168 FN registerConverters(FN f)
170 registerNumpyArrayConverters(boost::python::detail::get_signature(f));
180 struct TypeName<Singleband<T>>
185 struct TypeName<Multiband<T>>
189 template <
class T,
int N>
190 struct TypeName<TinyVector<T, N>>
195 struct TypeName<void>
197 static std::string name() {
198 return std::string(
"void");
200 static std::string sized_name() {
201 return std::string(
"void");
206 struct TypeName<bool>
208 static std::string name() {
209 return std::string(
"bool");
211 static std::string sized_name() {
212 return std::string(
"bool8");
216 #define VIGRA_SIGNED_INT_NAME(type) \ 218 struct TypeName<type> \ 220 static std::string name() { \ 221 return std::string(#type); \ 223 static std::string sized_name() { \ 224 return std::string("int") + std::to_string(sizeof(type)*8); \ 228 VIGRA_SIGNED_INT_NAME(
signed char)
229 VIGRA_SIGNED_INT_NAME(
short)
230 VIGRA_SIGNED_INT_NAME(
int)
231 VIGRA_SIGNED_INT_NAME(
long)
232 VIGRA_SIGNED_INT_NAME(
long long)
234 #define VIGRA_UNSIGNED_INT_NAME(type) \ 236 struct TypeName<type> \ 238 static std::string name() { \ 239 return std::string(#type); \ 241 static std::string sized_name() { \ 242 return std::string("uint") + std::to_string(sizeof(type)*8); \ 246 VIGRA_UNSIGNED_INT_NAME(
unsigned char)
247 VIGRA_UNSIGNED_INT_NAME(
unsigned short)
248 VIGRA_UNSIGNED_INT_NAME(
unsigned int)
249 VIGRA_UNSIGNED_INT_NAME(
unsigned long)
250 VIGRA_UNSIGNED_INT_NAME(
unsigned long long)
252 #define VIGRA_FLOAT_NAME(type) \ 254 struct TypeName<type> \ 256 static std::string name() { \ 257 return std::string(#type); \ 259 static std::string sized_name() { \ 260 return std::string("float") + std::to_string(sizeof(type)*8); \ 264 VIGRA_FLOAT_NAME(
float)
265 VIGRA_FLOAT_NAME(
double)
266 VIGRA_FLOAT_NAME(
long double)
268 #undef VIGRA_SIGNED_INT_NAME 269 #undef VIGRA_UNSIGNED_INT_NAME 270 #undef VIGRA_FLOAT_NAME 272 template <
class T =
void>
275 static char const * exec(
char const *) {
return 0; }
279 struct ExportDoc<void>
281 static char const * exec(
char const * h) {
return h; }
288 namespace boost {
namespace python {
295 #define VIGRA_PYTHON_MULTITYPE_FUNCTOR(functor_name, function) \ 297 struct functor_name##Impl \ 299 static void def(const char * pythonName) \ 301 boost::python::docstring_options doc(false); \ 302 boost::python::def(pythonName, vigra::registerConverters(&function<T>)); \ 305 template <class Args> \ 306 static void def(const char * pythonName, Args const & args) \ 308 boost::python::docstring_options doc(false); \ 309 boost::python::def(pythonName, vigra::registerConverters(&function<T>), args); \ 312 static void def(const char * pythonName, char const * help) \ 315 boost::python::def(pythonName, \ 316 vigra::registerConverters(&function<T>), help); \ 321 template <class Args> \ 322 static void def(const char * pythonName, Args const & args, char const * help) \ 325 boost::python::def(pythonName, \ 326 vigra::registerConverters(&function<T>), args, help); \ 328 def(pythonName, args); \ 333 struct functor_name##Impl<void> \ 335 static void def(const char *) {} \ 337 template <class A1> \ 338 static void def(const char *, A1 const &) {} \ 340 template <class A1, class A2> \ 341 static void def(const char *, A1 const &, A2 const &) {} \ 344 template <class T1, \ 356 struct functor_name \ 357 : public boost::python::PythonMultidefFunctor \ 359 bool install_fallback_, show_python_signature_; \ 362 : install_fallback_(false) \ 363 , show_python_signature_(true) \ 366 functor_name & installFallback() \ 368 install_fallback_ = true; \ 372 functor_name & noPythonSignature() \ 374 show_python_signature_ = false; \ 378 typedef boost::python::ArgumentMismatchMessage\ 379 <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Message; \ 380 typedef functor_name##Impl<T1 > F1; \ 381 typedef functor_name##Impl<T2 > F2; \ 382 typedef functor_name##Impl<T3 > F3; \ 383 typedef functor_name##Impl<T4 > F4; \ 384 typedef functor_name##Impl<T5 > F5; \ 385 typedef functor_name##Impl<T6 > F6; \ 386 typedef functor_name##Impl<T7 > F7; \ 387 typedef functor_name##Impl<T8 > F8; \ 388 typedef functor_name##Impl<T9 > F9; \ 389 typedef functor_name##Impl<T10> F10; \ 390 typedef functor_name##Impl<T11> F11; \ 391 typedef functor_name##Impl<T12> F12; \ 393 void def(const char * pythonName) const \ 395 boost::python::docstring_options doc(false, false, false); \ 396 if(install_fallback_) \ 397 Message::def(pythonName); \ 398 F1 ::def(pythonName); \ 399 F2 ::def(pythonName); \ 400 F3 ::def(pythonName); \ 401 F4 ::def(pythonName); \ 402 F5 ::def(pythonName); \ 403 F6 ::def(pythonName); \ 404 F7 ::def(pythonName); \ 405 F8 ::def(pythonName); \ 406 F9 ::def(pythonName); \ 407 F10::def(pythonName); \ 408 F11::def(pythonName); \ 409 F12::def(pythonName); \ 412 template <class Args> \ 413 void def(const char * pythonName, Args const & args) const \ 415 boost::python::docstring_options doc(false, false, false); \ 416 if(install_fallback_) \ 417 Message::def(pythonName); \ 418 F1 ::def(pythonName, args); \ 419 F2 ::def(pythonName, args); \ 420 F3 ::def(pythonName, args); \ 421 F4 ::def(pythonName, args); \ 422 F5 ::def(pythonName, args); \ 423 F6 ::def(pythonName, args); \ 424 F7 ::def(pythonName, args); \ 425 F8 ::def(pythonName, args); \ 426 F9 ::def(pythonName, args); \ 427 F10::def(pythonName, args); \ 428 F11::def(pythonName, args); \ 429 F12::def(pythonName, args); \ 432 void def(const char * pythonName, const char * help) const \ 434 if(install_fallback_) \ 435 Message::def(pythonName); \ 436 boost::python::docstring_options doc(true, show_python_signature_, false); \ 437 F1 ::def(pythonName, detail::ExportDoc<T2 >::exec(help)); \ 438 F2 ::def(pythonName, detail::ExportDoc<T3 >::exec(help)); \ 439 F3 ::def(pythonName, detail::ExportDoc<T4 >::exec(help)); \ 440 F4 ::def(pythonName, detail::ExportDoc<T5 >::exec(help)); \ 441 F5 ::def(pythonName, detail::ExportDoc<T6 >::exec(help)); \ 442 F6 ::def(pythonName, detail::ExportDoc<T7 >::exec(help)); \ 443 F7 ::def(pythonName, detail::ExportDoc<T8 >::exec(help)); \ 444 F8 ::def(pythonName, detail::ExportDoc<T9 >::exec(help)); \ 445 F9 ::def(pythonName, detail::ExportDoc<T10>::exec(help)); \ 446 F10::def(pythonName, detail::ExportDoc<T11>::exec(help)); \ 447 F11::def(pythonName, detail::ExportDoc<T12>::exec(help)); \ 448 F12::def(pythonName, detail::ExportDoc< >::exec(help)); \ 451 template <class Args> \ 452 void def(const char * pythonName, Args const & args, char const * help) const \ 454 if(install_fallback_) \ 455 Message::def(pythonName); \ 456 boost::python::docstring_options doc(true, show_python_signature_, false); \ 457 F1 ::def(pythonName, args, detail::ExportDoc<T2 >::exec(help)); \ 458 F2 ::def(pythonName, args, detail::ExportDoc<T3 >::exec(help)); \ 459 F3 ::def(pythonName, args, detail::ExportDoc<T4 >::exec(help)); \ 460 F4 ::def(pythonName, args, detail::ExportDoc<T5 >::exec(help)); \ 461 F5 ::def(pythonName, args, detail::ExportDoc<T6 >::exec(help)); \ 462 F6 ::def(pythonName, args, detail::ExportDoc<T7 >::exec(help)); \ 463 F7 ::def(pythonName, args, detail::ExportDoc<T8 >::exec(help)); \ 464 F8 ::def(pythonName, args, detail::ExportDoc<T9 >::exec(help)); \ 465 F9 ::def(pythonName, args, detail::ExportDoc<T10>::exec(help)); \ 466 F10::def(pythonName, args, detail::ExportDoc<T11>::exec(help)); \ 467 F11::def(pythonName, args, detail::ExportDoc<T12>::exec(help)); \ 468 F12::def(pythonName, args, detail::ExportDoc< >::exec(help)); \ 472 #define VIGRA_PYTHON_MULTITYPE_FUNCTOR_NDIM(functor_name, function) \ 473 template <class T, int FROM, int TO> \ 474 struct functor_name##Impl \ 476 typedef functor_name##Impl type; \ 478 static void def(const char * pythonName) \ 480 functor_name##Impl<T, FROM, FROM>::def(pythonName); \ 481 functor_name##Impl<T, FROM+1, TO>::def(pythonName); \ 484 template <class Args> \ 485 static void def(const char * pythonName, Args const & args) \ 487 functor_name##Impl<T, FROM, FROM>::def(pythonName, args); \ 488 functor_name##Impl<T, FROM+1, TO>::def(pythonName, args); \ 491 static void def(const char * pythonName, char const * help) \ 493 functor_name##Impl<T, FROM, FROM>::def(pythonName); \ 494 functor_name##Impl<T, FROM+1, TO>::def(pythonName, help); \ 497 template <class Args> \ 498 static void def(const char * pythonName, Args const & args, char const * help) \ 500 functor_name##Impl<T, FROM, FROM>::def(pythonName, args); \ 501 functor_name##Impl<T, FROM+1, TO>::def(pythonName, args, help); \ 505 template <class T, int N> \ 506 struct functor_name##Impl<T, N, N> \ 508 typedef functor_name##Impl type; \ 510 static void def(const char * pythonName) \ 512 boost::python::docstring_options doc(false); \ 513 boost::python::def(pythonName, vigra::registerConverters(&function<T, N>)); \ 516 template <class Args> \ 517 static void def(const char * pythonName, Args const & args) \ 519 boost::python::docstring_options doc(false); \ 520 boost::python::def(pythonName, vigra::registerConverters(&function<T, N>), args); \ 523 static void def(const char * pythonName, char const * help) \ 526 boost::python::def(pythonName, \ 527 vigra::registerConverters(&function<T, N>), help); \ 532 template <class Args> \ 533 static void def(const char * pythonName, Args const & args, char const * help) \ 536 boost::python::def(pythonName, \ 537 vigra::registerConverters(&function<T, N>), args, help); \ 539 def(pythonName, args); \ 543 template <int FROM, int TO> \ 544 struct functor_name##Impl<void, FROM, TO> \ 546 static void def(const char *) {} \ 548 template <class A1> \ 549 static void def(const char *, A1 const &) {} \ 551 template <class A1, class A2> \ 552 static void def(const char *, A1 const &, A2 const &) {} \ 556 struct functor_name##Impl<void, N, N> \ 558 static void def(const char *) {} \ 560 template <class A1> \ 561 static void def(const char *, A1 const &) {} \ 563 template <class A1, class A2> \ 564 static void def(const char *, A1 const &, A2 const &) {} \ 567 template <int FROM, int TO, \ 580 struct functor_name \ 581 : public boost::python::PythonMultidefFunctor \ 583 bool install_fallback_, show_python_signature_; \ 586 : install_fallback_(false) \ 587 , show_python_signature_(true) \ 589 static_assert(FROM <= TO, #functor_name ": dimension range empty (FROM > TO)"); \ 592 functor_name & installFallback() \ 594 install_fallback_ = true; \ 598 functor_name & noPythonSignature() \ 600 show_python_signature_ = false; \ 604 typedef boost::python::ArgumentMismatchMessage\ 605 <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Message; \ 606 typedef functor_name##Impl<T1 , FROM, TO> F1; \ 607 typedef functor_name##Impl<T2 , FROM, TO> F2; \ 608 typedef functor_name##Impl<T3 , FROM, TO> F3; \ 609 typedef functor_name##Impl<T4 , FROM, TO> F4; \ 610 typedef functor_name##Impl<T5 , FROM, TO> F5; \ 611 typedef functor_name##Impl<T6 , FROM, TO> F6; \ 612 typedef functor_name##Impl<T7 , FROM, TO> F7; \ 613 typedef functor_name##Impl<T8 , FROM, TO> F8; \ 614 typedef functor_name##Impl<T9 , FROM, TO> F9; \ 615 typedef functor_name##Impl<T10, FROM, TO> F10; \ 616 typedef functor_name##Impl<T11, FROM, TO> F11; \ 617 typedef functor_name##Impl<T12, FROM, TO> F12; \ 619 void def(const char * pythonName) const \ 621 boost::python::docstring_options doc(false, false, false); \ 622 if(install_fallback_) \ 623 Message::def(pythonName); \ 624 F1 ::def(pythonName); \ 625 F2 ::def(pythonName); \ 626 F3 ::def(pythonName); \ 627 F4 ::def(pythonName); \ 628 F5 ::def(pythonName); \ 629 F6 ::def(pythonName); \ 630 F7 ::def(pythonName); \ 631 F8 ::def(pythonName); \ 632 F9 ::def(pythonName); \ 633 F10::def(pythonName); \ 634 F11::def(pythonName); \ 635 F12::def(pythonName); \ 638 template <class Args> \ 639 void def(const char * pythonName, Args const & args) const \ 641 boost::python::docstring_options doc(false, false, false); \ 642 if(install_fallback_) \ 643 Message::def(pythonName); \ 644 F1 ::def(pythonName, args); \ 645 F2 ::def(pythonName, args); \ 646 F3 ::def(pythonName, args); \ 647 F4 ::def(pythonName, args); \ 648 F5 ::def(pythonName, args); \ 649 F6 ::def(pythonName, args); \ 650 F7 ::def(pythonName, args); \ 651 F8 ::def(pythonName, args); \ 652 F9 ::def(pythonName, args); \ 653 F10::def(pythonName, args); \ 654 F11::def(pythonName, args); \ 655 F12::def(pythonName, args); \ 658 void def(const char * pythonName, const char * help) const \ 660 if(install_fallback_) \ 661 Message::def(pythonName); \ 662 boost::python::docstring_options doc(true, show_python_signature_, false); \ 663 F1 ::def(pythonName, detail::ExportDoc<T2 >::exec(help)); \ 664 F2 ::def(pythonName, detail::ExportDoc<T3 >::exec(help)); \ 665 F3 ::def(pythonName, detail::ExportDoc<T4 >::exec(help)); \ 666 F4 ::def(pythonName, detail::ExportDoc<T5 >::exec(help)); \ 667 F5 ::def(pythonName, detail::ExportDoc<T6 >::exec(help)); \ 668 F6 ::def(pythonName, detail::ExportDoc<T7 >::exec(help)); \ 669 F7 ::def(pythonName, detail::ExportDoc<T8 >::exec(help)); \ 670 F8 ::def(pythonName, detail::ExportDoc<T9 >::exec(help)); \ 671 F9 ::def(pythonName, detail::ExportDoc<T10>::exec(help)); \ 672 F10::def(pythonName, detail::ExportDoc<T11>::exec(help)); \ 673 F11::def(pythonName, detail::ExportDoc<T12>::exec(help)); \ 674 F12::def(pythonName, detail::ExportDoc< >::exec(help)); \ 677 template <class Args> \ 678 void def(const char * pythonName, Args const & args, char const * help) const \ 680 if(install_fallback_) \ 681 Message::def(pythonName); \ 682 boost::python::docstring_options doc(true, show_python_signature_, false); \ 683 F1 ::def(pythonName, args, detail::ExportDoc<T2 >::exec(help)); \ 684 F2 ::def(pythonName, args, detail::ExportDoc<T3 >::exec(help)); \ 685 F3 ::def(pythonName, args, detail::ExportDoc<T4 >::exec(help)); \ 686 F4 ::def(pythonName, args, detail::ExportDoc<T5 >::exec(help)); \ 687 F5 ::def(pythonName, args, detail::ExportDoc<T6 >::exec(help)); \ 688 F6 ::def(pythonName, args, detail::ExportDoc<T7 >::exec(help)); \ 689 F7 ::def(pythonName, args, detail::ExportDoc<T8 >::exec(help)); \ 690 F8 ::def(pythonName, args, detail::ExportDoc<T9 >::exec(help)); \ 691 F9 ::def(pythonName, args, detail::ExportDoc<T10>::exec(help)); \ 692 F10::def(pythonName, args, detail::ExportDoc<T11>::exec(help)); \ 693 F11::def(pythonName, args, detail::ExportDoc<T12>::exec(help)); \ 694 F12::def(pythonName, args, detail::ExportDoc< >::exec(help)); \ 698 struct PythonMultidefFunctor {};
712 struct ArgumentMismatchMessage
714 static std::string message()
717 "No C++ overload matches the arguments. This can have three reasons:\n\n" 718 " * The array arguments may have an unsupported element type. You may need\n" 719 " to convert your array(s) to another element type using 'array.astype(...)'.\n" 720 " The function currently supports the following types:\n\n ");
721 res += vigra::detail::TypeName<T1>::sized_name();
723 if(vigra::detail::TypeName<T2>::sized_name() !=
"void")
724 res +=
", " + vigra::detail::TypeName<T2>::sized_name();
725 if(vigra::detail::TypeName<T3>::sized_name() !=
"void")
726 res +=
", " + vigra::detail::TypeName<T3>::sized_name();
727 if(vigra::detail::TypeName<T4>::sized_name() !=
"void")
728 res +=
", " + vigra::detail::TypeName<T4>::sized_name();
729 if(vigra::detail::TypeName<T5>::sized_name() !=
"void")
730 res +=
", " + vigra::detail::TypeName<T5>::sized_name();
731 if(vigra::detail::TypeName<T6>::sized_name() !=
"void")
732 res +=
", " + vigra::detail::TypeName<T6>::sized_name();
733 if(vigra::detail::TypeName<T7>::sized_name() !=
"void")
734 res +=
", " + vigra::detail::TypeName<T7>::sized_name();
735 if(vigra::detail::TypeName<T8>::sized_name() !=
"void")
736 res +=
", " + vigra::detail::TypeName<T8>::sized_name();
737 if(vigra::detail::TypeName<T9>::sized_name() !=
"void")
738 res +=
", " + vigra::detail::TypeName<T9>::sized_name();
739 if(vigra::detail::TypeName<T10>::sized_name() !=
"void")
740 res +=
", " + vigra::detail::TypeName<T10>::sized_name();
741 if(vigra::detail::TypeName<T11>::sized_name() !=
"void")
742 res +=
", " + vigra::detail::TypeName<T11>::sized_name();
743 if(vigra::detail::TypeName<T12>::sized_name() !=
"void")
744 res +=
", " + vigra::detail::TypeName<T12>::sized_name();
748 " * The dimension of your array(s) is currently unsupported (consult the\n" 749 " function's documentation for information about supported dimensions).\n\n" 750 " * You provided an unrecognized argument, or an argument with incorrect type\n" 751 " (consult the documentation for valid function signatures).\n\n" 752 "Additional overloads can easily be added in the vigranumpy C++ sources.\n" 753 "Please submit an issue at http://github.com/ukoethe/vigra/ to let us know\n" 754 "what you need (or a pull request if you solved it on your own :-).\n\n";
759 static void def(
const char * pythonName)
761 docstring_options doc(
false,
false,
false);
762 std::string msg = message(),
763 module = extract<std::string>(scope().attr(
"__name__"))() +
".";
764 msg +=
"Type 'help(" + module + pythonName +
")' to get full documentation.\n";
765 boost::python::def(pythonName,
766 raw_function([msg](tuple, dict) ->
object {
767 throw std::invalid_argument(msg);
775 template <
class Functor>
776 inline typename std::enable_if<std::is_base_of<PythonMultidefFunctor, Functor>::value,
778 multidef(
char const* python_name, Functor
const & f)
783 template <
class Functor,
class Args>
784 inline typename std::enable_if<std::is_base_of<PythonMultidefFunctor, Functor>::value,
786 multidef(
char const* python_name, Functor
const & f, Args
const& args)
788 f.def(python_name, args);
791 template <
class Functor>
792 inline typename std::enable_if<std::is_base_of<PythonMultidefFunctor, Functor>::value,
794 multidef(
char const* python_name, Functor
const & f,
const char * help)
796 f.def(python_name, help);
799 template <
class Functor,
class Args>
800 inline typename std::enable_if<std::is_base_of<PythonMultidefFunctor, Functor>::value,
802 multidef(
char const* python_name, Functor
const & f, Args
const& args,
const char * help)
804 f.def(python_name, args, help);
808 template <
class Functor>
809 inline typename std::enable_if<std::is_base_of<PythonMultidefFunctor, Functor>::value,
811 def(
char const* python_name, Functor
const & f)
813 static_assert(!std::is_base_of<PythonMultidefFunctor, Functor>::value,
814 "def(): use multidef() to export multiple overloads.");
817 template <
class Functor,
class Args>
818 inline typename std::enable_if<std::is_base_of<PythonMultidefFunctor, Functor>::value,
820 def(
char const* python_name, Functor
const & f, Args
const& args)
822 static_assert(!std::is_base_of<PythonMultidefFunctor, Functor>::value,
823 "def(): use multidef() to export multiple overloads.");
826 template <
class Functor>
827 inline typename std::enable_if<std::is_base_of<PythonMultidefFunctor, Functor>::value,
829 def(
char const* python_name, Functor
const & f,
const char * help)
831 static_assert(!std::is_base_of<PythonMultidefFunctor, Functor>::value,
832 "def(): use multidef() to export multiple overloads.");
835 template <
class Functor,
class Args>
836 inline typename std::enable_if<std::is_base_of<PythonMultidefFunctor, Functor>::value,
838 def(
char const* python_name, Functor
const & f, Args
const& args,
const char * help)
840 static_assert(!std::is_base_of<PythonMultidefFunctor, Functor>::value,
841 "def(): use multidef() to export multiple overloads.");
846 #endif // VIGRA_NUMPY_ARRAY_CONVERTERS_HXX Definition: adjacency_list_graph.hxx:1087
Definition: accessor.hxx:43
Definition: numpy_array_converters.hxx:288