mirror of
https://github.com/boostorg/type_index.git
synced 2025-06-24 19:41:39 +02:00
Implement initial version of C++20 module boost.type_index
(#15)
`#include <boost/type_index...` is now implicitly does `import boost.type_index` if the modules are supported All the library internals now have unconditional module level linkage. Significant differences from https://anarthal.github.io/cppblog/modules3: * `BOOST_TYPE_INDEX_USE_STD_MODULE` macro switch for `import std;` / `includes` while building module. This allows to use module in C++20 and even without usable `std` module.
This commit is contained in:
63
.github/workflows/ci.yml
vendored
63
.github/workflows/ci.yml
vendored
@ -49,10 +49,10 @@ jobs:
|
||||
compiler: clang++-14
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-22.04
|
||||
- toolset: clang
|
||||
compiler: clang++-10
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: ubuntu-20.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
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
@ -88,6 +88,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/type_index
|
||||
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/type_index
|
||||
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
|
||||
@ -175,6 +200,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/type_index
|
||||
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 without '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/type_index
|
||||
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: |
|
||||
|
@ -3,17 +3,35 @@
|
||||
# Distributed under the Boost Software License, Version 1.0.
|
||||
# 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_type_index VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)
|
||||
|
||||
add_library(boost_type_index INTERFACE)
|
||||
if (BOOST_USE_MODULES)
|
||||
add_library(boost_type_index)
|
||||
target_sources(boost_type_index PUBLIC
|
||||
FILE_SET modules_public TYPE CXX_MODULES FILES modules/boost_type_index.cppm
|
||||
)
|
||||
|
||||
target_compile_features(boost_type_index PUBLIC cxx_std_20)
|
||||
target_compile_definitions(boost_type_index PUBLIC BOOST_USE_MODULES)
|
||||
if (CMAKE_CXX_COMPILER_IMPORT_STD)
|
||||
target_compile_definitions(boost_type_index PRIVATE BOOST_TYPE_INDEX_USE_STD_MODULE)
|
||||
message(STATUS "Using `import std;`")
|
||||
else()
|
||||
message(STATUS "`import std;` is not awailable")
|
||||
endif()
|
||||
set(__scope PUBLIC)
|
||||
else()
|
||||
add_library(boost_type_index INTERFACE)
|
||||
set(__scope INTERFACE)
|
||||
endif()
|
||||
|
||||
target_include_directories(boost_type_index ${__scope} include)
|
||||
add_library(Boost::type_index ALIAS boost_type_index)
|
||||
|
||||
target_include_directories(boost_type_index INTERFACE include)
|
||||
|
||||
target_link_libraries(boost_type_index
|
||||
INTERFACE
|
||||
${__scope}
|
||||
Boost::config
|
||||
Boost::container_hash
|
||||
Boost::core
|
||||
|
@ -1,6 +1,6 @@
|
||||
[library Boost.TypeIndex
|
||||
[quickbook 1.6]
|
||||
[version 4.1]
|
||||
[version 4.2]
|
||||
[copyright 2012-2025 Antony Polukhin]
|
||||
[category Language Features Emulation]
|
||||
[license
|
||||
@ -314,6 +314,40 @@ Sometimes there may be a need to create your own type info system. This may be u
|
||||
|
||||
[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::type_index` CMake target provide it. After that an explicit usage of C++20 module `boost.type_index` is allowed:
|
||||
|
||||
[import ../modules/usage_sample.cpp]
|
||||
[type_index_module_example]
|
||||
|
||||
The `Boost::type_index` 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/type_index/...` includes implicilty do `import boost.type_index;` 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.type_index` 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_type_index.cppm` file.
|
||||
|
||||
For manual module build the following commands can be used for clang compiler:
|
||||
|
||||
```
|
||||
cd type_index/modules
|
||||
clang++ -I ../include -std=c++20 --precompile -x c++-module boost_type_index.cppm
|
||||
```
|
||||
|
||||
After that, the module could be used in the following way:
|
||||
|
||||
```
|
||||
clang++ -std=c++20 -fmodule-file=boost_type_index.pcm boost_type_index.pcm usage_sample.cpp
|
||||
```
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section Space and Performance]
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
/// By inclusion of this file most optimal type index classes will be included and used
|
||||
/// as a boost::typeindex::type_index and boost::typeindex::type_info.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_index/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
@ -49,8 +49,12 @@
|
||||
#define BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
BOOST_TYPE_INDEX_BEGIN_MODULE_EXPORT
|
||||
|
||||
#if defined(BOOST_TYPE_INDEX_DOXYGEN_INVOKED)
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_FUNCTION_SIGNATURE
|
||||
@ -257,9 +261,11 @@ inline type_index type_id_runtime(const T& runtime_val) noexcept {
|
||||
return type_index::type_id_runtime(runtime_val);
|
||||
}
|
||||
|
||||
BOOST_TYPE_INDEX_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
|
||||
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_HPP
|
||||
|
||||
|
@ -18,12 +18,19 @@
|
||||
/// It is used in situations when typeid() method is not available or
|
||||
/// BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro is defined.
|
||||
|
||||
#include <boost/type_index/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#include <boost/type_index/type_index_facade.hpp>
|
||||
#include <boost/type_index/detail/compile_time_type_info.hpp>
|
||||
|
||||
#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
@ -64,6 +71,8 @@ public:
|
||||
|
||||
} // namespace detail
|
||||
|
||||
BOOST_TYPE_INDEX_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// Helper method for getting detail::ctti_data of a template parameter T.
|
||||
template <class T>
|
||||
inline const detail::ctti_data& ctti_construct() noexcept {
|
||||
@ -132,6 +141,8 @@ public:
|
||||
inline static ctti_type_index type_id_runtime(const T& variable) noexcept;
|
||||
};
|
||||
|
||||
BOOST_TYPE_INDEX_END_MODULE_EXPORT
|
||||
|
||||
|
||||
inline const ctti_type_index::type_info_t& ctti_type_index::type_info() const noexcept {
|
||||
return *reinterpret_cast<const detail::ctti_data*>(data_);
|
||||
@ -197,8 +208,9 @@ inline std::size_t ctti_type_index::hash_code() const noexcept {
|
||||
return boost::hash_range(raw_name(), raw_name() + get_raw_name_length());
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_CTTI_TYPE_INDEX_HPP
|
||||
|
||||
|
@ -13,10 +13,12 @@
|
||||
/// \brief Contains helper macros and implementation details of boost::typeindex::ctti_type_index.
|
||||
/// Not intended for inclusion from user's code.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_index/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
|
32
include/boost/type_index/detail/config.hpp
Normal file
32
include/boost/type_index/detail/config.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
//
|
||||
// Copyright 2013-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)
|
||||
//
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_DETAIL_CONFIG_HPP
|
||||
#define BOOST_TYPE_INDEX_DETAIL_CONFIG_HPP
|
||||
|
||||
#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
#include <boost/config.hpp>
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_TYPE_INDEX_INTERFACE_UNIT
|
||||
# define BOOST_TYPE_INDEX_BEGIN_MODULE_EXPORT export {
|
||||
# define BOOST_TYPE_INDEX_END_MODULE_EXPORT }
|
||||
#else
|
||||
# define BOOST_TYPE_INDEX_BEGIN_MODULE_EXPORT
|
||||
# define BOOST_TYPE_INDEX_END_MODULE_EXPORT
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_USE_MODULES) && !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
import boost.type_index;
|
||||
#endif
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_DETAIL_CONFIG_HPP
|
||||
|
@ -19,15 +19,23 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
namespace boost { namespace typeindex { namespace detail {
|
||||
|
||||
BOOST_TYPE_INDEX_BEGIN_MODULE_EXPORT
|
||||
|
||||
template <class T>
|
||||
inline const ctti_data& ctti_construct_typeid_ref(const T*) noexcept {
|
||||
return boost::typeindex::ctti_construct<T>();
|
||||
}
|
||||
|
||||
BOOST_TYPE_INDEX_END_MODULE_EXPORT
|
||||
|
||||
}}} // namespace boost::typeindex::detail
|
||||
|
||||
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
/// @cond
|
||||
#define BOOST_TYPE_INDEX_REGISTER_CLASS \
|
||||
virtual const boost::typeindex::detail::ctti_data& boost_type_index_type_id_runtime_() const noexcept { \
|
||||
|
@ -19,15 +19,23 @@
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
namespace boost { namespace typeindex { namespace detail {
|
||||
|
||||
BOOST_TYPE_INDEX_BEGIN_MODULE_EXPORT
|
||||
|
||||
template <class T>
|
||||
inline const stl_type_index::type_info_t& stl_construct_typeid_ref(const T*) noexcept {
|
||||
return typeid(T);
|
||||
}
|
||||
|
||||
BOOST_TYPE_INDEX_END_MODULE_EXPORT
|
||||
|
||||
}}} // namespace boost::typeindex::detail
|
||||
|
||||
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
/// @cond
|
||||
#define BOOST_TYPE_INDEX_REGISTER_CLASS \
|
||||
virtual const boost::typeindex::stl_type_index::type_info_t& boost_type_index_type_id_runtime_() const noexcept { \
|
||||
|
@ -9,6 +9,8 @@
|
||||
#ifndef BOOST_TYPE_INDEX_RUNTIME_CAST_HPP
|
||||
#define BOOST_TYPE_INDEX_RUNTIME_CAST_HPP
|
||||
|
||||
#include <boost/type_index/detail/config.hpp>
|
||||
|
||||
/// \file runtime_cast.hpp
|
||||
/// \brief Contains the basic utilities necessary to fully emulate
|
||||
/// dynamic_cast for language level constructs (raw pointers and references).
|
||||
|
@ -13,21 +13,25 @@
|
||||
/// \brief Contains the overload of boost::typeindex::runtime_pointer_cast for
|
||||
/// boost::shared_ptr types.
|
||||
|
||||
#include <boost/type_index/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#include <boost/type_index/runtime_cast/detail/runtime_cast_impl.hpp>
|
||||
|
||||
#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
template<class T> class shared_ptr;
|
||||
}
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
/// \brief Creates a new instance of std::shared_ptr whose stored pointer is obtained from u's
|
||||
BOOST_TYPE_INDEX_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// \brief Creates a new instance of smart pointer whose stored pointer is obtained from u's
|
||||
/// stored pointer using a runtime_cast.
|
||||
///
|
||||
/// The new shared_ptr will share ownership with u, except that it is empty if the runtime_cast
|
||||
@ -37,14 +41,18 @@ namespace boost { namespace typeindex {
|
||||
/// \return If there exists a valid conversion from U* to T*, returns a boost::shared_ptr<T>
|
||||
/// that points to an address suitably offset from u.
|
||||
/// If no such conversion exists, returns boost::shared_ptr<T>();
|
||||
template<typename T, typename U>
|
||||
boost::shared_ptr<T> runtime_pointer_cast(boost::shared_ptr<U> const& u) {
|
||||
template<typename T, typename U, template <class> class SmartPointer>
|
||||
auto runtime_pointer_cast(SmartPointer<U> const& u) -> decltype(u.use_count(), SmartPointer<T>()) {
|
||||
T* value = detail::runtime_cast_impl<T>(u.get(), std::is_base_of<T, U>());
|
||||
if(value)
|
||||
return boost::shared_ptr<T>(u, value);
|
||||
return boost::shared_ptr<T>();
|
||||
return SmartPointer<T>(u, value);
|
||||
return SmartPointer<T>();
|
||||
}
|
||||
|
||||
BOOST_TYPE_INDEX_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_RUNTIME_CAST_BOOST_SHARED_PTR_CAST_HPP
|
||||
|
@ -19,7 +19,9 @@
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
|
||||
#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
|
@ -12,16 +12,22 @@
|
||||
/// \file pointer_class.hpp
|
||||
/// \brief Contains the function overloads of boost::typeindex::runtime_cast for
|
||||
/// pointer types.
|
||||
|
||||
#include <boost/type_index/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/type_index/runtime_cast/detail/runtime_cast_impl.hpp>
|
||||
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
BOOST_TYPE_INDEX_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// \brief Safely converts pointers to classes up, down, and sideways along the inheritance hierarchy.
|
||||
/// \tparam T The desired target type. Like dynamic_cast, must be a pointer to complete class type.
|
||||
/// \tparam U A complete class type of the source instance, u.
|
||||
@ -68,6 +74,10 @@ T const* runtime_pointer_cast(U const* u) noexcept {
|
||||
return detail::runtime_cast_impl<T>(u, std::is_base_of<T, U>());
|
||||
}
|
||||
|
||||
BOOST_TYPE_INDEX_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_RUNTIME_CAST_POINTER_CAST_HPP
|
||||
|
@ -13,18 +13,27 @@
|
||||
/// \brief Contains the overload of boost::typeindex::runtime_cast for
|
||||
/// reference types.
|
||||
|
||||
#include <boost/type_index/runtime_cast/detail/runtime_cast_impl.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_index/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#include <boost/type_index/runtime_cast/detail/runtime_cast_impl.hpp>
|
||||
|
||||
#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
BOOST_TYPE_INDEX_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// \brief Indicates that runtime_cast was unable to perform the desired cast operation
|
||||
/// because the source instance was not also an instance of the target type.
|
||||
struct BOOST_SYMBOL_VISIBLE bad_runtime_cast : std::exception
|
||||
@ -60,6 +69,10 @@ typename std::add_lvalue_reference<const T>::type runtime_cast(U const& u) {
|
||||
return *value;
|
||||
}
|
||||
|
||||
BOOST_TYPE_INDEX_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_RUNTIME_CAST_REFERENCE_CAST_HPP
|
||||
|
@ -12,14 +12,21 @@
|
||||
/// \file register_runtime_class.hpp
|
||||
/// \brief Contains the macros BOOST_TYPE_INDEX_IMPLEMENT_RUNTIME_CAST and
|
||||
/// BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS
|
||||
|
||||
#include <boost/type_index/detail/config.hpp>
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
|
||||
#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex { namespace detail {
|
||||
|
||||
BOOST_TYPE_INDEX_BEGIN_MODULE_EXPORT
|
||||
|
||||
template<typename T>
|
||||
inline type_index runtime_class_construct_type_id(T const*) {
|
||||
return boost::typeindex::type_id<T>();
|
||||
@ -39,8 +46,12 @@ const void* find_instance(boost::typeindex::type_index const& idx, const Self* s
|
||||
return boost::typeindex::detail::find_instance<OtherBases...>(idx, self);
|
||||
}
|
||||
|
||||
BOOST_TYPE_INDEX_END_MODULE_EXPORT
|
||||
|
||||
}}} // namespace boost::typeindex::detail
|
||||
|
||||
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
|
||||
/// \def BOOST_TYPE_INDEX_REGISTER_RUNTIME_CLASS
|
||||
/// \brief Macro used to make a class compatible with boost::typeindex::runtime_cast
|
||||
|
@ -13,8 +13,15 @@
|
||||
/// \brief Contains the overload of boost::typeindex::runtime_pointer_cast for
|
||||
/// std::shared_ptr types.
|
||||
|
||||
#include <boost/type_index/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#include <boost/type_index/runtime_cast/detail/runtime_cast_impl.hpp>
|
||||
|
||||
#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
@ -22,6 +29,8 @@
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
BOOST_TYPE_INDEX_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// \brief Creates a new instance of std::shared_ptr whose stored pointer is obtained from u's
|
||||
/// stored pointer using a runtime_cast.
|
||||
///
|
||||
@ -40,6 +49,10 @@ std::shared_ptr<T> runtime_pointer_cast(std::shared_ptr<U> const& u) {
|
||||
return std::shared_ptr<T>();
|
||||
}
|
||||
|
||||
BOOST_TYPE_INDEX_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_RUNTIME_CAST_STD_SHARED_PTR_CAST_HPP
|
||||
|
@ -19,6 +19,10 @@
|
||||
/// When typeid() is disabled or BOOST_TYPE_INDEX_FORCE_NO_RTTI_COMPATIBILITY macro
|
||||
/// is defined boost::typeindex::ctti is usually used instead of boost::typeindex::stl_type_index.
|
||||
|
||||
#include <boost/type_index/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#include <boost/type_index/type_index_facade.hpp>
|
||||
|
||||
// MSVC is capable of calling typeid(T) even when RTTI is off
|
||||
@ -26,12 +30,15 @@
|
||||
#error "File boost/type_index/stl_type_index.ipp is not usable when typeid() is not available."
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
#include <typeinfo>
|
||||
#include <cstring> // std::strcmp, std::strlen, std::strstr
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/core/demangle.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
@ -39,6 +46,8 @@
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
BOOST_TYPE_INDEX_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// \class stl_type_index
|
||||
/// This class is a wrapper around std::type_info, that workarounds issues and provides
|
||||
/// much more rich interface. \b For \b description \b of \b functions \b see type_index_facade.
|
||||
@ -93,6 +102,8 @@ public:
|
||||
inline static stl_type_index type_id_runtime(const T& value) noexcept;
|
||||
};
|
||||
|
||||
BOOST_TYPE_INDEX_END_MODULE_EXPORT
|
||||
|
||||
inline const stl_type_index::type_info_t& stl_type_index::type_info() const noexcept {
|
||||
return *data_;
|
||||
}
|
||||
@ -111,7 +122,7 @@ inline const char* stl_type_index::name() const noexcept {
|
||||
}
|
||||
|
||||
inline std::string stl_type_index::pretty_name() const {
|
||||
static const char cvr_saver_name[] = "boost::typeindex::detail::cvr_saver<";
|
||||
static const char cvr_saver_name[] = "boost::typeindex::detail::cvr_saver";
|
||||
static BOOST_CONSTEXPR_OR_CONST std::string::size_type cvr_saver_name_len = sizeof(cvr_saver_name) - 1;
|
||||
|
||||
// In case of MSVC demangle() is a no-op, and name() already returns demangled name.
|
||||
@ -131,6 +142,12 @@ 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<
|
||||
while (*b != '<') { // the string is zero terminated, we won't exceed the buffer size
|
||||
++ b;
|
||||
}
|
||||
++b;
|
||||
|
||||
// Trim leading spaces
|
||||
while (*b == ' ') { // the string is zero terminated, we won't exceed the buffer size
|
||||
++ b;
|
||||
@ -231,4 +248,6 @@ inline stl_type_index stl_type_index::type_id_runtime(const T& value) noexcept {
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_STL_TYPE_INDEX_HPP
|
||||
|
@ -9,19 +9,28 @@
|
||||
#ifndef BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
|
||||
#define BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
#include <boost/type_index/detail/config.hpp>
|
||||
|
||||
#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
#include <iosfwd> // for std::basic_ostream
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
namespace boost { namespace typeindex {
|
||||
|
||||
BOOST_TYPE_INDEX_BEGIN_MODULE_EXPORT
|
||||
|
||||
/// \class type_index_facade
|
||||
///
|
||||
/// This class takes care about the comparison operators, hash functions and
|
||||
@ -274,7 +283,11 @@ inline std::size_t hash_value(const type_index_facade<Derived, TypeInfo>& lhs) n
|
||||
return static_cast<Derived const&>(lhs).hash_code();
|
||||
}
|
||||
|
||||
BOOST_TYPE_INDEX_END_MODULE_EXPORT
|
||||
|
||||
}} // namespace boost::typeindex
|
||||
|
||||
#endif // #if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT)
|
||||
|
||||
#endif // BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP
|
||||
|
||||
|
55
modules/boost_type_index.cppm
Normal file
55
modules/boost_type_index.cppm
Normal file
@ -0,0 +1,55 @@
|
||||
// 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)
|
||||
|
||||
// To compile manually use a command like the folowing:
|
||||
// clang++ -I ../include -std=c++20 --precompile -x c++-module pfr.cppm
|
||||
|
||||
module;
|
||||
|
||||
#include <version>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/container_hash/hash_fwd.hpp>
|
||||
#include <boost/container_hash/hash.hpp>
|
||||
#include <boost/core/demangle.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#ifndef BOOST_TYPE_INDEX_USE_STD_MODULE
|
||||
#include <cstring>
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
#define BOOST_TYPE_INDEX_INTERFACE_UNIT
|
||||
|
||||
export module boost.type_index;
|
||||
|
||||
#ifdef BOOST_TYPE_INDEX_USE_STD_MODULE
|
||||
// Should not be in the global module fragment
|
||||
// https://eel.is/c++draft/module#global.frag-1
|
||||
import std;
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic ignored "-Winclude-angled-in-module-purview"
|
||||
#endif
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
#include <boost/type_index/ctti_type_index.hpp>
|
||||
#include <boost/type_index/runtime_cast.hpp>
|
||||
#include <boost/type_index/runtime_cast/boost_shared_ptr_cast.hpp>
|
||||
#include <boost/type_index/runtime_cast/pointer_cast.hpp>
|
||||
#include <boost/type_index/runtime_cast/reference_cast.hpp>
|
||||
#include <boost/type_index/runtime_cast/register_runtime_class.hpp>
|
||||
#include <boost/type_index/runtime_cast/std_shared_ptr_cast.hpp>
|
||||
#include <boost/type_index/stl_type_index.hpp>
|
||||
#include <boost/type_index/type_index_facade.hpp>
|
||||
|
18
modules/usage_sample.cpp
Normal file
18
modules/usage_sample.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
// 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)
|
||||
|
||||
// To compile manually use a command like the folowing:
|
||||
// clang++ -std=c++20 -fmodule-file=type_index.pcm type_index.pcm usage_sample.cpp
|
||||
|
||||
//[type_index_module_example
|
||||
#include <iostream>
|
||||
|
||||
import boost.type_index;
|
||||
|
||||
int main() {
|
||||
std::cout << boost::typeindex::type_id_with_cvr<const int>(); // Outputs: const int
|
||||
}
|
||||
//]
|
||||
|
13
modules/usage_test_mu1.cpp
Normal file
13
modules/usage_test_mu1.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
// 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 <iostream>
|
||||
|
||||
import boost.type_index;
|
||||
|
||||
void do_something(std::ostream& os) {
|
||||
os << boost::typeindex::type_id_with_cvr<const int>();
|
||||
}
|
||||
|
16
modules/usage_test_mu2.cpp
Normal file
16
modules/usage_test_mu2.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
// 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 <iostream>
|
||||
#include <boost/type_index.hpp>
|
||||
|
||||
void do_something(std::ostream& os);
|
||||
|
||||
int main() {
|
||||
do_something(std::cout);
|
||||
std::cout << '\n';
|
||||
std::cout << boost::typeindex::type_id_with_cvr<const int>(); // Outputs: const int
|
||||
}
|
||||
|
@ -50,10 +50,10 @@ exe testing_crossmodule_anonymous_no_rtti : testing_crossmodule_anonymous.cpp te
|
||||
|
||||
test-suite type_index
|
||||
:
|
||||
[ run type_index_test.cpp /boost/lexical_cast//boost_lexical_cast ]
|
||||
[ run type_index_test.cpp ]
|
||||
[ run type_index_runtime_cast_test.cpp /boost/smart_ptr//boost_smart_ptr ]
|
||||
[ run type_index_constexpr_test.cpp ]
|
||||
[ run type_index_test.cpp /boost/lexical_cast//boost_lexical_cast : : : <rtti>off $(norttidefines) : type_index_test_no_rtti ]
|
||||
[ run type_index_test.cpp : : : <rtti>off $(norttidefines) : type_index_test_no_rtti ]
|
||||
[ run ctti_print_name.cpp : : : <test-info>always_show_run_output ]
|
||||
[ run testing_crossmodule.cpp test_lib_rtti ]
|
||||
[ run testing_crossmodule.cpp test_lib_nortti : : : <rtti>off $(norttidefines) : testing_crossmodule_no_rtti ]
|
||||
|
52
test/cmake_subdir_test/CMakeLists.txt
Normal file
52
test/cmake_subdir_test/CMakeLists.txt
Normal file
@ -0,0 +1,52 @@
|
||||
# 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
|
||||
|
||||
cmake_minimum_required(VERSION 3.5...4.0)
|
||||
|
||||
project(type_index_subdir_test LANGUAGES CXX)
|
||||
|
||||
add_subdirectory(../../../assert boostorg/assert)
|
||||
add_subdirectory(../../../core boostorg/core)
|
||||
add_subdirectory(../../../config boostorg/config)
|
||||
add_subdirectory(../../../container_hash boostorg/container_hash)
|
||||
add_subdirectory(../../../describe boostorg/describe)
|
||||
add_subdirectory(../../../detail boostorg/detail)
|
||||
add_subdirectory(../../../integer boostorg/integer)
|
||||
add_subdirectory(../../../move boostorg/move)
|
||||
add_subdirectory(../../../mp11 boostorg/mp11)
|
||||
add_subdirectory(../../../preprocessor boostorg/preprocessor)
|
||||
add_subdirectory(../../../smart_ptr boostorg/smart_ptr)
|
||||
add_subdirectory(../../../static_assert boostorg/static_assert)
|
||||
add_subdirectory(../../../throw_exception boostorg/throw_exception)
|
||||
add_subdirectory(../../../type_traits boostorg/type_traits)
|
||||
|
||||
add_subdirectory(../../ boostorg/type_index)
|
||||
|
||||
enable_testing()
|
||||
|
||||
if (BOOST_USE_MODULES)
|
||||
add_executable(boost_type_index_module_usage ../../modules/usage_sample.cpp)
|
||||
target_link_libraries(boost_type_index_module_usage PRIVATE Boost::type_index)
|
||||
add_test(NAME boost_type_index_module_usage COMMAND boost_type_index_module_usage)
|
||||
|
||||
# Make sure that mixing includes and imports is fine for different TU
|
||||
add_executable(boost_type_index_module_usage_mu ../../modules/usage_test_mu1.cpp ../../modules/usage_test_mu2.cpp)
|
||||
target_link_libraries(boost_type_index_module_usage_mu PRIVATE Boost::type_index)
|
||||
add_test(NAME boost_type_index_module_usage_mu COMMAND boost_type_index_module_usage_mu)
|
||||
endif()
|
||||
|
||||
list(APPEND RUN_TESTS_SOURCES
|
||||
compare_ctti_stl.cpp
|
||||
ctti_print_name.cpp
|
||||
track_13621.cpp
|
||||
type_index_runtime_cast_test.cpp
|
||||
type_index_test.cpp
|
||||
)
|
||||
|
||||
foreach (testsourcefile ${RUN_TESTS_SOURCES})
|
||||
get_filename_component(testname ${testsourcefile} NAME_WLE)
|
||||
add_executable(${PROJECT_NAME}_${testname} ../${testsourcefile})
|
||||
target_link_libraries(${PROJECT_NAME}_${testname} Boost::type_index Boost::smart_ptr)
|
||||
add_test(NAME ${PROJECT_NAME}_${testname} COMMAND ${PROJECT_NAME}_${testname})
|
||||
endforeach()
|
@ -34,8 +34,8 @@ void compare()
|
||||
typedef boost::typeindex::ctti_type_index ctti;
|
||||
typedef boost::typeindex::stl_type_index stl;
|
||||
BOOST_TEST_EQ(
|
||||
ctti::type_id<int>().pretty_name(),
|
||||
stl::type_id<int>().pretty_name()
|
||||
ctti::type_id<T>().pretty_name(),
|
||||
stl::type_id<T>().pretty_name()
|
||||
);
|
||||
}
|
||||
|
||||
@ -44,14 +44,15 @@ int main()
|
||||
{
|
||||
compare<void>();
|
||||
compare<int>();
|
||||
compare<double*>();
|
||||
compare<const double&>();
|
||||
|
||||
#ifndef _MSC_VER // may add `class` to the type name
|
||||
compare<my_namespace1::my_class>();
|
||||
|
||||
compare<my_namespace3::my_template<
|
||||
my_namespace1::my_class,
|
||||
my_namespace2::my_class> >();
|
||||
|
||||
#endif
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include <boost/type_index.hpp>
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
@ -209,15 +209,20 @@ void type_id_storing_modifiers_vs_nonstoring()
|
||||
BOOST_TEST(t1.pretty_name() == "const int" || t1.pretty_name() == "int const");
|
||||
}
|
||||
|
||||
void type_index_stream_operator_via_lexical_cast_testing()
|
||||
void type_index_stream_operator_via_stringstream_testing()
|
||||
{
|
||||
using namespace boost::typeindex;
|
||||
|
||||
std::string s_int2 = boost::lexical_cast<std::string>(type_id<int>());
|
||||
BOOST_TEST_EQ(s_int2, "int");
|
||||
|
||||
std::string s_double2 = boost::lexical_cast<std::string>(type_id<double>());
|
||||
BOOST_TEST_EQ(s_double2, "double");
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << type_id<int>();
|
||||
BOOST_TEST_EQ(oss.str(), "int");
|
||||
}
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << type_id<double>();
|
||||
BOOST_TEST_EQ(oss.str(), "double");
|
||||
}
|
||||
}
|
||||
|
||||
void type_index_stripping_cvr_test()
|
||||
@ -386,7 +391,7 @@ int main() {
|
||||
|
||||
type_id_storing_modifiers();
|
||||
type_id_storing_modifiers_vs_nonstoring();
|
||||
type_index_stream_operator_via_lexical_cast_testing();
|
||||
type_index_stream_operator_via_stringstream_testing();
|
||||
type_index_stripping_cvr_test();
|
||||
type_index_user_defined_class_test();
|
||||
|
||||
|
Reference in New Issue
Block a user