From 76c8018a110e2135a88866199a9267c7ad6ad4a8 Mon Sep 17 00:00:00 2001 From: Denis Mikhailov Date: Sat, 25 Nov 2023 23:33:12 +0100 Subject: [PATCH 1/4] Add fmt library integration example --- example/fmtlib_formatter.cpp | 70 ++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 example/fmtlib_formatter.cpp diff --git a/example/fmtlib_formatter.cpp b/example/fmtlib_formatter.cpp new file mode 100644 index 00000000..3982480f --- /dev/null +++ b/example/fmtlib_formatter.cpp @@ -0,0 +1,70 @@ +// Copyright (c) 2023 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) + +#include +#include +#include + +namespace boost::pfr { + struct fmtlib_tag; +} + +template struct fmt::formatter::value>> +{ + constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator { + auto it = ctx.begin(), end = ctx.end(); + + if (it != end && *it != '}') throw_format_error("invalid format"); + + return it; + } + + auto format(const T& t, format_context& ctx) const -> format_context::iterator { + using namespace boost::pfr; + + auto out = ctx.out(); + + *out++ = '{'; + + const char* div = ""; + constexpr auto names = names_as_array(); + + for_each_field(t, [&](const auto& field, auto I) { + out = fmt::format_to(out, "{}", std::exchange(div, ",")); + out = fmt::format_to(out, " .{}={}", names[I], field); + }); + + out = fmt::format_to(out, "{}", std::strlen(div) == 0 ? "}" : " }"); + + return out; + } +}; + +struct point +{ + int x, y; +}; + +struct color +{ + unsigned char r, g, b; +}; + +struct line +{ + color clr; + point first, last; +}; + +template<> struct boost::pfr::is_reflectable : std::integral_constant {}; +template<> struct boost::pfr::is_reflectable : std::integral_constant {}; +template<> struct boost::pfr::is_reflectable : std::integral_constant {}; + +int main() +{ + fmt::print("{}\n", line{ { 255, 192, 16 }, { 1, 2 }, { 3, 4 } }); +} + From b99d44f7792c705ba5761747d23144ba3e419c6f Mon Sep 17 00:00:00 2001 From: Denis Mikhailov Date: Sat, 2 Dec 2023 19:39:52 +0100 Subject: [PATCH 2/4] Update ci.yml --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c7b41ea6..f2fdc557 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,6 +58,9 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Install {fmt} + run: sudo apt install libfmt-dev + - name: Install packages if: matrix.install run: sudo apt install ${{matrix.install}} From 9a753f3478e407c9107524b386a952dcfab2480f Mon Sep 17 00:00:00 2001 From: Denis Mikhailov Date: Sat, 2 Dec 2023 19:54:21 +0100 Subject: [PATCH 3/4] Migrate example to old version fmtlib --- example/fmtlib_formatter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/fmtlib_formatter.cpp b/example/fmtlib_formatter.cpp index 3982480f..d7e81d22 100644 --- a/example/fmtlib_formatter.cpp +++ b/example/fmtlib_formatter.cpp @@ -17,7 +17,7 @@ template struct fmt::formatter format_parse_context::iterator { auto it = ctx.begin(), end = ctx.end(); - if (it != end && *it != '}') throw_format_error("invalid format"); + if (it != end && *it != '}') ctx.error_handler().on_error( "invalid format" ); return it; } From c3ae67218cb92dd88f8b424222299f12f0de75d6 Mon Sep 17 00:00:00 2001 From: Denis Mikhailov Date: Sat, 2 Dec 2023 20:37:35 +0100 Subject: [PATCH 4/4] Install fmt on windows --- .github/workflows/ci.yml | 9 +++++++++ test/appveyor.yml | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2fdc557..51ea6169 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -154,6 +154,15 @@ jobs: steps: - uses: actions/checkout@v2 + - uses: microsoft/setup-msbuild@v1.1 + - name: Install {fmt} + uses: lukka/run-vcpkg@v6 + with: + vcpkgGitCommitId: '88b1071e39f13b632644d9d953738d345a4ac055' + vcpkgDirectory: '${{ runner.workspace }}/vcpkg' + vcpkgTriplet: x64-windows + vcpkgArguments: fmt + - name: Setup Boost shell: cmd run: | diff --git a/test/appveyor.yml b/test/appveyor.yml index 8dd154d5..2a297aba 100644 --- a/test/appveyor.yml +++ b/test/appveyor.yml @@ -69,7 +69,19 @@ environment: TOOLSET: gcc CXXSTD: 14,1z +cache: + - c:\tools\vcpkg\installed\ + before_build: + # Install {fmt} library in order to run examples + # FIXME: To be removed https://help.appveyor.com/discussions/problems/13000-cmake_toolchain_filevcpkgcmake-conflicts-with-cmake-native-findboostcmake" + - ps: 'Write-Host "Installing latest vcpkg.cmake module" -ForegroundColor Magenta' + - appveyor DownloadFile https://raw.githubusercontent.com/Microsoft/vcpkg/master/scripts/buildsystems/vcpkg.cmake -FileName "c:\tools\vcpkg\scripts\buildsystems\vcpkg.cmake" + - set "TRIPLET=x64-windows" + - vcpkg --triplet %TRIPLET% install fmt + - set PATH=C:\Tools\vcpkg\installed\%TRIPLET%\bin;%PATH% + - set VCPKG_I=C:\Tools\vcpkg\installed\%TRIPLET%\include + - set VCPKG_L=C:\Tools\vcpkg\installed\%TRIPLET%\lib - set BOOST_BRANCH=develop - if "%APPVEYOR_REPO_BRANCH%" == "master" set BOOST_BRANCH=master - echo "Testing %BOOST_LIBS_FOLDER%" @@ -85,6 +97,17 @@ before_build: - python tools/boostdep/depinst/depinst.py --git_args "--depth 10 --jobs 2" -I example -I examples %BOOST_LIBS_FOLDER% build_script: + - xcopy %APPVEYOR_BUILD_FOLDER%\fmt.jam %USERPROFILE% + - ps: | + # Creating %USERPROFILE%/user-config.jam file + @' + import os regex toolset ; + local toolset = [ regex.split [ os.environ TOOLSET ] "-" ] ; + local vcpkg_i = [ os.environ VCPKG_I ] ; + local vcpkg_l = [ os.environ VCPKG_L ] ; + using $(toolset[1]) : $(toolset[2-]:J="-") : ; + using fmt : : $(vcpkg_i) $(vcpkg_l) ; + '@ | sc "$env:USERPROFILE/user-config.jam" - cmd /c bootstrap - b2.exe headers - cd %BOOST%/libs/%BOOST_LIBS_FOLDER%/test