diff --git a/awkward-cpp/awkward/cpp/array/_table.cpp b/awkward-cpp/awkward/cpp/array/_table.cpp index a6737d58..5eeebb89 100644 --- a/awkward-cpp/awkward/cpp/array/_table.cpp +++ b/awkward-cpp/awkward/cpp/array/_table.cpp @@ -1,100 +1,171 @@ -#include #include +#include #include #include -#include #include +#include +#include +#include #include "any.h" namespace py = pybind11; +using T = std::int64_t; + // template class Table { py::object _view; std::shared_ptr _base; std::string rowname; ssize_t rowstart; - std::map _contents; + std::map> _contents; - ssize_t length() { - return _contents.size(); - } - - // py::dict vs py::array???? - public: + public: + // Table.Row class Row { - // Table* _table; std::shared_ptr
_table; ssize_t _index; - public: + public: Row(const Table& table, ssize_t index) { _table = std::make_shared
(table); _index = index; } - - }; // class Table - Table(py::object columns1, py::args columns2, py::kwargs columns3) { _view = py::none(); _base = NULL; rowname = "Row"; rowstart = 0; - + std::set seen; if (py::isinstance(columns1)) { auto columns = columns1.cast(); for (auto item : columns) { - std::string key = item.first.cast(); - if (seen.find(key) != seen.end()){ - throw std::invalid_argument("column "+key+" occurs more than once"); + auto key = item.first.cast(); + if (seen.find(key) != seen.end()) { + throw std::invalid_argument("column " + key + + " occurs more than once"); } seen.insert(key); - - - _contents.emplace(key, item.second); + auto value = item.second.cast>(); + _contents.emplace(key, value); } if (py::len(columns2) != 0) { - throw std::invalid_argument("only one positional argument when first argument is a dict"); + throw std::invalid_argument( + "only one positional argument when first argument is a " + "dict"); + } + } else { + ssize_t i = 0; + auto value = columns1.cast>(); + _contents.emplace(std::to_string(i++), value); + for (auto item : columns2) { + value = item.cast>(); + _contents.emplace(std::to_string(i), value); + seen.insert(std::to_string(i)); + i++; } } - else { - ssize_t i = 0; - _contents.emplace(std::to_string(i++),columns1); - for (auto item : columns2){ - _contents.emplace(std::to_string(i),item); - seen.insert(std::to_string(i)); - i++; - } - } - if (columns3){ + if (columns3) { for (auto item : columns3) { std::string key = item.first.cast(); if (seen.find(key) != seen.end()) { - throw std::invalid_argument("column "+key+" occurs more than once"); + throw std::invalid_argument("column " + key + + " occurs more than once"); } - _contents.emplace(key,item.second); + auto value = item.second.cast>(); + _contents.emplace(key, value); seen.insert(key); } } - - } - -}; + } + + // No need to consider view anymore + std::slice _index() { + if (py::isinstance(_view)) { + return std::slice(0, 1, length()); + + } else if (py::isinstance(_view)) { + auto myview = _view.cast>(); + auto start = std::get<0>(myview); + auto step = std::get<1>(myview); + auto length = std::get<2>(myview); + auto stop = start + step * length; + // std::vector ret(length / step + 1); + // for (auto i = start; i < length; i += step) { + // ret.push_back(i); + // } + return std::slice(start, stop, step); + + } else { + auto myview = _view.cast(); + return std::slice(myview, 1, 1); + } + } + + ssize_t length() { + ssize_t ret = 0; + if (py::isinstance(_view)) { + if (_contents.size() != 0) { + for (auto item : _contents) { + ret = std::min((size_t)ret, item.second.size()); + } + } + } else if (py::isinstance(_view)) { + auto myview = _view.cast>(); + ret = std::get<2>(myview); + } else { + ret = _view.cast(); + } + return ret; + } + + // void setitem(std::string where, py::handle whats) { + // if (!py::isinstance(_view)) { + // throw std::domain_error( + // "new columns can only be attached to the original Table, not + // a " "view (try table.base['col'] = array"); + // } + // } + + std::valarray getitem(std::string where) { + // string, not string slice + if (py::isinstance(_view)) { + if (_contents.find(where) == _contents.end()) { + throw std::invalid_argument("no column named " + where); + } + return _contents[where]; + } else { + auto index = _index(); + if (_contents.find(where) == _contents.end()) { + throw std::invalid_argument("no column named " + where); + } + return _contents[where][index]; + } + } + + // Row getitem(ssize_t where) { + // return Row(*this, where); + // } + + // std::valarray getitem(std::tuple where) { + // if + // } +}; PYBIND11_MODULE(_table, m) { - py::class_
(m, "Table") - .def(py::init(), py::arg("columns3") = py::dict()) - ; - + .def(py::init(), + py::arg("columns3") = py::dict()) + .def("__len__", &Table::length) + .def("__getitem__", &Table::getitem); - py::class_(m,"Table.Row") - .def(py::init(),py::arg("table"), py::arg("index")) - ; + py::class_(m, "Table.Row") + .def(py::init(), py::arg("table"), + py::arg("index")); } \ No newline at end of file diff --git a/tests/test_cpp.py b/tests/test_cpp.py index 4e61cac0..33cf38e1 100644 --- a/tests/test_cpp.py +++ b/tests/test_cpp.py @@ -36,8 +36,7 @@ import pytest import awkward -import awkward.cpp as awkward_cpp -# awkward_cpp = pytest.importorskip("awkward.cpp") +awkward_cpp = pytest.importorskip("awkward.cpp") class Test(unittest.TestCase): def runTest(self): diff --git a/tests/test_cpp_table.py b/tests/test_cpp_table.py index dbb4b878..d86f1555 100644 --- a/tests/test_cpp_table.py +++ b/tests/test_cpp_table.py @@ -48,6 +48,9 @@ def test_cpp_table_init(self): t1 = awkward_cpp.Table(a) t2 = awkward_cpp.Table({'column1' : a, 'column2' : b, 'column3' : c}) t3 = awkward_cpp.Table(column1 = a, column2 = b) + print(t1["0"]) + print(t2["column1"]) + print(t3["column1"]) pass # def test_table_nbytes(self): # assert isinstance(Table([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0.0, 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9]).nbytes, int)