Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 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
49 changes: 38 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,66 @@
# 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...3.31 )
project( boost_any VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX )
cmake_minimum_required(VERSION 3.21...4.2)
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@codeowners what is the minimum version that must be supported?

import std; is usable starting with cmake v3.30 AFAIK

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I don't think we want to bump the minimum version so much. These CMake files are invoked from the Boost superproject, so bumping a minimum version in one affects every other library. I think 3.8 is okay.

Copy link
Copy Markdown
Author

@ClausKlein ClausKlein Dec 4, 2025

Choose a reason for hiding this comment

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

on every build host cmake v4.2 may be installed with pipx install cmake?

I want to have PROJECT_IS_TOP_LEVEL available with cmake version 3.21 anything older is not state of the art!

project(boost_any VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX)

if (BOOST_USE_MODULES)
if(BOOST_USE_MODULES)
add_library(boost_any)
target_sources(boost_any PUBLIC
FILE_SET modules_public TYPE CXX_MODULES FILES
${CMAKE_CURRENT_LIST_DIR}/modules/boost_any.cppm
target_sources(
boost_any
PUBLIC
FILE_SET modules_public
TYPE CXX_MODULES
FILES ${CMAKE_CURRENT_LIST_DIR}/modules/boost_any.cppm
)

target_compile_features(boost_any PUBLIC cxx_std_20)
target_compile_definitions(boost_any PUBLIC BOOST_USE_MODULES)
if (CMAKE_CXX_COMPILER_IMPORT_STD)
if(${CMAKE_CXX_STANDARD} IN_LIST CMAKE_CXX_COMPILER_IMPORT_STD)
set(CMAKE_CXX_MODULE_STD ON)
target_compile_definitions(boost_any PRIVATE BOOST_ANY_USE_STD_MODULE)
message(STATUS "Using `import std;`")
else()
message(STATUS "`import std;` is not available")
message(WARNING "`import std;` is not available")
endif()
set(__scope PUBLIC)

add_executable(module_sample modules/usage_sample.cpp)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Please don't build examples from top-level cmakes

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

done

target_link_libraries(module_sample PRIVATE boost_any)
else()
set(CMAKE_VERIFY_INTERFACE_HEADER_SETS ON)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CMake docs suggest to not set this directly in code (https://cmake.org/cmake/help/latest/variable/CMAKE_VERIFY_INTERFACE_HEADER_SETS.html)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I changed it so it is only usable for standalone builds

add_library(boost_any INTERFACE)
set(__scope INTERFACE)
endif()

target_include_directories(boost_any ${__scope} include)
target_link_libraries( boost_any
if(CMAKE_SKIP_INSTALL_RULES OR PROJECT_IS_TOP_LEVEL)
target_sources(
boost_any
${__scope}
FILE_SET headers_public
TYPE HEADERS
BASE_DIRS include
FILES
include/boost/any/bad_any_cast.hpp
include/boost/any/basic_any.hpp
include/boost/any/fwd.hpp
include/boost/any/unique_any.hpp
include/boost/any/detail/config.hpp
include/boost/any/detail/placeholder.hpp
)
else()
target_include_directories(boost_any ${__scope} include)
endif()

target_link_libraries(
boost_any
${__scope}
Boost::config
Boost::throw_exception
Boost::type_index
)

add_library( Boost::any ALIAS boost_any )
add_library(Boost::any ALIAS boost_any)

if(BUILD_TESTING)
add_subdirectory(test)
Expand Down
3 changes: 3 additions & 0 deletions include/boost/any/fwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
#ifdef BOOST_HAS_PRAGMA_ONCE
# pragma once
#endif

#include <type_traits>

#endif // #ifndef BOOST_ANY_INTERFACE_UNIT

/// \file boost/any/fwd.hpp
Expand Down
4 changes: 3 additions & 1 deletion modules/boost_any.cppm
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ module;
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/throw_exception.hpp>
#include <boost/type_index.hpp>

// FIXME(CK): #include <boost/type_index.hpp>
import boost.type_index;
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@codeowners any reason to not use import?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#include <boost/type_index.hpp> automatically preprocesses to import boost.type_index; if the module is available

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

But direct import is right and clear?


#ifdef BOOST_ANY_USE_STD_MODULE
import std;
Expand Down
40 changes: 38 additions & 2 deletions modules/usage_sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,46 @@
// clang++ -std=c++20 -fmodule-file=type_index.pcm type_index.pcm usage_sample.cpp

//[any_module_example

#ifdef BOOST_ANY_USE_STD_MODULE
import std;
#else
# include <sstream>
# include <string>
# include <print>
#endif

import boost.any;

int main() {
boost::any a = 42;
namespace {

template <typename... Ts> auto any_to_string(const boost::any& a) -> std::string {
std::ostringstream oss;

auto try_cast = [&](auto* dummy) -> bool {
using T = std::decay_t<decltype(*dummy)>;
if (a.type() == typeid(T)) {
oss << boost::any_cast<T>(a);
return true;
}
return false;
};

// Expand over Ts...
bool const success = (try_cast((Ts*)nullptr) || ...);

if (!success) {
oss << "<unknown type: " << a.type().name() << ">";
}
return oss.str();
}

} // namespace

// Usage:
auto main() -> int {
boost::any const a = 42;
std::println(stdout, "{}", any_to_string<int, double, std::string>(a));
}
//]