diff --git a/AK/MaybeOwned.h b/AK/MaybeOwned.h new file mode 100644 index 00000000000..cc280ea0a39 --- /dev/null +++ b/AK/MaybeOwned.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022, Tim Schumacher + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace AK { + +template +class MaybeOwned { +public: + template U> + MaybeOwned(NonnullOwnPtr handle) + : m_handle(adopt_own(*handle.leak_ptr())) + { + } + + // This is made `explicit` to not accidentally create a non-owning MaybeOwned, + // which may not always be intended. + explicit MaybeOwned(T& handle) + : m_handle(&handle) + { + } + + T* ptr() + { + if (m_handle.template has()) + return m_handle.template get(); + else + return m_handle.template get>(); + } + + T const* ptr() const + { + if (m_handle.template has()) + return m_handle.template get(); + else + return m_handle.template get>(); + } + + T* operator->() { return ptr(); } + T const* operator->() const { return ptr(); } + + T& operator*() { return *ptr(); } + T const& operator*() const { return *ptr(); } + +private: + Variant, T*> m_handle; +}; + +} + +#if USING_AK_GLOBALLY +using AK::MaybeOwned; +#endif diff --git a/Tests/LibCore/TestLibCoreStream.cpp b/Tests/LibCore/TestLibCoreStream.cpp index 9467e1b2ab9..2200293b10b 100644 --- a/Tests/LibCore/TestLibCoreStream.cpp +++ b/Tests/LibCore/TestLibCoreStream.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -726,8 +727,8 @@ TEST_CASE(little_endian_bit_stream_input_output_match) // Note: The bit stream only ever reads from/writes to the underlying stream in one byte chunks, // so testing with sizes that will not trigger a write will yield unexpected results. - auto bit_write_stream = MUST(Core::Stream::LittleEndianOutputBitStream::construct(Core::Stream::Handle(*memory_stream))); - auto bit_read_stream = MUST(Core::Stream::LittleEndianInputBitStream::construct(Core::Stream::Handle(*memory_stream))); + auto bit_write_stream = MUST(Core::Stream::LittleEndianOutputBitStream::construct(MaybeOwned(*memory_stream))); + auto bit_read_stream = MUST(Core::Stream::LittleEndianInputBitStream::construct(MaybeOwned(*memory_stream))); // Test two mirrored chunks of a fully mirrored pattern to check that we are not dropping bits. { @@ -782,8 +783,8 @@ TEST_CASE(big_endian_bit_stream_input_output_match) // Note: The bit stream only ever reads from/writes to the underlying stream in one byte chunks, // so testing with sizes that will not trigger a write will yield unexpected results. - auto bit_write_stream = MUST(Core::Stream::BigEndianOutputBitStream::construct(Core::Stream::Handle(*memory_stream))); - auto bit_read_stream = MUST(Core::Stream::BigEndianInputBitStream::construct(Core::Stream::Handle(*memory_stream))); + auto bit_write_stream = MUST(Core::Stream::BigEndianOutputBitStream::construct(MaybeOwned(*memory_stream))); + auto bit_read_stream = MUST(Core::Stream::BigEndianInputBitStream::construct(MaybeOwned(*memory_stream))); // Test two mirrored chunks of a fully mirrored pattern to check that we are not dropping bits. { diff --git a/Userland/Libraries/LibArchive/TarStream.cpp b/Userland/Libraries/LibArchive/TarStream.cpp index a01081c1ba1..218520305e0 100644 --- a/Userland/Libraries/LibArchive/TarStream.cpp +++ b/Userland/Libraries/LibArchive/TarStream.cpp @@ -136,7 +136,7 @@ TarFileStream TarInputStream::file_contents() return TarFileStream(*this); } -TarOutputStream::TarOutputStream(Core::Stream::Handle stream) +TarOutputStream::TarOutputStream(MaybeOwned stream) : m_stream(move(stream)) { } diff --git a/Userland/Libraries/LibArchive/TarStream.h b/Userland/Libraries/LibArchive/TarStream.h index c50a87b27ef..f585d26ca1e 100644 --- a/Userland/Libraries/LibArchive/TarStream.h +++ b/Userland/Libraries/LibArchive/TarStream.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include #include @@ -58,14 +59,14 @@ private: class TarOutputStream { public: - TarOutputStream(Core::Stream::Handle); + TarOutputStream(MaybeOwned); ErrorOr add_file(StringView path, mode_t, ReadonlyBytes); ErrorOr add_link(StringView path, mode_t, StringView); ErrorOr add_directory(StringView path, mode_t); ErrorOr finish(); private: - Core::Stream::Handle m_stream; + MaybeOwned m_stream; bool m_finished { false }; friend class TarFileStream; diff --git a/Userland/Libraries/LibAudio/FlacLoader.cpp b/Userland/Libraries/LibAudio/FlacLoader.cpp index 1010e772836..8a7c9faa175 100644 --- a/Userland/Libraries/LibAudio/FlacLoader.cpp +++ b/Userland/Libraries/LibAudio/FlacLoader.cpp @@ -60,7 +60,7 @@ MaybeLoaderError FlacLoaderPlugin::initialize() // 11.5 STREAM MaybeLoaderError FlacLoaderPlugin::parse_header() { - auto bit_input = LOADER_TRY(BigEndianInputBitStream::construct(Core::Stream::Handle(*m_stream))); + auto bit_input = LOADER_TRY(BigEndianInputBitStream::construct(MaybeOwned(*m_stream))); // A mixture of VERIFY and the non-crashing TRY(). #define FLAC_VERIFY(check, category, msg) \ @@ -79,7 +79,7 @@ MaybeLoaderError FlacLoaderPlugin::parse_header() auto streaminfo = TRY(next_meta_block(*bit_input)); FLAC_VERIFY(streaminfo.type == FlacMetadataBlockType::STREAMINFO, LoaderError::Category::Format, "First block must be STREAMINFO"); auto streaminfo_data_memory = LOADER_TRY(Core::Stream::FixedMemoryStream::construct(streaminfo.data.bytes())); - auto streaminfo_data = LOADER_TRY(BigEndianInputBitStream::construct(Core::Stream::Handle(*streaminfo_data_memory))); + auto streaminfo_data = LOADER_TRY(BigEndianInputBitStream::construct(MaybeOwned(*streaminfo_data_memory))); // 11.10 METADATA_BLOCK_STREAMINFO m_min_block_size = LOADER_TRY(streaminfo_data->read_bits(16)); @@ -150,7 +150,7 @@ MaybeLoaderError FlacLoaderPlugin::parse_header() MaybeLoaderError FlacLoaderPlugin::load_picture(FlacRawMetadataBlock& block) { auto memory_stream = LOADER_TRY(Core::Stream::FixedMemoryStream::construct(block.data.bytes())); - auto picture_block_bytes = LOADER_TRY(BigEndianInputBitStream::construct(Core::Stream::Handle(*memory_stream))); + auto picture_block_bytes = LOADER_TRY(BigEndianInputBitStream::construct(MaybeOwned(*memory_stream))); PictureData picture {}; @@ -187,7 +187,7 @@ MaybeLoaderError FlacLoaderPlugin::load_picture(FlacRawMetadataBlock& block) MaybeLoaderError FlacLoaderPlugin::load_seektable(FlacRawMetadataBlock& block) { auto memory_stream = LOADER_TRY(Core::Stream::FixedMemoryStream::construct(block.data.bytes())); - auto seektable_bytes = LOADER_TRY(BigEndianInputBitStream::construct(Core::Stream::Handle(*memory_stream))); + auto seektable_bytes = LOADER_TRY(BigEndianInputBitStream::construct(MaybeOwned(*memory_stream))); for (size_t i = 0; i < block.length / 18; ++i) { // 11.14. SEEKPOINT FlacSeekPoint seekpoint { @@ -333,7 +333,7 @@ MaybeLoaderError FlacLoaderPlugin::next_frame(Span target_vector) } \ } while (0) - auto bit_stream = LOADER_TRY(BigEndianInputBitStream::construct(Core::Stream::Handle(*m_stream))); + auto bit_stream = LOADER_TRY(BigEndianInputBitStream::construct(MaybeOwned(*m_stream))); // TODO: Check the CRC-16 checksum (and others) by keeping track of read data diff --git a/Userland/Libraries/LibAudio/MP3Loader.cpp b/Userland/Libraries/LibAudio/MP3Loader.cpp index 85fc0b6272b..15c14eae336 100644 --- a/Userland/Libraries/LibAudio/MP3Loader.cpp +++ b/Userland/Libraries/LibAudio/MP3Loader.cpp @@ -41,7 +41,7 @@ Result, LoaderError> MP3LoaderPlugin::create(Byte MaybeLoaderError MP3LoaderPlugin::initialize() { - m_bitstream = LOADER_TRY(Core::Stream::BigEndianInputBitStream::construct(Core::Stream::Handle(*m_stream))); + m_bitstream = LOADER_TRY(Core::Stream::BigEndianInputBitStream::construct(MaybeOwned(*m_stream))); TRY(synchronize()); @@ -242,7 +242,7 @@ ErrorOr MP3LoaderPlugin::read_frame_data(MP3::Header TRY(m_bit_reservoir.discard(old_reservoir_size - frame.main_data_begin)); - auto reservoir_stream = TRY(Core::Stream::BigEndianInputBitStream::construct(Core::Stream::Handle(m_bit_reservoir))); + auto reservoir_stream = TRY(Core::Stream::BigEndianInputBitStream::construct(MaybeOwned(m_bit_reservoir))); for (size_t granule_index = 0; granule_index < 2; granule_index++) { for (size_t channel_index = 0; channel_index < header.channel_count(); channel_index++) { diff --git a/Userland/Libraries/LibCompress/Brotli.cpp b/Userland/Libraries/LibCompress/Brotli.cpp index 00d2e7c3c03..ee16bff271a 100644 --- a/Userland/Libraries/LibCompress/Brotli.cpp +++ b/Userland/Libraries/LibCompress/Brotli.cpp @@ -29,7 +29,7 @@ ErrorOr BrotliDecompressionStream::CanonicalCode::read_symbol(LittleEndi } BrotliDecompressionStream::BrotliDecompressionStream(Stream& stream) - : m_input_stream(Core::Stream::Handle(stream)) + : m_input_stream(MaybeOwned(stream)) { } diff --git a/Userland/Libraries/LibCompress/Deflate.cpp b/Userland/Libraries/LibCompress/Deflate.cpp index 2d462adf44b..f6afe0eb567 100644 --- a/Userland/Libraries/LibCompress/Deflate.cpp +++ b/Userland/Libraries/LibCompress/Deflate.cpp @@ -188,13 +188,13 @@ ErrorOr DeflateDecompressor::UncompressedBlock::try_read_more() return true; } -ErrorOr> DeflateDecompressor::construct(Core::Stream::Handle stream) +ErrorOr> DeflateDecompressor::construct(MaybeOwned stream) { auto output_buffer = TRY(CircularBuffer::create_empty(32 * KiB)); return TRY(adopt_nonnull_own_or_enomem(new (nothrow) DeflateDecompressor(move(stream), move(output_buffer)))); } -DeflateDecompressor::DeflateDecompressor(Core::Stream::Handle stream, CircularBuffer output_buffer) +DeflateDecompressor::DeflateDecompressor(MaybeOwned stream, CircularBuffer output_buffer) : m_input_stream(make(move(stream))) , m_output_buffer(move(output_buffer)) { @@ -446,7 +446,7 @@ ErrorOr DeflateDecompressor::decode_codes(CanonicalCode& literal_code, Opt return {}; } -ErrorOr> DeflateCompressor::construct(Core::Stream::Handle stream, CompressionLevel compression_level) +ErrorOr> DeflateCompressor::construct(MaybeOwned stream, CompressionLevel compression_level) { auto bit_stream = TRY(Core::Stream::LittleEndianOutputBitStream::construct(move(stream))); auto deflate_compressor = TRY(adopt_nonnull_own_or_enomem(new (nothrow) DeflateCompressor(move(bit_stream), compression_level))); @@ -1017,7 +1017,7 @@ ErrorOr DeflateCompressor::final_flush() ErrorOr DeflateCompressor::compress_all(ReadonlyBytes bytes, CompressionLevel compression_level) { auto output_stream = TRY(try_make()); - auto deflate_stream = TRY(DeflateCompressor::construct(Core::Stream::Handle(*output_stream), compression_level)); + auto deflate_stream = TRY(DeflateCompressor::construct(MaybeOwned(*output_stream), compression_level)); TRY(deflate_stream->write_entire_buffer(bytes)); TRY(deflate_stream->final_flush()); diff --git a/Userland/Libraries/LibCompress/Deflate.h b/Userland/Libraries/LibCompress/Deflate.h index a775d348eb7..6268996c58e 100644 --- a/Userland/Libraries/LibCompress/Deflate.h +++ b/Userland/Libraries/LibCompress/Deflate.h @@ -74,7 +74,7 @@ public: friend CompressedBlock; friend UncompressedBlock; - static ErrorOr> construct(Core::Stream::Handle stream); + static ErrorOr> construct(MaybeOwned stream); ~DeflateDecompressor(); virtual ErrorOr read(Bytes) override; @@ -86,7 +86,7 @@ public: static ErrorOr decompress_all(ReadonlyBytes); private: - DeflateDecompressor(Core::Stream::Handle stream, CircularBuffer buffer); + DeflateDecompressor(MaybeOwned stream, CircularBuffer buffer); ErrorOr decode_length(u32); ErrorOr decode_distance(u32); @@ -100,7 +100,7 @@ private: UncompressedBlock m_uncompressed_block; }; - Core::Stream::Handle m_input_stream; + MaybeOwned m_input_stream; CircularBuffer m_output_buffer; }; @@ -139,7 +139,7 @@ public: BEST // WARNING: this one can take an unreasonable amount of time! }; - static ErrorOr> construct(Core::Stream::Handle, CompressionLevel = CompressionLevel::GOOD); + static ErrorOr> construct(MaybeOwned, CompressionLevel = CompressionLevel::GOOD); ~DeflateCompressor(); virtual ErrorOr read(Bytes) override; diff --git a/Userland/Libraries/LibCompress/Gzip.cpp b/Userland/Libraries/LibCompress/Gzip.cpp index ce856b93765..0b702f28b7b 100644 --- a/Userland/Libraries/LibCompress/Gzip.cpp +++ b/Userland/Libraries/LibCompress/Gzip.cpp @@ -40,7 +40,7 @@ bool BlockHeader::supported_by_implementation() const ErrorOr> GzipDecompressor::Member::construct(BlockHeader header, Core::Stream::Stream& stream) { - auto deflate_stream = TRY(DeflateDecompressor::construct(Core::Stream::Handle(stream))); + auto deflate_stream = TRY(DeflateDecompressor::construct(MaybeOwned(stream))); return TRY(adopt_nonnull_own_or_enomem(new (nothrow) Member(header, move(deflate_stream)))); } @@ -186,7 +186,7 @@ ErrorOr GzipDecompressor::write(ReadonlyBytes) return Error::from_errno(EBADF); } -GzipCompressor::GzipCompressor(Core::Stream::Handle stream) +GzipCompressor::GzipCompressor(MaybeOwned stream) : m_output_stream(move(stream)) { } @@ -207,7 +207,7 @@ ErrorOr GzipCompressor::write(ReadonlyBytes bytes) header.extra_flags = 3; // DEFLATE sets 2 for maximum compression and 4 for minimum compression header.operating_system = 3; // unix TRY(m_output_stream->write_entire_buffer({ &header, sizeof(header) })); - auto compressed_stream = TRY(DeflateCompressor::construct(Core::Stream::Handle(*m_output_stream))); + auto compressed_stream = TRY(DeflateCompressor::construct(MaybeOwned(*m_output_stream))); TRY(compressed_stream->write_entire_buffer(bytes)); TRY(compressed_stream->final_flush()); Crypto::Checksum::CRC32 crc32; @@ -236,7 +236,7 @@ void GzipCompressor::close() ErrorOr GzipCompressor::compress_all(ReadonlyBytes bytes) { auto output_stream = TRY(try_make()); - GzipCompressor gzip_stream { Core::Stream::Handle(*output_stream) }; + GzipCompressor gzip_stream { MaybeOwned(*output_stream) }; TRY(gzip_stream.write_entire_buffer(bytes)); diff --git a/Userland/Libraries/LibCompress/Gzip.h b/Userland/Libraries/LibCompress/Gzip.h index 45c4b017339..ddda776f5e5 100644 --- a/Userland/Libraries/LibCompress/Gzip.h +++ b/Userland/Libraries/LibCompress/Gzip.h @@ -80,7 +80,7 @@ private: class GzipCompressor final : public Core::Stream::Stream { public: - GzipCompressor(Core::Stream::Handle); + GzipCompressor(MaybeOwned); virtual ErrorOr read(Bytes) override; virtual ErrorOr write(ReadonlyBytes) override; @@ -91,7 +91,7 @@ public: static ErrorOr compress_all(ReadonlyBytes bytes); private: - Core::Stream::Handle m_output_stream; + MaybeOwned m_output_stream; }; } diff --git a/Userland/Libraries/LibCompress/Zlib.cpp b/Userland/Libraries/LibCompress/Zlib.cpp index db1f5558e52..ff2d78aa9c1 100644 --- a/Userland/Libraries/LibCompress/Zlib.cpp +++ b/Userland/Libraries/LibCompress/Zlib.cpp @@ -69,13 +69,13 @@ u32 ZlibDecompressor::checksum() return m_checksum; } -ErrorOr> ZlibCompressor::construct(Core::Stream::Handle stream, ZlibCompressionLevel compression_level) +ErrorOr> ZlibCompressor::construct(MaybeOwned stream, ZlibCompressionLevel compression_level) { // Zlib only defines Deflate as a compression method. auto compression_method = ZlibCompressionMethod::Deflate; // FIXME: Find a way to compress with Deflate's "Best" compression level. - auto compressor_stream = TRY(DeflateCompressor::construct(Core::Stream::Handle(*stream), static_cast(compression_level))); + auto compressor_stream = TRY(DeflateCompressor::construct(MaybeOwned(*stream), static_cast(compression_level))); auto zlib_compressor = TRY(adopt_nonnull_own_or_enomem(new (nothrow) ZlibCompressor(move(stream), move(compressor_stream)))); TRY(zlib_compressor->write_header(compression_method, compression_level)); @@ -83,7 +83,7 @@ ErrorOr> ZlibCompressor::construct(Core::Stream::H return zlib_compressor; } -ZlibCompressor::ZlibCompressor(Core::Stream::Handle stream, NonnullOwnPtr compressor_stream) +ZlibCompressor::ZlibCompressor(MaybeOwned stream, NonnullOwnPtr compressor_stream) : m_output_stream(move(stream)) , m_compressor(move(compressor_stream)) { @@ -164,7 +164,7 @@ ErrorOr ZlibCompressor::finish() ErrorOr ZlibCompressor::compress_all(ReadonlyBytes bytes, ZlibCompressionLevel compression_level) { auto output_stream = TRY(try_make()); - auto zlib_stream = TRY(ZlibCompressor::construct(Core::Stream::Handle(*output_stream), compression_level)); + auto zlib_stream = TRY(ZlibCompressor::construct(MaybeOwned(*output_stream), compression_level)); TRY(zlib_stream->write_entire_buffer(bytes)); diff --git a/Userland/Libraries/LibCompress/Zlib.h b/Userland/Libraries/LibCompress/Zlib.h index 51bf4f30a95..a3ca0369d6b 100644 --- a/Userland/Libraries/LibCompress/Zlib.h +++ b/Userland/Libraries/LibCompress/Zlib.h @@ -7,6 +7,7 @@ #pragma once #include +#include #include #include #include @@ -62,7 +63,7 @@ private: class ZlibCompressor : public Core::Stream::Stream { public: - static ErrorOr> construct(Core::Stream::Handle, ZlibCompressionLevel = ZlibCompressionLevel::Default); + static ErrorOr> construct(MaybeOwned, ZlibCompressionLevel = ZlibCompressionLevel::Default); ~ZlibCompressor(); virtual ErrorOr read(Bytes) override; @@ -75,11 +76,11 @@ public: static ErrorOr compress_all(ReadonlyBytes bytes, ZlibCompressionLevel = ZlibCompressionLevel::Default); private: - ZlibCompressor(Core::Stream::Handle stream, NonnullOwnPtr compressor_stream); + ZlibCompressor(MaybeOwned stream, NonnullOwnPtr compressor_stream); ErrorOr write_header(ZlibCompressionMethod, ZlibCompressionLevel); bool m_finished { false }; - Core::Stream::Handle m_output_stream; + MaybeOwned m_output_stream; NonnullOwnPtr m_compressor; Crypto::Checksum::Adler32 m_adler32_checksum; }; diff --git a/Userland/Libraries/LibCore/BitStream.h b/Userland/Libraries/LibCore/BitStream.h index e1067c95145..db2f0c0c59e 100644 --- a/Userland/Libraries/LibCore/BitStream.h +++ b/Userland/Libraries/LibCore/BitStream.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,7 @@ namespace Core::Stream { /// in big-endian order from another stream. class BigEndianInputBitStream : public Stream { public: - static ErrorOr> construct(Handle stream) + static ErrorOr> construct(MaybeOwned stream) { return adopt_nonnull_own_or_enomem(new BigEndianInputBitStream(move(stream))); } @@ -118,26 +119,26 @@ public: ALWAYS_INLINE bool is_aligned_to_byte_boundary() const { return m_bit_offset == 0; } private: - BigEndianInputBitStream(Handle stream) + BigEndianInputBitStream(MaybeOwned stream) : m_stream(move(stream)) { } Optional m_current_byte; size_t m_bit_offset { 0 }; - Handle m_stream; + MaybeOwned m_stream; }; /// A stream wrapper class that allows you to read arbitrary amounts of bits /// in little-endian order from another stream. class LittleEndianInputBitStream : public Stream { public: - static ErrorOr> construct(Handle stream) + static ErrorOr> construct(MaybeOwned stream) { return adopt_nonnull_own_or_enomem(new LittleEndianInputBitStream(move(stream))); } - LittleEndianInputBitStream(Handle stream) + LittleEndianInputBitStream(MaybeOwned stream) : m_stream(move(stream)) { } @@ -234,14 +235,14 @@ public: private: Optional m_current_byte; size_t m_bit_offset { 0 }; - Handle m_stream; + MaybeOwned m_stream; }; /// A stream wrapper class that allows you to write arbitrary amounts of bits /// in big-endian order to another stream. class BigEndianOutputBitStream : public Stream { public: - static ErrorOr> construct(Handle stream) + static ErrorOr> construct(MaybeOwned stream) { return adopt_nonnull_own_or_enomem(new BigEndianOutputBitStream(move(stream))); } @@ -310,12 +311,12 @@ public: } private: - BigEndianOutputBitStream(Handle stream) + BigEndianOutputBitStream(MaybeOwned stream) : m_stream(move(stream)) { } - Handle m_stream; + MaybeOwned m_stream; u8 m_current_byte { 0 }; size_t m_bit_offset { 0 }; }; @@ -324,7 +325,7 @@ private: /// in little-endian order to another stream. class LittleEndianOutputBitStream : public Stream { public: - static ErrorOr> construct(Handle stream) + static ErrorOr> construct(MaybeOwned stream) { return adopt_nonnull_own_or_enomem(new LittleEndianOutputBitStream(move(stream))); } @@ -393,12 +394,12 @@ public: } private: - LittleEndianOutputBitStream(Handle stream) + LittleEndianOutputBitStream(MaybeOwned stream) : m_stream(move(stream)) { } - Handle m_stream; + MaybeOwned m_stream; u8 m_current_byte { 0 }; size_t m_bit_offset { 0 }; }; diff --git a/Userland/Libraries/LibCore/Stream.h b/Userland/Libraries/LibCore/Stream.h index 556c90ee129..0e58741b9b2 100644 --- a/Userland/Libraries/LibCore/Stream.h +++ b/Userland/Libraries/LibCore/Stream.h @@ -27,48 +27,6 @@ namespace Core::Stream { -template T> -class Handle { -public: - template U> - Handle(NonnullOwnPtr handle) - : m_handle(adopt_own(*handle.leak_ptr())) - { - } - - // This is made `explicit` to not accidentally create a non-owning Handle, - // which may not always be intended. - explicit Handle(T& handle) - : m_handle(&handle) - { - } - - T* ptr() - { - if (m_handle.template has()) - return m_handle.template get(); - else - return m_handle.template get>(); - } - - T const* ptr() const - { - if (m_handle.template has()) - return m_handle.template get(); - else - return m_handle.template get>(); - } - - T* operator->() { return ptr(); } - T const* operator->() const { return ptr(); } - - T& operator*() { return *ptr(); } - T const& operator*() const { return *ptr(); } - -private: - Variant, T*> m_handle; -}; - /// The base, abstract class for stream operations. This class defines the /// operations one can perform on every stream in LibCore. /// Operations without a sensible default that are unsupported by an implementation diff --git a/Userland/Utilities/pro.cpp b/Userland/Utilities/pro.cpp index 0756191ccc7..79c6f569298 100644 --- a/Userland/Utilities/pro.cpp +++ b/Userland/Utilities/pro.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -105,7 +106,7 @@ private: template class ConditionalOutputStream final : public Core::Stream::Stream { public: - ConditionalOutputStream(ConditionT&& condition, Core::Stream::Handle stream) + ConditionalOutputStream(ConditionT&& condition, MaybeOwned stream) : m_stream(move(stream)) , m_condition(condition) { @@ -140,7 +141,7 @@ public: } private: - Core::Stream::Handle m_stream; + MaybeOwned m_stream; ConditionT m_condition; };