24 #ifndef __TPIE_STREAM_CRTP_H__
25 #define __TPIE_STREAM_CRTP_H__
27 #include <tpie/tpie_export.h>
35 template <
typename child_t>
52 assert(
self().get_file().is_open());
54 offset +=
self().size();
55 else if (whence == current) {
57 if (offset >= 0 ||
static_cast<stream_size_type
>(-offset) <= m_index) {
58 stream_size_type new_index =
static_cast<stream_offset_type
>(offset+m_index);
60 if (new_index <
self().get_file().block_items()) {
62 m_index =
static_cast<memory_size_type
>(new_index);
67 offset +=
self().offset();
69 if (0 > offset || (stream_size_type)offset >
self().size())
72 stream_size_type b =
static_cast<stream_size_type
>(offset) /
self().get_file().block_items();
73 m_index =
static_cast<memory_size_type
>(offset - b*
self().get_file().block_items());
74 if (b ==
self().get_block().number) {
75 m_nextBlock = std::numeric_limits<stream_size_type>::max();
76 m_nextIndex = std::numeric_limits<memory_size_type>::max();
77 assert(
self().offset() == (stream_size_type)offset);
81 m_nextIndex = m_index;
82 m_index = std::numeric_limits<memory_size_type>::max();
83 assert(
self().offset() == (stream_size_type)offset);
91 inline stream_size_type
offset()
const throw() {
92 assert(
self().get_file().is_open());
93 if (m_nextBlock == std::numeric_limits<stream_size_type>::max())
94 return m_index + m_blockStartIndex;
95 return m_nextIndex + m_nextBlock *
self().get_file().block_items();
110 assert(
self().get_file().is_open());
111 if (m_index <
self().get_block().size )
return true;
112 return offset() <
self().size();
121 assert(
self().get_file().is_open());
122 if (m_nextBlock == std::numeric_limits<stream_size_type>::max())
123 return m_index > 0 || m_blockStartIndex > 0;
125 return m_nextIndex > 0 || m_nextBlock > 0;
133 inline stream_size_type
size()
const throw() {
137 const_cast<child_t&
>(
self()).update_vars();
138 return self().get_file().file_size();
142 inline void initialize() {
143 m_nextBlock = std::numeric_limits<stream_size_type>::max();
144 m_nextIndex = std::numeric_limits<memory_size_type>::max();
145 m_index = std::numeric_limits<memory_size_type>::max();
165 template <
typename IT,
typename Stream>
166 static inline void read_array(Stream & stream,
const IT & start,
const IT & end) {
167 typedef typename Stream::item_type T;
170 if (stream.m_index >= stream.block_items()) {
172 stream_size_type offs = stream.offset();
173 if (offs >= stream.size()
174 || offs + (end-i) > stream.size()) {
180 stream.update_block();
183 T * src =
reinterpret_cast<T*
>(stream.get_block().data) + stream.m_index;
186 memory_size_type count = std::min(stream.block_items()-stream.m_index,
static_cast<memory_size_type
>(end-i));
188 std::copy(src, src + count, i);
194 stream.m_index += count;
211 template <
typename IT,
typename Stream>
212 static inline void write_array(Stream & stream,
const IT & start,
const IT & end) {
213 typedef typename Stream::item_type T;
216 if (stream.m_index >= stream.block_items()) stream.update_block();
218 size_t streamRemaining = end - i;
219 size_t blockRemaining = stream.block_items()-stream.m_index;
221 IT till = (blockRemaining < streamRemaining) ? (i + blockRemaining) : end;
223 T * dest =
reinterpret_cast<T*
>(stream.get_block().data) + stream.m_index;
225 std::copy(i, till, dest);
227 stream.m_index += till - i;
228 stream.write_update();
259 inline child_t &
self() {
return *
static_cast<child_t*
>(
this);}
260 inline const child_t &
self()
const {
return *
static_cast<const child_t*
>(
this);}
265 #endif // __TPIE_STREAM_CRTP_H__