Skip to content

Implement initial version of C++20 module boost.any #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ jobs:
compiler: clang++-14
cxxstd: "03,11,14,17,2a"
os: ubuntu-22.04
- toolset: clang-19
cxxstd: "20,23"
os: ubuntu-24.04
install: clang-19 llvm-19 libclang-rt-19-dev libc++-19-dev libc++abi-19-dev clang-tools-19
# - toolset: clang
# cxxstd: "03,11,14,17,2a"
# os: macos-10.15
Expand Down Expand Up @@ -67,6 +71,31 @@ jobs:
./b2 -d0 headers
./b2 -j4 variant=debug tools/inspect/build

- name: Run modules tests wihtout 'import std;'
if: ${{matrix.toolset == 'clang-19'}}
run: |
cd ../boost-root/libs/any
mkdir build_module
cd build_module
cmake -DBOOST_USE_MODULES=1 -DBUILD_TESTING=1 -GNinja -DCMAKE_CXX_COMPILER=clang++-19 ../test/cmake_subdir_test/
cmake --build .
ctest -V
cd ..
rm -rf build_module

- name: Run modules tests
if: false
# if: ${{matrix.toolset == 'clang-19'}}
run: |
cd ../boost-root/libs/any
mkdir build_module
cd build_module
cmake -DBUILD_TESTING=1 -DBOOST_USE_MODULES=1 -DCMAKE_CXX_COMPILER=clang++-19 -DCMAKE_CXX_FLAGS=-stdlib=libc++ -DCMAKE_EXE_LINKER_FLAGS=-stdlib=libc++ -DCMAKE_CXX_STANDARD=23 -DCMAKE_EXPERIMENTAL_CXX_IMPORT_STD=0e5b6991-d74f-4b3d-a41c-cf096e0b2508 -G Ninja ../test/cmake_subdir_test/
cmake --build .
ctest -V
cd ..
rm -rf build_module

- name: Run tests
run: |
cd ../boost-root
Expand Down Expand Up @@ -114,6 +143,10 @@ jobs:
cxxstd: "03,11,14,17,2a"
addrmd: 64
os: windows-2019
- toolset: msvc-14.3
cxxstd: "14,17,20,latest"
addrmd: 32,64
os: windows-2022

runs-on: ${{matrix.os}}

Expand Down Expand Up @@ -142,6 +175,36 @@ jobs:
cmd /c bootstrap
b2 -d0 headers

- name: Run modules tests
if: ${{matrix.toolset == 'msvc-14.3'}}
shell: cmd
run: |
choco install --no-progress ninja
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvarsall.bat" x64
cd ../boost-root/libs/any
mkdir build_module
cd build_module
cmake -DBOOST_USE_MODULES=1 -DBUILD_TESTING=1 -DCMAKE_CXX_STANDARD=23 -DCMAKE_EXPERIMENTAL_CXX_IMPORT_STD=0e5b6991-d74f-4b3d-a41c-cf096e0b2508 -G Ninja ../test/cmake_subdir_test/
cmake --build .
ctest --no-tests=error -V
cd ..
rm -rf build_module

- name: Run modules tests wihtout 'import std;'
if: ${{matrix.toolset == 'msvc-14.3'}}
shell: cmd
run: |
choco install --no-progress ninja
call "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvarsall.bat" x64
cd ../boost-root/libs/any
mkdir build_module
cd build_module
cmake -DBOOST_USE_MODULES=1 -DBUILD_TESTING=1 -DCMAKE_CXX_STANDARD=20 -G Ninja ../test/cmake_subdir_test/
cmake --build .
ctest --no-tests=error -V
cd ..
rm -rf build_module

- name: Run tests
shell: cmd
run: |
Expand Down
36 changes: 31 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,43 @@
# Distributed under the Boost Software License, Version 1.0.
# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt

cmake_minimum_required( VERSION 3.5...3.20 )
cmake_minimum_required( VERSION 3.5...3.31 )
project( boost_any VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX )

add_library( boost_any INTERFACE )
add_library( Boost::any ALIAS boost_any )
if (BOOST_USE_MODULES)
add_library(boost_any)
target_sources(boost_any PUBLIC
FILE_SET modules_public TYPE CXX_MODULES FILES
${CMAKE_CURRENT_LIST_DIR}/modules/boost_any.cppm
)

