// C++17: own data, validate dimensions, reject overflow before making a view.
#include <cassert>
#include <cstdint>
#include <iostream>
#include <limits>
#include <stdexcept>
#include <vector>
std::size_t elements(const std::vector<int64_t>& shape) {
    std::size_t n = 1;
    for (auto dimension : shape) {
        if (dimension <= 0 || static_cast<uint64_t>(dimension) > std::numeric_limits<std::size_t>::max()/n)
            throw std::invalid_argument("invalid shape");
        n *= static_cast<std::size_t>(dimension);
    }
    return n;
}
struct Input {
    std::vector<int64_t> shape;
    std::vector<float> buffer;
    Input(std::vector<int64_t> s, std::vector<float> b):shape(std::move(s)),buffer(std::move(b)) {
        if (elements(shape) != buffer.size()) throw std::invalid_argument("element count mismatch");
    }
};
int main() {
    const Input input({1,3},{1,2,3}); // No reallocation or mutation while a tensor borrows buffer.
    assert(input.buffer.size()==3 && input.buffer[2]==3);
    bool bad = false;
    try { Input invalid({2,3},{1,2,3}); } catch(const std::invalid_argument&) { bad=true; }
    assert(bad); bad=false;
    try { elements({INT64_MAX,INT64_MAX}); } catch(const std::invalid_argument&) { bad=true; }
    assert(bad);
    std::cout << "PASS: owned input, shape mismatch and overflow rejection\n";
}
