Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core/StarDataStreamExtra.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/core/StarDataStreamExtra.hpp')
-rw-r--r--source/core/StarDataStreamExtra.hpp393
1 files changed, 393 insertions, 0 deletions
diff --git a/source/core/StarDataStreamExtra.hpp b/source/core/StarDataStreamExtra.hpp
new file mode 100644
index 0000000..c0965a9
--- /dev/null
+++ b/source/core/StarDataStreamExtra.hpp
@@ -0,0 +1,393 @@
+#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 <typename T>
+ void operator()(T const& t) const {
+ ds << t;
+ }
+};
+
+struct DataStreamReadFunctor {
+ DataStreamReadFunctor(DataStream& ds) : ds(ds) {}
+
+ DataStream& ds;
+ template <typename T>
+ 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 <typename ElementT, size_t SizeN>
+DataStream& operator<<(DataStream& ds, Array<ElementT, SizeN> const& array) {
+ for (size_t i = 0; i < SizeN; ++i)
+ ds << array[i];
+ return ds;
+}
+
+template <typename ElementT, size_t SizeN>
+DataStream& operator>>(DataStream& ds, Array<ElementT, SizeN>& array) {
+ for (size_t i = 0; i < SizeN; ++i)
+ ds >> array[i];
+ return ds;
+}
+
+template <typename ElementT, size_t RankN>
+DataStream& operator<<(DataStream& ds, MultiArray<ElementT, RankN> 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 <typename ElementT, size_t RankN>
+DataStream& operator>>(DataStream& ds, MultiArray<ElementT, RankN>& array) {
+ typename MultiArray<ElementT, RankN>::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<Vec4F>());
+ return ds;
+}
+
+template <typename First, typename Second>
+DataStream& operator<<(DataStream& ds, pair<First, Second> const& pair) {
+ ds << pair.first;
+ ds << pair.second;
+ return ds;
+}
+
+template <typename First, typename Second>
+DataStream& operator>>(DataStream& ds, pair<First, Second>& pair) {
+ ds >> pair.first;
+ ds >> pair.second;
+ return ds;
+}
+
+template <typename Element>
+DataStream& operator<<(DataStream& ds, std::shared_ptr<Element> const& ptr) {
+ ds.pwrite(ptr);
+ return ds;
+}
+
+template <typename Element>
+DataStream& operator>>(DataStream& ds, std::shared_ptr<Element>& ptr) {
+ ds.pread(ptr);
+ return ds;
+}
+
+template <typename BaseList>
+DataStream& operator<<(DataStream& ds, ListMixin<BaseList> const& list) {
+ ds.writeContainer(list);
+ return ds;
+}
+
+template <typename BaseList>
+DataStream& operator>>(DataStream& ds, ListMixin<BaseList>& list) {
+ ds.readContainer(list);
+ return ds;
+}
+
+template <typename BaseSet>
+DataStream& operator<<(DataStream& ds, SetMixin<BaseSet> const& set) {
+ ds.writeContainer(set);
+ return ds;
+}
+
+template <typename BaseSet>
+DataStream& operator>>(DataStream& ds, SetMixin<BaseSet>& set) {
+ ds.readContainer(set);
+ return ds;
+}
+
+template <typename BaseMap>
+DataStream& operator<<(DataStream& ds, MapMixin<BaseMap> const& map) {
+ ds.writeMapContainer(map);
+ return ds;
+}
+
+template <typename BaseMap>
+DataStream& operator>>(DataStream& ds, MapMixin<BaseMap>& map) {
+ ds.readMapContainer(map);
+ return ds;
+}
+
+template <typename Key, typename Value, typename Compare, typename Allocator>
+DataStream& operator>>(DataStream& ds, OrderedMap<Key, Value, Compare, Allocator>& map) {
+ ds.readMapContainer(map);
+ return ds;
+}
+
+template <typename Key, typename Value, typename Compare, typename Allocator>
+DataStream& operator<<(DataStream& ds, OrderedMap<Key, Value, Compare, Allocator> const& map) {
+ ds.writeMapContainer(map);
+ return ds;
+}
+
+template <typename Key, typename Value, typename Hash, typename Equals, typename Allocator>
+DataStream& operator>>(DataStream& ds, OrderedHashMap<Key, Value, Hash, Equals, Allocator>& map) {
+ ds.readMapContainer(map);
+ return ds;
+}
+
+template <typename Key, typename Value, typename Hash, typename Equals, typename Allocator>
+DataStream& operator<<(DataStream& ds, OrderedHashMap<Key, Value, Hash, Equals, Allocator> const& map) {
+ ds.writeMapContainer(map);
+ return ds;
+}
+
+template <typename Value, typename Compare, typename Allocator>
+DataStream& operator>>(DataStream& ds, OrderedSet<Value, Compare, Allocator>& set) {
+ ds.readContainer(set);
+ return ds;
+}
+
+template <typename Value, typename Compare, typename Allocator>
+DataStream& operator<<(DataStream& ds, OrderedSet<Value, Compare, Allocator> const& set) {
+ ds.writeContainer(set);
+ return ds;
+}
+
+template <typename Value, typename Hash, typename Equals, typename Allocator>
+DataStream& operator>>(DataStream& ds, OrderedHashSet<Value, Hash, Equals, Allocator>& set) {
+ ds.readContainer(set);
+ return ds;
+}
+
+template <typename Value, typename Hash, typename Equals, typename Allocator>
+DataStream& operator<<(DataStream& ds, OrderedHashSet<Value, Hash, Equals, Allocator> const& set) {
+ ds.writeContainer(set);
+ return ds;
+}
+
+template <typename DataT>
+DataStream& operator<<(DataStream& ds, Polygon<DataT> const& poly) {
+ ds.writeContainer(poly.vertexes());
+ return ds;
+}
+
+template <typename DataT>
+DataStream& operator>>(DataStream& ds, Polygon<DataT>& poly) {
+ ds.readContainer(poly.vertexes());
+ return ds;
+}
+
+template <typename DataT, size_t Dimensions>
+DataStream& operator<<(DataStream& ds, Box<DataT, Dimensions> const& box) {
+ ds.write(box.min());
+ ds.write(box.max());
+ return ds;
+}
+
+template <typename DataT, size_t Dimensions>
+DataStream& operator>>(DataStream& ds, Box<DataT, Dimensions>& box) {
+ ds.read(box.min());
+ ds.read(box.max());
+ return ds;
+}
+
+template <typename DataT>
+DataStream& operator<<(DataStream& ds, Matrix3<DataT> const& mat3) {
+ ds.write(mat3[0]);
+ ds.write(mat3[1]);
+ ds.write(mat3[2]);
+ return ds;
+}
+
+template <typename DataT>
+DataStream& operator>>(DataStream& ds, Matrix3<DataT>& 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 <typename FirstType, typename... RestTypes>
+DataStream& operator<<(DataStream& ds, Variant<FirstType, RestTypes...> const& variant) {
+ ds.write<VariantTypeIndex>(variant.typeIndex());
+ variant.call(DataStreamWriteFunctor{ds});
+ return ds;
+}
+
+template <typename FirstType, typename... RestTypes>
+DataStream& operator>>(DataStream& ds, Variant<FirstType, RestTypes...>& variant) {
+ variant.makeType(ds.read<VariantTypeIndex>());
+ variant.call(DataStreamReadFunctor{ds});
+ return ds;
+}
+
+template <typename... AllowedTypes>
+DataStream& operator<<(DataStream& ds, MVariant<AllowedTypes...> const& mvariant) {
+ ds.write<VariantTypeIndex>(mvariant.typeIndex());
+ mvariant.call(DataStreamWriteFunctor{ds});
+ return ds;
+}
+
+template <typename... AllowedTypes>
+DataStream& operator>>(DataStream& ds, MVariant<AllowedTypes...>& mvariant) {
+ mvariant.makeType(ds.read<VariantTypeIndex>());
+ mvariant.call(DataStreamReadFunctor{ds});
+ return ds;
+}
+
+// Writes / reads a Maybe type if the underlying type has operator<< /
+// operator>> defined for DataStream
+
+template <typename T, typename WriteFunction>
+void writeMaybe(DataStream& ds, Maybe<T> const& maybe, WriteFunction&& writeFunction) {
+ if (maybe) {
+ ds.write<bool>(true);
+ writeFunction(ds, *maybe);
+ } else {
+ ds.write<bool>(false);
+ }
+}
+
+template <typename T, typename ReadFunction>
+void readMaybe(DataStream& ds, Maybe<T>& maybe, ReadFunction&& readFunction) {
+ bool set = ds.read<bool>();
+ if (set) {
+ T t;
+ readFunction(ds, t);
+ maybe = move(t);
+ } else {
+ maybe.reset();
+ }
+}
+
+template <typename T>
+DataStream& operator<<(DataStream& ds, Maybe<T> const& maybe) {
+ writeMaybe(ds, maybe, [](DataStream& ds, T const& t) { ds << t; });
+ return ds;
+}
+
+template <typename T>
+DataStream& operator>>(DataStream& ds, Maybe<T>& 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 <typename Left, typename Right>
+DataStream& operator<<(DataStream& ds, Either<Left, Right> const& either) {
+ if (either.isLeft()) {
+ ds.write<uint8_t>(1);
+ ds.write(either.left());
+ } else if (either.isRight()) {
+ ds.write<uint8_t>(2);
+ ds.write(either.right());
+ } else {
+ ds.write<uint8_t>(0);
+ }
+ return ds;
+}
+
+template <typename Left, typename Right>
+DataStream& operator>>(DataStream& ds, Either<Left, Right>& either) {
+ uint8_t m = ds.read<uint8_t>();
+ if (m == 1)
+ either = makeLeft(ds.read<Left>());
+ else if (m == 2)
+ either = makeRight(ds.read<Right>());
+ return ds;
+}
+
+template <typename DataT, size_t Dimensions>
+DataStream& operator<<(DataStream& ds, Line<DataT, Dimensions> const& line) {
+ ds.write(line.min());
+ ds.write(line.max());
+ return ds;
+}
+
+template <typename DataT, size_t Dimensions>
+DataStream& operator>>(DataStream& ds, Line<DataT, Dimensions>& line) {
+ ds.read(line.min());
+ ds.read(line.max());
+ return ds;
+}
+
+template <typename T>
+DataStream& operator<<(DataStream& ds, tuple<T> const& t) {
+ ds << get<0>(t);
+ return ds;
+}
+
+struct DataStreamReader {
+ DataStream& ds;
+
+ template <typename RT>
+ void operator()(RT& t) {
+ ds >> t;
+ }
+};
+
+struct DataStreamWriter {
+ DataStream& ds;
+
+ template <typename RT>
+ void operator()(RT const& t) {
+ ds << t;
+ }
+};
+
+template <typename... T>
+DataStream& operator>>(DataStream& ds, tuple<T...>& t) {
+ tupleCallFunction(t, DataStreamReader{ds});
+ return ds;
+}
+
+template <typename... T>
+DataStream& operator<<(DataStream& ds, tuple<T...> const& t) {
+ tupleCallFunction(t, DataStreamWriter{ds});
+ return ds;
+}
+
+}
+
+#endif