diff --git a/docs/users_guide/examples/tags_index.md b/docs/users_guide/examples/tags_index.md index f8e603165e..0f1d4da8c3 100644 --- a/docs/users_guide/examples/tags_index.md +++ b/docs/users_guide/examples/tags_index.md @@ -1,5 +1,11 @@ # Tags Index +!!! note + + **mp-units** usage example applications are meant to be built on all of + [the supported compilers](../../getting_started/installation_and_usage.md#cpp-compiler-support). + This is why they benefit from the [Wide Compatibility](../use_cases/wide_compatibility.md) mode. + !!! tip All usage examples in this chapter are categorized with appropriate tags to simplify navigation and diff --git a/docs/users_guide/use_cases/wide_compatibility.md b/docs/users_guide/use_cases/wide_compatibility.md new file mode 100644 index 0000000000..5b9f75f241 --- /dev/null +++ b/docs/users_guide/use_cases/wide_compatibility.md @@ -0,0 +1,159 @@ +# Wide Compatibility + +The **mp-units** allows us to implement nice and terse code targeting a specific C++ version and +configuration. Such code is easy to write and understand but might not be portable to some older +environments. + +However, sometimes, we want to develop code that can be compiled on a wide range of various +compilers and configurations. This is why the library also exposes and uses special preprocessor +macros that can be used to ensure the wide compatibility of our code. + +!!! note + + Those macros are used in our short [example applications](../examples/tags_index.md) as those are meant + to be built on all of [the supported compilers](../../getting_started/installation_and_usage.md#cpp-compiler-support). + Some still do not support `std::format`, C++ modules, or C++ versions newer than C++20. + + +## Various compatibility options + +Depending on your compiler's conformance, you can choose to use any of the below styles to write +your code using **mp-units**: + +=== "C++23" + + ```cpp + #include + #include + import mp_units; + + // ... + + inline constexpr struct horizontal_length : quantity_spec {} horizontal_length; + + // ... + + std::cout << std::format(...) << "\n"; + ``` + +=== "C++20" + + ```cpp + #include + #include + import mp_units; + + // ... + + inline constexpr struct horizontal_length : quantity_spec {} horizontal_length; + + // ... + + std::cout << std::format(...) << "\n"; + ``` + +=== "C++20 with header files" + + ```cpp + #include + #include + #include + #include + #include + #include + #include + + // ... + + inline constexpr struct horizontal_length : quantity_spec {} horizontal_length; + + // ... + + std::cout << std::format(...) << "\n"; + ``` + +=== "C++20 with header files + libfmt" + + ```cpp + #include + #include + #include + #include + #include + #include + #include + + // ... + + inline constexpr struct horizontal_length : quantity_spec {} horizontal_length; + + // ... + + std::cout << fmt::format(...) << "\n"; + ``` + +=== "Wide Compatibility" + + ```cpp + #include + #ifdef MP_UNITS_MODULES + #include + import mp_units; + #else + #include + #include + #include + #include + #include + #endif + + // ... + + QUANTITY_SPEC(horizontal_length, isq::length); + + // ... + + std::cout << MP_UNITS_STD_FMT::format(...) << "\n"; + ``` + +!!! tip + + Depending on your preferences, you can either write: + + - terse code directly targeting your specific compiler's abilities, + - verbose code using preprocessor branches and macros that provide the widest compatibility + across various compilers. + + +## Compatibility macros + +This chapter describes only the most essential tools the **mp-units** users need. +All the compatibility macros can be found in the _mp-units/compat_macros.h_ header file. + +!!! tip + + The _mp-units/compat_macros.h_ header file is implicitly included when we use "legacy" headers + in our translation units. However, it has to be explicitly included when we use C++20 modules, + as those do not propagate preprocessor macros. + +### `QUANTITY_SPEC(name, ...)` { #QUANTITY_SPEC } + +Quantity specification definitions benefit from an +[explicit object parameter](https://en.cppreference.com/w/cpp/language/member_functions#Explicit_object_parameter) +added in C++23 to remove the need for CRTP idiom, which significantly simplifies the code. + +This macro benefits from the new C++23 feature if available. Otherwise, it uses the CRTP idiom under +the hood. + +*[CRTP]: Curiously Recurring Template Pattern + +### `MP_UNITS_STD_FMT` + +Some of the supported compilers do not support [std::format](https://en.cppreference.com/w/cpp/utility/format/format) +and related tools. Also, despite using a conformant compiler, some projects still choose to +use [fmtlib](https://github.com/fmtlib/fmt) as their primary formatting facility (e.g., to benefit +from additional features provided with the library). + +This macro resolves to either the `std` or `fmt` namespace, depending on the value of +[MP_UNITS_USE_LIBFMT](../../getting_started/installation_and_usage.md#MP_UNITS_USE_LIBFMT) +CMake option. diff --git a/mkdocs.yml b/mkdocs.yml index 5f685665ee..c60403e197 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -147,6 +147,7 @@ nav: - Using Custom Representation Types: users_guide/use_cases/using_custom_representation_types.md - Interoperability with Other Libraries: users_guide/use_cases/interoperability_with_other_libraries.md - Extending the Library: users_guide/use_cases/extending_the_library.md + - Wide Compatibility: users_guide/use_cases/wide_compatibility.md - Examples: - Tags Index: users_guide/examples/tags_index.md - All Examples: