From dc78cf182521692e52e34711a27ada19c81dd22c Mon Sep 17 00:00:00 2001 From: Antony Polukhin Date: Mon, 12 May 2025 17:35:17 +0300 Subject: [PATCH] Implement initial version of C++20 module `boost.type_index` (#15) `#include +#include #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 diff --git a/include/boost/type_index/ctti_type_index.hpp b/include/boost/type_index/ctti_type_index.hpp index fac0a3c..d680594 100644 --- a/include/boost/type_index/ctti_type_index.hpp +++ b/include/boost/type_index/ctti_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 + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) + #include #include +#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) #include #include + #include +#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 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(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 diff --git a/include/boost/type_index/detail/compile_time_type_info.hpp b/include/boost/type_index/detail/compile_time_type_info.hpp index 95469bd..49f2ebe 100644 --- a/include/boost/type_index/detail/compile_time_type_info.hpp +++ b/include/boost/type_index/detail/compile_time_type_info.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 +#include +#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) #include #include +#endif #ifdef BOOST_HAS_PRAGMA_ONCE # pragma once diff --git a/include/boost/type_index/detail/config.hpp b/include/boost/type_index/detail/config.hpp new file mode 100644 index 0000000..041d596 --- /dev/null +++ b/include/boost/type_index/detail/config.hpp @@ -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 +#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 + diff --git a/include/boost/type_index/detail/ctti_register_class.hpp b/include/boost/type_index/detail/ctti_register_class.hpp index e004be0..b8dd905 100644 --- a/include/boost/type_index/detail/ctti_register_class.hpp +++ b/include/boost/type_index/detail/ctti_register_class.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 inline const ctti_data& ctti_construct_typeid_ref(const T*) noexcept { return boost::typeindex::ctti_construct(); } +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 { \ diff --git a/include/boost/type_index/detail/stl_register_class.hpp b/include/boost/type_index/detail/stl_register_class.hpp index 0e44a26..67b34f3 100644 --- a/include/boost/type_index/detail/stl_register_class.hpp +++ b/include/boost/type_index/detail/stl_register_class.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 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 { \ diff --git a/include/boost/type_index/runtime_cast.hpp b/include/boost/type_index/runtime_cast.hpp index c72b119..d1adccf 100644 --- a/include/boost/type_index/runtime_cast.hpp +++ b/include/boost/type_index/runtime_cast.hpp @@ -9,6 +9,8 @@ #ifndef BOOST_TYPE_INDEX_RUNTIME_CAST_HPP #define BOOST_TYPE_INDEX_RUNTIME_CAST_HPP +#include + /// \file runtime_cast.hpp /// \brief Contains the basic utilities necessary to fully emulate /// dynamic_cast for language level constructs (raw pointers and references). diff --git a/include/boost/type_index/runtime_cast/boost_shared_ptr_cast.hpp b/include/boost/type_index/runtime_cast/boost_shared_ptr_cast.hpp index 2664c01..a1af74e 100644 --- a/include/boost/type_index/runtime_cast/boost_shared_ptr_cast.hpp +++ b/include/boost/type_index/runtime_cast/boost_shared_ptr_cast.hpp @@ -13,21 +13,25 @@ /// \brief Contains the overload of boost::typeindex::runtime_pointer_cast for /// boost::shared_ptr types. +#include + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) + #include +#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) #include +#endif #ifdef BOOST_HAS_PRAGMA_ONCE # pragma once #endif -namespace boost { - template 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 /// that points to an address suitably offset from u. /// If no such conversion exists, returns boost::shared_ptr(); -template -boost::shared_ptr runtime_pointer_cast(boost::shared_ptr const& u) { +template class SmartPointer> +auto runtime_pointer_cast(SmartPointer const& u) -> decltype(u.use_count(), SmartPointer()) { T* value = detail::runtime_cast_impl(u.get(), std::is_base_of()); if(value) - return boost::shared_ptr(u, value); - return boost::shared_ptr(); + return SmartPointer(u, value); + return SmartPointer(); } +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 diff --git a/include/boost/type_index/runtime_cast/detail/runtime_cast_impl.hpp b/include/boost/type_index/runtime_cast/detail/runtime_cast_impl.hpp index 12a1b0e..8b6ed5f 100644 --- a/include/boost/type_index/runtime_cast/detail/runtime_cast_impl.hpp +++ b/include/boost/type_index/runtime_cast/detail/runtime_cast_impl.hpp @@ -19,7 +19,9 @@ #include +#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) #include +#endif #ifdef BOOST_HAS_PRAGMA_ONCE # pragma once diff --git a/include/boost/type_index/runtime_cast/pointer_cast.hpp b/include/boost/type_index/runtime_cast/pointer_cast.hpp index e4f94c1..f30a6d5 100644 --- a/include/boost/type_index/runtime_cast/pointer_cast.hpp +++ b/include/boost/type_index/runtime_cast/pointer_cast.hpp @@ -12,16 +12,22 @@ /// \file pointer_class.hpp /// \brief Contains the function overloads of boost::typeindex::runtime_cast for /// pointer types. + +#include + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) + #include #include - #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(u, std::is_base_of()); } +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 diff --git a/include/boost/type_index/runtime_cast/reference_cast.hpp b/include/boost/type_index/runtime_cast/reference_cast.hpp index 674a289..08f997c 100644 --- a/include/boost/type_index/runtime_cast/reference_cast.hpp +++ b/include/boost/type_index/runtime_cast/reference_cast.hpp @@ -13,18 +13,27 @@ /// \brief Contains the overload of boost::typeindex::runtime_cast for /// reference types. -#include -#include +#include +#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) + +#include + +#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) #include #include +#include +#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::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 diff --git a/include/boost/type_index/runtime_cast/register_runtime_class.hpp b/include/boost/type_index/runtime_cast/register_runtime_class.hpp index 957224e..db45285 100644 --- a/include/boost/type_index/runtime_cast/register_runtime_class.hpp +++ b/include/boost/type_index/runtime_cast/register_runtime_class.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 + #include +#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 inline type_index runtime_class_construct_type_id(T const*) { return boost::typeindex::type_id(); @@ -39,8 +46,12 @@ const void* find_instance(boost::typeindex::type_index const& idx, const Self* s return boost::typeindex::detail::find_instance(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 diff --git a/include/boost/type_index/runtime_cast/std_shared_ptr_cast.hpp b/include/boost/type_index/runtime_cast/std_shared_ptr_cast.hpp index 7b09db5..8fcdc17 100644 --- a/include/boost/type_index/runtime_cast/std_shared_ptr_cast.hpp +++ b/include/boost/type_index/runtime_cast/std_shared_ptr_cast.hpp @@ -13,8 +13,15 @@ /// \brief Contains the overload of boost::typeindex::runtime_pointer_cast for /// std::shared_ptr types. +#include + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) + #include + +#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) #include +#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 runtime_pointer_cast(std::shared_ptr const& u) { return std::shared_ptr(); } +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 diff --git a/include/boost/type_index/stl_type_index.hpp b/include/boost/type_index/stl_type_index.hpp index 680ef9a..810339a 100644 --- a/include/boost/type_index/stl_type_index.hpp +++ b/include/boost/type_index/stl_type_index.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 + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) + #include // 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 #include // std::strcmp, std::strlen, std::strstr #include #include + #include #include +#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 diff --git a/include/boost/type_index/type_index_facade.hpp b/include/boost/type_index/type_index_facade.hpp index 891797e..7e6261e 100644 --- a/include/boost/type_index/type_index_facade.hpp +++ b/include/boost/type_index/type_index_facade.hpp @@ -9,19 +9,28 @@ #ifndef BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP #define BOOST_TYPE_INDEX_TYPE_INDEX_FACADE_HPP -#include -#include +#include + +#if !defined(BOOST_USE_MODULES) || defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) + +#if !defined(BOOST_TYPE_INDEX_INTERFACE_UNIT) #include #include #include #include // for std::basic_ostream +#include +#include +#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& lhs) n return static_cast(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 diff --git a/modules/boost_type_index.cppm b/modules/boost_type_index.cppm new file mode 100644 index 0000000..37061c1 --- /dev/null +++ b/modules/boost_type_index.cppm @@ -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 +#include +#include + +#include +#include +#include +#include +#include + +#ifndef BOOST_TYPE_INDEX_USE_STD_MODULE +#include +#include +#include +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + diff --git a/modules/usage_sample.cpp b/modules/usage_sample.cpp new file mode 100644 index 0000000..89b82b2 --- /dev/null +++ b/modules/usage_sample.cpp @@ -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 + +import boost.type_index; + +int main() { + std::cout << boost::typeindex::type_id_with_cvr(); // Outputs: const int +} +//] + diff --git a/modules/usage_test_mu1.cpp b/modules/usage_test_mu1.cpp new file mode 100644 index 0000000..001145d --- /dev/null +++ b/modules/usage_test_mu1.cpp @@ -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 + +import boost.type_index; + +void do_something(std::ostream& os) { + os << boost::typeindex::type_id_with_cvr(); +} + diff --git a/modules/usage_test_mu2.cpp b/modules/usage_test_mu2.cpp new file mode 100644 index 0000000..120539c --- /dev/null +++ b/modules/usage_test_mu2.cpp @@ -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 +#include + +void do_something(std::ostream& os); + +int main() { + do_something(std::cout); + std::cout << '\n'; + std::cout << boost::typeindex::type_id_with_cvr(); // Outputs: const int +} + diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 90ab669..fb91641 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -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 : : : off $(norttidefines) : type_index_test_no_rtti ] + [ run type_index_test.cpp : : : off $(norttidefines) : type_index_test_no_rtti ] [ run ctti_print_name.cpp : : : always_show_run_output ] [ run testing_crossmodule.cpp test_lib_rtti ] [ run testing_crossmodule.cpp test_lib_nortti : : : off $(norttidefines) : testing_crossmodule_no_rtti ] diff --git a/test/cmake_subdir_test/CMakeLists.txt b/test/cmake_subdir_test/CMakeLists.txt new file mode 100644 index 0000000..645507b --- /dev/null +++ b/test/cmake_subdir_test/CMakeLists.txt @@ -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() diff --git a/test/compare_ctti_stl.cpp b/test/compare_ctti_stl.cpp index fdcbfd1..b8c0c34 100644 --- a/test/compare_ctti_stl.cpp +++ b/test/compare_ctti_stl.cpp @@ -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().pretty_name(), - stl::type_id().pretty_name() + ctti::type_id().pretty_name(), + stl::type_id().pretty_name() ); } @@ -44,14 +44,15 @@ int main() { compare(); compare(); - compare(); compare(); + +#ifndef _MSC_VER // may add `class` to the type name compare(); compare >(); - +#endif return boost::report_errors(); } diff --git a/test/type_index_test.cpp b/test/type_index_test.cpp index ccb391e..99286b2 100644 --- a/test/type_index_test.cpp +++ b/test/type_index_test.cpp @@ -7,7 +7,7 @@ #include -#include +#include #include @@ -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(type_id()); - BOOST_TEST_EQ(s_int2, "int"); - - std::string s_double2 = boost::lexical_cast(type_id()); - BOOST_TEST_EQ(s_double2, "double"); + { + std::ostringstream oss; + oss << type_id(); + BOOST_TEST_EQ(oss.str(), "int"); + } + { + std::ostringstream oss; + oss << type_id(); + 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();