Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
dd9a77f
first commit hihi
AlexPapadakis Aug 19, 2025
4d43883
added contracts in core
AlexPapadakis Oct 1, 2025
b6b8fe1
resolved cmake errors
AlexPapadakis Oct 1, 2025
2478e78
fixed some cmake flag errors
AlexPapadakis Oct 1, 2025
f745187
removed a failed attempt to automate some flags
AlexPapadakis Oct 1, 2025
6664927
correecting
AlexPapadakis Oct 1, 2025
6dbc21c
contracts: Restructure test suite for clarity and completeness
AlexPapadakis Oct 3, 2025
c8c63d1
added config test to automatically run the appropriate tests for eith…
AlexPapadakis Oct 6, 2025
b8884fb
improved documentation
AlexPapadakis Oct 6, 2025
798d06d
corrected native contracts syntax
AlexPapadakis Oct 6, 2025
26d5669
corrections
AlexPapadakis Oct 6, 2025
85a5f20
corrected definition logic
AlexPapadakis Oct 7, 2025
1c44549
updated fallback logic, added config test for experimental builds
AlexPapadakis Oct 13, 2025
dcac630
reverted example to original and deleted a temporary testing dir
AlexPapadakis Oct 14, 2025
20ec40f
deleted temporary testing
AlexPapadakis Oct 14, 2025
e9bd415
Merge branch 'STEllAR-GROUP:master' into contract_test
AlexPapadakis Oct 14, 2025
e6de62b
Delete test_atomic
AlexPapadakis Oct 14, 2025
ef88eea
Delete Makefile
AlexPapadakis Oct 14, 2025
d3cdced
Delete cmake_install.cmake
AlexPapadakis Oct 14, 2025
a053543
fixed cmake format errors
AlexPapadakis Oct 16, 2025
d67df99
Fix clang-format violations in contracts module
AlexPapadakis Oct 16, 2025
679f4f2
Fix cmake-format violations in root CMakeLists.txt
AlexPapadakis Oct 16, 2025
090f885
fixed inspect errors
AlexPapadakis Oct 17, 2025
e10d53d
Merge branch 'master' into contract_test
isidorostsa Oct 17, 2025
88088e2
updated cmake option for enchanced asserts to follow convention
AlexPapadakis Oct 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1490,6 +1490,24 @@ if(NOT "${HPX_PLATFORM_UC}" STREQUAL "BLUEGENEQ")
endif()

# Debugging related build options
hpx_option(
HPX_WITH_CONTRACTS BOOL "Enable C++ contracts support in HPX" OFF
CATEGORY "Debugging"
)

if(HPX_WITH_CONTRACTS)
hpx_add_config_define(HPX_HAVE_CONTRACTS)
endif()

hpx_option(
HPX_WITH_ASSERTS_AS_CONTRACT_ASSERTS BOOL
"Swap hpx_assert with hpx_contract_assert" OFF CATEGORY "Debugging"
)

if(HPX_WITH_ASSERTS_AS_CONTRACT_ASSERTS)
hpx_add_config_define(HPX_HAVE_ASSERTS_AS_CONTRACT_ASSERTS)
endif()

