How do I write my own stream conversion in C ++?

I am learning C ++ doing a lot with Haskell and functional languages ​​in general, and I found myself constantly trying to solve the same problem:

  • Read some data from the input stream
  • Designate them based on a specific algorithm
  • Process Tokens

If it were Haskell, I would just take advantage of the fact that everything is lazy and write my transform when I think about it, and then it will be applied when the stream down is consumed. There are even libraries that do this exact pattern ( conduit and pipes ).

Let's say that I wanted to take a sequence 1 2 3 4 5 6 ...

and output 12 34 56 ...

. I can see how to write custom code that works with a stream and processes data. But I would like to know if there is an abstraction mechanism that allows me to create a new stream by transforming data (in any way imaginable) from another stream. This abstraction should allow me to buffer the data as I process it, and not just simply map one element to a new value.

Here are the limitations:

  • I cannot use any other library other than stdlib.
  • It should work in C ++ 03 (which means no C ++ 11 features)

If you think this is homework? Okay, I am getting a lot of class assignments that require me to work with data streams (which is the reason for the lack of a library and C ++ 03 limitations). It's not that I don't know how to do it using loops while

, but I would like to know if an existing stream abstraction exists in stl, just waiting for it to be detected and used.

But if the only way to do this is using C ++ 11, then I would like to know.

+3


source to share


2 answers


Concept code not tested. There are many errors and correct syntax when rendering.



struct add : public std::binary_function<int,int,int> {
  int operator() (int a, int b) {return (a + b);}
};

template<typename inType, typename dType, typename outType, class binFunc>
outType Transformer(inType& inStream, outType& outStream, binFunc func) {
  dType a, b;
  // Read some data from an input stream
  // Tokenize them based on a specific algorithm
  inStream>> a >> b; 
  //outStream << func(a, b);
  return func(a,b); // Process the tokens
}

int main() {
  std::ifstream in("input.dat", std::ifstream::in); // , std::ios::binary
  std::ofstream out("output.dat");
  struct add adder;  // to Process the tokens

  out << Transformer(in, out, adder);

  return exit_success;
}

      

+1


source


The following doesn't match your need for a no-library-solution (and I don't have enough reputation to leave it as a comment); nevertheless, it will be useful for your functional thinking.

David Sankel gave a great talk about FRP using C ++ on C ++ Now 2014. He even provided the library they use for production.

The video can be found here: https://www.youtube.com/watch?v=tyaYLGQSr4g&list=UU5e__RG9K3cHrPotPABnrwg



The slides are linked to the video description and github links at the end of the slides.

I suspect you will get some inspiration from here too: http://ericniebler.com/2013/11/07/input-iterators-vs-input-ranges/

std :: transform with stream iterators should pretty much do what you want.

0


source







All Articles