Skip to content

Commit 2af4c6e

Browse files
committed
clean-up
1 parent 5185bf4 commit 2af4c6e

11 files changed

Lines changed: 286 additions & 92 deletions

File tree

.github/workflows/modules.yml

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
name: Modules
2+
3+
on: [push, pull_request]
4+
5+
permissions: read-all
6+
7+
jobs:
8+
modules:
9+
strategy:
10+
fail-fast: false
11+
matrix:
12+
config:
13+
- { compiler: "clang-19", cc: "clang-19", cxx: "clang++-19", os: "ubuntu-24.04", standard: "20", stdlib: "libstdc++", import_std: "FALSE", build_types: "Release Debug", cmake: "4.3.4" }
14+
- { compiler: "clang-19", cc: "clang-19", cxx: "clang++-19", os: "ubuntu-24.04", standard: "23", stdlib: "libc++", import_std: "TRUE", build_types: "Debug", cmake: "4.4.0" }
15+
- { compiler: "clang-22", cc: "clang", cxx: "clang++", os: "macos-26", standard: "23", stdlib: "libc++", import_std: "FALSE", build_types: "Release Debug", cmake: "4.3.4" }
16+
- { compiler: "gcc-16", cc: "gcc-16", cxx: "g++-16", os: "ubuntu-26.04", standard: "26", stdlib: "libstdc++", import_std: "TRUE", build_types: "Release", cmake: "4.4.0" }
17+
18+
name: "${{ format('{0} / {1} / C++{2} / {3} / IMPORT_STD={4}', matrix.config.os, matrix.config.compiler, matrix.config.standard, matrix.config.stdlib, matrix.config.import_std) }}"
19+
runs-on: ${{ matrix.config.os }}
20+
env:
21+
CC: ${{ matrix.config.cc }}
22+
CXX: ${{ matrix.config.cxx }}
23+
24+
steps:
25+
- uses: actions/checkout@v7
26+
27+
- name: Install Clang
28+
if: ${{ startsWith(matrix.config.os, 'ubuntu') && startsWith(matrix.config.compiler, 'clang') }}
29+
run: |
30+
wget -qO - https://apt.llvm.org/llvm-snapshot.gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/llvm-archive-keyring.gpg > /dev/null
31+
32+
clang_version="${{ matrix.config.cc }}"
33+
clang_version="${clang_version#clang-}"
34+
ubuntu_codename="$(lsb_release -cs)"
35+
llvm_repository="http://apt.llvm.org/${ubuntu_codename}/"
36+
llvm_suite="llvm-toolchain-${ubuntu_codename}-${clang_version}"
37+
38+
echo "deb [signed-by=/etc/apt/keyrings/llvm-archive-keyring.gpg] ${llvm_repository} ${llvm_suite} main" \
39+
| sudo tee /etc/apt/sources.list.d/llvm.list
40+
sudo apt update
41+
sudo apt install -y ${{ matrix.config.cc }}
42+
43+
if [[ "${{ matrix.config.stdlib }}" == "libc++" ]]; then
44+
sudo apt install -y \
45+
"libclang-rt-${clang_version}-dev" \
46+
"libc++-${clang_version}-dev" \
47+
"libc++abi-${clang_version}-dev" \
48+
"clang-tools-${clang_version}"
49+
fi
50+
51+
- name: Install Clang on macOS
52+
if: ${{ startsWith(matrix.config.os, 'macos') }}
53+
run: |
54+
brew install llvm@22 ninja
55+
llvm_prefix="$(brew --prefix llvm@22)"
56+
echo "${llvm_prefix}/bin" >> "${GITHUB_PATH}"
57+
echo "CC=${llvm_prefix}/bin/clang" >> "${GITHUB_ENV}"
58+
echo "CXX=${llvm_prefix}/bin/clang++" >> "${GITHUB_ENV}"
59+
60+
- name: Install GCC
61+
if: ${{ startsWith(matrix.config.cc, 'gcc') }}
62+
run: |
63+
sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y
64+
sudo apt update
65+
sudo apt install -y ${{ matrix.config.cxx }}
66+
67+
- name: Install pinned CMake
68+
run: python3 -m pip install cmake==${{ matrix.config.cmake }} --break-system-packages
69+
70+
- name: Configure
71+
run: |
72+
stdlib_options=()
73+
if [[ "${{ matrix.config.stdlib }}" == "libc++" ]]; then
74+
stdlib_options=(-DCMAKE_CXX_FLAGS:STRING=-stdlib=libc++)
75+
elif [[ "${{ matrix.config.import_std }}" == "TRUE" ]]; then
76+
stdlib_options=(-DCMAKE_CXX_STDLIB_MODULES_JSON="$("${CXX}" -print-file-name=libstdc++.modules.json)")
77+
fi
78+
79+
import_std_options=()
80+
if [[ "${{ matrix.config.import_std }}" == "TRUE" ]]; then
81+
import_std_options=(-DCMAKE_EXPERIMENTAL_CXX_IMPORT_STD=f35a9ac6-8463-4d38-8eec-5d6008153e7d)
82+
fi
83+
84+
for build_type in ${{ matrix.config.build_types }}; do
85+
build_dir="build-${build_type}"
86+
cmake -S . -B "${build_dir}" -G Ninja \
87+
-DCMAKE_BUILD_TYPE="${build_type}" \
88+
-DCMAKE_CXX_STANDARD=${{ matrix.config.standard }} \
89+
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
90+
-DCMAKE_CXX_EXTENSIONS=OFF \
91+
-DMAGIC_ENUM_USE_MODULES=ON \
92+
-DMAGIC_ENUM_MODULE_IMPORT_STD=${{ matrix.config.import_std }} \
93+
-DMAGIC_ENUM_MODULE_WITH_FMT=OFF \
94+
"${stdlib_options[@]}" \
95+
"${import_std_options[@]}"
96+
done
97+
98+
- name: Build
99+
run: |
100+
for build_type in ${{ matrix.config.build_types }}; do
101+
cmake --build "build-${build_type}" --parallel --config "${build_type}"
102+
done
103+
104+
- name: Test
105+
run: |
106+
for build_type in ${{ matrix.config.build_types }}; do
107+
ctest --test-dir "build-${build_type}" --output-on-failure --no-tests=error -C "${build_type}"
108+
done

