Skip to content

Conversation

Copilot
Copy link

@Copilot Copilot AI commented Oct 11, 2025

This PR adds optional support for modern C++ formatting (std::format or fmtlib) to the http_io examples, addressing the need for better formatting capabilities in the server example.

Problem

The server example's logger currently uses std::stringstream for formatting, which is verbose and less efficient. As noted in the issue, the server example needs fmtlib or std::format to be fully useful. Additionally, the burl client example had a TODO comment to replace ostringstream usage.

Solution

This implementation uses a tiered conditional compilation approach that automatically detects and uses the best available formatting method:

  1. C++20 std::format - Used automatically when C++20 is available (via std::vformat for runtime format strings)
  2. fmtlib - Used as fallback if <fmt/core.h> is available
  3. std::stringstream - Legacy fallback for maximum compatibility

The solution requires no changes to existing code and introduces no hard dependencies - fmtlib is completely optional.

API Examples

When std::format or fmtlib is available, the logger supports modern format strings:

section log;
LOG_INF(log, "Request from {} for {}", client_ip, path);
LOG_DBG(log, "Response time: {:.2f}ms", response_time);

When neither is available, the legacy variadic API continues to work:

section log;
LOG_INF(log, "Request from ", client_ip, " for ", path);
LOG_DBG(log, "Response time: ", response_time, "ms");

Both styles work regardless of which backend is used, ensuring seamless migration.

Changes

Core Implementation:

  • Added example/server/format.hpp - Conditional compilation utility for format detection
  • Updated example/server/logger.hpp - Format string support when available, with inline docs
  • Updated example/server/CMakeLists.txt - Optional fmtlib detection via find_package(fmt QUIET)
  • Updated example/server/Jamfile - Optional fmtlib linking via ac.check-library
  • Updated example/client/burl/utils.cpp - Format support for format_size() function (resolves TODO)
  • Updated example/client/burl/CMakeLists.txt - Optional fmtlib detection
  • Updated example/client/burl/Jamfile - Optional fmtlib linking via ac.check-library

Documentation:

  • Added example/server/README.md - Comprehensive usage guide and build instructions
  • Added example/server/logger_example.cpp - Working examples of both API styles
  • Updated README.adoc - Optional dependencies section with installation instructions
  • Added IMPLEMENTATION_NOTES.md - Technical details and design rationale

Building

The examples build successfully with or without format support:

With CMake:

# C++20 with std::format (auto-detected)
cmake -DCMAKE_CXX_STANDARD=20 ..

# With fmtlib via vcpkg
vcpkg install fmt
cmake -DCMAKE_TOOLCHAIN_FILE=path/to/vcpkg/scripts/buildsystems/vcpkg.cmake ..

# Without format support (C++11 compatible)
cmake ..

With Boost.Build (b2):

# Builds with fmtlib if available, otherwise falls back to stringstream
b2 example/server
b2 example/client/burl

Benefits

  • ✅ Zero breaking changes - all existing code continues to work unchanged
  • ✅ No hard dependencies - fmtlib is completely optional
  • ✅ Automatic detection - uses best available formatting method
  • ✅ Backward compatible - works with C++11, C++17, and C++20
  • ✅ Performance - modern formatting is more efficient than stringstream
  • ✅ Industry standard - aligns with modern C++ direction (std::format is in C++20 standard)
  • ✅ Both CMake and Boost.Build support - works with either build system

Testing

  • Verified compilation with C++11 (stringstream fallback)
  • Verified compilation with C++20 (std::format auto-detected and used)
  • Confirmed backward compatibility with existing logger usage in worker.hpp
  • No API breaking changes
  • Both CMake and Boost.Build configurations updated

Fixes #50

Original prompt

This section details on the original issue you should resolve

<issue_title>need fmtlib or std::format or both</issue_title>
<issue_description>The server example really needs to have fmtlib or std::format to be fully useful. Not sure what the best way to integrate it is.
</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #50


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

@Copilot Copilot AI changed the title [WIP] Add fmtlib or std::format integration to server example Add optional std::format and fmtlib support to examples Oct 11, 2025
@Copilot Copilot AI requested a review from vinniefalco October 11, 2025 21:40
Copilot finished work on behalf of vinniefalco October 11, 2025 21:40
@vinniefalco
Copy link
Member

@copilot please also update the Jamfiles to support fmtlib

Copy link
Author

Copilot AI commented Oct 13, 2025

@copilot please also update the Jamfiles to support fmtlib

Updated both Jamfiles to support optional fmtlib linking. The Jamfiles now use ac.check-library to conditionally link fmtlib if available, matching the pattern used for other optional dependencies like zlib and brotli. (commit ef2575c)

Copilot finished work on behalf of vinniefalco October 13, 2025 13:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

need fmtlib or std::format or both

2 participants