How to check if iterators form a contiguous memory zone?

Currently, I have the following function to read an array or raw data vector ( _readStream- 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 feature look normal to you?

When we read the memory block directly, it will only work if the memory block from firstto lastis adjacent in memory. How to check it?

+5
source share
3 answers

Leaving aside your fetch function, you can never be completely sure that iterators form continuous memory without checking the address of each element between them.

, , , , : :

assert(&*last - &*first == last - first &&
    "Iterators must represent a contiguous memory region");
+4

n4183 - , . ++ 1z (, ++ 17).

std::is_contiguous_iterator<It>::value , It - . ( ).

+3
typename std::iterator_traits<IteratorType>::iterator_category* = nullptr

, std::iterator_traits iterator_category. , , - SFINAE, , .

When we read the memory block directly, it will work only if the memory block from the first to the last is continuous in memory. How to check it?

I do not know what exact requirements you would put in the concept of "contiguous in memory." However, did you consider the following?

template<typename T>
bool readRawData(T* first, T* last);

with a precondition, which [ first, last )is a valid range of pointer-and-iterator to an array.

If you want to add additional requirements to T(for example, trivial copyability, as you use read), you can also express and document them.

+2
source

All Articles