.github/workflows/ubuntu.yml

Lines changed: 20 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,24 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
compiler:
13-
- { cc: "gcc-11", cxx: "g++-11", os: "ubuntu-22.04", modules: "FALSE", import_std: "FALSE" }
14-
- { cc: "gcc-12", cxx: "g++-12", os: "ubuntu-22.04", modules: "FALSE", import_std: "FALSE" }
15-
- { cc: "gcc-13", cxx: "g++-13", os: "ubuntu-24.04", modules: "FALSE", import_std: "FALSE" }
16-
- { cc: "gcc-14", cxx: "g++-14", os: "ubuntu-24.04", modules: "FALSE", import_std: "FALSE" }
17-
- { cc: "gcc-15", cxx: "g++-15", os: "ubuntu-24.04", modules: "FALSE", import_std: "FALSE" }
18-
- { cc: "gcc-16", cxx: "g++-16", os: "ubuntu-26.04", modules: "TRUE", import_std: "TRUE" }
19-
- { cc: "clang-13", cxx: "clang++-13", os: "ubuntu-22.04", modules: "FALSE", import_std: "FALSE" }
20-
- { cc: "clang-14", cxx: "clang++-14", os: "ubuntu-22.04", modules: "FALSE", import_std: "FALSE" }
21-
- { cc: "clang-15", cxx: "clang++-15", os: "ubuntu-22.04", modules: "FALSE", import_std: "FALSE" }
22-
- { cc: "clang-16", cxx: "clang++-16", os: "ubuntu-22.04", modules: "FALSE", import_std: "FALSE" }
23-
- { cc: "clang-17", cxx: "clang++-17", os: "ubuntu-24.04", modules: "FALSE", import_std: "FALSE" }
24-
- { cc: "clang-18", cxx: "clang++-18", os: "ubuntu-24.04", modules: "FALSE", import_std: "FALSE" }
25-
- { cc: "clang-19", cxx: "clang++-19", os: "ubuntu-24.04", modules: "FALSE", import_std: "FALSE" }
26-
- { cc: "clang-19", cxx: "clang++-19", os: "ubuntu-24.04", modules: "TRUE", import_std: "TRUE" }
27-
- { cc: "clang-20", cxx: "clang++-20", os: "ubuntu-24.04", modules: "FALSE", import_std: "FALSE" }
28-
- { cc: "clang-20", cxx: "clang++-20", os: "ubuntu-24.04", modules: "TRUE", import_std: "FALSE" }
29-
- { cc: "clang-21", cxx: "clang++-21", os: "ubuntu-24.04", modules: "FALSE", import_std: "FALSE" }
30-
- { cc: "clang-21", cxx: "clang++-21", os: "ubuntu-24.04", modules: "TRUE", import_std: "FALSE" }
31-
- { cc: "clang-22", cxx: "clang++-22", os: "ubuntu-24.04", modules: "FALSE", import_std: "FALSE" }
32-
- { cc: "clang-22", cxx: "clang++-22", os: "ubuntu-24.04", modules: "TRUE", import_std: "FALSE" }
33-
34-
name: "${{ format('{0} MODULES={1} IMPORT_STD={2}', matrix.compiler.cc, matrix.compiler.modules, matrix.compiler.import_std) }}"
13+
- { cc: "gcc-11", cxx: "g++-11", os: "ubuntu-22.04" }
14+
- { cc: "gcc-12", cxx: "g++-12", os: "ubuntu-22.04" }
15+
- { cc: "gcc-13", cxx: "g++-13", os: "ubuntu-24.04" }
16+
- { cc: "gcc-14", cxx: "g++-14", os: "ubuntu-24.04" }
17+
- { cc: "gcc-15", cxx: "g++-15", os: "ubuntu-24.04" }
18+
- { cc: "gcc-16", cxx: "g++-16", os: "ubuntu-26.04" }
19+
- { cc: "clang-13", cxx: "clang++-13", os: "ubuntu-22.04" }
20+
- { cc: "clang-14", cxx: "clang++-14", os: "ubuntu-22.04" }
21+
- { cc: "clang-15", cxx: "clang++-15", os: "ubuntu-22.04" }
22+
- { cc: "clang-16", cxx: "clang++-16", os: "ubuntu-22.04" }
23+
- { cc: "clang-17", cxx: "clang++-17", os: "ubuntu-24.04" }
24+
- { cc: "clang-18", cxx: "clang++-18", os: "ubuntu-24.04" }
25+
- { cc: "clang-19", cxx: "clang++-19", os: "ubuntu-24.04" }
26+
- { cc: "clang-20", cxx: "clang++-20", os: "ubuntu-24.04" }
27+
- { cc: "clang-21", cxx: "clang++-21", os: "ubuntu-24.04" }
28+
- { cc: "clang-22", cxx: "clang++-22", os: "ubuntu-24.04" }
29+
30+
name: "${{ matrix.compiler.cc }}"
3531
runs-on: ${{ matrix.compiler.os }}
3632
env:
3733
CC: ${{ matrix.compiler.cc }}
@@ -55,15 +51,6 @@ jobs:
5551
sudo apt update
5652
sudo apt install -y ${{ matrix.compiler.cc }}
5753
58-
if [[ "${{ matrix.compiler.import_std }}" == "TRUE" ]]; then
59-
# Note: std module is currently supported only with libc++.
60-
sudo apt install -y \
61-
"libclang-rt-${clang_version}-dev" \
62-
"libc++-${clang_version}-dev" \
63-
"libc++abi-${clang_version}-dev" \
64-
"clang-tools-${clang_version}"
65-
fi
66-
6754
- name: Configure gcc
6855
if: ${{ startsWith(matrix.compiler.cc, 'gcc') }}
6956
run: |
@@ -79,25 +66,14 @@ jobs:
7966
"${CXX}" -std=c++26 -freflection -Wall -Wextra -Wshadow -pedantic-errors -Werror -Iinclude test/test_nonascii.cpp -o test_nonascii_reflection
8067
./test_nonascii_reflection
8168
82-
- name: Install pinned CMake
83-
if: ${{ matrix.compiler.modules == 'TRUE' }}
84-
run: |
85-
if [[ "${{ matrix.compiler.import_std }}" == "TRUE" ]]; then
86-
pip install cmake==4.4.0 --break-system-packages
87-
else
88-
pip install cmake==4.3.4 --break-system-packages
89-
fi
90-
9169
- name: Configure Release
9270
run: |
9371
standard_options=()
94-
if [[ "${{ matrix.compiler.cc }}" == "gcc-16" && "${{ matrix.compiler.modules }}" == "TRUE" ]]; then
72+
if [[ "${{ matrix.compiler.cc }}" == "gcc-16" ]]; then
9573
standard_options=(-DCMAKE_CXX_STANDARD=26 -DCMAKE_CXX_STANDARD_REQUIRED=ON)
9674
fi
9775
cmake -S . -B build-release \
9876
-DCMAKE_BUILD_TYPE=Release \
99-
-DMAGIC_ENUM_USE_MODULES:BOOL=${{ matrix.compiler.modules }} \
100-
${{ matrix.compiler.modules == 'TRUE' && '-G Ninja' || '' }} \
10177
"${standard_options[@]}"
10278
10379
- name: Build Release
@@ -109,13 +85,11 @@ jobs:
10985
- name: Configure Debug
11086
run: |
11187
standard_options=()
112-
if [[ "${{ matrix.compiler.cc }}" == "gcc-16" && "${{ matrix.compiler.modules }}" == "TRUE" ]]; then
88+
if [[ "${{ matrix.compiler.cc }}" == "gcc-16" ]]; then
11389
standard_options=(-DCMAKE_CXX_STANDARD=26 -DCMAKE_CXX_STANDARD_REQUIRED=ON)
11490
fi
11591
cmake -S . -B build-debug \
11692
-DCMAKE_BUILD_TYPE=Debug \
117-
-DMAGIC_ENUM_USE_MODULES:BOOL=${{ matrix.compiler.modules }} \
118-
${{ matrix.compiler.modules == 'TRUE' && '-G Ninja' || '' }} \
11993
"${standard_options[@]}"
12094
12195
- name: Build Debug
@@ -124,36 +98,6 @@ jobs:
12498
- name: Test Debug
12599
run: ctest --test-dir build-debug --output-on-failure --no-tests=error -C Debug
126100

