Skip to content

Commit b5df3fa

Browse files
committed
Add some tuple pbt tests
1 parent 4aec31e commit b5df3fa

File tree

8 files changed

+346
-16
lines changed

8 files changed

+346
-16
lines changed

.github/workflows/asciidoctor-ghpages.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
runs-on: ${{ github.repository_owner == 'intel' && 'intel-' || '' }}ubuntu-24.04
3434
steps:
3535
- name: Checkout source
36-
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
36+
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
3737
- name: Setup Node.js
3838
uses: actions/setup-node@0a44ba7841725637a19e28fa30b79a866c81b0a6 # v4.0.4
3939
with:

.github/workflows/unit_tests.yml

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,10 @@ jobs:
9898
- name: Install build tools
9999
run: |
100100
${{ matrix.install }}
101-
sudo apt install -y ninja-build
101+
sudo apt install -y ninja-build pipx
102+
pipx install pytest
103+
pipx inject pytest pytest-forked pytest-xdist hypothesis
104+
echo "/opt/pipx_bin" >> $GITHUB_PATH
102105
103106
- name: Restore CPM cache
104107
env:
@@ -177,7 +180,10 @@ jobs:
177180
- name: Install build tools
178181
run: |
179182
${{ matrix.install }}
180-
sudo apt install -y ninja-build
183+
sudo apt install -y ninja-build pipx
184+
pipx install pytest
185+
pipx inject pytest pytest-forked pytest-xdist hypothesis
186+
echo "/opt/pipx_bin" >> $GITHUB_PATH
181187
182188
- name: Restore CPM cache
183189
env:
@@ -292,7 +298,10 @@ jobs:
292298
- name: Install build tools
293299
run: |
294300
${{ matrix.install }}
295-
sudo apt install -y ninja-build
301+
sudo apt install -y ninja-build pipx
302+
pipx install pytest
303+
pipx inject pytest pytest-forked pytest-xdist hypothesis
304+
echo "/opt/pipx_bin" >> $GITHUB_PATH
296305
297306
- name: Restore CPM cache
298307
env:
@@ -338,7 +347,10 @@ jobs:
338347

339348
- name: Install build tools
340349
run: |
341-
sudo apt update && sudo apt install -y gcc-${{env.DEFAULT_GCC_VERSION}} g++-${{env.DEFAULT_GCC_VERSION}} ninja-build valgrind
350+
sudo apt update && sudo apt install -y gcc-${{env.DEFAULT_GCC_VERSION}} g++-${{env.DEFAULT_GCC_VERSION}} ninja-build valgrind pipx
351+
pipx install pytest
352+
pipx inject pytest pytest-forked pytest-xdist hypothesis
353+
echo "/opt/pipx_bin" >> $GITHUB_PATH
342354
343355
- name: Restore CPM cache
344356
env:
@@ -409,7 +421,10 @@ jobs:
409421

410422
- name: Install build tools
411423
run: |
412-
sudo apt update && sudo apt install -y clang-${{env.MULL_LLVM_VERSION}} ninja-build
424+
sudo apt update && sudo apt install -y clang-${{env.MULL_LLVM_VERSION}} ninja-build pipx
425+
pipx install pytest
426+
pipx inject pytest pytest-forked pytest-xdist hypothesis
427+
echo "/opt/pipx_bin" >> $GITHUB_PATH
413428
414429
- name: Install mull
415430
env:

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,7 @@
1010
.cmake-format.yaml
1111
CMakePresets.json
1212
/toolchains
13+
__pycache__
14+
.mypy_cache
15+
.pytest_cache
16+
.hypothesis

include/stdx/tuple_algorithms.hpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -319,16 +319,17 @@ template <tuplelike... Ts> constexpr auto cartesian_product_copy(Ts &&...ts) {
319319
return []<typename First, typename... Rest>(First &&first,
320320
Rest &&...rest) {
321321
auto const c = cartesian_product_copy(std::forward<Rest>(rest)...);
322-
return std::forward<First>(first).apply(
323-
[&]<typename... Elems>(Elems &&...elems) {
324-
auto const prepend = [&]<typename E>(E &&e) {
325-
return c.apply([&](auto... subs) {
326-
return make_tuple(tuple_cat(
327-
make_tuple(std::forward<E>(e)), subs)...);
328-
});
329-
};
330-
return tuple_cat(prepend(std::forward<Elems>(elems))...);
331-
});
322+
return std::forward<First>(first).apply([&]<typename... Elems>(
323+
Elems &&...elems) {
324+
// NOTE: it's always used, but gcc sometimes gets it wrong :(
325+
[[maybe_unused]] auto const prepend = [&]<typename E>(E &&e) {
326+
return c.apply([&](auto... subs) {
327+
return make_tuple(
328+
tuple_cat(make_tuple(std::forward<E>(e)), subs)...);
329+
});
330+
};
331+
return tuple_cat(prepend(std::forward<Elems>(elems))...);
332+
});
332333
}(std::forward<Ts>(ts)...);
333334
}
334335
}

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,4 @@ if(${CMAKE_CXX_STANDARD} GREATER_EQUAL 20)
6464
endif()
6565

