Skip to content
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
88 changes: 78 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,52 @@ jobs:
matrix:
include:
- toolset: gcc-14 # Do not remove! It is the only toolset that tests CMake tests down below
compiler: g++-14
cxxstd: "03,11,14,17,20"
os: ubuntu-24.04
- toolset: gcc-12
compiler: g++-12
cxxstd: "03,11,14,17,2a"
os: ubuntu-22.04
cxxflags: "cxxflags=--coverage -fsanitize=address,leak,undefined -fno-sanitize-recover=undefined"
linkflags: "linkflags=--coverage -lasan -lubsan"
gcov_tool: "gcov-12"
- toolset: clang
- toolset: clang-14
compiler: clang++-14
cxxstd: "03,11,14,17,2a"
os: ubuntu-22.04
- toolset: clang-19
compiler: clang++-19
cxxstd: "20"
cmake_cxx_standard: ""
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this and next jobs are required to check that using C++20 standard import std is not materialized

os: ubuntu-24.04
install: &cxx19
- clang-19
- llvm-19
- libclang-rt-19-dev
- libc++-19-dev
- libc++abi-19-dev
- clang-tools-19
- toolset: clang-19
compiler: clang++-19
cxxstd: "20"
cmake_cxx_standard: 20
os: ubuntu-24.04
install: *cxx19
- toolset: clang-19
compiler: clang++-19
cxxstd: "23"
cmake_cxx_standard: 23
os: ubuntu-24.04
install: *cxx19
- toolset: clang-19
compiler: clang++-19
cxxstd: "26"
cmake_cxx_standard: 26
os: ubuntu-24.04
install: *cxx19

name: ${{matrix.os}}, ${{matrix.toolset}}, ${{matrix.cxxstd}}

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

Expand All @@ -38,7 +72,7 @@ jobs:

- name: Install packages
if: matrix.install
run: sudo apt install ${{matrix.install}}
run: sudo apt install -y ${{join(matrix.install, ' ')}}

- name: Setup Boost
run: |
Expand All @@ -65,16 +99,50 @@ jobs:
./b2 -j4 variant=debug tools/inspect

- name: Run CMake tests
if: ${{matrix.toolset == 'gcc-14'}}
if: ${{matrix.toolset == 'gcc-14' || matrix.toolset == 'clang-19'}}
run: |
cd ../boost-root/
mkdir __build
cd __build
cmake -DBUILD_TESTING=1 -DBOOST_INCLUDE_LIBRARIES=conversion -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_C_COMPILER=gcc-14 ..
cmake --build . --target tests
ctest --output-on-failure --no-tests=error
cd ..
cmake -S . -B __build \
-DBUILD_TESTING=1 \
-DBOOST_INCLUDE_LIBRARIES=conversion \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
${{ matrix.cmake_cxx_standard != '' && format('-DCMAKE_CXX_STANDARD={0}', matrix.cmake_cxx_standard) || '' }}
cmake --build __build --target tests
ctest --test-dir __build --output-on-failure --no-tests=error
rm -rf __build

- name: Run modules tests
if: ${{matrix.toolset == 'clang-19'}}
run: |
cd ../boost-root/libs/$LIBRARY
cmake -S test/cmake_subdir_test \
-B build_module \
-GNinja \
-DBOOST_USE_MODULES=1 \
-DBUILD_TESTING=1 \
${{ matrix.cmake_cxx_standard != '' && format('-DCMAKE_CXX_STANDARD={0}', matrix.cmake_cxx_standard) || '' }} \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}} \
-DCMAKE_CXX_MODULE_STD=ON \
-DCMAKE_EXPERIMENTAL_CXX_IMPORT_STD=0e5b6991-d74f-4b3d-a41c-cf096e0b2508 \
-DCMAKE_CXX_FLAGS=-stdlib=libc++
cmake --build build_module
ctest --test-dir build_module -VV
rm -rf build_module

- name: Run modules tests without 'import std;'
if: ${{matrix.toolset == 'clang-19'}}
run: |
cd ../boost-root/libs/$LIBRARY
cmake -S test/cmake_subdir_test \
-B build_module \
-GNinja \
-DBOOST_USE_MODULES=1 \
-DBUILD_TESTING=1 \
${{ matrix.cmake_cxx_standard != '' && format('-DCMAKE_CXX_STANDARD={0}', matrix.cmake_cxx_standard) || '' }} \
-DCMAKE_CXX_COMPILER=${{matrix.compiler}}
cmake --build build_module
ctest --test-dir build_module -VV
rm -rf build_module