127-
- name: Configure with `import std;`
128-
if: ${{ matrix.compiler.import_std == 'TRUE' }}
129-
run: |
130-
cxx_standard=23
131-
stdlib_options=(-DCMAKE_CXX_FLAGS:STRING=-stdlib=libc++)
132-
if [[ "${CC}" == gcc-* ]]; then
133-
cxx_standard=26
134-
stdlib_options=(-DCMAKE_CXX_STDLIB_MODULES_JSON="$("${CXX}" -print-file-name=libstdc++.modules.json)")
135-
fi
136-
137-
cmake -S . -B build-import-std \
138-
-DCMAKE_BUILD_TYPE=Debug \
139-
-DCMAKE_EXPERIMENTAL_CXX_IMPORT_STD=f35a9ac6-8463-4d38-8eec-5d6008153e7d \
140-
-DCMAKE_CXX_STANDARD="${cxx_standard}" \
141-
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
142-
-DCMAKE_CXX_EXTENSIONS=OFF \
143-
-DMAGIC_ENUM_USE_MODULES:BOOL=TRUE \
144-
-DMAGIC_ENUM_MODULE_IMPORT_STD:BOOL=TRUE \
145-
-DMAGIC_ENUM_MODULE_WITH_FMT:BOOL=FALSE \
146-
-GNinja \
147-
"${stdlib_options[@]}"
148-
149-
- name: Build with `import std;`
150-
if: ${{ matrix.compiler.import_std == 'TRUE' }}
151-
run: cmake --build build-import-std --parallel --config Debug
152-
153-
- name: Test with `import std;`
154-
if: ${{ matrix.compiler.import_std == 'TRUE' }}
155-
run: ctest --test-dir build-import-std --output-on-failure --no-tests=error -C Debug
156-
157101
bazel:
158102
name: Bazel
159103
runs-on: ubuntu-24.04