target_include_directories( boost_any INTERFACE include )
target_compile_features(boost_any PUBLIC cxx_std_20)
target_compile_definitions(boost_any PUBLIC BOOST_USE_MODULES)
if (CMAKE_CXX_COMPILER_IMPORT_STD)
target_compile_definitions(boost_any PRIVATE BOOST_ANY_USE_STD_MODULE)
message(STATUS "Using `import std;`")
else()
message(STATUS "`import std;` is not awailable")
endif()
set(__scope PUBLIC)
else()
add_library(boost_any INTERFACE)
set(__scope INTERFACE)
endif()

target_include_directories(boost_any ${__scope} include)
target_link_libraries( boost_any
INTERFACE
${__scope}
Boost::config
Boost::throw_exception
Boost::type_index
)

add_library( Boost::any ALIAS boost_any )

enable_testing()
if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")

add_subdirectory(test)

endif()
34 changes: 34 additions & 0 deletions doc/any.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,40 @@ The specific requirements on value types to be used in an

[endsect]

[section C++20 module]

[caution C++20 module support is on early stage, targets, flags and behavior may change in the future]

If using modern CMake define CMake option `-DBOOST_USE_MODULES=1` to build a C++20 module and
make the `Boost::any` CMake target provide it. After that an explicit usage of C++20 module `boost.any` is allowed:

[import ../modules/usage_sample.cpp]
[any_module_example]

The `Boost::any` CMake target gives an ability to mix includes and imports of the library in different translation units. Moreover,
if `BOOST_USE_MODULES` macro is defined then all the `boost/any...` includes implicilty do `import boost.any;` to give all the
benifits of modules without changing the existing code.

[note For better compile times make sure that `import std;` is available when building the `boost.any` module (in CMake logs there should be
a 'Using `import std;`' message). ]

If not using CMake, then the module could be build manually from the `modules/boost_any.cppm` file.

For manual module build the following commands could be used for clang compiler:

```
cd any/modules
clang++ -I ../include -std=c++20 --precompile -x c++-module boost_any.cppm
```

After that, the module could be used in the following way:

```
clang++ -std=c++20 -fmodule-file=boost_any.pcm boost_any.pcm usage_sample.cpp
```

[endsect]

[xinclude autodoc_any.xml]

[section Acknowledgements]
Expand Down
31 changes: 23 additions & 8 deletions include/boost/any.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,26 @@
#ifndef BOOST_ANY_INCLUDED
#define BOOST_ANY_INCLUDED

#include <boost/any/detail/config.hpp>

#if !defined(BOOST_USE_MODULES) || defined(BOOST_ANY_INTERFACE_UNIT)

/// \file boost/any.hpp
/// \brief \copybrief boost::any

#ifndef BOOST_ANY_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif

/// \file boost/any.hpp
/// \brief \copybrief boost::any
#include <memory> // for std::addressof
#include <type_traits>

#include <boost/throw_exception.hpp>
#include <boost/type_index.hpp>

#endif // #ifndef BOOST_ANY_INTERFACE_UNIT

// what: variant type boost::any
// who: contributed by Kevlin Henney,
Expand All @@ -21,14 +34,11 @@
#include <boost/any/bad_any_cast.hpp>
#include <boost/any/fwd.hpp>
#include <boost/any/detail/placeholder.hpp>
#include <boost/throw_exception.hpp>
#include <boost/type_index.hpp>

#include <memory> // for std::addressof
#include <type_traits>
namespace boost {

BOOST_ANY_BEGIN_MODULE_EXPORT

namespace boost
{
/// \brief A class whose instances can hold instances of any
/// type that satisfies \forcedlink{ValueType} requirements.
class any
Expand Down Expand Up @@ -355,6 +365,9 @@ namespace boost
);
return boost::any_cast<ValueType>(operand);
}

BOOST_ANY_END_MODULE_EXPORT

}

// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
Expand All @@ -364,4 +377,6 @@ namespace boost
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_ANY_INTERFACE_UNIT)

#endif
11 changes: 11 additions & 0 deletions include/boost/any/bad_any_cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
#ifndef BOOST_ANYS_BAD_ANY_CAST_HPP_INCLUDED
#define BOOST_ANYS_BAD_ANY_CAST_HPP_INCLUDED

#include <boost/any/detail/config.hpp>

#if !defined(BOOST_USE_MODULES) || defined(BOOST_ANY_INTERFACE_UNIT)

#ifndef BOOST_ANY_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
Expand All @@ -19,9 +24,12 @@
#endif

#include <stdexcept>
#endif // #ifndef BOOST_ANY_INTERFACE_UNIT

