Skip to content

Commit 2447a48

Browse files
committed
✨ Add preprocessor mapping function
Problem: - It's useful to have `map`/`transform` in the preprocessor. Solution: - Add `pp_map.hpp`.
1 parent 6ca46e9 commit 2447a48

File tree

4 files changed

+70
-2
lines changed

4 files changed

+70
-2
lines changed

CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ target_sources(
6262
include/stdx/detail/list_common.hpp
6363
include/stdx/env.hpp
6464
include/stdx/for_each_n_args.hpp
65-
include/stdx/functional.hpp
6665
include/stdx/function_traits.hpp
66+
include/stdx/functional.hpp
6767
include/stdx/intrusive_forward_list.hpp
6868
include/stdx/intrusive_list.hpp
6969
include/stdx/iterator.hpp
@@ -72,14 +72,15 @@ target_sources(
7272
include/stdx/numeric.hpp
7373
include/stdx/optional.hpp
7474
include/stdx/panic.hpp
75+
include/stdx/pp_map.hpp
7576
include/stdx/priority.hpp
7677
include/stdx/ranges.hpp
7778
include/stdx/rollover.hpp
7879
include/stdx/span.hpp
7980
include/stdx/static_assert.hpp
81+
include/stdx/tuple.hpp
8082
include/stdx/tuple_algorithms.hpp
8183
include/stdx/tuple_destructure.hpp
82-
include/stdx/tuple.hpp
8384
include/stdx/type_traits.hpp
8485
include/stdx/udls.hpp
8586
include/stdx/utility.hpp)

include/stdx/pp_map.hpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#pragma once
2+
3+
// NOLINTBEGIN(cppcoreguidelines-macro-usage)
4+
5+
#define STDX_EVAL0(...) __VA_ARGS__
6+
#define STDX_EVAL1(...) STDX_EVAL0(STDX_EVAL0(STDX_EVAL0(__VA_ARGS__)))
7+
#define STDX_EVAL2(...) STDX_EVAL1(STDX_EVAL1(STDX_EVAL1(__VA_ARGS__)))
8+
#define STDX_EVAL3(...) STDX_EVAL2(STDX_EVAL2(STDX_EVAL2(__VA_ARGS__)))
9+
#define STDX_EVAL4(...) STDX_EVAL3(STDX_EVAL3(STDX_EVAL3(__VA_ARGS__)))
10+
#define STDX_EVAL5(...) STDX_EVAL4(STDX_EVAL4(STDX_EVAL4(__VA_ARGS__)))
11+
#define STDX_EVAL(...) STDX_EVAL5(__VA_ARGS__)
12+
13+
#define STDX_MAP_END(...)
14+
#define STDX_MAP_OUT
15+
16+
#define STDX_EMPTY()
17+
#define STDX_DEFER(id) id STDX_EMPTY()
18+
19+
#define STDX_MAP_GET_END2() 0, STDX_MAP_END
20+
#define STDX_MAP_GET_END1(...) STDX_MAP_GET_END2
21+
#define STDX_MAP_GET_END(...) STDX_MAP_GET_END1
22+
#define STDX_MAP_NEXT0(test, next, ...) next STDX_MAP_OUT
23+
#define STDX_MAP_NEXT1(test, next) STDX_DEFER(STDX_MAP_NEXT0)(test, next, 0)
24+
#define STDX_MAP_NEXT(test, next) STDX_MAP_NEXT1(STDX_MAP_GET_END test, next)
25+
#define STDX_MAP_INC(X) STDX_MAP_INC_##X
26+
27+
#define STDX_MAP_A(f, x, peek, ...) \
28+
, f(x) STDX_DEFER(STDX_MAP_NEXT(peek, STDX_MAP_B))(f, peek, __VA_ARGS__)
29+
#define STDX_MAP_B(f, x, peek, ...) \
30+
, f(x) STDX_DEFER(STDX_MAP_NEXT(peek, STDX_MAP_A))(f, peek, __VA_ARGS__)
31+
32+
#define STDX_DROP0(X, ...) __VA_ARGS__
33+
#define STDX_DROP1(...) STDX_DROP0(__VA_ARGS__)
34+
35+
#define STDX_MAP(f, ...) \
36+
__VA_OPT__(STDX_DROP1( \
37+
0 STDX_EVAL(STDX_MAP_A(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))))
38+
39+
// NOLINTEND(cppcoreguidelines-macro-usage)

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ add_tests(
5454
optional
5555
overload
5656
panic
57+
pp_map
5758
priority
5859
ranges
5960
remove_cvref

test/pp_map.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <stdx/compiler.hpp>
2+
#include <stdx/pp_map.hpp>
3+
4+
#include <catch2/catch_test_macros.hpp>
5+
6+
namespace {
7+
auto count_args = [](auto const &...args) { return sizeof...(args); };
8+
} // namespace
9+
10+
TEST_CASE("pp_map zero arguments", "[pp_map]") {
11+
STDX_PRAGMA(diagnostic push)
12+
STDX_PRAGMA(diagnostic ignored "-Wgnu-zero-variadic-macro-arguments")
13+
static_assert(count_args(STDX_MAP(int)) == 0);
14+
STDX_PRAGMA(diagnostic pop)
15+
}
16+
17+
TEST_CASE("pp_map one argument", "[pp_map]") {
18+
static_assert(count_args(STDX_MAP(double, 1)) == 1.0);
19+
}
20+
21+
TEST_CASE("pp_map n arguments", "[pp_map]") {
22+
static_assert(count_args(STDX_MAP(double, 1, 2, 3)) == 3);
23+
}
24+
25+
TEST_CASE("pp_map parenthesized arguments", "[pp_map]") {
26+
static_assert(count_args(STDX_MAP(double, ((void)1, 2), 3)) == 2);
27+
}

0 commit comments

Comments
 (0)