I currently have the following function to read an array or a vector of raw data (_readStream
is a std::ifstream
) :
template<typename IteratorType>
inline bool MyClass::readRawData(
const IteratorType& first,
const IteratorType& last,
typename std::iterator_traits<IteratorType>::iterator_category* = nullptr
)
{
_readStream.read(reinterpret_cast<char*>(&*first), (last-first)*sizeof(*first));
return _readStream.good();
}
First question : does this function seem ok for you ?
As we read directly a block of memory, it will only work if the memory block from first
to last
is contiguous in memory. How to check that ?
A checked iterator refers to an iterator that calls invalid_parameter_handler if you attempt to move past the boundaries of the container. For more information about invalid_parameter_handler, see Parameter Validation. The iterator adaptors that support checked iterators are checked_array_iterator Class and unchecked_array_iterator Class.
contiguous_iterator is modeled by every pointer type to complete object type. Iterator types in the standard library that are required to satisfy the LegacyContiguousIterator requirements in C++17 are also required to model contiguous_iterator in C++20.
As the physical pages must be contiguous (not the case for user space malloced memory). It is often difficult to obtain large contiguous memory regions from the kernel, especially the longer the system is up and running.
If _ITERATOR_DEBUG_LEVEL is defined as 1 or 2, unsafe use of iterators causes a runtime error and the program is terminated. If defined as 0, checked iterators are disabled. By default, the value for _ITERATOR_DEBUG_LEVEL is 0 for release builds and 2 for debug builds. Older documentation and source code may refer to the _SECURE_SCL macro.
Leaving aside your sample function, you can never be completely sure that iterators will form a contiguous memory without checking the address of every element between the two.
A reasonable sanity test, though, would be to just check if the memory area between the two is the same as the count between the two:
assert(&*last - &*first == last - first &&
"Iterators must represent a contiguous memory region");
n4183 is a paper that goes over the idea of adding a contiguous iterator trait. It is currently under consideration for C++1z (hopefully C++17).
Under it, you can do std::is_contiguous_iterator<It>::value
and get if It
is a contiguous iterator or not. (This will require support from the designer of the iterator).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With