diff --git a/Makefile.am b/Makefile.am
index ba22eb6817..6f107dc3ea 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -301,10 +301,6 @@ test_libbitcoin_system_test_SOURCES = \
test/hash/sha/sha256.cpp \
test/hash/sha/sha512.cpp \
test/hash/sha/vectorization.cpp \
- test/hash/sha/clone/algorithm.hpp \
- test/hash/sha/clone/algorithm.ipp \
- test/hash/sha/clone/algorithm_compression.ipp \
- test/hash/sha/clone/algorithm_vectorization.ipp \
test/intrinsics/haves.cpp \
test/intrinsics/intrinsics.cpp \
test/intrinsics/xcpu/cpuid.cpp \
@@ -343,9 +339,9 @@ test_libbitcoin_system_test_SOURCES = \
test/stream/devices/copy_source.cpp \
test/stream/devices/flip_sink.cpp \
test/stream/devices/push_sink.cpp \
- test/stream/simple/iostream.cpp \
- test/stream/simple/istream.cpp \
- test/stream/simple/ostream.cpp \
+ test/stream/iostream/iostream.cpp \
+ test/stream/iostream/istream.cpp \
+ test/stream/iostream/ostream.cpp \
test/stream/streamers/bit_flipper.cpp \
test/stream/streamers/bit_reader.cpp \
test/stream/streamers/bit_writer.cpp \
@@ -647,10 +643,11 @@ include_bitcoin_system_impl_streamdir = ${includedir}/bitcoin/system/impl/stream
include_bitcoin_system_impl_stream_HEADERS = \
include/bitcoin/system/impl/stream/device.ipp
-include_bitcoin_system_impl_stream_simpledir = ${includedir}/bitcoin/system/impl/stream/simple
-include_bitcoin_system_impl_stream_simple_HEADERS = \
- include/bitcoin/system/impl/stream/simple/istream.ipp \
- include/bitcoin/system/impl/stream/simple/ostream.ipp
+include_bitcoin_system_impl_stream_iostreamdir = ${includedir}/bitcoin/system/impl/stream/iostream
+include_bitcoin_system_impl_stream_iostream_HEADERS = \
+ include/bitcoin/system/impl/stream/iostream/iostream.ipp \
+ include/bitcoin/system/impl/stream/iostream/istream.ipp \
+ include/bitcoin/system/impl/stream/iostream/ostream.ipp
include_bitcoin_system_impl_stream_streamersdir = ${includedir}/bitcoin/system/impl/stream/streamers
include_bitcoin_system_impl_stream_streamers_HEADERS = \
@@ -741,6 +738,7 @@ include_bitcoin_system_streamdir = ${includedir}/bitcoin/system/stream
include_bitcoin_system_stream_HEADERS = \
include/bitcoin/system/stream/binary.hpp \
include/bitcoin/system/stream/device.hpp \
+ include/bitcoin/system/stream/iostream.hpp \
include/bitcoin/system/stream/make_stream.hpp \
include/bitcoin/system/stream/make_streamer.hpp \
include/bitcoin/system/stream/stream.hpp \
@@ -755,12 +753,6 @@ include_bitcoin_system_stream_devices_HEADERS = \
include/bitcoin/system/stream/devices/flip_sink.hpp \
include/bitcoin/system/stream/devices/push_sink.hpp
-include_bitcoin_system_stream_simpledir = ${includedir}/bitcoin/system/stream/simple
-include_bitcoin_system_stream_simple_HEADERS = \
- include/bitcoin/system/stream/simple/iostream.hpp \
- include/bitcoin/system/stream/simple/istream.hpp \
- include/bitcoin/system/stream/simple/ostream.hpp
-
include_bitcoin_system_stream_streamersdir = ${includedir}/bitcoin/system/stream/streamers
include_bitcoin_system_stream_streamers_HEADERS = \
include/bitcoin/system/stream/streamers/bit_flipper.hpp \
diff --git a/builds/cmake/CMakeLists.txt b/builds/cmake/CMakeLists.txt
index 9975fadc7b..5ef9672f14 100644
--- a/builds/cmake/CMakeLists.txt
+++ b/builds/cmake/CMakeLists.txt
@@ -775,10 +775,6 @@ if (with-tests)
"../../test/hash/sha/sha256.cpp"
"../../test/hash/sha/sha512.cpp"
"../../test/hash/sha/vectorization.cpp"
- "../../test/hash/sha/clone/algorithm.hpp"
- "../../test/hash/sha/clone/algorithm.ipp"
- "../../test/hash/sha/clone/algorithm_compression.ipp"
- "../../test/hash/sha/clone/algorithm_vectorization.ipp"
"../../test/intrinsics/haves.cpp"
"../../test/intrinsics/intrinsics.cpp"
"../../test/intrinsics/xcpu/cpuid.cpp"
@@ -817,9 +813,9 @@ if (with-tests)
"../../test/stream/devices/copy_source.cpp"
"../../test/stream/devices/flip_sink.cpp"
"../../test/stream/devices/push_sink.cpp"
- "../../test/stream/simple/iostream.cpp"
- "../../test/stream/simple/istream.cpp"
- "../../test/stream/simple/ostream.cpp"
+ "../../test/stream/iostream/iostream.cpp"
+ "../../test/stream/iostream/istream.cpp"
+ "../../test/stream/iostream/ostream.cpp"
"../../test/stream/streamers/bit_flipper.cpp"
"../../test/stream/streamers/bit_reader.cpp"
"../../test/stream/streamers/bit_writer.cpp"
diff --git a/builds/msvc/vs2022/libbitcoin-system-test/libbitcoin-system-test.vcxproj b/builds/msvc/vs2022/libbitcoin-system-test/libbitcoin-system-test.vcxproj
index d4870b6541..d1a77d673a 100644
--- a/builds/msvc/vs2022/libbitcoin-system-test/libbitcoin-system-test.vcxproj
+++ b/builds/msvc/vs2022/libbitcoin-system-test/libbitcoin-system-test.vcxproj
@@ -211,9 +211,9 @@
-
-
-
+
+
+
$(IntDir)test_stream_stream.obj
@@ -296,7 +296,6 @@
-
@@ -310,9 +309,6 @@
-
-
-
@@ -346,11 +342,6 @@
-
-
- "$(TargetPath)" --run_test=istream_tests --show_progress=no --build_info=yes
-
-
{39F60708-FF48-4C22-952D-43470866F684}
@@ -359,4 +350,4 @@
-
\ No newline at end of file
+
diff --git a/builds/msvc/vs2022/libbitcoin-system-test/libbitcoin-system-test.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-system-test/libbitcoin-system-test.vcxproj.filters
index ce8ee07768..0927a3985a 100644
--- a/builds/msvc/vs2022/libbitcoin-system-test/libbitcoin-system-test.vcxproj.filters
+++ b/builds/msvc/vs2022/libbitcoin-system-test/libbitcoin-system-test.vcxproj.filters
@@ -46,14 +46,11 @@
{51A424A9-2C12-4211-0000-000000000005}
-
- {51A424A9-2C12-4211-0000-000000000007}
-
{51A424A9-2C12-4211-0000-000000000008}
- {51A424A9-2C12-4211-0000-000000000008}
+ {51A424A9-2C12-4211-0000-000000000007}
{51A424A9-2C12-4211-0000-000000000009}
@@ -71,37 +68,37 @@
{51A424A9-2C12-4211-0000-00000000000D}
- {51A424A9-2C12-4211-0000-000000000009}
+ {51A424A9-2C12-4211-0000-000000000008}
-
- {51A424A9-2C12-4211-0000-000000000010}
+
+ {51A424A9-2C12-4211-0000-000000000009}
- {51A424A9-2C12-4211-0000-0000000000A1}
+ {51A424A9-2C12-4211-0000-000000000010}
{51A424A9-2C12-4211-0000-00000000000E}
- {51A424A9-2C12-4211-0000-0000000000B1}
+ {51A424A9-2C12-4211-0000-0000000000A1}
{51A424A9-2C12-4211-0000-00000000000F}
- {51A424A9-2C12-4211-0000-0000000000C1}
+ {51A424A9-2C12-4211-0000-0000000000B1}
- {51A424A9-2C12-4211-0000-0000000000D1}
+ {51A424A9-2C12-4211-0000-0000000000C1}
- {51A424A9-2C12-4211-0000-0000000000E1}
+ {51A424A9-2C12-4211-0000-0000000000D1}
{51A424A9-2C12-4211-0000-000000000001}
- {51A424A9-2C12-4211-0000-0000000000F1}
+ {51A424A9-2C12-4211-0000-0000000000E1}
@@ -468,14 +465,14 @@
src\stream\devices
-
- src\stream\simple
+
+ src\stream\iostream
-
- src\stream\simple
+
+ src\stream\iostream
-
- src\stream\simple
+
+ src\stream\iostream
src\stream
@@ -671,9 +668,6 @@
src\hash\performance
-
- src\hash\sha\clone
-
src\hash
@@ -709,15 +703,6 @@
-
- src\hash\sha\clone
-
-
- src\hash\sha\clone
-
-
- src\hash\sha\clone
-
diff --git a/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj b/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj
index 19af639a32..619323cece 100644
--- a/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj
+++ b/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj
@@ -407,11 +407,9 @@
+
-
-
-
@@ -559,8 +557,9 @@
-
-
+
+
+
diff --git a/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj.filters b/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj.filters
index bfb5208f3c..8e504d94c8 100644
--- a/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj.filters
+++ b/builds/msvc/vs2022/libbitcoin-system/libbitcoin-system.vcxproj.filters
@@ -82,7 +82,7 @@
{39F60708-FF48-4C22-0000-000000000010}
-
+
{39F60708-FF48-4C22-0000-0000000000C3}
@@ -124,41 +124,38 @@
{39F60708-FF48-4C22-0000-000000000005}
-
- {39F60708-FF48-4C22-0000-000000000006}
-
- {39F60708-FF48-4C22-0000-000000000007}
+ {39F60708-FF48-4C22-0000-000000000006}
- {39F60708-FF48-4C22-0000-000000000008}
+ {39F60708-FF48-4C22-0000-000000000007}
{39F60708-FF48-4C22-0000-000000000011}
- {39F60708-FF48-4C22-0000-000000000009}
+ {39F60708-FF48-4C22-0000-000000000008}
{39F60708-FF48-4C22-0000-0000000000A2}
- {39F60708-FF48-4C22-0000-000000000010}
+ {39F60708-FF48-4C22-0000-000000000009}
- {39F60708-FF48-4C22-0000-000000000011}
+ {39F60708-FF48-4C22-0000-000000000010}
- {39F60708-FF48-4C22-0000-000000000012}
+ {39F60708-FF48-4C22-0000-000000000011}
{39F60708-FF48-4C22-0000-0000000000B2}
- {39F60708-FF48-4C22-0000-000000000013}
+ {39F60708-FF48-4C22-0000-000000000012}
- {39F60708-FF48-4C22-0000-0000000000A4}
+ {39F60708-FF48-4C22-0000-000000000013}
{39F60708-FF48-4C22-0000-000000000000}
@@ -1100,21 +1097,15 @@
include\bitcoin\system\stream\devices
+
+ include\bitcoin\system\stream
+
include\bitcoin\system\stream
include\bitcoin\system\stream
-
- include\bitcoin\system\stream\simple
-
-
- include\bitcoin\system\stream\simple
-
-
- include\bitcoin\system\stream\simple
-
include\bitcoin\system\stream
@@ -1552,11 +1543,14 @@
include\bitcoin\system\impl\stream
-
- include\bitcoin\system\impl\stream\simple
+
+ include\bitcoin\system\impl\stream\iostream
+
+
+ include\bitcoin\system\impl\stream\iostream
-
- include\bitcoin\system\impl\stream\simple
+
+ include\bitcoin\system\impl\stream\iostream
include\bitcoin\system\impl\stream\streamers
diff --git a/include/bitcoin/system.hpp b/include/bitcoin/system.hpp
index ebc9b3020b..687f3f649b 100755
--- a/include/bitcoin/system.hpp
+++ b/include/bitcoin/system.hpp
@@ -177,6 +177,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -187,9 +188,6 @@
#include
#include
#include
-#include
-#include
-#include
#include
#include
#include
diff --git a/include/bitcoin/system/hash/sha/algorithm.hpp b/include/bitcoin/system/hash/sha/algorithm.hpp
index e49b383b9b..bb04e495f8 100644
--- a/include/bitcoin/system/hash/sha/algorithm.hpp
+++ b/include/bitcoin/system/hash/sha/algorithm.hpp
@@ -269,10 +269,10 @@ class algorithm
const xstate_t& xstate) NOEXCEPT;
template = true>
- INLINE static void merkle_hash_v_(idigests_t& digests,
+ INLINE static void merkle_hash_invoke(idigests_t& digests,
iblocks_t& blocks) NOEXCEPT;
- INLINE static void merkle_hash_v(digests_t& digests) NOEXCEPT;
+ INLINE static void merkle_hash_dispatch(digests_t& digests) NOEXCEPT;
/// Message Schedule (block vectorization).
/// -----------------------------------------------------------------------
@@ -285,15 +285,17 @@ class algorithm
INLINE static Word extract(xWord a) NOEXCEPT;
template
- INLINE static void compress_v(state_t& state,
+ INLINE static void compress_dispatch(state_t& state,
const xbuffer_t& xbuffer) NOEXCEPT;
template = true>
- INLINE static void iterate_v_(state_t& state, iblocks_t& blocks) NOEXCEPT;
+ INLINE static void iterate_invoke(state_t& state, iblocks_t& blocks) NOEXCEPT;
template
- INLINE static void iterate_v(state_t& state, const ablocks_t& blocks) NOEXCEPT;
- INLINE static void iterate_v(state_t& state, iblocks_t& blocks) NOEXCEPT;
+ INLINE static void iterate_dispatch(state_t& state,
+ const ablocks_t& blocks) NOEXCEPT;
+ INLINE static void iterate_dispatch(state_t& state,
+ iblocks_t& blocks) NOEXCEPT;
/// Message Schedule (sigma vectorization).
/// -----------------------------------------------------------------------
@@ -303,17 +305,20 @@ class algorithm
auto x6, auto x7, auto x8) NOEXCEPT;
template
- INLINE static void prepare_v(buffer_t& buffer) NOEXCEPT;
- INLINE static void schedule_v(auto& buffer) NOEXCEPT;
+ INLINE static void prepare_dispatch(buffer_t& buffer) NOEXCEPT;
+ INLINE static void schedule_invoke(buffer_t& buffer) NOEXCEPT;
+ INLINE static void schedule_dispatch(auto& buffer) NOEXCEPT;
public:
static constexpr auto have_x128 = Vectorized && system::with_sse41;
static constexpr auto have_x256 = Vectorized && system::with_avx2;
static constexpr auto have_x512 = Vectorized && system::with_avx512;
- static constexpr auto min_lanes = (have_x128 ? 16 : (have_x256 ? 32 :
- (have_x128 ? 64 : 0))) / SHA::word_bytes;
- static constexpr auto vectorization = (have_x128 || have_x256 || have_x512) &&
- !(build_x32 && is_same_size);
+ static constexpr auto vectorization = (have_x128 || have_x256 || have_x512)
+ && !(build_x32 && is_same_size);
+ static constexpr auto min_lanes =
+ (have_x128 ? bytes<128> :
+ (have_x256 ? bytes<256> :
+ (have_x512 ? bytes<512> : 0))) / SHA::word_bytes;
};
} // namespace sha
diff --git a/include/bitcoin/system/impl/hash/sha/algorithm.ipp b/include/bitcoin/system/impl/hash/sha/algorithm.ipp
index 3673eb710a..3cd0429ed3 100644
--- a/include/bitcoin/system/impl/hash/sha/algorithm.ipp
+++ b/include/bitcoin/system/impl/hash/sha/algorithm.ipp
@@ -573,7 +573,7 @@ schedule(auto& buffer) NOEXCEPT
}
else if constexpr (vectorization)
{
- schedule_v(buffer);
+ schedule_dispatch(buffer);
}
else
{
@@ -1198,7 +1198,7 @@ iterate(state_t& state, const ablocks_t& blocks) NOEXCEPT
}
else if constexpr (vectorization)
{
- iterate_v(state, blocks);
+ iterate_dispatch(state, blocks);
}
else
{
@@ -1212,7 +1212,7 @@ iterate(state_t& state, iblocks_t& blocks) NOEXCEPT
{
if constexpr (vectorization)
{
- iterate_v(state, blocks);
+ iterate_dispatch(state, blocks);
}
else
{
@@ -1284,7 +1284,7 @@ merkle_hash(digests_t& digests) NOEXCEPT
}
else if constexpr (vectorization)
{
- merkle_hash_v(digests);
+ merkle_hash_dispatch(digests);
}
else
{
diff --git a/include/bitcoin/system/impl/hash/sha/algorithm_vectorization.ipp b/include/bitcoin/system/impl/hash/sha/algorithm_vectorization.ipp
index a8cc497ed7..a3435e2a98 100644
--- a/include/bitcoin/system/impl/hash/sha/algorithm_vectorization.ipp
+++ b/include/bitcoin/system/impl/hash/sha/algorithm_vectorization.ipp
@@ -404,15 +404,19 @@ output(idigests_t& digests, const xstate_t& xstate) NOEXCEPT
digests.template advance();
}
+// Merkle Hash.
+// ----------------------------------------------------------------------------
+
TEMPLATE
template >
INLINE void CLASS::
-merkle_hash_v_(idigests_t& digests, iblocks_t& blocks) NOEXCEPT
+merkle_hash_invoke(idigests_t& digests, iblocks_t& blocks) NOEXCEPT
{
BC_ASSERT(digests.size() == blocks.size());
constexpr auto lanes = capacity;
static_assert(is_valid_lanes);
+ // RUNTIME INTRINSIC CHECK
if (blocks.size() >= lanes && have())
{
static auto initial = pack(H::get);
@@ -447,7 +451,7 @@ merkle_hash_v_(idigests_t& digests, iblocks_t& blocks) NOEXCEPT
TEMPLATE
INLINE void CLASS::
-merkle_hash_v(digests_t& digests) NOEXCEPT
+merkle_hash_dispatch(digests_t& digests) NOEXCEPT
{
// Merkle vector dispatch.
static_assert(sizeof(digest_t) == to_half(sizeof(block_t)));
@@ -463,11 +467,11 @@ merkle_hash_v(digests_t& digests) NOEXCEPT
// Merkle hash vector dispatch.
if constexpr (have_x512)
- merkle_hash_v_(idigests, iblocks);
+ merkle_hash_invoke(idigests, iblocks);
if constexpr (have_x256)
- merkle_hash_v_(idigests, iblocks);
+ merkle_hash_invoke(idigests, iblocks);
if constexpr (have_x128)
- merkle_hash_v_(idigests, iblocks);
+ merkle_hash_invoke(idigests, iblocks);
// iblocks.size() is reduced by vectorization.
offset = blocks - iblocks.size();
@@ -484,7 +488,7 @@ merkle_hash_v(digests_t& digests) NOEXCEPT
TEMPLATE
template
INLINE void CLASS::
-compress_v(state_t& state, const xbuffer_t& xbuffer) NOEXCEPT
+compress_dispatch(state_t& state, const xbuffer_t& xbuffer) NOEXCEPT
{
constexpr auto lanes = capacity;
@@ -521,11 +525,12 @@ compress_v(state_t& state, const xbuffer_t& xbuffer) NOEXCEPT
TEMPLATE
template >
INLINE void CLASS::
-iterate_v_(state_t& state, iblocks_t& blocks) NOEXCEPT
+iterate_invoke(state_t& state, iblocks_t& blocks) NOEXCEPT
{
constexpr auto lanes = capacity;
static_assert(is_valid_lanes);
+ // RUNTIME INTRINSIC CHECK
if (blocks.size() >= lanes && have())
{
BC_PUSH_WARNING(NO_UNINITIALZIED_VARIABLE)
@@ -537,7 +542,7 @@ iterate_v_(state_t& state, iblocks_t& blocks) NOEXCEPT
// input() advances block iterator by lanes.
input(xbuffer, blocks);
schedule_(xbuffer);
- compress_v(state, xbuffer);
+ compress_dispatch(state, xbuffer);
}
while (blocks.size() >= lanes);
}
@@ -545,17 +550,17 @@ iterate_v_(state_t& state, iblocks_t& blocks) NOEXCEPT
TEMPLATE
INLINE void CLASS::
-iterate_v(state_t& state, iblocks_t& blocks) NOEXCEPT
+iterate_dispatch(state_t& state, iblocks_t& blocks) NOEXCEPT
{
if (blocks.size() >= min_lanes)
{
// Schedule iteration vector dispatch.
if constexpr (have_x512)
- iterate_v_(state, blocks);
+ iterate_invoke(state, blocks);
if constexpr (have_x256)
- iterate_v_(state, blocks);
+ iterate_invoke(state, blocks);
if constexpr (have_x128)
- iterate_v_(state, blocks);
+ iterate_invoke(state, blocks);
}
// Complete rounds using normal form.
@@ -566,12 +571,12 @@ iterate_v(state_t& state, iblocks_t& blocks) NOEXCEPT
TEMPLATE
template
INLINE void CLASS::
-iterate_v(state_t& state, const ablocks_t& blocks) NOEXCEPT
+iterate_dispatch(state_t& state, const ablocks_t& blocks) NOEXCEPT
{
if (blocks.size() >= min_lanes)
{
auto iblocks = iblocks_t{ array_cast(blocks) };
- iterate_v(state, iblocks);
+ iterate_dispatch(state, iblocks);
}
else
{
@@ -602,7 +607,7 @@ sigma0_8(auto x1, auto x2, auto x3, auto x4, auto x5, auto x6, auto x7,
TEMPLATE
template
INLINE void CLASS::
-prepare_v(buffer_t& buffer) NOEXCEPT
+prepare_dispatch(buffer_t& buffer) NOEXCEPT
{
// Requires avx512 for sha512 and avx2 for sha256.
// sigma0x8 message scheduling for single block iteration.
@@ -668,35 +673,50 @@ prepare_v(buffer_t& buffer) NOEXCEPT
TEMPLATE
INLINE void CLASS::
-schedule_v(auto& buffer) NOEXCEPT
+schedule_invoke(buffer_t& buffer) NOEXCEPT
{
- using word = decltype(buffer.front());
+ // RUNTIME INTRINSIC CHECK
+ if (have_lanes())
+ {
+ prepare_dispatch<16>(buffer);
+ prepare_dispatch<24>(buffer);
+ prepare_dispatch<32>(buffer);
+ prepare_dispatch<40>(buffer);
+ prepare_dispatch<48>(buffer);
+ prepare_dispatch<56>(buffer);
+
+ if constexpr (SHA::rounds == 80)
+ {
+ prepare_dispatch<64>(buffer);
+ prepare_dispatch<72>(buffer);
+ }
- if constexpr (SHA::strength == 160 || !is_same_type)
+ add_k(buffer);
+ }
+ else
{
schedule_(buffer);
}
- else if (!have_lanes())
+}
+
+TEMPLATE
+INLINE void CLASS::
+schedule_dispatch(auto& buffer) NOEXCEPT
+{
+ // buffer may be vectorized via merkle execution path.
+ using word = decltype(buffer.front());
+
+ // Schedule prepare vector dispatch.
+ if constexpr ((SHA::strength != 160) && is_same_type &&
+ ((have_x512 && (capacity == 8u)) ||
+ (have_x256 && (capacity == 8u)) ||
+ (have_x128 && (capacity == 8u))))
{
- schedule_(buffer);
+ schedule_invoke(buffer);
}
else
{
- // Schedule prepare vector dispatch.
- prepare_v<16>(buffer);
- prepare_v<24>(buffer);
- prepare_v<32>(buffer);
- prepare_v<40>(buffer);
- prepare_v<48>(buffer);
- prepare_v<56>(buffer);
-
- if constexpr (SHA::rounds == 80)
- {
- prepare_v<64>(buffer);
- prepare_v<72>(buffer);
- }
-
- add_k(buffer);
+ schedule_(buffer);
}
}
diff --git a/include/bitcoin/system/impl/stream/iostream/iostream.ipp b/include/bitcoin/system/impl/stream/iostream/iostream.ipp
new file mode 100644
index 0000000000..3d22521ed9
--- /dev/null
+++ b/include/bitcoin/system/impl/stream/iostream/iostream.ipp
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2011-2023 libbitcoin developers (see AUTHORS)
+ *
+ * This file is part of libbitcoin.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+#ifndef LIBBITCOIN_SYSTEM_STREAM_IOSTREAM_IOSTREAM_IPP
+#define LIBBITCOIN_SYSTEM_STREAM_IOSTREAM_IOSTREAM_IPP
+
+#include
+
+namespace libbitcoin {
+namespace system {
+
+BC_PUSH_WARNING(NO_POINTER_ARITHMETIC)
+
+template
+INLINE iostream::iostream(Buffer& buffer) NOEXCEPT
+ : position_(buffer.data()),
+ begin_(position_),
+ end_(begin_ + buffer.size()),
+ state_(goodbit)
+{
+}
+
+template
+INLINE iostream::iostream(uint8_t* begin,
+ ptrdiff_t size) NOEXCEPT
+ : position_(begin),
+ begin_(position_),
+ end_(begin_ + size),
+ state_(goodbit)
+{
+}
+
+template
+INLINE typename iostream::iostate
+iostream::rdstate() const NOEXCEPT
+{
+ return state_;
+}
+
+template
+INLINE void
+iostream::setstate(iostate state) NOEXCEPT
+{
+ state_ |= state;
+}
+
+template
+INLINE void
+iostream::clear(iostate state) NOEXCEPT
+{
+ state_ = state;
+}
+
+// private
+template
+INLINE bool
+iostream::is_overflow(pos_type size) const NOEXCEPT
+{
+ return (state_ != goodbit) || (size > (end_ - position_));
+}
+
+BC_POP_WARNING()
+
+} // namespace system
+} // namespace libbitcoin
+
+#endif
diff --git a/include/bitcoin/system/impl/stream/simple/istream.ipp b/include/bitcoin/system/impl/stream/iostream/istream.ipp
similarity index 60%
rename from include/bitcoin/system/impl/stream/simple/istream.ipp
rename to include/bitcoin/system/impl/stream/iostream/istream.ipp
index c9345f74d3..e0bd6939d2 100644
--- a/include/bitcoin/system/impl/stream/simple/istream.ipp
+++ b/include/bitcoin/system/impl/stream/iostream/istream.ipp
@@ -16,8 +16,8 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-#ifndef LIBBITCOIN_SYSTEM_STREAM_SIMPLE_ISTREAM_IPP
-#define LIBBITCOIN_SYSTEM_STREAM_SIMPLE_ISTREAM_IPP
+#ifndef LIBBITCOIN_SYSTEM_STREAM_IOSTREAM_ISTREAM_IPP
+#define LIBBITCOIN_SYSTEM_STREAM_IOSTREAM_ISTREAM_IPP
#include
#include
@@ -26,25 +26,18 @@
namespace libbitcoin {
namespace system {
-template
-inline istream