Boost logo

Boost :

From: Daniela Engert (dani_at_[hidden])
Date: 2024-07-07 06:56:08


Hi,

what you're describing is the technique what I coined the term "dual
mode support" for in my presentations. I've added it to {fmt} in 2021 to
enable the use of the library as both #include and import; MS-STL
adopted it for their implementation of the standard library

Please take into account that I usually also add something along
xxx_ATTACH_TO_GLOBAL_MODULE (in this case xxx = BOOST) to avoid
potential ODR violations for projects that use a library either as
module or through headers. Otherwise users may end up with conflicting,
but apparently *identical* definitions that they cannot decipher the
reason for: one definition is attached to the named module, the other to
the global module. The compiler will be very upset. Linkers usually work.

Boost libraries that intend to support modules *must* also *add* tests
that check that the exported entities are
 Â  * available on the consumer side
 Â  * instantiation and name lookup works when called from the consumer side

Module implementation units have two relevant interfaces, not one.
Almost all libraries that claim module capability support, and that I've
seen so far, fail to do that. In rare cases I have forks that add this
missing piece.
Lacking those gives users horrible experiences and modules a bad reputation.

On the standard library: *all* C++ implementers of the standard library
have agreed to support C++20 modules also for C++20 build modes. So
you're not tied to C++23.

And lastly, there is BMI compatibility and the story of compiler flags
matching. But that's for a different day.

Dani

Am 06.07.2024 um 14:20 schrieb Antony Polukhin via Boost:
> Hi,
>
> C++20 modules seem to be a good tool to improve compile times and to hide
> the implementation details of the libraries.
>
> I've been looking throught the sources of {fmt} library. Looks like the fmt
> library approach to C++20 modularization seems to fit Boost quite well.
>
> How about adding the following macro to Boost:
> * BOOST_BEGIN_MODULE_EXPORT - starts the scope of things to export if Boost
> is build as a C++20 module
> * BOOST_END_MODULE_EXPORT - ends the scope of things to export if Boost is
> build as a C++20 module
> * BOOST_MODULE_EXPORT - for a single entity export if Boost is build as a
> C++20 module
>
>
> As a result, if Boost is build as a module the above macros are defined in
> the following way:
>
> #define BOOST_MODULE_EXPORT export
> #define BOOST_BEGIN_MODULE_EXPORT export {
> #define BOOST_END_MODULE_EXPORT }
>
> Helper macro BOOST_NO_CXX23_IMPORT_STD for detecting availability of
> `import std` also seems useful.
>
> Macro BOOST_NO_CXX20_MODULES - for notifying the libraries that compiler
> does not support modules or Boost modules are not compiled.
>
> With all the above macros the Boost libraries could look like:
>
> /// header
>
> #include <boost/library_that_is_known_to_not_support_modules.hpp>
>
> #ifdef BOOST_NO_CXX20_MODULES
> #include <boost/library_that_supports_modules.hpp>
> #else
> import Boost.LibraryThatSupportsModules;
> #endif
>
> #ifdef BOOST_NO_CXX23_IMPORT_STD
> #include <iostream>
> #else
> import std;
> #endif
>
> namespace boost {
> namespace detail {
> template <class T>
> bool try_do(const T&);
> }
>
> BOOST_BEGIN_MODULE_EXPORT
>
> template <class T, class From>
> bool try_lexiacal_convert(const From& f, T& to) { /*impl*/ }
>
> template <class T, class From>
> T lexiacal_cast(const From& f) { /*impl*/ }
>
> BOOST_END_MODULE_EXPORT
> }
>
>
> /// module src file
>
> export module Boost.MyLibraryName;
>
> #ifdef BOOST_NO_CXX20_MODULES
> #error ???
> #endif
>
> #include <boost/my_library.hpp>
>
>

-- 
PGP/GPG: 2CCB 3ECB 0954 5CD3 B0DB 6AA0 BA03 56A1 2C4638C5

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk