diff --git a/include/io/read.h b/include/io/read.h index b7527d6..29b607f 100644 --- a/include/io/read.h +++ b/include/io/read.h @@ -47,6 +47,8 @@ namespace io { return value; } + + template requires std::is_convertible_v T read(std::istream& is, size_t length) { std::vector t(length); @@ -62,14 +64,13 @@ namespace io { return read(is, length); } - // @todo We need to support std::array - // Extra concept that checks if the size is static + + template T read(std::istream& is, size_t length) { - // @todo Properly constuct the container T v(length); - for (size_t i = 0; i < length; ++i) { - v[i] = io::read(is); + for (auto& e : v) { + e = io::read(is); } return v; } @@ -79,4 +80,14 @@ namespace io { size_t length = io::read(is); return read(is, length); } + + // Static sized container + template requires requires (T a) { std::tuple_size::value; } + T read(std::istream& is) { + T v; + for (size_t i = 0; i < std::tuple_size::value; ++i) { + v[i] = io::read(is); + } + return v; + } } diff --git a/include/io/write.h b/include/io/write.h index ba3c916..b061c3f 100644 --- a/include/io/write.h +++ b/include/io/write.h @@ -2,6 +2,7 @@ #include "helper.h" #include #include +#include namespace io { // This exists to allow for specialization and clearer errors @@ -59,6 +60,7 @@ namespace io { os << s; } + // @todo Merge this into one function with the proper default automatically template void write(std::ostream& os, T value, bool store_length = true) { if (store_length) { @@ -68,4 +70,14 @@ namespace io { write(os, entry); } } + + template requires requires (T a) { std::tuple_size::value; } + void write(std::ostream& os, T value, bool store_length = false) { + if (store_length) { + write(os, value.size()); + } + for (const auto& entry : value) { + write(os, entry); + } + } } diff --git a/test/src/test.cpp b/test/src/test.cpp index 69c3df8..a8f9470 100644 --- a/test/src/test.cpp +++ b/test/src/test.cpp @@ -2,7 +2,9 @@ #include #include +#include #include +#include struct A { int b; @@ -29,12 +31,25 @@ int main() { io::write(f, "test"); std::array a = {'a', 'b'}; + // Does not store length by default io::write(f, a); - std::array b = {"Hello", "World"}; - io::write(f, b); + std::array b = {"Hello", "World"}; + // Explicitly store length + io::write(f, b, true); + + std::vector c = {1, 2, 3, 4, 5}; + // Stores length by default + io::write(f, c); + + std::list d = {6, 7, 8, 9}; + // Stores length by default + io::write(f, d); io::write(f, A{4}); + + std::array e = {A{1}, A{5}, A{3}}; + io::write(f, e, true); } { @@ -43,19 +58,39 @@ int main() { std::cout << io::read(f) << '\n'; std::cout << io::read(f) << '\n'; - // auto v = io::read>(f); - auto a = io::read>(f); + // Length is implied by the array + auto a = io::read>(f); for (auto& v : a) { std::cout << v << ' '; } std::cout << '\n'; + // Length is read from file (optionally can be provided as parameter) auto b = io::read>(f); for (auto& v : b) { std::cout << v << ' '; } std::cout << '\n'; + auto c = io::read>(f); + for (auto& v : c) { + std::cout << v << ' '; + } + std::cout << '\n'; + + auto d = io::read>(f); + for (auto& v : d) { + std::cout << v << ' '; + } + std::cout << '\n'; + std::cout << io::read(f).b << '\n'; + + auto e = io::read>(f); + for (auto& v : e) { + std::cout << v << ' '; + } + std::cout << '\n'; + } }