8000 remove support for plot(Iterable, Callable), due to template conflicts · Cryoris/matplotlib-cpp@a3580cb · GitHub
[go: up one dir, main page]

Skip to content

Commit a3580cb

Browse files
committed
remove support for plot(Iterable, Callable), due to template conflicts
A call to plot with an iterable as first and callable as second argument also matches the plot(VectorX, VectorY) template function. Since latter is needed for Eigen and matplotlib inherently doesn't support plot(x, function) callables aren't supported anymore. If necessary this feature could be implemented using template-deduction via is_callable as before.
1 parent b00e391 commit a3580cb

File tree

1 file changed

+2
-107
lines changed

1 file changed

+2
-107
lines changed

matplotlibcpp.h

Lines changed: 2 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,117 +1763,12 @@ inline void tight_layout() {
17631763
Py_DECREF(res);
17641764
}
17651765

1766-
// Support for variadic plot() and initializer lists:
1767-
1768-
namespace detail {
1769-
1770-
template <typename T>
1771-
using is_function = typename std::is_function<
1772-
std::remove_pointer<std::remove_reference<T>>>::type;
1773-
1774-
template <bool obj, typename T> struct is_callable_impl;
1775-
1776-
template <typename T> struct is_callable_impl<false, T> {
1777-
typedef is_function<T> type;
1778-
}; // a non-object is callable iff it is a function
1779-
1780-
template <typename T> struct is_callable_impl<true, T> {
1781-
struct Fallback {
1782-
void operator()();
1783-
};
1784-
struct Derived : T, Fallback {};
1785-
1786-
template <typename U, U> struct Check;
1787-
1788-
template <typename U>
1789-
static std::true_type
1790-
test(...); // use a variadic function to make sure (1) it accepts everything
1791-
// and (2) its always the worst match
1792-
1793-
template <typename U>
1794-
static std::false_type test(Check<void (Fallback::*)(), &U::operator()> *);
1795-
1796-
public:
1797-
typedef decltype(test<Derived>(nullptr)) type;
1798-
typedef decltype(&Fallback::operator()) dtype;
1799-
static constexpr bool value = type::value;
1800-
}; // an object is callable iff it defines operator()
1801-
1802-
template <typename T> struct is_callable {
1803-
// dispatch to is_callable_impl<true, T> or is_callable_impl<false, T>
1804-
// depending on whether T is of class type or not
1805-
typedef typename is_callable_impl<std::is_class<T>::value, T>::type type;
1806-
};
1807-
1808-
template <typename IsYDataCallable> struct plot_impl {};
1809-
1810-
template <> struct plot_impl<std::false_type> {
1811-
template <typename IterableX, typename IterableY>
1812-
bool operator()(const IterableX &x, const IterableY &y,
1813-
const std::string &format) {
1814-
detail::_interpreter::get();
1815-
1816-
// 2-phase lookup for distance, begin, end
1817-
using std::begin;
1818-
using std::distance;
1819-
using std::end;
1820-
1821-
auto xs = distance(begin(x), end(x));
1822-
auto ys = distance(begin(y), end(y));
1823-
assert(xs == ys && "x and y data must have the same number of elements!");
1824-
1825-
PyObject *xlist = PyList_New(xs);
1826-
PyObject *ylist = PyList_New(ys);
1827-
PyObject *pystring = PyString_FromString(format.c_str());
1828-
1829-
auto itx = begin(x), ity = begin(y);
1830-
for (size_t i = 0; i < xs; ++i) {
1831-
PyList_SetItem(xlist, i, PyFloat_FromDouble(*itx++));
1832-
PyList_SetItem(ylist, i, PyFloat_FromDouble(*ity++));
1833-
}
1834-
1835-
PyObject *plot_args = PyTuple_New(3);
1836-
PyTuple_SetItem(plot_args, 0, xlist);
1837-
PyTuple_SetItem(plot_args, 1, ylist);
1838-
PyTuple_SetItem(plot_args, 2, pystring);
1839-
1840-
PyObject *res = PyObject_CallObject(
1841-
detail::_interpreter::get().s_python_function_plot, plot_args);
1842-
1843-
Py_DECREF(plot_args);
1844-
if (res)
1845-
Py_DECREF(res);
1846-
1847-
return res;
1848-
}
1849-
};
1850-
1851-
template <> struct plot_impl<std::true_type> {
1852-
template <typename Iterable, typename Callable>
1853-
bool operator()(const Iterable &ticks, const Callable &f,
1854-
const std::string &format) {
1855-
if (begin(ticks) == end(ticks))
1856-
return true;
1857-
1858-
// We could use additional meta-programming to deduce the correct element
1859-
// type of y, but all values have to be convertible to double anyways
1860-
std::vector<double> y;
1861-
for (auto x : ticks)
1862-
y.push_back(f(x));
1863-
return plot_impl<std::false_type>()(ticks, y, format);
1864-
}
1865-
};
1866-
1867-
} // end namespace detail
1868-
1869-
// recursion stop for the above
1766+
// recursion stop for the below
18701767
template <typename... Args> bool plot() { return true; }
18711768

18721769
template <typename A, typename B, typename... Args>
18731770
bool plot(const A &a, const B &b, const std::string &format, Args... args) {
1874-
return detail::plot_impl<typename detail::is_callable<B>::type>()(a, b,
1875-
format) &&
1876-
plot(args...);
1771+
return plot(a, b, format) && plot(args...);
18771772
}
18781773

18791774
/*

0 commit comments

Comments
 (0)
0