#ifndef STAR_DATA_STREAM_EXTRA_HPP #define STAR_DATA_STREAM_EXTRA_HPP #include "StarDataStream.hpp" #include "StarMultiArray.hpp" #include "StarColor.hpp" #include "StarPoly.hpp" #include "StarMaybe.hpp" #include "StarEither.hpp" #include "StarOrderedMap.hpp" #include "StarOrderedSet.hpp" namespace Star { struct DataStreamWriteFunctor { DataStreamWriteFunctor(DataStream& ds) : ds(ds) {} DataStream& ds; template void operator()(T const& t) const { ds << t; } }; struct DataStreamReadFunctor { DataStreamReadFunctor(DataStream& ds) : ds(ds) {} DataStream& ds; template void operator()(T& t) const { ds >> t; } }; inline DataStream& operator<<(DataStream& ds, Empty const&) { return ds; } inline DataStream& operator>>(DataStream& ds, Empty&) { return ds; } template DataStream& operator<<(DataStream& ds, Array const& array) { for (size_t i = 0; i < SizeN; ++i) ds << array[i]; return ds; } template DataStream& operator>>(DataStream& ds, Array& array) { for (size_t i = 0; i < SizeN; ++i) ds >> array[i]; return ds; } template DataStream& operator<<(DataStream& ds, MultiArray const& array) { auto size = array.size(); for (size_t i = 0; i < RankN; ++i) ds.writeVlqU(size[i]); size_t count = array.count(); for (size_t i = 0; i < count; ++i) ds << array.atIndex(i); return ds; } template DataStream& operator>>(DataStream& ds, MultiArray& array) { typename MultiArray::SizeList size; for (size_t i = 0; i < RankN; ++i) size[i] = ds.readVlqU(); array.setSize(size); size_t count = array.count(); for (size_t i = 0; i < count; ++i) ds >> array.atIndex(i); return ds; } inline DataStream& operator<<(DataStream& ds, Color const& color) { ds << color.toRgbaF(); return ds; } inline DataStream& operator>>(DataStream& ds, Color& color) { color = Color::rgbaf(ds.read()); return ds; } template DataStream& operator<<(DataStream& ds, pair const& pair) { ds << pair.first; ds << pair.second; return ds; } template DataStream& operator>>(DataStream& ds, pair& pair) { ds >> pair.first; ds >> pair.second; return ds; } template DataStream& operator<<(DataStream& ds, std::shared_ptr const& ptr) { ds.pwrite(ptr); return ds; } template DataStream& operator>>(DataStream& ds, std::shared_ptr& ptr) { ds.pread(ptr); return ds; } template DataStream& operator<<(DataStream& ds, ListMixin const& list) { ds.writeContainer(list); return ds; } template DataStream& operator>>(DataStream& ds, ListMixin& list) { ds.readContainer(list); return ds; } template DataStream& operator<<(DataStream& ds, SetMixin const& set) { ds.writeContainer(set); return ds; } template DataStream& operator>>(DataStream& ds, SetMixin& set) { ds.readContainer(set); return ds; } template DataStream& operator<<(DataStream& ds, MapMixin const& map) { ds.writeMapContainer(map); return ds; } template DataStream& operator>>(DataStream& ds, MapMixin& map) { ds.readMapContainer(map); return ds; } template DataStream& operator>>(DataStream& ds, OrderedMap& map) { ds.readMapContainer(map); return ds; } template DataStream& operator<<(DataStream& ds, OrderedMap const& map) { ds.writeMapContainer(map); return ds; } template DataStream& operator>>(DataStream& ds, OrderedHashMap& map) { ds.readMapContainer(map); return ds; } template DataStream& operator<<(DataStream& ds, OrderedHashMap const& map) { ds.writeMapContainer(map); return ds; } template DataStream& operator>>(DataStream& ds, OrderedSet& set) { ds.readContainer(set); return ds; } template DataStream& operator<<(DataStream& ds, OrderedSet const& set) { ds.writeContainer(set); return ds; } template DataStream& operator>>(DataStream& ds, OrderedHashSet& set) { ds.readContainer(set); return ds; } template DataStream& operator<<(DataStream& ds, OrderedHashSet const& set) { ds.writeContainer(set); return ds; } template DataStream& operator<<(DataStream& ds, Polygon const& poly) { ds.writeContainer(poly.vertexes()); return ds; } template DataStream& operator>>(DataStream& ds, Polygon& poly) { ds.readContainer(poly.vertexes()); return ds; } template DataStream& operator<<(DataStream& ds, Box const& box) { ds.write(box.min()); ds.write(box.max()); return ds; } template DataStream& operator>>(DataStream& ds, Box& box) { ds.read(box.min()); ds.read(box.max()); return ds; } template DataStream& operator<<(DataStream& ds, Matrix3 const& mat3) { ds.write(mat3[0]); ds.write(mat3[1]); ds.write(mat3[2]); return ds; } template DataStream& operator>>(DataStream& ds, Matrix3& mat3) { ds.read(mat3[0]); ds.read(mat3[1]); ds.read(mat3[2]); return ds; } // Writes / reads a Variant type if every type has operator<< / operator>> // defined for DataStream and if it is default constructible. template DataStream& operator<<(DataStream& ds, Variant const& variant) { ds.write(variant.typeIndex()); variant.call(DataStreamWriteFunctor{ds}); return ds; } template DataStream& operator>>(DataStream& ds, Variant& variant) { variant.makeType(ds.read()); variant.call(DataStreamReadFunctor{ds}); return ds; } template DataStream& operator<<(DataStream& ds, MVariant const& mvariant) { ds.write(mvariant.typeIndex()); mvariant.call(DataStreamWriteFunctor{ds}); return ds; } template DataStream& operator>>(DataStream& ds, MVariant& mvariant) { mvariant.makeType(ds.read()); mvariant.call(DataStreamReadFunctor{ds}); return ds; } // Writes / reads a Maybe type if the underlying type has operator<< / // operator>> defined for DataStream template void writeMaybe(DataStream& ds, Maybe const& maybe, WriteFunction&& writeFunction) { if (maybe) { ds.write(true); writeFunction(ds, *maybe); } else { ds.write(false); } } template void readMaybe(DataStream& ds, Maybe& maybe, ReadFunction&& readFunction) { bool set = ds.read(); if (set) { T t; readFunction(ds, t); maybe = std::move(t); } else { maybe.reset(); } } template DataStream& operator<<(DataStream& ds, Maybe const& maybe) { writeMaybe(ds, maybe, [](DataStream& ds, T const& t) { ds << t; }); return ds; } template DataStream& operator>>(DataStream& ds, Maybe& maybe) { readMaybe(ds, maybe, [](DataStream& ds, T& t) { ds >> t; }); return ds; } // Writes / reads an Either type, an Either can either have a left or right // value, or in edge cases, nothing. template DataStream& operator<<(DataStream& ds, Either const& either) { if (either.isLeft()) { ds.write(1); ds.write(either.left()); } else if (either.isRight()) { ds.write(2); ds.write(either.right()); } else { ds.write(0); } return ds; } template DataStream& operator>>(DataStream& ds, Either& either) { uint8_t m = ds.read(); if (m == 1) either = makeLeft(ds.read()); else if (m == 2) either = makeRight(ds.read()); return ds; } template DataStream& operator<<(DataStream& ds, Line const& line) { ds.write(line.min()); ds.write(line.max()); return ds; } template DataStream& operator>>(DataStream& ds, Line& line) { ds.read(line.min()); ds.read(line.max()); return ds; } template DataStream& operator<<(DataStream& ds, tuple const& t) { ds << get<0>(t); return ds; } struct DataStreamReader { DataStream& ds; template void operator()(RT& t) { ds >> t; } }; struct DataStreamWriter { DataStream& ds; template void operator()(RT const& t) { ds << t; } }; template DataStream& operator>>(DataStream& ds, tuple& t) { tupleCallFunction(t, DataStreamReader{ds}); return ds; } template DataStream& operator<<(DataStream& ds, tuple const& t) { tupleCallFunction(t, DataStreamWriter{ds}); return ds; } } #endif