commit 62343d06e0b786f05f650828934995d4f865cb56 Author: Dreaded_X Date: Fri Dec 13 02:05:53 2019 +0100 Stared reimplementing iohelper using concepts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..154005c --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +### Git ### +*.orig + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### premake-gmake ### +Makefile +*.make +build/ + +### Vim ### +# swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-v][a-z] +[._]sw[a-p] +# session +Session.vim +# temporary +.netrwhist +# auto-generated tag files +tags +.clangd/ +compile_commands.json + +### Other stuff ### +.build +bootstrap/build/ +bootstrap/vendor/ diff --git a/src/write.cpp b/src/write.cpp new file mode 100644 index 0000000..bf94814 --- /dev/null +++ b/src/write.cpp @@ -0,0 +1,105 @@ +#include +#include + +namespace io { + template + void write(std::ostream&, T) { + static_assert(!std::is_same_v, "No known specialization of io::write for type"); + } + + template + concept NumberByte = std::is_integral_v && sizeof(T) == 1; + + template + void write(std::ostream& os, T value) { + os.write(reinterpret_cast(&value), sizeof(T)); + } + + namespace { + template + void write_bytes(std::ostream& os, T value, size_t length) { + for (auto i = length; i > 0; --i) { + uint8_t byte = (value >> (i-1)*8) & 0xFF; + write(os, byte); + } + } + } + + template requires std::is_integral_v + void write(std::ostream& os, T value) { + write_bytes(os, value, sizeof(T)); + } + + // Special implementation for size_t (also uint64_t, so maybe this is not that smart) + template <> + void write(std::ostream& os, size_t value) { + // Check if we need more then one byte + if (value > 0b01111111) { + // Calculate how many bytes we need to store the number + uint8_t length = 0; + auto x = value; + while (x != 0) { + x >>= 8; + length++; + } + + write(os, length | 0b10000000); + write_bytes(os, value, length); + } else { + write(os, value); + } + } + + template requires std::is_convertible_v + void write(std::ostream& os, T value) { + std::string_view s = value; + write(os, s.length()); + os << s; + } + + template + concept Container = requires (T a) { + typename T::value_type; + typename T::size_type; + typename T::iterator; + typename T::const_iterator; + a.size(); + a.begin(); + a.end(); + a.cbegin(); + a.cend(); + } && !std::is_convertible_v; + + template + void write(std::ostream& os, T value) { + write(os, value.size()); + for (const auto& entry : value) { + write(os, entry); + } + } +} + +#include +#include + +struct A { + int b; +}; + +namespace io { + template <> + void write(std::ostream& os, A value) { + write(os, value.b); + } +} + +int main() { + std::cout << "TEST\n"; + io::write(std::cout, 50); + + std::array a = {'a', 'b'}; + io::write(std::cout, a); + io::write(std::cout, "test"); + io::write(std::cout, A{4}); + std::cout << '\n'; +} diff --git a/test b/test new file mode 100755 index 0000000..92c840f Binary files /dev/null and b/test differ