- name: Run tests
run: |
Expand All @@ -95,7 +163,7 @@ jobs:

echo "$LCOV --directory ../boost-root/bin.v2/libs/$LIBRARY/ --base-directory `pwd`/libs/$LIBRARY/test --capture --output-file $GITHUB_WORKSPACE/coveralls/coverage.info"
$LCOV --directory ../boost-root/bin.v2/libs/$LIBRARY/ --base-directory ../boost-root/ --capture --output-file $GITHUB_WORKSPACE/coveralls/coverage.info
$LCOV --remove $GITHUB_WORKSPACE/coveralls/coverage.info "/usr*" "*/$LIBRARY/test/*" ${{matrix.ignore_coverage}} "*/$LIBRARY/tests/*" "*/$LIBRARY/examples/*" "*/$LIBRARY/example/*" -o $GITHUB_WORKSPACE/coveralls/coverage.info
$LCOV --remove $GITHUB_WORKSPACE/coveralls/coverage.info "/usr*" "*/$LIBRARY/test/*" "*/$LIBRARY/tests/*" "*/$LIBRARY/examples/*" "*/$LIBRARY/example/*" -o $GITHUB_WORKSPACE/coveralls/coverage.info

cd ../boost-root
OTHER_LIBS=`grep "submodule .*" .gitmodules | sed 's/\[submodule\ "\(.*\)"\]/"\*\/boost\/\1\.hpp" "\*\/boost\/\1\/\*"/g'| sed "/\"\*\/boost\/$LIBRARY\/\*\"/d" | sed ':a;N;$!ba;s/\n/ /g'`
Expand Down
38 changes: 31 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +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...4.20 )
project( boost_conversion VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX )
cmake_minimum_required(VERSION 3.5...4.20)
project(boost_conversion VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)

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

target_include_directories( boost_conversion INTERFACE include )
target_compile_features(boost_conversion PUBLIC cxx_std_20)
target_compile_definitions(boost_conversion PUBLIC BOOST_USE_MODULES)
get_property(__standard TARGET boost_conversion PROPERTY CXX_STANDARD)
if (__standard IN_LIST CMAKE_CXX_COMPILER_IMPORT_STD)
target_compile_definitions(boost_conversion PRIVATE BOOST_CONVERSION_USE_STD_MODULE)
message(STATUS "Using `import std;`")
else()
message(STATUS "`import std;` is not available")
endif()
unset(__standard)
set(__scope PUBLIC)
else()
add_library(boost_conversion INTERFACE)
set(__scope INTERFACE)
endif()

target_include_directories(boost_conversion ${__scope} include)
add_library(Boost::conversion ALIAS boost_conversion)

target_link_libraries( boost_conversion
INTERFACE
target_link_libraries(boost_conversion
${__scope}
Boost::assert
Boost::config
Boost::throw_exception
Boost::smart_ptr
)

if(BUILD_TESTING)
Expand Down
28 changes: 28 additions & 0 deletions include/boost/conversion/detail/config.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) 2016-2026 Antony Polukhin
//
// 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_CONVERSION_DETAIL_CONFIG_HPP
#define BOOST_CONVERSION_DETAIL_CONFIG_HPP

#if !defined(BOOST_CONVERSION_INTERFACE_UNIT)
# include <boost/config.hpp>
# ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
# endif
#endif

#ifdef BOOST_CONVERSION_INTERFACE_UNIT
# define BOOST_CONVERSION_BEGIN_MODULE_EXPORT export {
# define BOOST_CONVERSION_END_MODULE_EXPORT }
#else
# define BOOST_CONVERSION_BEGIN_MODULE_EXPORT
# define BOOST_CONVERSION_END_MODULE_EXPORT
#endif

#if defined(BOOST_USE_MODULES) && !defined(BOOST_CONVERSION_INTERFACE_UNIT)
import boost.conversion;
#endif

#endif
10 changes: 9 additions & 1 deletion include/boost/implicit_cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
#ifndef BOOST_IMPLICIT_CAST_DWA200356_HPP
#define BOOST_IMPLICIT_CAST_DWA200356_HPP

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

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

#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif
Expand All @@ -22,6 +25,8 @@ template<class T> struct icast_identity

} // namespace detail

