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

Popular posts from this blog

html - Outlook 2010 Anchor (url/address/link) -

javascript - Why does running this loop 9 times take 100x longer than running it 8 times? -

Getting gateway time-out Rails app with Nginx + Puma running on Digital Ocean -