c++ - Specifying input and output ranges to algorithms -
there number of use cases in standard library, , have run own code, situations want pass input , output range must same size, algorithm. @ present requires three, or 4 if want careful, iterators. there bunch of checking make sure iterators make sense.
i aware array_view might, in cases, coalesce pairs of being/end iterators still leaves checks required input , output array_views might different size. has there been discussion on class contain both input , output range specifications? maybe range proposal solves or of of i'm not clear how does.
i have similar use case. have found versatile method pass reference output 'container' concept rather range or pair of iterators. algorithm free resize or extend container necessary , possibility of buffer overruns disappears.
for (a simple contrived) example, like:
template<class inputiter, class outputcontainer> void encrypt_to(outputcontainer& dest, inputiter first, inputiter last) { dest.resize(last - first); // ... todo: replace actual encryption std::copy(first, last, dest.begin()); }
for functions want hide implementation, have abstract interface representing destination container. needs virtual begin()
, end()
, resize()
methods.
for example:
#include <iostream> #include <algorithm> #include <vector> struct mutable_byte_buffer_concept { using iterator=uint8_t*; virtual iterator begin() = 0; virtual iterator end() = 0; virtual void resize(size_t newsize) = 0; // note : no virtual destructor - design. }; template<class container> struct mutable_byte_buffer_model : mutable_byte_buffer_concept { mutable_byte_buffer_model(container& container) : container(container) { } virtual iterator begin() override { return reinterpret_cast<iterator>(&container[0]); } virtual iterator end() override { return reinterpret_cast<iterator>(&container[0]) + container.size(); } virtual void resize(size_t newsize) override { container.resize(newsize); } container& container; }; template<class container> auto make_mutable_buffer(container& c) -> mutable_byte_buffer_model<container> { return { c }; } // note: accepting rvalue allows me use polymorphism @ call site without needing memory allocation template<class iter> void copy_to(mutable_byte_buffer_concept&& dest, iter first, iter last) { dest.resize(last - first); std::copy(first, last, dest.begin()); } using namespace std; auto main() -> int { auto = "hello, world"s; string b; vector<uint8_t> c; string d; copy_to(make_mutable_buffer(b), begin(a), end(a)); copy_to(make_mutable_buffer(c), begin(b), end(b)); copy_to(make_mutable_buffer(d), begin(c), end(c)); cout << d << endl; return 0; }
Comments
Post a Comment