| 44 | argument::argument(const shape& s, const argument::data_t& d) : m_shape(s), m_data(d) {} |
| 45 | |
| 46 | void argument::assign_buffer(std::function<char*()> d) |
| 47 | { |
| 48 | const shape& s = m_shape; |
| 49 | if(s.type() != shape::tuple_type) |
| 50 | { |
| 51 | m_data = {std::move(d)}; |
| 52 | return; |
| 53 | } |
| 54 | // Collect all shapes |
| 55 | std::unordered_map<std::size_t, shape> shapes; |
| 56 | { |
| 57 | std::size_t i = 0; |
| 58 | fix([&](auto self, auto ss) { |
| 59 | if(ss.sub_shapes().empty()) |
| 60 | { |
| 61 | shapes[i] = ss; |
| 62 | i++; |
| 63 | } |
| 64 | else |
| 65 | { |
| 66 | for(auto&& child : ss.sub_shapes()) |
| 67 | self(child); |
| 68 | } |
| 69 | })(s); |
| 70 | } |
| 71 | // Sort by type size |
| 72 | std::vector<std::size_t> order(shapes.size()); |
| 73 | std::iota(order.begin(), order.end(), 0); |
| 74 | std::sort(order.begin(), order.end(), by(std::greater<>{}, [&](auto i) { |
| 75 | return shapes[i].type_size(); |
| 76 | })); |
| 77 | // Compute offsets |
| 78 | std::unordered_map<std::size_t, std::size_t> offsets; |
| 79 | std::size_t offset = 0; |
| 80 | for(auto i : order) |
| 81 | { |
| 82 | offsets[i] = offset; |
| 83 | offset += shapes[i].bytes(); |
| 84 | } |
| 85 | assert(offset == s.bytes()); |
| 86 | |
| 87 | std::size_t i = 0; |
| 88 | m_data = fix<data_t>([&](auto self, auto ss) { |
| 89 | data_t result; |
| 90 | if(ss.sub_shapes().empty()) |
| 91 | { |
| 92 | auto n = offsets[i]; |
| 93 | result = {[d, n]() mutable { return d() + n; }}; |
| 94 | i++; |
| 95 | return result; |
| 96 | } |
| 97 | std::vector<data_t> subs; |
| 98 | std::transform(ss.sub_shapes().begin(), |
| 99 | ss.sub_shapes().end(), |
| 100 | std::back_inserter(subs), |
| 101 | [&](auto child) { return self(child); }); |
| 102 | result.sub = subs; |
| 103 | return result; |
nothing calls this directly
no test coverage detected