Skip to content
This repository was archived by the owner on Jan 29, 2026. It is now read-only.

Commit c02d4db

Browse files
committed
Test for std::format using __cpp_lib_format
With specialization for libc++. Fixes compilation on libc++ 16-18 that has incomplete std::format support.
1 parent f32138f commit c02d4db

File tree

6 files changed

+41
-10
lines changed

6 files changed

+41
-10
lines changed

docs/spec/proxy_view.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ using proxy_view = proxy<observer_facade<F>>;
3737
## Example
3838

3939
```cpp
40+
#include <cstdio>
4041
#include <map>
4142

4243
#include <proxy/proxy.h>

include/proxy/v4/proxy.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
#if __has_include(<format>)
2424
#include <format>
2525
#endif // __has_include(<format>)
26+
#if __cpp_lib_format || (defined(_LIBCPP_VERSION) && _LIBCPP_VERSION >= 170000)
27+
#define _PRO4D_HAS_FORMAT
28+
#endif // __cpp_lib_format || _LIBCPP_VERSION >= 170000
2629
#endif // __STDC_HOSTED__
2730

2831
#if __cpp_rtti >= 199711L
@@ -2125,7 +2128,7 @@ struct weak_conversion_dispatch : cast_dispatch_base<false, true> {
21252128
template <class F>
21262129
using weak_conversion_overload = weak_proxy<F>() const noexcept;
21272130

2128-
#if __STDC_HOSTED__ && __has_include(<format>)
2131+
#ifdef _PRO4D_HAS_FORMAT
21292132
template <class CharT>
21302133
struct format_overload_traits;
21312134
template <>
@@ -2166,7 +2169,7 @@ struct format_dispatch {
21662169
return impl.format(self, fc);
21672170
}
21682171
};
2169-
#endif // __STDC_HOSTED__ && __has_include(<format>)
2172+
#endif // _PRO4D_HAS_FORMAT
21702173

21712174
#if __cpp_rtti >= 199711L
21722175
struct proxy_cast_context {
@@ -2273,7 +2276,7 @@ struct proxy_typeid_reflector {
22732276

22742277
namespace skills {
22752278

2276-
#if __STDC_HOSTED__ && __has_include(<format>)
2279+
#ifdef _PRO4D_HAS_FORMAT
22772280
template <class FB>
22782281
using format =
22792282
typename FB::template add_convention<details::format_dispatch,
@@ -2283,7 +2286,7 @@ template <class FB>
22832286
using wformat =
22842287
typename FB::template add_convention<details::format_dispatch,
22852288
details::format_overload_t<wchar_t>>;
2286-
#endif // __STDC_HOSTED__ && __has_include(<format>)
2289+
#endif // _PRO4D_HAS_FORMAT
22872290

22882291
#if __cpp_rtti >= 199711L
22892292
template <class FB>
@@ -2604,7 +2607,7 @@ struct weak_dispatch : D {
26042607
// == Adapters (std::formatter) ==
26052608
// =============================================================================
26062609

2607-
#if __STDC_HOSTED__ && __has_include(<format>)
2610+
#ifdef _PRO4D_HAS_FORMAT
26082611
namespace std {
26092612

26102613
template <pro::v4::facade F, class CharT>
@@ -2635,7 +2638,7 @@ struct formatter<pro::v4::proxy_indirect_accessor<F>, CharT> {
26352638
};
26362639

26372640
} // namespace std
2638-
#endif // __STDC_HOSTED__ && __has_include(<format>)
2641+
#endif // _PRO4D_HAS_FORMAT
26392642

26402643
#undef PROD_UNREACHABLE
26412644
#undef PROD_NO_UNIQUE_ADDRESS_ATTRIBUTE

include/proxy/v4/proxy.ixx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ using v4::weak_proxy;
4141

4242
namespace skills {
4343

44-
#if __STDC_HOSTED__ && __has_include(<format>)
44+
#ifdef _PRO4D_HAS_FORMAT
4545
using skills::format;
4646
using skills::wformat;
47-
#endif // __STDC_HOSTED__ && __has_include(<format>)
47+
#endif // _PRO4D_HAS_FORMAT
4848

4949
#if __cpp_rtti >= 199711L
5050
using skills::direct_rtti;
@@ -60,10 +60,10 @@ using skills::slim;
6060

6161
} // namespace pro::inline v4
6262

63-
#if __STDC_HOSTED__ && __has_include(<format>)
63+
#ifdef _PRO4D_HAS_FORMAT
6464
export namespace std {
6565

6666
using std::formatter;
6767

6868
} // namespace std
69-
#endif // __STDC_HOSTED__ && __has_include(<format>)
69+
#endif // _PRO4D_HAS_FORMAT

tests/proxy_dispatch_tests.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,7 @@ TEST(ProxyDispatchTests, TestFreeAsMemDispatch) {
829829
}
830830

831831
TEST(ProxyDispatchTests, TestSubstitutionDispatch) {
832+
#ifdef _PRO4D_HAS_FORMAT
832833
struct Base : pro::facade_builder //
833834
::add_skill<pro::skills::format> //
834835
::build {};
@@ -844,4 +845,7 @@ TEST(ProxyDispatchTests, TestSubstitutionDispatch) {
844845
pro::proxy<Base> p3 = std::move(p1);
845846
ASSERT_FALSE(p1.has_value());
846847
ASSERT_EQ(std::format("{}", *p3), "123");
848+
#else
849+
GTEST_SKIP() << "std::format not available";
850+
#endif // _PRO4D_HAS_FORMAT
847851
}

tests/proxy_format_tests.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <gtest/gtest.h>
55
#include <proxy/proxy.h>
66

7+
#ifdef _PRO4D_HAS_FORMAT
78
namespace proxy_format_tests_details {
89

910
struct NonFormattable : pro::facade_builder::build {};
@@ -29,17 +30,26 @@ static_assert(
2930
} // namespace proxy_format_tests_details
3031

3132
namespace details = proxy_format_tests_details;
33+
#endif // _PRO4D_HAS_FORMAT
3234

3335
TEST(ProxyFormatTests, TestFormat) {
36+
#ifdef _PRO4D_HAS_FORMAT
3437
int v = 123;
3538
pro::proxy<details::Formattable> p = &v;
3639
ASSERT_EQ(std::format("{}", *p), "123");
3740
ASSERT_EQ(std::format("{:*<6}", *p), "123***");
41+
#else
42+
GTEST_SKIP() << "std::format not available";
43+
#endif // _PRO4D_HAS_FORMAT
3844
}
3945

4046
TEST(ProxyFormatTests, TestWformat) {
47+
#ifdef _PRO4D_HAS_FORMAT
4148
int v = 123;
4249
pro::proxy<details::Formattable> p = &v;
4350
ASSERT_EQ(std::format(L"{}", *p), L"123");
4451
ASSERT_EQ(std::format(L"{:*<6}", *p), L"123***");
52+
#else
53+
GTEST_SKIP() << "std::format not available";
54+
#endif // _PRO4D_HAS_FORMAT
4555
}

tools/extract_example_code_from_docs.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,19 @@ def extract_cpp_code(md_path: Path) -> T.Optional[str]:
2727
2828
""".lstrip()
2929

30+
if "pro::skills::format" in cpp_code:
31+
cpp_code = f"""
32+
#include <proxy/proxy.h>
33+
#ifdef _PRO4D_HAS_FORMAT
34+
{cpp_code}
35+
#else
36+
int main() {{
37+
// std::format is not fully available
38+
return 77;
39+
}}
40+
#endif
41+
""".strip()
42+
3043
return header + cpp_code
3144

3245

0 commit comments

Comments
 (0)