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&gt 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;
}