Skip to content

Commit

Permalink
Add Clang support
Browse files Browse the repository at this point in the history
  • Loading branch information
denzor200 committed Aug 19, 2023
1 parent b15196c commit 6242604
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 13 deletions.
8 changes: 6 additions & 2 deletions include/boost/pfr/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,12 @@
#endif

#ifndef BOOST_PFR_ENABLE_GETTING_NAMES
# if defined(__cpp_nontype_template_args) && __cpp_nontype_template_args >= 201911 && BOOST_PFR_FUNCTION_MACRO_SUPPORTED
# define BOOST_PFR_ENABLE_GETTING_NAMES 1
# if (defined(__cpp_nontype_template_args) && __cpp_nontype_template_args >= 201911) || (defined(__clang_major__) && __clang_major__ >= 12)
# if BOOST_PFR_FUNCTION_MACRO_SUPPORTED
# define BOOST_PFR_ENABLE_GETTING_NAMES 1
# else
# define BOOST_PFR_ENABLE_GETTING_NAMES 0
# endif
# else
# define BOOST_PFR_ENABLE_GETTING_NAMES 0
# endif
Expand Down
39 changes: 34 additions & 5 deletions include/boost/pfr/detail/core_name20_static.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ constexpr auto make_sequence_tuple(Args... args) noexcept {
return sequence_tuple::tuple<Args...>{ args... };
}

template <typename MsvcWorkaround, auto* ptr>
template <typename MsvcWorkaround, auto ptr>
consteval auto name_of_field_impl() noexcept {
#ifdef _MSC_VER
constexpr std::string_view sv = __FUNCSIG__;
// - strlen("(void)") - strlen(" noexcept")
constexpr auto last = sv.find_last_not_of(" >(", sv.size() - 6 - 9);
constexpr auto last = sv.find_last_not_of(" >(}", sv.size() - 6 - 9);
#else
constexpr std::string_view sv = __PRETTY_FUNCTION__;
constexpr auto last = sv.find_last_not_of(" ])");
constexpr auto last = sv.find_last_not_of(" ])}");
#endif
constexpr auto first = sv.find_last_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789", last);
auto res = std::array<char, last - first + 2>{};
Expand All @@ -51,11 +51,40 @@ consteval auto name_of_field_impl() noexcept {
template <typename T>
extern const T fake_object;

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundefined-var-template"

template<class T>
struct clang_workaround_t {
T v;
};
template<class T>
clang_workaround_t(T) -> clang_workaround_t<T>;

template<typename T>
constexpr auto clang_workaround(const T& arg) noexcept {
return clang_workaround_t{arg};
}

#else

template<typename T>
constexpr const T& clang_workaround(const T& arg) noexcept {
return arg;
}

#endif

// Without passing 'T' into 'name_of_field_impl' different fields from different structures might have the same name!
template <class T, std::size_t I>
constexpr auto stored_name_of_field = name_of_field_impl<T, &detail::sequence_tuple::get<I>(
constexpr auto stored_name_of_field = name_of_field_impl<T, clang_workaround(&detail::sequence_tuple::get<I>(
detail::tie_as_tuple(fake_object<T>)
)>();
))>();

#ifdef __clang__
#pragma clang diagnostic pop
#endif

template <class T, std::size_t... I>
constexpr auto tie_as_names_tuple_impl(std::index_sequence<I...>) noexcept {
Expand Down
11 changes: 5 additions & 6 deletions test/core_name/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import python ;
import testing ;
import ../../config/checks/config : requires ;

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

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

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

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

project
: source-location .
: requirements
<define>BOOST_PFR_DETAIL_STRICT_RVALUE_TESTING=1
[ check-target-builds ../core_name//compiler_supports_cxx20_nontype_template_args : : <build>no ]
[ check-target-builds ../core_name//compiler_supports_cxx20_nontype_template_args : : [ check-target-builds ../core_name//compiler_supports_cxx20_clang_workaround : : <build>no ] ]
;


Expand Down
32 changes: 32 additions & 0 deletions test/core_name/cxx20_clang_workaround_detection.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) 2023 Bela Schaum, X-Ryl669, Denis Mikhailov.
//
// 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)


// Initial implementation by Bela Schaum, https://github.com/schaumb
// The way to make it union and UB free by X-Ryl669, https://github.com/X-Ryl669
//

template <auto p>
class X {};

template <class T>
struct Store
{
T v;
};

template <class T>
Store(T) -> Store<T>;

struct S
{
int m;
} s;

X<Store{&s.m}> x4;

int main() {}


0 comments on commit 6242604

Please sign in to comment.