namespace boost {

BOOST_ANY_BEGIN_MODULE_EXPORT

/// The exception thrown in the event of a failed boost::any_cast of
/// an boost::any, boost::anys::basic_any or boost::anys::unique_any value.
class BOOST_SYMBOL_VISIBLE bad_any_cast :
Expand All @@ -39,7 +47,10 @@ class BOOST_SYMBOL_VISIBLE bad_any_cast :
}
};

BOOST_ANY_END_MODULE_EXPORT

} // namespace boost

#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_ANY_INTERFACE_UNIT)

#endif // #ifndef BOOST_ANYS_BAD_ANY_CAST_HPP_INCLUDED
30 changes: 23 additions & 7 deletions include/boost/any/basic_any.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,36 @@
#ifndef BOOST_ANYS_BASIC_ANY_HPP_INCLUDED
#define BOOST_ANYS_BASIC_ANY_HPP_INCLUDED

#include <boost/any/detail/config.hpp>

#if !defined(BOOST_USE_MODULES) || defined(BOOST_ANY_INTERFACE_UNIT)

/// \file boost/any/basic_any.hpp
/// \brief \copybrief boost::anys::basic_any

#ifndef BOOST_ANY_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif

/// \file boost/any/basic_any.hpp
/// \brief \copybrief boost::anys::basic_any
#include <memory> // for std::addressof
#include <type_traits>

#include <boost/any/bad_any_cast.hpp>
#include <boost/any/fwd.hpp>
#include <boost/assert.hpp>
#include <boost/type_index.hpp>
#include <boost/throw_exception.hpp>
#endif // #ifndef BOOST_ANY_INTERFACE_UNIT

#include <memory> // for std::addressof
#include <type_traits>

#include <boost/any/bad_any_cast.hpp>
#include <boost/any/fwd.hpp>

namespace boost {

namespace anys {

BOOST_ANY_BEGIN_MODULE_EXPORT

/// \brief A class with customizable Small Object Optimization whose
/// instances can hold instances of any type that satisfies
/// \forcedlink{ValueType} requirements. Use boost::any instead if not sure.
Expand Down Expand Up @@ -546,11 +554,19 @@ namespace anys {
}
/// @endcond

BOOST_ANY_END_MODULE_EXPORT

} // namespace anys

BOOST_ANY_BEGIN_MODULE_EXPORT

using boost::anys::any_cast;
using boost::anys::unsafe_any_cast;

BOOST_ANY_END_MODULE_EXPORT

} // namespace boost

#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_ANY_INTERFACE_UNIT)

#endif // #ifndef BOOST_ANYS_BASIC_ANY_HPP_INCLUDED
22 changes: 22 additions & 0 deletions include/boost/any/detail/config.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright Antony Polukhin, 2021-2025.
//
// 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)

#ifndef BOOST_ANY_ANYS_DETAIL_CONFIG_HPP
#define BOOST_ANY_ANYS_DETAIL_CONFIG_HPP

#ifdef BOOST_ANY_INTERFACE_UNIT
# define BOOST_ANY_BEGIN_MODULE_EXPORT export {
# define BOOST_ANY_END_MODULE_EXPORT }
#else
# define BOOST_ANY_BEGIN_MODULE_EXPORT
# define BOOST_ANY_END_MODULE_EXPORT
#endif

#if defined(BOOST_USE_MODULES) && !defined(BOOST_ANY_INTERFACE_UNIT)
import boost.any;
#endif

#endif // #ifndef BOOST_ANY_ANYS_DETAIL_CONFIG_HPP
8 changes: 8 additions & 0 deletions include/boost/any/detail/placeholder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,18 @@
#ifndef BOOST_ANY_ANYS_DETAIL_PLACEHOLDER_HPP
#define BOOST_ANY_ANYS_DETAIL_PLACEHOLDER_HPP

#include <boost/any/detail/config.hpp>

#if !defined(BOOST_USE_MODULES) || defined(BOOST_ANY_INTERFACE_UNIT)

#ifndef BOOST_ANY_INTERFACE_UNIT
#include <boost/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif

#include <boost/type_index.hpp>
#endif

/// @cond
namespace boost {
Expand All @@ -30,4 +36,6 @@ class BOOST_SYMBOL_VISIBLE placeholder {
} // namespace boost
/// @endcond

#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_ANY_INTERFACE_UNIT)

#endif // #ifndef BOOST_ANY_ANYS_DETAIL_PLACEHOLDER_HPP
Loading