hpx_option(
HPX_WITH_VALGRIND BOOL "Enable Valgrind instrumentation support." OFF
CATEGORY "Debugging"
Expand Down
36 changes: 36 additions & 0 deletions cmake/tests/contracts.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2025 Alexandros Papadakis
// Copyright (c) 2025 Panagiotis Syskakis
//
// SPDX-License-Identifier: BSL-1.0
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

// This tests whether C++26 contracts are supported by the compiler

#if __cpp_contracts
// Test native contract syntax
int divide(int a, int b) pre(b != 0) post(r; r == a / b)
{
return a / b;
}

void test_contract_assert()
{
contract_assert(true);
}

int main()
{
int result = divide(10, 2);
test_contract_assert();
return result == 5 ? 0 : 1;
}

#else
// Fallback test - contracts not available
int main()
{
// Test would fail if contracts were required but not available
return 0;
}
#endif
1 change: 1 addition & 0 deletions libs/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ set(_hpx_core_modules
concurrency
config
config_registry
contracts
coroutines
datastructures
debugging
Expand Down
35 changes: 35 additions & 0 deletions libs/core/contracts/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright (c) 2025 The STE||AR-Group
# Copyright (c) 2025 Alexandros Papadakis
#
# SPDX-License-Identifier: BSL-1.0
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# Default location is $HPX_ROOT/libs/contracts/include
set(contracts_headers hpx/contracts.hpp hpx/modules/contracts.hpp)

# Default location is $HPX_ROOT/libs/contracts/include_compatibility
# cmake-format: off
set(contracts_compat_headers
# Add any legacy header mappings here if needed in the future
# hpx/old_contracts.hpp => hpx/contracts.hpp
)
# cmake-format: on

# Default location is $HPX_ROOT/libs/contracts/src
set(contracts_sources # Add source files here when implementation is added
# contracts.cpp
)

include(HPX_AddModule)
add_hpx_module(
core contracts
GLOBAL_HEADER_GEN OFF
SOURCES ${contracts_sources}
HEADERS ${contracts_headers}
COMPAT_HEADERS ${contracts_compat_headers}
MODULE_DEPENDENCIES hpx_config hpx_preprocessor hpx_assertion
CMAKE_SUBDIRS examples tests
)
76 changes: 76 additions & 0 deletions libs/core/contracts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<!--
Copyright (c) 2025 The STE||AR-Group
Copyright (c) 2025 Alexandros Papadakis

SPDX-License-Identifier: BSL-1.0
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-->

# HPX Contracts Module

A forward-compatible C++ contracts implementation for HPX with intelligent fallback to assertions.

## Quick Start

```cpp
#include <hpx/contracts.hpp>

// Preconditions and postconditions with return value access
int factorial(int n) HPX_PRE(n >= 0) HPX_POST(r: r > 0) {
return n <= 1 ? 1 : n * factorial(n - 1);
}

// Contract assertions (always available)
void process(std::vector<int>& data, size_t index) {
HPX_CONTRACT_ASSERT(index < data.size());
data[index] *= 2;
}
```

## Build Configuration

```bash
# Enable contracts
cmake -DHPX_WITH_CONTRACTS=ON -DCMAKE_CXX_STANDARD=26

# Enable contract-enhanced assertions (optional)
cmake -DHPX_WITH_CONTRACTS=ON -DHPX_WITH_ASSERTS_AS_CONTRACT_ASSERTS=ON

# Contracts disabled (hpx_contract_assert will work as hpx_assert)
cmake -DHPX_WITH_CONTRACTS=OFF #default
```

## Advanced Features

### Contract-Enhanced Assertions
When `HPX_WITH_ASSERTS_AS_CONTRACT_ASSERTS=ON`, regular `HPX_ASSERT` calls are automatically upgraded to use contract assertions:

```cpp
void process_data(std::vector<int>& data, size_t index) {
HPX_ASSERT(index < data.size()); // Becomes HPX_CONTRACT_ASSERT() -> adapts to current mode
data[index] *= 2;
}
```

**Important**: 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 warn you if you enable this option without native contract support.

The implementation works by overriding the `HPX_ASSERT` macro in `contracts.hpp` to use `HPX_CONTRACT_ASSERT`, which automatically adapts to the current contract mode (native C++26 contracts when available, or assertion fallback otherwise).

## API Reference

- **`HPX_PRE(condition)`**: Precondition contracts
- **`HPX_POST(condition)`**: Postcondition contracts
- **`HPX_CONTRACT_ASSERT(condition)`**: Contract assertions (always available)

## Documentation

See [Module Documentation](docs/index.rst) for comprehensive usage guide, API reference, and implementation details.

## Features

- ✅ Automatic C++26 native contract detection
- ✅ Graceful fallback: HPX_PRE/HPX_POST become no-ops, HPX_CONTRACT_ASSERT maps to HPX_ASSERT
- ✅ Zero overhead when disabled
- ✅ Forward-compatible API
- ✅ Comprehensive test suite with automatic mode detection
158 changes: 158 additions & 0 deletions libs/core/contracts/docs/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
..
Copyright (c) 2025 The STE||AR-Group
Copyright (c) 2025 Alexandros Papadakis

SPDX-License-Identifier: BSL-1.0
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

.. _modules_contracts:

=========
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: :c:macro:`HPX_PRE`,
:c:macro:`HPX_POST`, and :c:macro:`HPX_CONTRACT_ASSERT`. These macros
automatically adapt their behavior based on compiler capabilities:

* When C++26 native contracts are available (``__cpp_contracts`` defined),
they map to standard contract syntax
* When contracts are not available but ``HPX_WITH_CONTRACTS=ON``, preconditions
and postconditions become no-ops while contract assertions fall back to
:c:macro:`HPX_ASSERT` for compatibility
* When ``HPX_WITH_CONTRACTS=OFF``, preconditions and postconditions become
no-ops while contract assertions remain available as enhanced assertions

Configuration
=============

Enable contracts in CMake::

cmake -DHPX_WITH_CONTRACTS=ON -DCMAKE_CXX_STANDARD=26

Enable contract-enhanced assertions (optional)::

cmake -DHPX_WITH_CONTRACTS=ON -DHPX_WITH_ASSERTS_AS_CONTRACT_ASSERTS=ON

Contract assertions work even when contracts are disabled::

cmake -DHPX_WITH_CONTRACTS=OFF # HPX_CONTRACT_ASSERT still maps to HPX_ASSERT

Advanced Features
=================

Contract-Enhanced Assertions
----------------------------

When ``HPX_WITH_ASSERTS_AS_CONTRACT_ASSERTS=ON`` is enabled, regular
:c:macro:`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_CONTRACTS=ON`` - Contracts module is enabled
* ``HPX_WITH_ASSERTS_AS_CONTRACT_ASSERTS=ON`` - Assertion enhancement is enabled
* ``HPX_HAVE_NATIVE_CONTRACTS=ON`` - C++26 native contracts are available (from config test)

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=OFF`` because it provides value
as an enhanced assertion. Maps to :c:macro:`HPX_ASSERT` in 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_contracts`` is available
* **Fallback 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 :ref:`API reference <modules_contracts_api>` of the module for more details.
16 changes: 16 additions & 0 deletions libs/core/contracts/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright (c) 2025 Alexandros Papadakis
# Copyright (c) 2025 Panagiotis Syskakis
# HPX Contracts Module Examples
#
# SPDX-License-Identifier: BSL-1.0
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

# Currently no examples for contracts module Examples will be added in future
# iterations when the contract API is stabilized

if(HPX_WITH_EXAMPLES)
# Future: Add contract usage examples here
# add_hpx_executable(contract_examples SOURCES basic_contract_usage.cpp
# COMPONENT_DEPENDENCIES hpx_core )
endif()
10 changes: 10 additions & 0 deletions libs/core/contracts/include/hpx/contracts.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright (c) 2025 The STE||AR-Group
// Copyright (c) 2025 Alexandros Papadakis
//
// SPDX-License-Identifier: BSL-1.0
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#pragma once

#include <hpx/modules/contracts.hpp>
Loading
Loading