diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ee6a940..f5dc11d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,6 +17,9 @@ jobs: fail-fast: false matrix: include: + - toolset: gcc-14 # Do not remove! It is the only toolset that tests CMake tests down below + cxxstd: "03,11,14,17,20" + os: ubuntu-24.04 - toolset: gcc-12 cxxstd: "03,11,14,17,2a" os: ubuntu-22.04 @@ -85,9 +88,20 @@ jobs: cp -r $GITHUB_WORKSPACE/* libs/$LIBRARY python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--depth 10 --jobs 3" $LIBRARY ./bootstrap.sh - ./b2 -d0 headers ./b2 -j4 variant=debug tools/inspect + - name: Run CMake tests + if: ${{matrix.toolset == 'gcc-14'}} + run: | + cd ../boost-root/ + mkdir __build + cd __build + cmake -DBUILD_TESTING=1 -DBOOST_INCLUDE_LIBRARIES=type_index -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_C_COMPILER=gcc-14 .. + cmake --build . --target tests + ctest --output-on-failure --no-tests=error + cd .. + rm -rf __build + - name: Run modules tests wihtout 'import std;' if: ${{matrix.toolset == 'clang-19'}} run: | @@ -194,7 +208,21 @@ jobs: git submodule update --init tools/boostdep python tools/boostdep/depinst/depinst.py --include benchmark --include example --include examples --include tools --git_args "--jobs 3" %LIBRARY% cmd /c bootstrap - b2 -d0 headers + + - name: Run CMake 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/ + mkdir __build + cd __build + cmake -DBUILD_TESTING=1 -DBOOST_INCLUDE_LIBRARIES=type_index .. + cmake --build . --target tests --config Debug + ctest --output-on-failure --no-tests=error -C Debug + cd .. + rm -rf __build - name: Run modules tests if: ${{matrix.toolset == 'msvc-14.3'}} diff --git a/CMakeLists.txt b/CMakeLists.txt index ed0601e..0ec3256 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,12 +34,9 @@ target_link_libraries(boost_type_index ${__scope} Boost::config Boost::container_hash - Boost::core Boost::throw_exception ) -if(BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt") - +if(BUILD_TESTING) add_subdirectory(test) - endif() diff --git a/build.jam b/build.jam index 83a486a..7db4e15 100644 --- a/build.jam +++ b/build.jam @@ -8,7 +8,6 @@ require-b2 5.2 ; constant boost_dependencies : /boost/config//boost_config /boost/container_hash//boost_container_hash - /boost/core//boost_core /boost/throw_exception//boost_throw_exception ; project /boost/type_index diff --git a/include/boost/type_index/stl_type_index.hpp b/include/boost/type_index/stl_type_index.hpp index 810339a..38e53cc 100644 --- a/include/boost/type_index/stl_type_index.hpp +++ b/include/boost/type_index/stl_type_index.hpp @@ -30,14 +30,38 @@ #error "File boost/type_index/stl_type_index.ipp is not usable when typeid() is not available." #endif +#if defined(__has_include) +# if __has_include() +# define BOOST_TYPE_INDEX_IMPL_HAS_CXXABI +# endif +#endif + #if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) #include #include // std::strcmp, std::strlen, std::strstr +#include #include +#include #include #include -#include + +#ifdef BOOST_TYPE_INDEX_IMPL_HAS_CXXABI +# include +# include +# include +#endif + +#endif + +// Copied from boost/core/demangle.hpp +#ifdef BOOST_TYPE_INDEX_IMPL_HAS_CXXABI +// For some architectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is implemented by gabi++ library +// (https://android.googlesource.com/platform/ndk/+/master/sources/cxx-stl/gabi++/), which does not implement +// abi::__cxa_demangle(). We detect this implementation by checking the include guard here. +# ifdef __GABIXX_CXXABI_H__ +# undef BOOST_TYPE_INDEX_IMPL_HAS_CXXABI +# endif #endif #ifdef BOOST_HAS_PRAGMA_ONCE @@ -46,6 +70,34 @@ namespace boost { namespace typeindex { +namespace impl { + +#ifdef BOOST_TYPE_INDEX_IMPL_HAS_CXXABI + +inline const char* demangle_alloc(const char* name) noexcept { + int status = 0; + std::size_t size = 0; + return abi::__cxa_demangle(name, NULL, &size, &status); +} + +inline void demangle_free(const void* name) noexcept { + std::free(const_cast(name)); +} + +#else + +inline const char* demangle_alloc(const char* name) noexcept { + return name; +} + +inline void demangle_free(const void* ) noexcept {} + +#endif + +#undef BOOST_TYPE_INDEX_IMPL_HAS_CXXABI + +} // namespace impl + BOOST_TYPE_INDEX_BEGIN_MODULE_EXPORT /// \class stl_type_index @@ -127,7 +179,9 @@ inline std::string stl_type_index::pretty_name() const { // In case of MSVC demangle() is a no-op, and name() already returns demangled name. // In case of GCC and Clang (on non-Windows systems) name() returns mangled name and demangle() undecorates it. - const boost::core::scoped_demangled_name demangled_name(data_->name()); + const std::unique_ptr demangled_name( + impl::demangle_alloc(data_->name()), &impl::demangle_free + ); const char* begin = demangled_name.get(); if (!begin) { @@ -142,7 +196,7 @@ inline std::string stl_type_index::pretty_name() const { if (b) { b += cvr_saver_name_len; - // Trim everuthing till '<'. In modules the name could be boost::typeindex::detail::cvr_saver@boost.type_index< + // Trim everything till '<'. In modules the name could be boost::typeindex::detail::cvr_saver@boost.type_index< while (*b != '<') { // the string is zero terminated, we won't exceed the buffer size ++ b; } diff --git a/modules/boost_type_index.cppm b/modules/boost_type_index.cppm index 37061c1..cd9084e 100644 --- a/modules/boost_type_index.cppm +++ b/modules/boost_type_index.cppm @@ -4,7 +4,7 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // To compile manually use a command like the folowing: -// clang++ -I ../include -std=c++20 --precompile -x c++-module pfr.cppm +// clang++ -I ../include -std=c++20 --precompile -x c++-module boost_type_index.cppm module; @@ -12,14 +12,18 @@ module; #include #include +#if __has_include() +# include +#endif + #include #include #include -#include #include #ifndef BOOST_TYPE_INDEX_USE_STD_MODULE #include +#include #include #include #include diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..40e1e44 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,81 @@ +# Copyright (c) 2016-2025 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(BoostTest OPTIONAL RESULT_VARIABLE HAVE_BOOST_TEST) + +if(NOT HAVE_BOOST_TEST) + return() +endif() + +if(MSVC) + set(BOOST_TYPEINDEX_DETAIL_NO_RTTI "/GR-") + set(BOOST_TYPEINDEX_DETAIL_RTTI "/GR") +else() + set(BOOST_TYPEINDEX_DETAIL_NO_RTTI "-fno-rtti") + set(BOOST_TYPEINDEX_DETAIL_RTTI "-frtti") +endif() + +# Making libraries that CANNOT work between rtti-on/rtti-off modules +add_library(boost_type_index_test_lib_nortti SHARED test_lib.cpp) +target_compile_options(boost_type_index_test_lib_nortti PRIVATE ${BOOST_TYPEINDEX_DETAIL_NO_RTTI}) +target_link_libraries(boost_type_index_test_lib_nortti PRIVATE Boost::type_index) + +add_library(boost_type_index_test_lib_anonymous_nortti SHARED test_lib_anonymous.cpp) +target_compile_options(boost_type_index_test_lib_anonymous_nortti PRIVATE ${BOOST_TYPEINDEX_DETAIL_NO_RTTI}) +target_link_libraries(boost_type_index_test_lib_anonymous_nortti PRIVATE Boost::type_index) + +add_library(boost_type_index_test_lib_rtti SHARED test_lib.cpp) +target_compile_options(boost_type_index_test_lib_rtti PRIVATE ${BOOST_TYPEINDEX_DETAIL_RTTI}) +target_link_libraries(boost_type_index_test_lib_rtti PRIVATE Boost::type_index) + +add_library(boost_type_index_test_lib_anonymous_rtti SHARED test_lib_anonymous.cpp) +target_compile_options(boost_type_index_test_lib_anonymous_rtti PRIVATE ${BOOST_TYPEINDEX_DETAIL_RTTI}) +target_link_libraries(boost_type_index_test_lib_anonymous_rtti PRIVATE Boost::type_index) + +# Making libraries that can work between rtti-on/rtti-off modules +add_library(boost_type_index_test_lib_nortti_compat SHARED test_lib.cpp) +target_compile_options(boost_type_index_test_lib_nortti_compat PRIVATE ${BOOST_TYPEINDEX_DETAIL_NO_RTTI}) +target_compile_definitions(boost_type_index_test_lib_nortti_compat PUBLIC BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY) +target_link_libraries(boost_type_index_test_lib_nortti_compat PRIVATE Boost::type_index) + +add_library(boost_type_index_test_lib_rtti_compat SHARED test_lib.cpp) +target_compile_options(boost_type_index_test_lib_rtti_compat PRIVATE ${BOOST_TYPEINDEX_DETAIL_RTTI}) +target_compile_definitions(boost_type_index_test_lib_rtti_compat PUBLIC BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY) +target_link_libraries(boost_type_index_test_lib_rtti_compat PRIVATE Boost::type_index) + +set(BOOST_TEST_LINK_LIBRARIES Boost::type_index Boost::core) + +boost_test(TYPE run SOURCES type_index_test.cpp) +boost_test(TYPE run SOURCES type_index_runtime_cast_test.cpp LINK_LIBRARIES Boost::smart_ptr) +boost_test(TYPE run SOURCES type_index_constexpr_test.cpp) +boost_test(TYPE run SOURCES type_index_test.cpp COMPILE_OPTIONS -fno-rtti NAME type_index_test_no_rtti) +boost_test(TYPE run SOURCES ctti_print_name.cpp) + +boost_test(TYPE run SOURCES testing_crossmodule.cpp LINK_LIBRARIES boost_type_index_test_lib_rtti) +boost_test(TYPE run SOURCES testing_crossmodule.cpp LINK_LIBRARIES boost_type_index_test_lib_nortti COMPILE_OPTIONS -fno-rtti NAME testing_crossmodule_no_rtti) +boost_test(TYPE run SOURCES testing_crossmodule_anonymous.cpp LINK_LIBRARIES boost_type_index_test_lib_anonymous_rtti) + +boost_test(TYPE run SOURCES compare_ctti_stl.cpp) +boost_test(TYPE run SOURCES track_13621.cpp) + +boost_test(TYPE compile-fail SOURCES type_index_test_ctti_copy_fail.cpp) +boost_test(TYPE compile-fail SOURCES type_index_test_ctti_construct_fail.cpp) +boost_test(TYPE compile SOURCES type_index_test_ctti_alignment.cpp) + +# Mixing RTTI on and off +boost_test(TYPE link-fail SOURCES testing_crossmodule.cpp LINK_LIBRARIES boost_type_index_test_lib_rtti COMPILE_OPTIONS -fno-rtti NAME link_fail_nortti_rtti) +boost_test(TYPE link-fail SOURCES testing_crossmodule.cpp LINK_LIBRARIES boost_type_index_test_lib_nortti NAME link_fail_rtti_nortti) + +boost_test(TYPE run SOURCES testing_crossmodule.cpp LINK_LIBRARIES boost_type_index_test_lib_rtti_compat COMPILE_OPTIONS -fno-rtti NAME testing_crossmodule_nortti_rtti_compat) +boost_test(TYPE run SOURCES testing_crossmodule.cpp LINK_LIBRARIES boost_type_index_test_lib_nortti_compat NAME testing_crossmodule_rtti_nortti_compat) + +file(GLOB EXAMPLE_FILES "../examples/*.cpp") +foreach (testsourcefile ${EXAMPLE_FILES}) + boost_test(TYPE run SOURCES ${testsourcefile} INCLUDE_DIRECTORIES ../examples LINK_LIBRARIES Boost::unordered) + + get_filename_component(testname ${testsourcefile} NAME_WE) + if(NOT testname STREQUAL "table_of_names") + boost_test(TYPE run SOURCES ${testsourcefile} NAME ${testname}_no_rtti COMPILE_OPTIONS -fno-rtti INCLUDE_DIRECTORIES ../examples LINK_LIBRARIES Boost::unordered) + endif() +endforeach()