diff --git a/CMakeLists.txt b/CMakeLists.txt index a994885..b23f702 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,10 @@ target_link_libraries(boost_throw_exception Boost::config ) +if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.28.0" AND BUILD_MODULE) + add_subdirectory(module) +endif() + if(BUILD_TESTING) add_subdirectory(test) diff --git a/include/boost/exception/exception.hpp b/include/boost/exception/exception.hpp index 4ec18d7..5c09e33 100644 --- a/include/boost/exception/exception.hpp +++ b/include/boost/exception/exception.hpp @@ -6,16 +6,28 @@ #ifndef BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593 #define BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593 +#ifndef BOOST_THROW_EXCEPTION_BEGIN_MODULE_EXPORT +#define BOOST_THROW_EXCEPTION_BEGIN_MODULE_EXPORT +#endif + +#ifndef BOOST_THROW_EXCEPTION_END_MODULE_EXPORT +#define BOOST_THROW_EXCEPTION_END_MODULE_EXPORT +#endif + #include #include #include #ifdef BOOST_EXCEPTION_MINI_BOOST #include +BOOST_THROW_EXCEPTION_BEGIN_MODULE_EXPORT namespace boost { namespace exception_detail { using std::shared_ptr; } } +BOOST_THROW_EXCEPTION_END_MODULE_EXPORT #else +BOOST_THROW_EXCEPTION_BEGIN_MODULE_EXPORT namespace boost { template class shared_ptr; } namespace boost { namespace exception_detail { using boost::shared_ptr; } } +BOOST_THROW_EXCEPTION_END_MODULE_EXPORT #endif #if !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) @@ -31,6 +43,7 @@ namespace boost { namespace exception_detail { using boost::shared_ptr; } } #endif #endif +BOOST_THROW_EXCEPTION_BEGIN_MODULE_EXPORT namespace boost { @@ -566,4 +579,6 @@ boost #pragma warning(pop) #endif +BOOST_THROW_EXCEPTION_END_MODULE_EXPORT + #endif // #ifndef BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593 diff --git a/include/boost/throw_exception.hpp b/include/boost/throw_exception.hpp index 7c7fcbd..679dcd4 100644 --- a/include/boost/throw_exception.hpp +++ b/include/boost/throw_exception.hpp @@ -19,6 +19,7 @@ // http://www.boost.org/libs/throw_exception #include + #include #include #include @@ -38,8 +39,10 @@ namespace boost #if defined( BOOST_NO_EXCEPTIONS ) +BOOST_THROW_EXCEPTION_BEGIN_MODULE_EXPORT BOOST_NORETURN void throw_exception( std::exception const & e ); // user defined BOOST_NORETURN void throw_exception( std::exception const & e, boost::source_location const & loc ); // user defined +BOOST_THROW_EXCEPTION_END_MODULE_EXPORT #endif @@ -68,6 +71,9 @@ template struct wrapexcept_add_base } // namespace detail + +BOOST_THROW_EXCEPTION_BEGIN_MODULE_EXPORT + template struct BOOST_SYMBOL_VISIBLE wrapexcept: public detail::wrapexcept_add_base::type, public E, @@ -175,6 +181,8 @@ template BOOST_NORETURN void throw_exception( E const & e, boost::sourc #endif // !defined( BOOST_NO_EXCEPTIONS ) +BOOST_THROW_EXCEPTION_END_MODULE_EXPORT + } // namespace boost // BOOST_THROW_EXCEPTION @@ -217,6 +225,8 @@ template class BOOST_SYMBOL_VISIBLE with_throw_location: public E, publ } // namespace detail +BOOST_THROW_EXCEPTION_BEGIN_MODULE_EXPORT + #if !defined(BOOST_NO_EXCEPTIONS) #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) @@ -273,6 +283,8 @@ template boost::source_location get_throw_location( E const & e ) #endif } +BOOST_THROW_EXCEPTION_END_MODULE_EXPORT + } // namespace boost #endif // #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED diff --git a/module/CMakeLists.txt b/module/CMakeLists.txt new file mode 100644 index 0000000..d3f876d --- /dev/null +++ b/module/CMakeLists.txt @@ -0,0 +1,37 @@ +# Copyright (c) 2025 Antony Polukhin +# +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +cmake_minimum_required(VERSION 3.28) + +function (_add_boost_throw_exception_module_impl NAME) + add_library(${NAME}) + target_compile_features(${NAME} PUBLIC cxx_std_20) + target_sources(${NAME} PUBLIC + FILE_SET modules_public TYPE CXX_MODULES FILES + ${CMAKE_CURRENT_LIST_DIR}/throw_exception.cppm + ) +endfunction() + +function (add_boost_throw_exception_module NAME) + _add_boost_throw_exception_module_impl(${NAME}) + target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../include) + + _add_boost_throw_exception_module_impl(${NAME}_migration) + target_include_directories(${NAME}_migration PUBLIC ${CMAKE_CURRENT_LIST_DIR}/../include) + target_compile_definitions(${NAME}_migration PRIVATE BOOST_THROW_EXCEPTION_ATTACH_TO_GLOBAL_MODULE) +endfunction() + +add_boost_throw_exception_module(boost_throw_exception_module) +add_library(Boost::throw_exception_module ALIAS boost_throw_exception_module) +add_library(Boost::throw_exception_module_migration ALIAS boost_throw_exception_module_migration) + +if (BUILD_TESTING) + add_executable(boost_throw_exception_module_usage usage_sample.cpp) + target_link_libraries(boost_throw_exception_module_usage PRIVATE Boost::throw_exception_module) + + # Make sure that mixing includes and imports is fine for different TU + add_executable(boost_throw_exception_module_usage_mu usage_test_mu1.cpp usage_test_mu2.cpp) + target_link_libraries(boost_throw_exception_module_usage_mu PRIVATE Boost::throw_exception_module_migration) +endif() diff --git a/module/throw_exception.cppm b/module/throw_exception.cppm new file mode 100644 index 0000000..a0018a5 --- /dev/null +++ b/module/throw_exception.cppm @@ -0,0 +1,43 @@ +// Copyright (c) 2016-2024 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 throw_exception.cppm + +#define BOOST_THROW_EXCEPTION_BEGIN_MODULE_EXPORT export { +#define BOOST_THROW_EXCEPTION_END_MODULE_EXPORT } + +module; + +#include // TODO: modularize +#include +#include + +#ifndef BOOST_THROW_EXCEPTION_HAS_STD_MODULE +#include +#include +#include +#include +#include +#include +#endif + +export module Boost.ThrowException; + +#ifdef BOOST_THROW_EXCEPTION_HAS_STD_MODULE +import std; +#endif + +#ifdef __clang__ +# pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" +#endif + +#ifdef BOOST_THROW_EXCEPTION_ATTACH_TO_GLOBAL_MODULE +extern "C++" { +#include +} +#else +#include +#endif diff --git a/module/usage_sample.cpp b/module/usage_sample.cpp new file mode 100644 index 0000000..68e48f6 --- /dev/null +++ b/module/usage_sample.cpp @@ -0,0 +1,33 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. +//Copyright (c) 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=throw_exception.pcm throw_exception.pcm usage_sample.cpp + +#include + +import Boost.ThrowException; + +class my_exception: public std::exception { }; + +int +main() + { + try + { + boost::throw_exception(my_exception()); + return 1; + } + catch( + my_exception & ) + { + } + catch( + ... ) + { + return 2; + } + }