BOOST_CONVERSION_BEGIN_MODULE_EXPORT

// implementation originally suggested by C. Green in
// http://lists.boost.org/MailArchives/boost/msg00886.php

Expand All @@ -32,7 +37,10 @@ constexpr T implicit_cast (typename boost::detail::icast_identity<T>::type x) {
return x;
}

BOOST_CONVERSION_END_MODULE_EXPORT

} // namespace boost

#endif // !defined(BOOST_USE_MODULES) || defined(BOOST_CONVERSION_INTERFACE_UNIT)

#endif // BOOST_IMPLICIT_CAST_DWA200356_HPP
12 changes: 11 additions & 1 deletion include/boost/polymorphic_cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,31 @@
#ifndef BOOST_POLYMORPHIC_CAST_HPP
#define BOOST_POLYMORPHIC_CAST_HPP

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

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

#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif

#if !defined(BOOST_CONVERSION_INTERFACE_UNIT)
# include <boost/assert.hpp>
# include <boost/throw_exception.hpp>

# include <memory> // std::addressof
# include <typeinfo>
# include <type_traits>
#endif

#if defined(__cpp_constexpr) && __cpp_constexpr >= 201907L
#define BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST constexpr
#else
#define BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST inline
#endif

BOOST_CONVERSION_BEGIN_MODULE_EXPORT

namespace boost
{
// See the documentation for descriptions of how to choose between
Expand Down Expand Up @@ -125,8 +131,12 @@ namespace boost
);
}

BOOST_CONVERSION_END_MODULE_EXPORT

} // namespace boost

#undef BOOST_CONVERSION_IMPL_CONSTEXPR_DYN_CAST

#endif // !defined(BOOST_USE_MODULES) || defined(BOOST_CONVERSION_INTERFACE_UNIT)

#endif // BOOST_POLYMORPHIC_CAST_HPP
12 changes: 10 additions & 2 deletions include/boost/polymorphic_pointer_cast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,21 @@
#ifndef BOOST_CONVERSION_POLYMORPHIC_POINTER_CAST_HPP
#define BOOST_CONVERSION_POLYMORPHIC_POINTER_CAST_HPP

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

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

#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif

#if !defined(BOOST_CONVERSION_INTERFACE_UNIT)
# include <boost/assert.hpp>
# include <boost/pointer_cast.hpp>
# include <boost/throw_exception.hpp>
#endif


BOOST_CONVERSION_BEGIN_MODULE_EXPORT
namespace boost
{
// See the documentation for descriptions of how to choose between
Expand Down Expand Up @@ -56,5 +61,8 @@ namespace boost
}

} // namespace boost
BOOST_CONVERSION_END_MODULE_EXPORT

#endif // !defined(BOOST_USE_MODULES) || defined(BOOST_CONVERSION_INTERFACE_UNIT)

#endif // BOOST_CONVERSION_POLYMORPHIC_POINTER_CAST_HPP
33 changes: 33 additions & 0 deletions modules/boost_conversion.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) 2016-2026 Antony Polukhin
//
// 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)

module;

#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include <boost/assert.hpp>
#include <boost/pointer_cast.hpp>

#ifndef BOOST_CONVERSION_USE_STD_MODULE
#include <memory>
#include <typeinfo>
#include <type_traits>
#endif

#define BOOST_CONVERSION_INTERFACE_UNIT

export module boost.conversion;

#ifdef BOOST_CONVERSION_USE_STD_MODULE
import std;
#endif

#ifdef __clang__
# pragma clang diagnostic ignored "-Winclude-angled-in-module-purview"
#endif

#include <boost/implicit_cast.hpp>
#include <boost/polymorphic_cast.hpp>
#include <boost/polymorphic_pointer_cast.hpp>
36 changes: 36 additions & 0 deletions modules/usage_sample.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) 2016-2026 Antony Polukhin
//
// 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)

#include <iostream>
#include <memory>
#include <string>

import boost.conversion;

namespace {

struct Base {
virtual ~Base() = default;
virtual std::string name() const {
return "base";
}
};

struct Derived : Base {
std::string name() const override {
return "derived";
}
};

}

int main() {
std::cerr << boost::implicit_cast<long>(42) << '\n';

std::unique_ptr<Base> base = std::make_unique<Derived>();
std::cerr << boost::polymorphic_downcast<Derived&>(*base).name() << '\n';

return 0;
}
Loading