contracts#
The contracts module provides C++ contracts support for HPX with intelligent fallback to assertions when native contracts are not available. This module implements a forward-compatible API that works across different C++ standards and compiler capabilities.
The module provides three primary macros: HPX_PRE,
HPX_POST, and HPX_CONTRACT_ASSERT. These macros
automatically adapt their behavior based on compiler capabilities:
When C++26 native contracts are available (
__cpp_contractsdefined), they map to standard contract syntaxWhen
HPX_WITH_CX26_CONTRACTS=OFF, preconditions and postconditions become no-ops while contract assertions remain available as enhanced assertions
Configuration#
Enable contracts in CMake:
cmake -DHPX_WITH_CXX26_CONTRACTS=ON -DCMAKE_CXX_STANDARD=26
Enable contract-enhanced assertions (optional):
cmake -DHPX_WITH_CXX26_CONTRACTS=ON -DHPX_CONTRACTS_WITH_ASSERTS_AS_CONTRACT_ASSERTS=ON
Contract assertions work even when contracts are disabled:
cmake -DHPX_WITH_CXX26_CONTRACTS=OFF # HPX_CONTRACT_ASSERT still maps to HPX_ASSERT
Advanced Features#
Contract-Enhanced Assertions#
When HPX_CONTRACTS_WITH_ASSERTS_AS_CONTRACT_ASSERTS=ON is enabled, regular
HPX_ASSERT calls are automatically upgraded to use contract
assertions in C++26 mode:
void example_function(int value)
{
HPX_ASSERT(value > 0); // Becomes contract_assert(value > 0) in C++26 mode
// ... rest of function
}
Warning
Enhanced assertions only provide benefits when native C++26 contracts are
supported by the compiler. Without native contract support,
HPX_ASSERT -> HPX_CONTRACT_ASSERT -> HPX_ASSERT (no enhancement).
CMake will issue a warning if you enable this option without native contract support.
This provides enhanced contract semantics throughout your existing codebase
without requiring changes to assertion code. The transformation occurs in the
contracts module (contracts.hpp) where the HPX_ASSERT macro is
overridden to use HPX_CONTRACT_ASSERT when HPX_WITH_ASSERTS_AS_CONTRACT_ASSERTS=ON:
HPX_WITH_CXX26_CONTRACTS=ON- Contracts module is enabledHPX_CONTRACTS_WITH_ASSERTS_AS_CONTRACT_ASSERTS=ON- Assertion enhancement is enabled
The implementation works by redefining HPX_ASSERT in contracts.hpp to
use HPX_CONTRACT_ASSERT, which automatically adapts to the current contract
mode (native C++26 contracts or assertion fallback). This ensures all existing
HPX_ASSERT calls throughout the HPX codebase automatically gain contract
semantics when available.
Usage Examples#
Preconditions and postconditions using declaration syntax (C++26):
int divide(int a, int b) HPX_PRE(b != 0)
{
return a / b;
}
int factorial(int n) HPX_PRE(n >= 0) HPX_POST(r; r > 0)
{
return n <= 1 ? 1 : n * factorial(n - 1);
}
Contract assertions (available in all modes):
void process_array(std::vector<int>& arr, size_t index)
{
HPX_CONTRACT_ASSERT(index < arr.size());
arr[index] *= 2;
}
Design Philosophy#
- HPX_CONTRACT_ASSERT: Enhanced assertion mechanism
Available even when
HPX_WITH_CONTRACTS=OFFbecause it provides value as an enhanced assertion. Maps toHPX_ASSERTin all configurations.- HPX_PRE/HPX_POST: True contract syntax
Represent language-level contract semantics. When contracts are enabled but native C++26 contracts are not available, these become no-ops to maintain forward compatibility. When
HPX_WITH_CONTRACTS=OFF, they are also no-ops. This prepares for C++26 migration where they will be attached to function declarations rather than used in function bodies.
Migration Strategy#
The module is designed for smooth migration to C++26 native contracts:
Current (transition mode):
int func(int x)
{
HPX_PRE(x > 0); // No-op in fallback mode, active in native mode
return x;
}
Target (C++26 native):
int func(int x) HPX_PRE(x > 0)
{
return x;
}
Note: In fallback mode, HPX_PRE and HPX_POST become no-ops to maintain
forward compatibility and avoid performance overhead. Use HPX_CONTRACT_ASSERT
when you need runtime validation in all modes.
Testing#
The module includes comprehensive testing with automatic compiler capability detection. Tests are organized into three categories:
Declaration tests: Test C++26 native contract syntax when
__cpp_contractsis availableFallback tests: Test assertion fallback behavior when contracts are not natively supported
Disabled tests: Test no-op behavior when contracts are disabled
The test suite automatically detects compiler capabilities at configure time and builds only the appropriate tests for the current configuration.
See the API reference of the module for more details.