Skip to content

Commit 9c850f3

Browse files
authored
readme improvements. (#6)
1 parent 0e1192f commit 9c850f3

File tree

1 file changed

+139
-20
lines changed

1 file changed

+139
-20
lines changed

README.md

Lines changed: 139 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,139 @@
1-
# CPP-Stream
2-
C++ imitation of Java 8 Stream API
3-
4-
## Setting up
5-
### Unix:
6-
Variable CMAKE_ARGS is for passing arguments to cmake invocation
7-
8-
* Simple run : `make`
9-
* Make **DEBUG** build and run tests: `make CMAKE_ARGS="-DCMAKE_BUILD_TYPE=Debug"`
10-
* Make **RELEASE** build and run tests: `make CMAKE_ARGS="-DCMAKE_BUILD_TYPE=Release"`
11-
* Testing coverage (**DEBUG** build only): `make CMAKE_ARGS="-DCMAKE_BUILD_TYPE=Debug" collect_coverage`
12-
13-
### Windows:
14-
Use [cmake](https://cmake.org/download/) for generating MSVS solution / smth else : `cd build && cmake.exe ../`
15-
16-
### Testing coverage (Unix only)
17-
Testing coverage has the next dependencies:
18-
* [gcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html)
19-
* [lcov](https://wiki.documentfoundation.org/Development/Lcov) (install using apt : `apt-get install lcov`)
20-
* [genhtml](https://linux.die.net/man/1/genhtml)
1+
# cpp-stream
2+
C++17-compatible imitation of [Java 8 Stream API](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html).
3+
Elements are processed lazily and with minimum overhead.
4+
5+
## Example
6+
```cpp
7+
#include <stream/stream.h> // stream::Stream
8+
#include <stream/operations.h> // stream::ops::*
9+
#include <vector> // std::vector
10+
#include <string> // std::string
11+
#include <algorithm> // std::transform
12+
#include <iostream> // std::cout
13+
14+
int main()
15+
{
16+
namespace ops = stream::ops;
17+
18+
const std::vector strings = {
19+
"dignity",
20+
"respect",
21+
"Fred's",
22+
"sun",
23+
"color",
24+
"friends",
25+
"premium",
26+
"run",
27+
"sector",
28+
"fried",
29+
"smile",
30+
"Fritos",
31+
"for",
32+
"global",
33+
"Fridays",
34+
"broadcast",
35+
"food"
36+
};
37+
38+
// no copying or moving, string is stored via reference
39+
stream::Stream(strings)
40+
| ops::filter([](const char *str) { // select only strings started with 'F' or 'f'
41+
return (str[0] == 'f' || str[0] == 'F');
42+
}) // nothing will be evaluated at this point
43+
| ops::map([](std::string str) { // make every word is in uppercase
44+
(void)std::transform(str.begin(), str.end(), str.begin(), [](unsigned char ch) { return std::toupper(ch); });
45+
return str;
46+
}) // still nothing will be evaluated
47+
| ops::print_to(std::cout); // there is terminal operation - causes evaluating everything
48+
49+
return 0;
50+
}
51+
```
52+
Output:
53+
> FRED'S FRIENDS FRIED FRITOS FOR FRIDAYS FOOD
54+
55+
## Supported terminal operations
56+
* `print_to(ostream)` - prints all elements of the stream to a given output stream `ostream`;
57+
* `reduce(identityFn, accumulatorFn)` - reduces all elements of the stream to 1 similar to the following pseudo-code:
58+
```cpp
59+
stream::Stream s(...);
60+
auto v = identityFn(s.getNext());
61+
while (!s.isEnd())
62+
v = accumulatorFn(v, s.getNext());
63+
return v;
64+
```
65+
* `reduce(accumulatorFn)` - reduces all elements of the stream to 1 similar to the following pseudo-code:
66+
```cpp
67+
stream::Stream s(...);
68+
auto v = s.getNext();
69+
while (!s.isEnd())
70+
v = accumulatorFn(v, s.getNext());
71+
return v;
72+
```
73+
* `nth(n)` - returns `n`th element of the stream;
74+
* `to_vector()` - moves all elements of the origin stream to a `std::vector`.
75+
76+
## Supported non terminal operations
77+
* `skip(n)` - skips n elements of the stream;
78+
* `get(n)` - takes only n first elements from the stream;
79+
* `map(mapFn)` - creates a new stream of results of applying the given functor `mapFn` to every element of the given stream;
80+
* `filter(predicateFn)` - leaves only elements to which applying `predicateFn` functor returns true;
81+
* `group(n)` - creates a new stream of `std::vector`s with `n` elements of the origin stream.
82+
83+
## Requirements
84+
* Using the library:
85+
* C++17-compatible compiler and STL
86+
* For running tests, you need:
87+
* [git](https://git-scm.com/downloads)
88+
* [CMake](https://cmake.org/download/) >= v3.1
89+
* Additionally, if you want to measure code coverage, you need:
90+
* compiler,q
91+
[gcov](https://en.wikipedia.org/wiki/Gcov)
92+
[, optional: [lcov](https://wiki.documentfoundation.org/Development/Lcov)]
93+
compatible with each other
94+
(for example, gcc 6.3.0, gcov 6.3.0 and lcov 1.13 are compatible)
95+
* [genhtml](https://linux.die.net/man/1/genhtml)
96+
* [CMake](https://cmake.org/download/) >= v3.13
97+
98+
## Build and run tests
99+
See [Requirements](#requirements) chapter first.
100+
101+
Just use [CMake](https://cmake.org/download/) (run from project root):
102+
```bash
103+
# Build
104+
cd build
105+
cmake -DCMAKE_BUILD_TYPE=Release ..
106+
cmake --build .
107+
108+
# Running tests
109+
ctest -C Release -V
110+
```
111+
112+
Note: This project uses [GoogleTest](https://github.com/google/googletest) for testing.
113+
114+
## Code coverage measurement
115+
See [Requirements](#requirements) chapter first.
116+
117+
CMake scripts provides the next additional variables for setting up the measurement:
118+
* `COLLECT_CODE_COVERAGE=<LCOV|OTHER|OFF>` - if set to `LCOV` then code coverage target `collect_coverage` will be created. `OTHER` assumes compiling/linking code for measuring via different than lcov instrument ([gcov](https://en.wikipedia.org/wiki/Gcov) for example). `OFF` does nothing and set by default.
119+
* `GCOV_PATH` - allows to specify path to [gcov](https://en.wikipedia.org/wiki/Gcov) executable. `gcov` by default.
120+
121+
It's recommended to build the code in `Debug` mode for coverage measurement.
122+
123+
Example (run from project root):
124+
```bash
125+
# Build
126+
cd build
127+
cmake -DCMAKE_BUILD_TYPE=Debug \
128+
-DCMAKE_C_COMPILER=gcc-6.3.0 \
129+
-DCMAKE_CXX_COMPILER=g++-6.3.0 \
130+
-DCOLLECT_CODE_COVERAGE=LCOV \
131+
-DGCOV_PATH=gcov-6.3.0 \
132+
..
133+
134+
# Collecting the coverage:
135+
cmake --build . --target collect_coverage
136+
137+
# Html reports will be generated. Use browser to see it:
138+
<your_browser_name> ./collect_coverage/index.html &
139+
```

0 commit comments

Comments
 (0)