RustCxx is a modern C++20 header-only library that provides Rust-style enums, Result
, and Option
types for C++. It's designed to bring the expressiveness and safety of Rust's type system to C++.
- π Header-only: Just include and use
- π¦ Rust-inspired: Familiar API for Rust developers
- π Type-safe: Compile-time type checking
- π― Pattern Matching: Expressive pattern matching with lambdas
- β‘ Modern C++: Requires C++20, uses
std::variant
under the hood - π§ͺ Well-tested: Comprehensive test suite
#include "rustcxx/rustcxx.hpp"
using namespace rustcxx;
// Define enum variants
ENUM_VARIANT(Red);
ENUM_VARIANT(Green);
ENUM_VARIANT(Blue, int intensity);
using Color = Enum<Red, Green, Blue>;
// Usage
Color color = Blue{128};
// Pattern matching
auto description = color.match(
[](const Red&) { return "It's red!"; },
[](const Green&) { return "It's green!"; },
[](const Blue& b) {
return "It's blue with intensity " + std::to_string(b.intensity);
}
);
auto divide = [](int a, int b) -> Result<double, std::string> {
if (b == 0) {
return Result<double, std::string>::Err("Division by zero!");
}
return Result<double, std::string>::Ok(static_cast<double>(a) / b);
};
auto result = divide(10, 2);
// Pattern matching
result.match(
[](double value) { std::cout << "Result: " << value << std::endl; },
[](const std::string& error) { std::cout << "Error: " << error << std::endl; }
);
// Safe access
double value = result.unwrap_or(-1.0);
// Chaining
auto chained = divide(20, 4)
.map([](double x) { return x * 2; })
.and_then([&](double x) { return divide(static_cast<int>(x), 2); });
auto find_user = [](int id) -> Option<std::string> {
if (id == 1) return Option<std::string>::Some("Alice");
if (id == 2) return Option<std::string>::Some("Bob");
return Option<std::string>::None();
};
auto user = find_user(1);
// Pattern matching
user.match(
[](const std::string& name) { std::cout << "Found: " << name << std::endl; },
[]() { std::cout << "User not found" << std::endl; }
);
// Chaining operations
auto greeting = find_user(1)
.map([](const std::string& name) { return "Hello, " + name + "!"; })
.unwrap_or("Hello, stranger!");
- C++20 compatible compiler
- CMake 3.14 or later
mkdir build && cd build
cmake ..
make
./basic_usage
cmake -DRUSTCXX_BUILD_TESTS=ON ..
make
ctest
Core enum type that wraps std::variant
with ergonomic APIs.
bool is<T>() const
- Check if enum holds type TT& get<T>()
- Get value of type T (throws if wrong type)T* get_if<T>()
- Get pointer to value if type T, nullptr otherwiseauto match(lambdas...)
- Pattern match over all variantsstd::size_t index() const
- Get index of current variant
Type-safe error handling similar to Rust's Result<T, E>
.
Result::Ok(value)
- Create successful resultResult::Err(error)
- Create error result
bool is_ok() const
- Check if result is Okbool is_err() const
- Check if result is ErrT unwrap()
- Get Ok value (throws if Err)T unwrap_or(default)
- Get Ok value or defaultE unwrap_err()
- Get Err value (throws if Ok)auto map(func)
- Transform Ok valueauto map_err(func)
- Transform Err valueauto and_then(func)
- Chain Resultsauto match(ok_func, err_func)
- Pattern match
Nullable type similar to Rust's Option<T>
.
Option::Some(value)
- Create Some optionOption::None()
- Create None option
bool is_some() const
- Check if option has valuebool is_none() const
- Check if option is emptyT unwrap()
- Get value (throws if None)T unwrap_or(default)
- Get value or defaultauto map(func)
- Transform Some valueauto and_then(func)
- Chain Optionsauto match(some_func, none_func)
- Pattern match
ENUM_VARIANT(name)
- Define empty variant
If installed:
find_package(rustcxx REQUIRED)
target_link_libraries(your_target rustcxx::rustcxx)
Or as subdirectory:
add_subdirectory(path/to/rustcxx)
target_link_libraries(your_target rustcxx)
Simply copy include/rustcxx/rustcxx.hpp
to your project and include it.
See the examples/
directory for more comprehensive examples:
basic_usage.cpp
- Demonstrates all core features- More examples coming soon!
Rust | RustCxx |
---|---|
enum Color { Red, Green, Blue(u8) } |
ENUM_VARIANT(Red); ENUM_VARIANT(Red); ENUM_VARIANT(Blue, uint8_t intensity); using Color = Enum<Red, Green, Blue>; |
Result<T, E> |
Result<T, E> |
Option<T> |
Option<T> |
match expr { ... } |
expr.match(...) |
result? |
result.and_then(...) |
option.map(f) |
option.map(f) |
Contributions are welcome! Please feel free to submit a Pull Request.
Licensed under the Apache License, Version 2.0. See LICENSE for details.
Inspired by Rust's excellent type system and the many discussions about bringing similar functionality to C++.