|
|
|
#ifndef BINARY_OUTPUT_HPP
|
|
|
|
#define BINARY_OUTPUT_HPP
|
|
|
|
|
|
|
|
#include <ostream>
|
|
|
|
|
|
|
|
// static_asserts are not too good...
|
|
|
|
|
|
|
|
// Normal
|
|
|
|
template <typename T>
|
|
|
|
struct binary {
|
|
|
|
T thing;
|
|
|
|
binary(T const t):thing(t) {}
|
|
|
|
binary(binary const& c):thing(c.thing) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
binary<T> make_binary(T const t) {
|
|
|
|
return binary<T>(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
std::ostream& operator<<(std::ostream& out, binary<T> const& rhs) {
|
|
|
|
static_assert(std::is_pod<T>::value, "Please specialise this function if your type is not POD");
|
|
|
|
static_assert(!std::is_pointer<T>::value, "Writing pointer");
|
|
|
|
out.write(reinterpret_cast<const char*>(&(rhs.thing)), sizeof(rhs.thing));
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Array
|
|
|
|
// NOTE: it uses references...
|
|
|
|
template <typename T, size_t N>
|
|
|
|
struct binary_arr {
|
|
|
|
T const(& thing)[N];
|
|
|
|
binary_arr(const T(& t)[N]):thing(t) {}
|
|
|
|
binary_arr(binary_arr const& c):thing(c.thing) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T, size_t N>
|
|
|
|
binary_arr<T, N> make_binary(const T(& t)[N]) {
|
|
|
|
static_assert(N>=0, "lijp");
|
|
|
|
return binary_arr<T, N>(t);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, size_t N>
|
|
|
|
std::ostream& operator<<(std::ostream& out, binary_arr<T, N> const& rhs) {
|
|
|
|
static_assert(std::is_pod<T>::value, "Please specialise this function if your type is not POD");
|
|
|
|
static_assert(!std::is_pointer<T>::value, "Writing pointer");
|
|
|
|
out.write(reinterpret_cast<const char*>(&(rhs.thing)), sizeof(rhs.thing));
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // BINARY_OUTPUT_HPP
|
|
|
|
|