I wrote a range library some years ago and then found a proposal to include a range library in the std library.
I adopted the proposed library and over time I have added additional features to ease usage of C APIs. One feature I added is make_range_raw
.
make_range
works by requiring that the Range passed in has support for the begin
and end
free-functions. This produces range<Iterator>
where Iterator
is a raw pointer for built-in arrays but uses the iterator type defined by the Range when it is a collection like vector
or wstring
. This is the desired behavior for make_range
but when trying to interface between collections and C APIs it would be better to access the raw pointer for contiguous array collections like vector
and wstring
.
make_raw_range
requires that the collection support raw access via operator []
. Using &r[0]
for begin
and &r[0] + size(r)
for end
produces range<Iterator>
where Iterator
is always a raw pointer. (for well behaved collections this is true. vector<bool>
is not well behaved)
Implementation
maintained here
template< class Range > auto make_range_raw(Range && r) -> decltype( make_range( &r[0], &r[0] + size(r) ) ) { if (size(r) == 0) { decltype( make_range( &r[0], &r[0] + size(r) ) ) result; return result; } return make_range( &r[0], &r[0] + size(r) ); } template< class Range > auto make_range_raw( Range && r, typename range_difference<Range>::type advance_begin, typename range_difference<Range>::type advance_end ) -> decltype( make_range( &r[0], &r[0] + size(r) ) ) { decltype( make_range( &r[0], &r[0] + size(r) ) ) result; if (size(r) != 0) { result = make_range( &r[0], &r[0] + size(r) ); } result.advance_begin(advance_begin); result.advance_end(advance_end); return result; }
No comments:
Post a Comment