-
Repo: httpx://github.com/lvv/ro[GitHub], httpx://bitbucket.org/lvv/ro[BitBucket]
-
Requires: C++11 compiler. Tested with gcc-4.8.1 and clang-3.3
-
License: httpx://en.wikipedia.org/wiki/Boost_Software_License[Boost Software License]
RO is C++ headers only library, which provides alternative interface to STL, mostly through overloaded operators and with some elements of functional programming. RO operates on ranges which are STL containers, RO-ranges, Tuples, C-arrays and C-strings.
RO strives for simpler and more expressive C++ code with zero overhead.
Some consider that use of overloaded operators, not having meaningful names and having multiple overloads are confusing and ambiguous. I will try to show that it is not so. Below follow examples comparing STL vs RO code.
In below RO code snippet, you can probably figure out what it does without explanation:
container << value1 << value2;
Yes, this was like applying two push_back
(if container was vector-like). That was simple.
If you want to add two values to a container with STL - that would be not so simple:
-
If above container is
std::vector
- we will usepush_back
; -
If
std::set
- we needinsert
; -
If
std::map
-operator[]
orinsert
; -
If
std::stack
- that would bepush
; -
If
value1
is container too, it will depend on type of container. It can bestd::copy
possibly withstd::back_insert_iterator
. Orstd::slice
. Or plain for-loop; -
If container is a C-string, you will need to close your STL reference and start looking at
man string
;
There is logical explanation for STL’s non-uniformity. Operations performed under the hood are very different for each case. End result is that even after many years of using it, I still need STL reference manual handy.
With RO, above snippet won’t change for any of above listed cases. RO library has same interface for STL containers, C-strings, C-arrays and RO-Ranges.
In next example we need to perform another simple operation: remove a value from a
std::vector
:
vec.erase(stl::remove(vec.begin(), vec.end(), x), vec.end());
For above you need not only STL reference, but you will need know erase-remove idiom.
If container is not std::vector
, you will have to find out how STL
does erase for your particular container.
With RO you won’t need expression with calls to 4 member function, 1 algorithm and 10 parenthesis:
vec - x;
And again, above expression won’t change if we use any container (or range) and if
x
is a value, a predicate, iterator or sub-range.
If we need to erase subrange:
vec - range(it1,it2);
One more example. This was used by someone as example of terseness and
simplicity of C++11. We need to find an element bigger than val
:
find_if(vec.begin(), vec.end(), [=](int i){ return i > val})
With RO (using RO’s lambdas):
vec / (_1 > val) ---------------------------- Again, with STL, you will need different algorithm if you are looking for a value or sub-range. With RO, that would be the same divide op: `v / something`. Usually we need to find not 1st, but all values. Like in this code: -------------------------- vector<int> result; auto it = vec.begin(); while(it!=vec.end()) { it = find_if(it, vec.end(), [=](int i){ return i > val;}); if (it == vec.end()) break; result.push_back(*it++); }
This is rather low level way of doing things. RO provides mulch simpler code with filtered range:
vector<int> result = vec | (_1 > val);