Skip to content

Commit

Permalink
docs: "Wide Compatibility" chapter added
Browse files Browse the repository at this point in the history
  • Loading branch information
mpusz committed Jan 3, 2024
1 parent f1eec04 commit 376487d
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 0 deletions.
6 changes: 6 additions & 0 deletions docs/users_guide/examples/tags_index.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
159 changes: 159 additions & 0 deletions docs/users_guide/use_cases/wide_compatibility.md
Original file line number Diff line number Diff line change
@@ -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 <format>
#include <iostream>
import mp_units;

// ...

inline constexpr struct horizontal_length : quantity_spec<isq::length> {} horizontal_length;

// ...

std::cout << std::format(...) << "\n";
```

=== "C++20"

```cpp
#include <format>
#include <iostream>
import mp_units;

// ...

inline constexpr struct horizontal_length : quantity_spec<horizontal_length, isq::length> {} horizontal_length;

// ...

std::cout << std::format(...) << "\n";
```

=== "C++20 with header files"

```cpp
#include <mp-units/format.h>
#include <mp-units/ostream.h>
#include <mp-units/systems/international/international.h>
#include <mp-units/systems/isq/isq.h>
#include <mp-units/systems/si/si.h>
#include <format>
#include <iostream>

// ...

inline constexpr struct horizontal_length : quantity_spec<horizontal_length, isq::length> {} horizontal_length;

// ...

std::cout << std::format(...) << "\n";
```

=== "C++20 with header files + libfmt"

```cpp
#include <mp-units/format.h>
#include <mp-units/ostream.h>
#include <mp-units/systems/international/international.h>
#include <mp-units/systems/isq/isq.h>
#include <mp-units/systems/si/si.h>
#include <fmt/format.h>
#include <iostream>

// ...

inline constexpr struct horizontal_length : quantity_spec<horizontal_length, isq::length> {} horizontal_length;

// ...

std::cout << fmt::format(...) << "\n";
```

=== "Wide Compatibility"

```cpp
#include <iostream>
#ifdef MP_UNITS_MODULES
#include <mp-units/compat_macros.h>
import mp_units;
#else
#include <mp-units/format.h>
#include <mp-units/ostream.h>
#include <mp-units/systems/international/international.h>
#include <mp-units/systems/isq/isq.h>
#include <mp-units/systems/si/si.h>
#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.
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down

0 comments on commit 376487d

Please sign in to comment.