include/magic_enum/magic_enum.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,8 @@ template <typename E, int O, enum_subtype S, typename U = std::underlying_type_t
970970
constexpr U ualue(std::size_t i) noexcept {
971971
if constexpr (S == enum_subtype::flags) {
972972
using V = make_unsigned_t<U>;
973-
return static_cast<U>(V{1} << static_cast<V>(static_cast<int>(i) + O));
973+
const auto shifted = V{1} << static_cast<V>(static_cast<int>(i) + O);
974+
return static_cast<U>(shifted);
974975
} else {
975976
return static_cast<U>(static_cast<int>(i) + O);
976977
}

test/CMakeLists.txt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,14 @@ magic_enum_add_tests(cpp17 c++17)
280280
magic_enum_make_test(test_range.cpp test_range-cpp17 c++17)
281281
magic_enum_make_test(test.cpp test-hash-cpp17 c++17)
282282
target_compile_definitions(test-hash-cpp17 PRIVATE MAGIC_ENUM_ENABLE_HASH=1)
283+
magic_enum_make_test(test_flags.cpp test_flags-hash-cpp17 c++17)
284+
target_compile_definitions(test_flags-hash-cpp17 PRIVATE MAGIC_ENUM_ENABLE_HASH=1)
283285
magic_enum_make_test(test.cpp test-hash-switch-cpp17 c++17)
284286
target_compile_definitions(test-hash-switch-cpp17 PRIVATE MAGIC_ENUM_ENABLE_HASH_SWITCH=1)
287+
magic_enum_make_test(test_flags.cpp test_flags-hash-switch-cpp17 c++17)
288+
target_compile_definitions(test_flags-hash-switch-cpp17 PRIVATE MAGIC_ENUM_ENABLE_HASH_SWITCH=1)
289+
magic_enum_make_test(test_fuse.cpp test-no-typesafe-enum-fuse-cpp17 c++17)
290+
target_compile_definitions(test-no-typesafe-enum-fuse-cpp17 PRIVATE MAGIC_ENUM_NO_TYPESAFE_ENUM_FUSE=1)
285291
magic_enum_make_configuration_compile_fail_test(
286292
conflicting-assert
287293
1
@@ -340,7 +346,20 @@ if(MAGIC_ENUM_CAN_COMPILE_STD_REFLECTION)
340346
magic_enum_add_std_reflection_options(${test_name}-cpp26-reflection)
341347
target_compile_definitions(${test_name}-cpp26-reflection PRIVATE MAGIC_ENUM_TEST_STD_REFLECTION=1)
342348
endforeach()
343-
target_compile_definitions(test-cpp26-reflection PRIVATE MAGIC_ENUM_ENABLE_HASH=1)
349+
target_compile_definitions(
350+
test-cpp26-reflection
351+
test_flags-cpp26-reflection
352+
PRIVATE MAGIC_ENUM_ENABLE_HASH=1
353+
)
354+
355+
magic_enum_add_tests(cpp26-force-compiler-specific ${MAGIC_ENUM_CPP26_STANDARD_FLAG})
356+
foreach(test_name IN LISTS MAGIC_ENUM_TEST_SOURCES)
357+
magic_enum_add_std_reflection_options(${test_name}-cpp26-force-compiler-specific)
358+
target_compile_definitions(
359+
${test_name}-cpp26-force-compiler-specific
360+
PRIVATE MAGIC_ENUM_FORCE_COMPILER_SPECIFIC_REFLECTION=1
361+
)
362+
endforeach()
344363

345364
set(reflection_test test_std_reflection-auto-cpp26)
346365
magic_enum_make_test(test_reflection.cpp ${reflection_test} ${MAGIC_ENUM_CPP26_STANDARD_FLAG})

test/aliases.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ struct MyStringView {
4747

4848
constexpr MyStringView() : str{} {} // required
4949
constexpr MyStringView(const char* cstr, std::size_t size) : str{cstr, size} {} // required
50-
constexpr MyStringView(const MyStringView&) = default;
51-
constexpr MyStringView& operator=(const MyStringView&) = delete;
5250
constexpr bool empty() const { return str.empty(); } // required
5351
constexpr std::size_t size() const { return str.size(); } // required
5452
constexpr const char* data() const { return str.data(); } // required

test/installed_module/main.cpp

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import std;
1212
#else
1313
# include <functional>
14+
# include <sstream>
1415
# if defined(__cpp_lib_format) && __cpp_lib_format >= 201907L
1516
# include <format>
1617
# endif
@@ -19,8 +20,14 @@ import std;
1920
import magic_enum;
2021

2122
enum class Color { RED, GREEN, BLUE };
23+
enum class Directions { LEFT = 1, RIGHT = 2 };
2224
enum class ReflectionRange { Low = -1000, High = 1000 };
2325

26+
template <>
27+
struct magic_enum::customize::enum_range<Directions> {
28+
static constexpr bool is_flags = true;
29+
};
30+
2431
template <>
2532
struct magic_enum::customize::enum_range<ReflectionRange> {
2633
static constexpr int min = -1;
@@ -31,6 +38,8 @@ static_assert(magic_enum::enum_count<Color>() == 3);
3138
static_assert(magic_enum::enum_integer(Color::GREEN) == 1);
3239
static_assert(magic_enum::string_view{"BLUE"}.size() == 4);
3340
static_assert(magic_enum::optional<int>{7}.value() == 7);
41+
static_assert(magic_enum::enum_cast<Color>("GREEN") == Color::GREEN);
42+
static_assert(magic_enum::enum_flags_cast<Directions>("LEFT|RIGHT") == static_cast<Directions>(3));
3443

3544
#ifdef MAGIC_ENUM_TEST_STD_REFLECTION
3645
constexpr auto reflection_range_values = magic_enum::enum_values<ReflectionRange>();
@@ -46,16 +55,46 @@ constexpr magic_enum::containers::bitset<Color> color_bits{magic_enum::container
4655
int main() {
4756
if (std::hash<magic_enum::containers::bitset<Color>>{}(color_bits) !=
4857
std::hash<unsigned long long>{}(5ULL)) {
49-
return 3;
58+
return 1;
59+
}
60+
{
61+
using namespace magic_enum::iostream_operators;
62+
63+
std::ostringstream output;
64+
output << Color::GREEN << ' ' << static_cast<Directions>(3);
65+
if (output.str() != "GREEN LEFT|RIGHT") {
66+
return 2;
67+
}
68+
69+
Color parsed_color = Color::RED;
70+
std::istringstream input{"BLUE"};
71+
input >> parsed_color;
72+
if (!input || parsed_color != Color::BLUE) {
73+
return 3;
74+
}
75+
}
76+
{
77+
std::ostringstream output;
78+
output << color_bits;
79+
if (output.str() != "RED|BLUE") {
80+
return 4;
81+
}
82+
83+
magic_enum::containers::bitset<Color> parsed_bits;
84+
std::istringstream input{"RED|BLUE"};
85+
input >> parsed_bits;
86+
if (!input || parsed_bits.to_ullong(magic_enum::containers::raw_access) != 5ULL) {
87+
return 5;
88+
}
5089
}
5190
#if defined(__cpp_lib_format) && __cpp_lib_format >= 201907L
5291
if (std::format("{}", Color::GREEN) != "GREEN") {
53-
return 1;
92+
return 6;
5493
}
5594
#endif
5695
#ifdef MAGIC_ENUM_TEST_FMT
5796
if (fmt::format("{}", Color::BLUE) != "BLUE") {
58-
return 2;
97+
return 7;
5998
}
6099
#endif
61100
}

0 commit comments

Comments
 (0)