6666
add_subdirectory(fail)
67+
add_subdirectory(pbt)

test/pbt/CMakeLists.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
set(COMPILER_ARGS_FILE "${CMAKE_BINARY_DIR}/warnings.txt")
2+
get_target_property(warn_list warnings INTERFACE_COMPILE_OPTIONS)
3+
string(REPLACE ";" "," warn_list "${warn_list}")
4+
file(
5+
GENERATE
6+
OUTPUT "${COMPILER_ARGS_FILE}"
7+
CONTENT "${warn_list}" TARGET warnings)
8+
9+
get_target_property(SANITIZER_COMPILER_ARGS sanitizers
10+
INTERFACE_COMPILE_OPTIONS)
11+
if(SANITIZER_COMPILER_ARGS AND NOT SANITIZER_COMPILER_ARGS STREQUAL
12+
"SANITIZER_COMPILER_ARGS-NOTFOUND")
13+
list(APPEND COMPILER_ARGS ${SANITIZER_COMPILER_ARGS})
14+
endif()
15+
16+
list(APPEND COMPILER_ARGS "--std=c++${CMAKE_CXX_STANDARD};-Wno-missing-braces")
17+
18+
string(REPLACE ";" "," COMPILER_ARGS "${COMPILER_ARGS}")
19+
20+
get_target_property(INCLUDE_DIRS stdx INTERFACE_INCLUDE_DIRECTORIES)
21+
string(REPLACE ";" "," INCLUDE_DIRS "${INCLUDE_DIRS}")
22+
23+
if(${CMAKE_CXX_STANDARD} GREATER_EQUAL 20)
24+
add_unit_test(
25+
tuple
26+
PYTEST
27+
FILES
28+
tuple.py
29+
EXTRA_ARGS
30+
-vv
31+
-n2
32+
--compiler=${CMAKE_CXX_COMPILER}
33+
--compiler-args=${COMPILER_ARGS}
34+
--compiler-args-file=${COMPILER_ARGS_FILE}
35+
--includes=${INCLUDE_DIRS})
36+
endif()

test/pbt/conftest.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import pytest
2+
import hypothesis
3+
import subprocess
4+
import tempfile
5+
import os
6+
7+
hypothesis.settings.register_profile("ci", max_examples=500)
8+
hypothesis.settings.register_profile("fast", max_examples=10)
9+
10+
11+
def pytest_addoption(parser):
12+
parser.addoption("--includes", action="store", help="C++ include directories", default="", required=False)
13+
parser.addoption("--compiler", action="store", help="C++ compiler", required=True)
14+
parser.addoption("--compiler-args", action="store", help="C++ compiler arguments", default="", required=False)
15+
parser.addoption("--compiler-args-file", action="store", help="File with C++ compiler arguments", default=None, required=False)
16+
17+
18+
@pytest.fixture(scope="module")
19+
def compiler(pytestconfig):
20+
return pytestconfig.getoption("compiler")
21+
22+
@pytest.fixture(scope="module")
23+
def include_dirs(pytestconfig):
24+
return [i for i in pytestconfig.getoption("includes").split(",") if i]
25+
26+
@pytest.fixture(scope="module")
27+
def compiler_args(pytestconfig):
28+
retval = []
29+
30+
args_file = pytestconfig.getoption("compiler_args_file")
31+
if args_file:
32+
with open(args_file, "r") as f:
33+
for line in f.readlines():
34+
retval += [i for i in line.split(",") if i]
35+
36+
args = pytestconfig.getoption("compiler_args")
37+
if args:
38+
retval += [i for i in args.split(",") if i]
39+
40+
return retval
41+
42+
43+
@pytest.fixture(scope="module")
44+
def compile(compiler, compiler_args, include_dirs):
45+
include_args = [f"-I{i}" for i in include_dirs]
46+
def f(code_str):
47+
code_str += "\n"
48+
with tempfile.NamedTemporaryFile(delete=False, suffix=".cpp") as temp_cpp_file:
49+
temp_cpp_file.write(code_str.encode('utf-8'))
50+
temp_cpp_file_path = temp_cpp_file.name
51+
52+
try:
53+
compile_command = [
54+
compiler, temp_cpp_file_path,
55+
"-o", temp_cpp_file_path + ".out"
56+
] + compiler_args + include_args
57+
58+
result = subprocess.run(compile_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
59+
60+
if result.returncode == 0:
61+
return True
62+
else:
63+
error_message = (
64+
f"Compiler returned non-zero exit code: {result.returncode}\n"
65+
f"Compilation command: {' '.join(compile_command)}\n"
66+
f"Source code:\n{code_str}\n"
67+
f"Compiler stderr:\n{result.stderr.decode('utf-8')}\n"
68+
f"Compiler stdout:\n{result.stdout.decode('utf-8')}\n"
69+
)
70+
pytest.fail(error_message)
71+
72+
except Exception as e:
73+
pytest.fail(str(e))
74+
finally:
75+
os.remove(temp_cpp_file_path)
76+
if os.path.exists(temp_cpp_file_path + ".out"):
77+
os.remove(temp_cpp_file_path + ".out")
78+
79+
return f
80+

0 commit comments

Comments
 (0)