Convert Figma logo to code with AI

ReactiveX logoRxCpp

Reactive Extensions for C++

3,025
390
3,025
97

Top Related Projects

47,869

RxJava – Reactive Extensions for the JVM – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.

24,358

Reactive Programming in Swift

30,713

A reactive programming library for JavaScript

RxJava bindings for Kotlin

1,207

Boost.org asio module

28,292

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

  1. 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;
}
  1. 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;
}
  1. 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:

  1. Clone the repository: git clone https://github.com/ReactiveX/RxCpp.git
  2. Add the Rx/v2/src directory to your include path
  3. Include the necessary headers in your C++ file: #include <rxcpp/rx.hpp>
  4. 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

47,869

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.

24,358

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.

30,713

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.

1,207

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.

28,292

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 Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

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.

TaskStatus
rxcpp CIrxcpp CI
SourceBadges
GithubGitHub license
GitHub release
GitHub commits
Gitter.imJoin in on gitter.im
PackagesNuGet version vcpkg port
Documentationrxcpp doxygen documentation
reactivex intro rx marble diagrams

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

lines from bytes

#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

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.

Developers Material

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.