tcw165 / ReactivePlusPlus

One more implementation of ReactiveX approach in C++ with care about performance and templates in mind

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ReactivePlusPlus

CI codecov GitHub Join the chat at https://gitter.im/ReactivePlusPlus/community Join the chat in Discord: https://discord.gg/KWMR3RNkVz

Lines of Code Maintainability Rating GitHub commit activity

ReactivePlusPlus is reactive programming library for C++ language inspired by "official implementation" (RxCpp) and original idea (ReactiveX)

In short: ReactivePlusPlus is library for building asynchronous event-driven streams of data with help of sequences of primitive operators in the declarative form. For example:

rpp::source::from_callable(&::getchar)
   .repeat()
   .take_while([](char v) { return v != '0'; })
   .filter(std::not_fn(&::isdigit))
   .map(&::toupper)
   .subscribe([](char v) { std::cout << v; });

Main advantages of ReactivePlusPlus are that it is written in Modern C++ with Performance and Usage in mind. As a result it is fast, readable, easy to use and well-documented.

NOTE: ReactivePlusPlus is library for C++20. So, it works only on compilers that supports most C++20 features. CI uses gcc-10, clang-11, visual studio 2022

What about existing Reactive Extension libraries for C++?

Reactive programming is excelent programming paradigm and approach for creation of multi-threading and real-time programs which reacts on some events. Unfortunately, there is only one stable and fully-implemented library at the moment of creation of ReactivePlusPlus - RxCpp.

RxCpp is great and awesome library and perfect implementation of ReactiveX approach. However RxCpp has some disadvantages:

  • It is a bit "old" library written in C++11 with some parts written in the pre-C++11 style (mess of old-style classes and wrappers)
  • Issue with template parameters: rxcpp::observable contains full chain of operators as second template parameter... where each operator has a bunch of another template parameters itself. It forces IDEs works slower while parsing resulting type of observable. Also it forces to generate heavier binaries and debug symbols and slower build time.
  • It has high perfomance cost due to tremendous amount of usage of heap

Another implementation of RX for c++: another-rxcpp. It partly solves issues of RxCpp via eliminating of template parameter with help of type-erasing and making each callback as std::function. As a result issue with templates resvoled, but this approach has disadvantages related to runtime: resulting size of observers/observables becomes greater due to heavy std::function object, usage of heap for storing everything causes perfomance issues, implementation is just pretty simple and provides a lot of copies of passed objects.

Why ReactivePlusPlus?

ReactivePlusPlus tries to solve all mentioned issues:

  • ReactivePlusPlus written in Modern C++ (C++20) with concepts which makes code-base a lot more understandable and clean:
    • Concepts provide more clear errors and checks: you will understand that pass something incorrect before compilation in IDE or during compilation with understandable errors instead of "invalid template class map_invalid_t"
    • Everywhere while possible used deduction of template arguments, for example, type of values of observable by type of subscriber used in on_subscribe and etc
  • ReactivePlusPlus keeps balance between performance and type-erasing mechanism: Read about it in "Performance vs Flexibility: Specific vs Dynamic"
  • ReactivePlusPlus is fast: every part of code written with perfomance in mind. Starting from tests over amount of copies/move and finishing to Continous Benchmarking. Benchmarks show that RPP faster that RxCPP in most cases: Continous benchmarking results

Useful links

Building and installing

See the BUILDING document. If you are going to know more details about developing for RPP check HACKING document.

Contributing

See the CONTRIBUTING document.

Licensing

Boost Software License - Version 1.0 - August 17th, 2003

Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following:

The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Credits:

ReactivePlusPlus library uses:

  • Catch2 for unit testing only, fetched (or used via find_package) automatically in case of RPP_BUILD_TESTS enabled
  • RxCpp only for comparison of performance between RPP and RxCpp in CI benchmarks. Used as cmake dependency under option
  • reactivex.io as source for insipration and definition of entities used in RPP. Some comments used in RPP source code taken from reactivex.io
  • rxmarbles python as generator of marbles graphs in doxygen documentation
  • cmake-init as generator for most part of initial CMakes

About

One more implementation of ReactiveX approach in C++ with care about performance and templates in mind

License:Boost Software License 1.0


Languages

Language:C++ 96.4%Language:CMake 2.3%Language:Python 1.4%