/*
    tests/test_stl_binders.cpp -- Usage of stl_binders functions

    Copyright (c) 2016 Sergey Lyskov

    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_tests.h"

#include <pybind11/stl_bind.h>
#include <pybind11/numpy.h>
#include <map>
#include <deque>
#include <unordered_map>

class El {
public:
    El() = delete;
    explicit El(int v) : a(v) {}

    int a;
};

std::ostream & operator<<(std::ostream &s, El const&v) {
    s << "El{" << v.a << '}';
    return s;
}

/// Issue #487: binding std::vector<E> with E non-copyable
class E_nc {
public:
    explicit E_nc(int i) : value{i} {}
    E_nc(const E_nc &) = delete;
    E_nc &operator=(const E_nc &) = delete;
    E_nc(E_nc &&) = default;
    E_nc &operator=(E_nc &&) = default;

    int value;
};

template <class Container> Container *one_to_n(int n) {
    auto v = new Container();
    for (int i = 1; i <= n; i++)
        v->emplace_back(i);
    return v;
}

template <class Map> Map *times_ten(int n) {
    auto m = new Map();
    for (int i = 1; i <= n; i++)
        m->emplace(int(i), E_nc(10*i));
    return m;
}

template <class NestMap> NestMap *times_hundred(int n) {
    auto m = new NestMap();
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            (*m)[i].emplace(int(j*10), E_nc(100*j));
    return m;
}

TEST_SUBMODULE(stl_binders, m) {
    // test_vector_int
    py::bind_vector<std::vector<unsigned int>>(m, "VectorInt", py::buffer_protocol());

    // test_vector_custom
    py::class_<El>(m, "El")
        .def(py::init<int>());
    py::bind_vector<std::vector<El>>(m, "VectorEl");
    py::bind_vector<std::vector<std::vector<El>>>(m, "VectorVectorEl");

    // test_map_string_double
    py::bind_map<std::map<std::string, double>>(m, "MapStringDouble");
    py::bind_map<std::unordered_map<std::string, double>>(m, "UnorderedMapStringDouble");

    // test_map_string_double_const
    py::bind_map<std::map<std::string, double const>>(m, "MapStringDoubleConst");
    py::bind_map<std::unordered_map<std::string, double const>>(m, "UnorderedMapStringDoubleConst");

    py::class_<E_nc>(m, "ENC")
        .def(py::init<int>())
        .def_readwrite("value", &E_nc::value);

    // test_noncopyable_containers
    py::bind_vector<std::vector<E_nc>>(m, "VectorENC");
    m.def("get_vnc", &one_to_n<std::vector<E_nc>>);
    py::bind_vector<std::deque<E_nc>>(m, "DequeENC");
    m.def("get_dnc", &one_to_n<std::deque<E_nc>>);
    py::bind_map<std::map<int, E_nc>>(m, "MapENC");
    m.def("get_mnc", &times_ten<std::map<int, E_nc>>);
    py::bind_map<std::unordered_map<int, E_nc>>(m, "UmapENC");
    m.def("get_umnc", &times_ten<std::unordered_map<int, E_nc>>);
    // Issue #1885: binding nested std::map<X, Container<E>> with E non-copyable
    py::bind_map<std::map<int, std::vector<E_nc>>>(m, "MapVecENC");
    m.def("get_nvnc", [](int n)
        {
            auto m = new std::map<int, std::vector<E_nc>>();
            for (int i = 1; i <= n; i++)
                for (int j = 1; j <= n; j++)
                    (*m)[i].emplace_back(j);
            return m;
        });
    py::bind_map<std::map<int, std::map<int, E_nc>>>(m, "MapMapENC");
    m.def("get_nmnc", &times_hundred<std::map<int, std::map<int, E_nc>>>);
    py::bind_map<std::unordered_map<int, std::unordered_map<int, E_nc>>>(m, "UmapUmapENC");
    m.def("get_numnc", &times_hundred<std::unordered_map<int, std::unordered_map<int, E_nc>>>);

    // test_vector_buffer
    py::bind_vector<std::vector<unsigned char>>(m, "VectorUChar", py::buffer_protocol());
    // no dtype declared for this version:
    struct VUndeclStruct { bool w; uint32_t x; double y; bool z; };
    m.def("create_undeclstruct", [m] () mutable {
        py::bind_vector<std::vector<VUndeclStruct>>(m, "VectorUndeclStruct", py::buffer_protocol());
    });

    // The rest depends on numpy:
    try { py::module_::import("numpy"); }
    catch (...) { return; }

    // test_vector_buffer_numpy
    struct VStruct { bool w; uint32_t x; double y; bool z; };
    PYBIND11_NUMPY_DTYPE(VStruct, w, x, y, z);
    py::class_<VStruct>(m, "VStruct").def_readwrite("x", &VStruct::x);
    py::bind_vector<std::vector<VStruct>>(m, "VectorStruct", py::buffer_protocol());
    m.def("get_vectorstruct", [] {
        return std::vector<VStruct>{{false, 5, 3.0, true}, {true, 30, -1e4, false}};
    });
}
