Top Related Projects
RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
Reactive Programming in Swift
A reactive programming library for JavaScript
RxJava bindings for Kotlin
Boost.org asio module
An open-source C++ library developed and used at Facebook.
Quick Overview
RxCpp is a C++ implementation of the Reactive Extensions (ReactiveX) library. It provides a set of tools for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators, allowing developers to easily manage complex asynchronous operations and data streams in C++.
Pros
- Powerful abstraction for handling asynchronous operations and event streams
- Extensive set of operators for transforming, combining, and manipulating observables
- Cross-platform support and integration with modern C++ features
- Helps reduce callback hell and simplifies complex asynchronous logic
Cons
- Steep learning curve for developers unfamiliar with reactive programming concepts
- Can introduce overhead for simple use cases
- Documentation could be more comprehensive and include more examples
- May require careful memory management in certain scenarios
Code Examples
- Creating and subscribing to an observable:
#include <rxcpp/rx.hpp>
#include <iostream>
int main() {
auto observable = rxcpp::observable<>::create<int>([](rxcpp::subscriber<int> s) {
s.on_next(1);
s.on_next(2);
s.on_next(3);
s.on_completed();
});
observable.subscribe(
[](int v) { std::cout << "Received: " << v << std::endl; },
[]() { std::cout << "Completed" << std::endl; }
);
return 0;
}
- Using operators to transform an observable:
#include <rxcpp/rx.hpp>
#include <iostream>
int main() {
auto numbers = rxcpp::observable<>::range(1, 10);
numbers
.filter([](int n) { return n % 2 == 0; })
.map([](int n) { return n * n; })
.subscribe([](int n) { std::cout << n << " "; });
std::cout << std::endl;
return 0;
}
- Combining multiple observables:
#include <rxcpp/rx.hpp>
#include <iostream>
int main() {
auto obs1 = rxcpp::observable<>::just(1, 2, 3);
auto obs2 = rxcpp::observable<>::just(4, 5, 6);
obs1.merge(obs2)
.subscribe([](int v) { std::cout << v << " "; });
std::cout << std::endl;
return 0;
}
Getting Started
To get started with RxCpp:
- Clone the repository:
git clone https://github.com/ReactiveX/RxCpp.git
- Add the
Rx/v2/src
directory to your include path - Include the necessary headers in your C++ file:
#include <rxcpp/rx.hpp>
- Compile your program with C++11 or later support
Example compilation command:
g++ -std=c++11 -I/path/to/RxCpp/Rx/v2/src your_file.cpp -o your_program
Make sure to link against any required libraries for your specific use case.
Competitor Comparisons
RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
Pros of RxJava
- Larger community and more extensive documentation
- Better integration with Android development
- More comprehensive set of operators and utilities
Cons of RxJava
- Higher memory footprint and potential performance overhead
- Steeper learning curve for developers new to reactive programming
Code Comparison
RxJava:
Observable.just(1, 2, 3, 4, 5)
.map(x -> x * x)
.filter(x -> x % 2 == 0)
.subscribe(System.out::println);
RxCpp:
auto values = rxcpp::observable<>::just(1, 2, 3, 4, 5);
values.map([](int x) { return x * x; })
.filter([](int x) { return x % 2 == 0; })
.subscribe([](int x) { std::cout << x << std::endl; });
Both RxJava and RxCpp provide similar functionality for reactive programming, but RxJava has a more mature ecosystem and is particularly well-suited for Android development. RxCpp, on the other hand, offers a native C++ implementation that may be more appropriate for certain performance-critical applications or when working in C++ environments. The code comparison demonstrates the similarity in syntax and usage between the two libraries, with minor differences in language-specific constructs.
Reactive Programming in Swift
Pros of RxSwift
- Better integration with Swift's language features and iOS/macOS ecosystem
- More extensive documentation and community support for mobile development
- Stronger type safety and compile-time checks
Cons of RxSwift
- Limited to Swift and Apple platforms, less versatile than RxCpp
- Potentially steeper learning curve for developers new to functional reactive programming
- May introduce additional complexity in simpler iOS/macOS applications
Code Comparison
RxSwift:
Observable.from([1, 2, 3, 4, 5])
.filter { $0 % 2 == 0 }
.map { $0 * 2 }
.subscribe(onNext: { print($0) })
RxCpp:
auto values = rxcpp::observable<>::from(1, 2, 3, 4, 5);
values.filter([](int v) { return v % 2 == 0; })
.map([](int v) { return v * 2; })
.subscribe([](int v) { std::cout << v << std::endl; });
Both libraries provide similar functionality for reactive programming, but RxSwift is tailored for Swift and iOS/macOS development, while RxCpp offers a more platform-agnostic approach for C++ projects. RxSwift benefits from tighter integration with Apple's ecosystem, while RxCpp provides greater flexibility across different platforms and programming environments.
A reactive programming library for JavaScript
Pros of rxjs
- Larger ecosystem and community support in JavaScript/TypeScript
- Seamless integration with Angular and other web frameworks
- More comprehensive documentation and learning resources
Cons of rxjs
- Potentially larger bundle size for web applications
- Steeper learning curve for developers new to reactive programming
- Performance overhead in some scenarios compared to native JavaScript
Code Comparison
rxjs:
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
of(1, 2, 3).pipe(
map(x => x * 2)
).subscribe(console.log);
RxCpp:
#include <rxcpp/rx.hpp>
rxcpp::observable<>::just(1, 2, 3)
.map([](int x) { return x * 2; })
.subscribe([](int v) { std::cout << v << std::endl; });
Both libraries provide similar functionality for reactive programming, but rxjs is tailored for JavaScript/TypeScript environments, while RxCpp is designed for C++ applications. rxjs offers better integration with web technologies and frameworks, making it more suitable for front-end development. RxCpp, on the other hand, provides reactive programming capabilities for C++ projects, which can be beneficial for systems programming and performance-critical applications.
RxJava bindings for Kotlin
Pros of RxKotlin
- Seamless integration with Kotlin's language features, including coroutines
- More concise syntax due to Kotlin's expressive nature
- Better null safety and type inference
Cons of RxKotlin
- Limited to Kotlin and JVM ecosystems
- Potentially slower performance compared to native C++ implementation
Code Comparison
RxKotlin:
Observable.just(1, 2, 3)
.map { it * 2 }
.subscribe { println(it) }
RxCpp:
auto observable = rxcpp::observable<>::just(1, 2, 3);
observable
.map([](int x) { return x * 2; })
.subscribe([](int x) { std::cout << x << std::endl; });
Additional Considerations
- RxCpp offers better performance for systems programming and resource-constrained environments
- RxKotlin provides a more modern and developer-friendly experience
- RxCpp has a steeper learning curve due to C++'s complexity
- RxKotlin benefits from Kotlin's multiplatform capabilities
- Both libraries follow ReactiveX principles, making it easier to switch between them if needed
Overall, the choice between RxCpp and RxKotlin depends on the specific project requirements, target platform, and developer preferences. RxKotlin is generally more suitable for Android and JVM-based applications, while RxCpp is better for high-performance, cross-platform C++ projects.
Boost.org asio module
Pros of Asio
- Mature and widely adopted library for asynchronous I/O and networking
- Provides both synchronous and asynchronous programming models
- Supports a wide range of platforms and compilers
Cons of Asio
- Steeper learning curve, especially for beginners
- Can be complex to use for simple tasks
- Requires more boilerplate code compared to RxCpp
Code Comparison
Asio (basic TCP client):
asio::io_context io_context;
tcp::socket socket(io_context);
socket.connect(tcp::endpoint(address::from_string("127.0.0.1"), 1234));
socket.write_some(asio::buffer("Hello, World!"));
RxCpp (basic observable):
auto observable = rxcpp::observable<>::create<int>([](rxcpp::subscriber<int> s) {
s.on_next(1);
s.on_next(2);
s.on_completed();
});
While Asio focuses on low-level networking and I/O operations, RxCpp provides a higher-level abstraction for reactive programming. Asio is more suitable for network-centric applications, while RxCpp excels in handling event streams and composing asynchronous operations. The choice between the two depends on the specific requirements of your project and the programming paradigm you prefer.
An open-source C++ library developed and used at Facebook.
Pros of Folly
- Broader scope: Folly is a comprehensive C++ library with a wide range of utilities, while RxCpp focuses specifically on reactive programming
- Active development: Folly has more frequent updates and contributions from Facebook's engineering team
- Performance optimizations: Folly includes highly optimized components for concurrent and asynchronous programming
Cons of Folly
- Steeper learning curve: Due to its extensive feature set, Folly may be more challenging to learn and integrate compared to RxCpp's focused approach
- Larger footprint: Folly's comprehensive nature results in a larger codebase and potential overhead for projects that don't need all its features
Code Comparison
Folly (using folly::Future
):
folly::Future<int> computeAsync() {
return folly::makeFuture(42)
.then([](int value) { return value * 2; });
}
RxCpp:
auto observable = rxcpp::observable<>::just(42)
.map([](int value) { return value * 2; });
Both examples demonstrate asynchronous computation, but Folly uses futures while RxCpp employs observables. Folly's approach is more general-purpose, while RxCpp is tailored for reactive programming patterns.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
The Reactive Extensions for C++ (RxCpp) is a library of algorithms for values-distributed-in-time. The Range-v3 library does the same for values-distributed-in-space.
Task | Status |
---|---|
rxcpp CI |
Source | Badges |
---|---|
Github | |
Gitter.im | |
Packages | |
Documentation | |
Usage
RxCpp is a header-only C++ library that only depends on the standard library. The CMake build generates documentation and unit tests. The unit tests depend on a git submodule for the Catch library.
Example
Add Rx/v2/src
to the include paths
#include "rxcpp/rx.hpp"
namespace Rx {
using namespace rxcpp;
using namespace rxcpp::sources;
using namespace rxcpp::operators;
using namespace rxcpp::util;
}
using namespace Rx;
#include <regex>
#include <random>
using namespace std;
using namespace std::chrono;
int main()
{
random_device rd; // non-deterministic generator
mt19937 gen(rd());
uniform_int_distribution<> dist(4, 18);
// for testing purposes, produce byte stream that from lines of text
auto bytes = range(0, 10) |
flat_map([&](int i){
auto body = from((uint8_t)('A' + i)) |
repeat(dist(gen)) |
as_dynamic();
auto delim = from((uint8_t)'\r');
return from(body, delim) | concat();
}) |
window(17) |
flat_map([](observable<uint8_t> w){
return w |
reduce(
vector<uint8_t>(),
[](vector<uint8_t> v, uint8_t b){
v.push_back(b);
return v;
}) |
as_dynamic();
}) |
tap([](const vector<uint8_t>& v){
// print input packet of bytes
copy(v.begin(), v.end(), ostream_iterator<long>(cout, " "));
cout << endl;
});
//
// recover lines of text from byte stream
//
auto removespaces = [](string s){
s.erase(remove_if(s.begin(), s.end(), ::isspace), s.end());
return s;
};
// create strings split on \r
auto strings = bytes |
concat_map([](vector<uint8_t> v){
string s(v.begin(), v.end());
regex delim(R"/(\r)/");
cregex_token_iterator cursor(&s[0], &s[0] + s.size(), delim, {-1, 0});
cregex_token_iterator end;
vector<string> splits(cursor, end);
return iterate(move(splits));
}) |
filter([](const string& s){
return !s.empty();
}) |
publish() |
ref_count();
// filter to last string in each line
auto closes = strings |
filter(
[](const string& s){
return s.back() == '\r';
}) |
Rx::map([](const string&){return 0;});
// group strings by line
auto linewindows = strings |
window_toggle(closes | start_with(0), [=](int){return closes;});
// reduce the strings for a line into one string
auto lines = linewindows |
flat_map([&](observable<string> w) {
return w | start_with<string>("") | sum() | Rx::map(removespaces);
});
// print result
lines |
subscribe<string>(println(cout));
return 0;
}
Reactive Extensions
The ReactiveX Observable model allows you to treat streams of asynchronous events with the same sort of simple, composable operations that you use for collections of data items like arrays. It frees you from tangled webs of callbacks, and thereby makes your code more readable and less prone to bugs.
Credit ReactiveX.io
Other language implementations
Resources
- Intro
- Tutorials
- Marble Diagrams
- twitter stream analysis app
- Algorithm Design For Values Distributed In Time
Cloning RxCpp
RxCpp uses a git submodule (in ext/catch
) for the excellent Catch library. The easiest way to ensure that the submodules are included in the clone is to add --recursive
in the clone command.
git clone --recursive https://github.com/ReactiveX/RxCpp.git
cd RxCpp
Installing
To install RxCpp into your OS you need to follow standart procedure:
mkdir build
cd build
cmake ..
make install
If you're using the vcpkg dependency manager, you can install RxCpp using a single one-line command:
vcpkg install rxcpp
Vcpkg will acquire RxCpp, build it from source in your computer, and provide CMake integration support for your projects.
See the vcpkg repository for more information.
Importing
After you have successfully installed RxCpp you can import it into any project by simply adding to your CMakeLists.txt:
find_package(rxcpp CONFIG)
Building RxCpp Unit Tests
- RxCpp is regularly tested on OSX and Windows.
- RxCpp is regularly built with Clang, Gcc and VC
- RxCpp depends on the latest compiler releases.
RxCpp uses CMake to create build files for several platforms and IDE's
ide builds
XCode
mkdir projects/build
cd projects/build
cmake -G"Xcode" -DRXCPP_DISABLE_TESTS_AND_EXAMPLES=0 ../CMake -B.
Visual Studio 2017
mkdir projects\build
cd projects\build
cmake -G "Visual Studio 15" -DRXCPP_DISABLE_TESTS_AND_EXAMPLES=0 ..\CMake\
msbuild Project.sln
makefile builds
OSX
mkdir projects/build
cd projects/build
cmake -G"Unix Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DRXCPP_DISABLE_TESTS_AND_EXAMPLES=0 -B. ../CMake
make
Linux --- Clang
mkdir projects/build
cd projects/build
cmake -G"Unix Makefiles" -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_EXE_LINKER_FLAGS="-stdlib=libc++" -DRXCPP_DISABLE_TESTS_AND_EXAMPLES=0 -B. ../CMake
make
Linux --- GCC
mkdir projects/build
cd projects/build
cmake -G"Unix Makefiles" -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=RelWithDebInfo -DRXCPP_DISABLE_TESTS_AND_EXAMPLES=0 -B. ../CMake
make
Windows
mkdir projects\build
cd projects\build
cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DRXCPP_DISABLE_TESTS_AND_EXAMPLES=0 -B. ..\CMake
nmake
The build only produces test and example binaries.
Running tests
- You can use the CMake test runner
ctest
- You can run the test binaries directly
rxcpp_test_*
- Tests can be selected by name or tag Example of by-tag
rxcpp_test_subscription [perf]
Documentation
RxCpp uses Doxygen to generate project documentation.
When Doxygen+Graphviz is installed, CMake creates a special build task named doc
. It creates actual documentation and puts it to projects/doxygen/html/
folder, which can be published to the gh-pages
branch. Each merged pull request will build the docs and publish them.
Contributing Code
Before submitting a feature or substantial code contribution please discuss it with the team and ensure it follows the product roadmap. Note that all code submissions will be rigorously reviewed and tested by the Rx Team, and only those that meet an extremely high bar for both quality and design/roadmap appropriateness will be merged into the source.
Microsoft Open Source Code of Conduct
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.
Top Related Projects
RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
Reactive Programming in Swift
A reactive programming library for JavaScript
RxJava bindings for Kotlin
Boost.org asio module
An open-source C++ library developed and used at Facebook.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot