| /* | |
| * Copyright 2025 Rive | |
| */ | |
| #pragma once | |
| #include "rive/refcnt.hpp" | |
| #include <cassert> | |
| #include <deque> | |
| namespace rive | |
| { | |
| // Stream for recording objects of a specific type, using C++-style "<<" ">>" | |
| // operators. | |
| template <typename T> class ObjectStream | |
| { | |
| public: | |
| bool empty() const { return m_stream.empty(); } | |
| ObjectStream& operator<<(T obj) | |
| { | |
| m_stream.push_back(std::move(obj)); | |
| return *this; | |
| } | |
| ObjectStream& operator>>(T& dst) | |
| { | |
| assert(!empty()); | |
| dst = std::move(m_stream.front()); | |
| m_stream.pop_front(); | |
| return *this; | |
| } | |
| private: | |
| std::deque<T> m_stream; | |
| }; | |
| // Stream for recording objects of any trivially-copyable type, using C++-style | |
| // "<<" ">>" operators. Object types must be read back in the same order they | |
| // were writen. | |
| class PODStream | |
| { | |
| public: | |
| bool empty() const { return m_byteStream.empty(); } | |
| template <typename T> PODStream& operator<<(T obj) | |
| { | |
| static_assert(std::is_trivial<T>() && std::is_standard_layout<T>(), | |
| "PODStream only accepts plain-old-data types"); | |
| const char* data = reinterpret_cast<const char*>(&obj); | |
| m_byteStream.insert(m_byteStream.end(), data, data + sizeof(T)); | |
| return *this; | |
| } | |
| template <typename T> PODStream& operator>>(T& dst) | |
| { | |
| static_assert(std::is_trivial<T>() && std::is_standard_layout<T>(), | |
| "PODStream only accepts plain-old-data types"); | |
| assert(m_byteStream.size() >= sizeof(T)); | |
| char* data = reinterpret_cast<char*>(&dst); | |
| std::copy(m_byteStream.begin(), m_byteStream.begin() + sizeof(T), data); | |
| m_byteStream.erase(m_byteStream.begin(), | |
| m_byteStream.begin() + sizeof(T)); | |
| return *this; | |
| } | |
| template <typename T> PODStream& operator<<(rcp<T> obj) | |
| { | |
| return *this << obj.release(); | |
| } | |
| template <typename T> PODStream& operator>>(rcp<T>& obj) | |
| { | |
| T* raw; | |
| *this >> raw; | |
| obj = rcp<T>(raw); | |
| return *this; | |
| } | |
| private: | |
| std::deque<char> m_byteStream; | |
| }; | |
| }; // namespace rive |