/*
    tests/test_numpy_vectorize.cpp -- auto-vectorize functions over NumPy array
    arguments

    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>

    All rights reserved. Use of this source code is governed by a
    BSD-style license that can be found in the LICENSE file.
*/

#include <pybind11/numpy.h>

#include "pybind11_tests.h"

#include <utility>

double my_func(int x, float y, double z) {
    py::print("my_func(x:int={}, y:float={:.0f}, z:float={:.0f})"_s.format(x, y, z));
    return (float) x * y * z;
}

TEST_SUBMODULE(numpy_vectorize, m) {
    try {
        py::module_::import("numpy");
    } catch (const py::error_already_set &) {
        return;
    }

    // test_vectorize, test_docs, test_array_collapse
    // Vectorize all arguments of a function (though non-vector arguments are also allowed)
    m.def("vectorized_func", py::vectorize(my_func));

    // Vectorize a lambda function with a capture object (e.g. to exclude some arguments from the
    // vectorization)
    m.def("vectorized_func2", [](py::array_t<int> x, py::array_t<float> y, float z) {
        return py::vectorize([z](int x, float y) { return my_func(x, y, z); })(std::move(x),
                                                                               std::move(y));
    });

    // Vectorize a complex-valued function
    m.def("vectorized_func3",
          py::vectorize([](std::complex<double> c) { return c * std::complex<double>(2.f); }));

    // test_type_selection
    // NumPy function which only accepts specific data types
    // A lot of these no lints could be replaced with const refs, and probably should at some
    // point.
    m.def("selective_func",
          [](const py::array_t<int, py::array::c_style> &) { return "Int branch taken."; });
    m.def("selective_func",
          [](const py::array_t<float, py::array::c_style> &) { return "Float branch taken."; });
    m.def("selective_func", [](const py::array_t<std::complex<float>, py::array::c_style> &) {
        return "Complex float branch taken.";
    });

    // test_passthrough_arguments
    // Passthrough test: references and non-pod types should be automatically passed through (in
    // the function definition below, only `b`, `d`, and `g` are vectorized):
    struct NonPODClass {
        explicit NonPODClass(int v) : value{v} {}
        int value;
    };
    py::class_<NonPODClass>(m, "NonPODClass")
        .def(py::init<int>())
        .def_readwrite("value", &NonPODClass::value);
    m.def("vec_passthrough",
          py::vectorize([](const double *a,
                           double b,
                           // Changing this broke things
                           // NOLINTNEXTLINE(performance-unnecessary-value-param)
                           py::array_t<double> c,
                           const int &d,
                           int &e,
                           NonPODClass f,
                           const double g) { return *a + b + c.at(0) + d + e + f.value + g; }));

    // test_method_vectorization
    struct VectorizeTestClass {
        explicit VectorizeTestClass(int v) : value{v} {};
        float method(int x, float y) const { return y + (float) (x + value); }
        int value = 0;
    };
    py::class_<VectorizeTestClass> vtc(m, "VectorizeTestClass");
    vtc.def(py::init<int>()).def_readwrite("value", &VectorizeTestClass::value);

    // Automatic vectorizing of methods
    vtc.def("method", py::vectorize(&VectorizeTestClass::method));

    // test_trivial_broadcasting
    // Internal optimization test for whether the input is trivially broadcastable:
    py::enum_<py::detail::broadcast_trivial>(m, "trivial")
        .value("f_trivial", py::detail::broadcast_trivial::f_trivial)
        .value("c_trivial", py::detail::broadcast_trivial::c_trivial)
        .value("non_trivial", py::detail::broadcast_trivial::non_trivial);
    m.def("vectorized_is_trivial",
          [](const py::array_t<int, py::array::forcecast> &arg1,
             const py::array_t<float, py::array::forcecast> &arg2,
             const py::array_t<double, py::array::forcecast> &arg3) {
              py::ssize_t ndim = 0;
              std::vector<py::ssize_t> shape;
              std::array<py::buffer_info, 3> buffers{
                  {arg1.request(), arg2.request(), arg3.request()}};
              return py::detail::broadcast(buffers, ndim, shape);
          });

    m.def("add_to", py::vectorize([](NonPODClass &x, int a) { x.value += a; }));
}
