Stared reimplementing iohelper using concepts
This commit is contained in:
commit
62343d06e0
42
.gitignore
vendored
Normal file
42
.gitignore
vendored
Normal file
|
@ -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/
|
105
src/write.cpp
Normal file
105
src/write.cpp
Normal file
|
@ -0,0 +1,105 @@
|
|||
#include <iostream>
|
||||
#include <cstdint>
|
||||
|
||||
namespace io {
|
||||
template <typename T>
|
||||
void write(std::ostream&, T) {
|
||||
static_assert(!std::is_same_v<T,T>, "No known specialization of io::write for type");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
concept NumberByte = std::is_integral_v<T> && sizeof(T) == 1;
|
||||
|
||||
template <NumberByte T>
|
||||
void write(std::ostream& os, T value) {
|
||||
os.write(reinterpret_cast<const char*>(&value), sizeof(T));
|
||||
}
|
||||
|
||||
namespace {
|
||||
template <typename T>
|
||||
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<uint8_t>(os, byte);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> requires std::is_integral_v<T>
|
||||
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<uint8_t>(os, length | 0b10000000);
|
||||
write_bytes(os, value, length);
|
||||
} else {
|
||||
write<uint8_t>(os, value);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> requires std::is_convertible_v<T, std::string_view>
|
||||
void write(std::ostream& os, T value) {
|
||||
std::string_view s = value;
|
||||
write<size_t>(os, s.length());
|
||||
os << s;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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<T, std::string_view>;
|
||||
|
||||
template <Container T>
|
||||
void write(std::ostream& os, T value) {
|
||||
write<size_t>(os, value.size());
|
||||
for (const auto& entry : value) {
|
||||
write<typename T::value_type>(os, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
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<size_t>(std::cout, 50);
|
||||
|
||||
std::array<char, 2> a = {'a', 'b'};
|
||||
io::write(std::cout, a);
|
||||
io::write(std::cout, "test");
|
||||
io::write(std::cout, A{4});
|
||||
std::cout << '\n';
|
||||
}
|
Loading…
Reference in New Issue
Block a user