#include <algorithm>
#include <fstream>
#include <iostream>
#include <type_traits>

template <typename T>
struct SizedArray
{
    T arr;
    size_t length;
    SizedArray(T arr, size_t length) : arr(arr), length(length){};

    template <typename T2, size_t N>
    SizedArray(T2 (&arr)[N]) : arr(arr), length(N){};
};

/* This is a deduction guide, but clang-format thinks it's operator-> */
// clang-format off
template <typename T2, size_t N> SizedArray(T2 (&arr)[N]) -> SizedArray<T2*>;
// clang-format on

template <typename T>
auto& operator>>(std::istream& is, T&& arg)
{
    SizedArray sink(arg);
    std::for_each(sink.arr, sink.arr + sink.length,
                  [&is](auto&& v) { is >> v; });
    return is;
}

template <typename T>
auto& operator<<(std::ostream& os, T&& arg)
{
    SizedArray source(arg);
    std::for_each(source.arr, source.arr + source.length,
                  [&os](auto&& v) { os << v; });
    return os;
}

int main()
{
    int* a    = new int[10];
    int b[10] = {0};
    std::ifstream st("test.data");
    st >> SizedArray(a, 10);
    st.seekg(st.beg);
    st >> b;
    std::cout << SizedArray{a, 10} << std::endl;
    std::cout << b << std::endl;
    return 0;
}
