Skip to content

Commit 6242604

Browse files
committed
Add Clang support
1 parent b15196c commit 6242604

File tree

4 files changed

+77
-13
lines changed

4 files changed

+77
-13
lines changed

Diff for: include/boost/pfr/config.hpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,12 @@
107107
#endif
108108

109109
#ifndef BOOST_PFR_ENABLE_GETTING_NAMES
110-
# if defined(__cpp_nontype_template_args) && __cpp_nontype_template_args >= 201911 && BOOST_PFR_FUNCTION_MACRO_SUPPORTED
111-
# define BOOST_PFR_ENABLE_GETTING_NAMES 1
110+
# if (defined(__cpp_nontype_template_args) && __cpp_nontype_template_args >= 201911) || (defined(__clang_major__) && __clang_major__ >= 12)
111+
# if BOOST_PFR_FUNCTION_MACRO_SUPPORTED
112+
# define BOOST_PFR_ENABLE_GETTING_NAMES 1
113+
# else
114+
# define BOOST_PFR_ENABLE_GETTING_NAMES 0
115+
# endif
112116
# else
113117
# define BOOST_PFR_ENABLE_GETTING_NAMES 0
114118
# endif

Diff for: include/boost/pfr/detail/core_name20_static.hpp

+34-5
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ constexpr auto make_sequence_tuple(Args... args) noexcept {
3030
return sequence_tuple::tuple<Args...>{ args... };
3131
}
3232

33-
template <typename MsvcWorkaround, auto* ptr>
33+
template <typename MsvcWorkaround, auto ptr>
3434
consteval auto name_of_field_impl() noexcept {
3535
#ifdef _MSC_VER
3636
constexpr std::string_view sv = __FUNCSIG__;
3737
// - strlen("(void)") - strlen(" noexcept")
38-
constexpr auto last = sv.find_last_not_of(" >(", sv.size() - 6 - 9);
38+
constexpr auto last = sv.find_last_not_of(" >(}", sv.size() - 6 - 9);
3939
#else
4040
constexpr std::string_view sv = __PRETTY_FUNCTION__;
41-
constexpr auto last = sv.find_last_not_of(" ])");
41+
constexpr auto last = sv.find_last_not_of(" ])}");
4242
#endif
4343
constexpr auto first = sv.find_last_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789", last);
4444
auto res = std::array<char, last - first + 2>{};
@@ -51,11 +51,40 @@ consteval auto name_of_field_impl() noexcept {
5151
template <typename T>
5252
extern const T fake_object;
5353

54+
#ifdef __clang__
55+
#pragma clang diagnostic push
56+
#pragma clang diagnostic ignored "-Wundefined-var-template"
57+
58+
template<class T>
59+
struct clang_workaround_t {
60+
T v;
61+
};
62+
template<class T>
63+
clang_workaround_t(T) -> clang_workaround_t<T>;
64+
65+
template<typename T>
66+
constexpr auto clang_workaround(const T& arg) noexcept {
67+
return clang_workaround_t{arg};
68+
}
69+
70+
#else
71+
72+
template<typename T>
73+
constexpr const T& clang_workaround(const T& arg) noexcept {
74+
return arg;
75+
}
76+
77+
#endif
78+
5479
// Without passing 'T' into 'name_of_field_impl' different fields from different structures might have the same name!
5580
template <class T, std::size_t I>
56-
constexpr auto stored_name_of_field = name_of_field_impl<T, &detail::sequence_tuple::get<I>(
81+
constexpr auto stored_name_of_field = name_of_field_impl<T, clang_workaround(&detail::sequence_tuple::get<I>(
5782
detail::tie_as_tuple(fake_object<T>)
58-
)>();
83+
))>();
84+
85+
#ifdef __clang__
86+
#pragma clang diagnostic pop
87+
#endif
5988

6089
template <class T, std::size_t... I>
6190
constexpr auto tie_as_names_tuple_impl(std::index_sequence<I...>) noexcept {

Diff for: test/core_name/Jamfile.v2

+5-6
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import python ;
1212
import testing ;
1313
import ../../config/checks/config : requires ;
1414

15-
########## BEGIN of helpers to detect C++20 non-type template args support
15+
########## BEGIN of helpers to detect C++20 features support
1616

1717
actions mp_simple_run_action
1818
{
@@ -31,17 +31,16 @@ rule mp-run-simple ( sources + : args * : input-files * : requirements * : targe
3131
mp-run-simple cxx20_nontype_template_args_detection.cpp : : : : compiler_supports_cxx20_nontype_template_args ;
3232
explicit compiler_supports_cxx20_nontype_template_args ;
3333

34-
########## END of helpers to detect C++20 non-type template args support
34+
mp-run-simple cxx20_clang_workaround_detection.cpp : : : : compiler_supports_cxx20_clang_workaround ;
35+
explicit compiler_supports_cxx20_clang_workaround ;
3536

36-
local REQUIRE_CXX20_NONTYPE_TEMPLATE_ARGS =
37-
[ check-target-builds ../core_name//compiler_supports_cxx20_nontype_template_args : : <build>no ]
38-
;
37+
########## END of helpers to detect C++20 features support
3938

4039
project
4140
: source-location .
4241
: requirements
4342
<define>BOOST_PFR_DETAIL_STRICT_RVALUE_TESTING=1
44-
[ check-target-builds ../core_name//compiler_supports_cxx20_nontype_template_args : : <build>no ]
43+
[ check-target-builds ../core_name//compiler_supports_cxx20_nontype_template_args : : [ check-target-builds ../core_name//compiler_supports_cxx20_clang_workaround : : <build>no ] ]
4544
;
4645

4746

Diff for: test/core_name/cxx20_clang_workaround_detection.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2023 Bela Schaum, X-Ryl669, Denis Mikhailov.
2+
//
3+
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4+
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5+
6+
7+
// Initial implementation by Bela Schaum, https://github.com/schaumb
8+
// The way to make it union and UB free by X-Ryl669, https://github.com/X-Ryl669
9+
//
10+
11+
template <auto p>
12+
class X {};
13+
14+
template <class T>
15+
struct Store
16+
{
17+
T v;
18+
};
19+
20+
template <class T>
21+
Store(T) -> Store<T>;
22+
23+
struct S
24+
{
25+
int m;
26+
} s;
27+
28+
X<Store{&s.m}> x4;
29+
30+
int main() {}
31+
32+

0 commit comments

Comments
 (0)