diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 7fe60c1be..2a1ee816f 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -52,7 +52,7 @@ jobs: if: ${{ matrix.os == 'ubuntu-22.04' }} run: | sudo apt-get update - sudo apt-get install ninja-build liblapack-dev libboost-dev libboost-locale-dev libboost-regex-dev libeigen3-dev openmpi-bin libopenmpi-dev ccache + sudo apt-get install ninja-build liblapack-dev libboost-dev libboost-locale-dev libboost-random-dev libboost-regex-dev libeigen3-dev openmpi-bin libopenmpi-dev ccache - name: Prepare ccache timestamp id: ccache_cache_timestamp shell: cmake -P {0} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 23f1509ca..fd5c27bf6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -38,5 +38,5 @@ repos: name: Format C/C++ code using clang-format. language: system files: \.(c|cc|cxx|cpp|h|hpp|hxx)$ - entry: clang-format -i - args: [--style=file] + entry: bin/admin/clang-format.sh + args: [--style=file -i] diff --git a/CMakeLists.txt b/CMakeLists.txt index 8bf403d2f..1363b82ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,26 +138,8 @@ check_cxx_execution_header(SEQUANT) # Ranges-V3 include(FindOrFetchRangeV3) -# need header-only Boost + (compiled) Boost.Regex and Boost.Locale -# NB Boost.Container is broken in v1.70 -if (NOT TARGET Boost::boost OR NOT TARGET Boost::regex OR NOT TARGET Boost::locale) - find_package(Boost ${SEQUANT_TRACKED_BOOST_VERSION} CONFIG COMPONENTS regex locale) - if (Boost_VERSION_STRING VERSION_LESS ${SEQUANT_TRACKED_BOOST_VERSION} OR NOT TARGET Boost::boost OR NOT TARGET Boost::regex OR NOT TARGET Boost::locale) - find_package(Boost ${SEQUANT_TRACKED_BOOST_VERSION} REQUIRED COMPONENTS regex locale) - message(STATUS "Found Boost (version ${Boost_VERSION}) via FindBoost module") - set(Boost_USE_CONFIG FALSE) - else () - message(STATUS "Found Boost (version ${Boost_VERSION}) via CONFIG ${Boost_CONFIG}") - set(Boost_USE_CONFIG TRUE) - endif () - # Boost.Move is broken in 1.77 and 1.78 unless using c++20 - # fixed in 1.79 via https://github.com/boostorg/move/commit/78f26da1f3a5a3831e9e70efe83f9c56eef94e8c - if (CMAKE_CXX_STANDARD LESS 20) - if (Boost_VERSION_MACRO GREATER_EQUAL 107700 AND Boost_VERSION_MACRO LESS 107900) - message(FATAL_ERROR "Found Boost 1.77 <= version < 1.79, but its Boost.Move is broken with pre-C++20: use a version older than 1.77 or newer than 1.78") - endif () - endif () -endif () +# Boost will be added after defining SeQuant +include(external/boost.cmake) # embedded bliss-0.73 add_library(SeQuant-bliss @@ -269,16 +251,25 @@ set_source_files_properties( SeQuant/domain/mbpt/op.cpp SeQuant/domain/mbpt/sr.cpp SeQuant/domain/mbpt/mr.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) ### optional prereqs -if (NOT TARGET Eigen3::Eigen) - # re:NO_CMAKE_PACKAGE_REGISTRY: eigen3 registers its *build* tree with the user package registry ... - # to avoid issues with wiped build directory look for installed eigen - find_package(Eigen3 3.0 NO_MODULE NO_CMAKE_PACKAGE_REGISTRY) -endif() if (SEQUANT_EVAL_TESTS) include(FindOrFetchTiledArray) endif (SEQUANT_EVAL_TESTS) +if (NOT TARGET Eigen3::Eigen) + # use TA's Eigen, if available + if (TARGET TiledArray_Eigen) + add_library(Eigen3::Eigen ALIAS TiledArray_Eigen) + else() + # re:NO_CMAKE_PACKAGE_REGISTRY: eigen3 registers its *build* tree with the user package registry ... + # to avoid issues with wiped build directory look for installed eigen + find_package(Eigen3 3.0 NO_MODULE NO_CMAKE_PACKAGE_REGISTRY) + endif() +endif() +if (TARGET Eigen3::Eigen) + set(SEQUANT_HAS_EIGEN ON) + endif() if (TARGET tiledarray) + set(SEQUANT_HAS_TILEDARRAY ON) list(APPEND SeQuant_src SeQuant/domain/eval/cache_manager.cpp SeQuant/domain/eval/cache_manager.hpp @@ -299,7 +290,19 @@ set_source_files_properties( "SEQUANT_GIT_REVISION=\"${SEQUANT_GIT_REVISION}\";SEQUANT_GIT_DESCRIPTION=\"${SEQUANT_GIT_DESCRIPTION}\"" ) -target_link_libraries(SeQuant PUBLIC range-v3::range-v3 Boost::regex Boost::locale Boost::boost SeQuant-bliss Threads::Threads) +target_link_libraries(SeQuant PUBLIC range-v3::range-v3 Boost::regex Boost::locale Boost::headers SeQuant-bliss Threads::Threads) +# modularized Boost has finer grained targets than just Boost::headers +if (Boost_IS_MODULARIZED) + target_link_libraries(SeQuant PUBLIC + Boost::container + Boost::container_hash + Boost::multiprecision + Boost::numeric_conversion + Boost::numeric_interval + Boost::range + Boost::spirit + ) +endif() if (TARGET tiledarray) target_link_libraries(SeQuant PUBLIC tiledarray) endif () @@ -359,6 +362,11 @@ if (SEQUANT_MIMALLOC) target_compile_definitions(SeQuant PUBLIC SEQUANT_HAS_MIMALLOC=1) endif () +# build all of boost before SeQuant, including parts it does not use +if (Boost_BUILT_FROM_SOURCE AND TARGET build-boost-in-SeQuant) + add_dependencies(SeQuant build-boost-in-SeQuant) +endif() + ### unit tests include(CTest) @@ -498,7 +506,7 @@ if (BUILD_TESTING) examples/eval/btas/data_world_btas.hpp examples/eval/btas/scf_btas.hpp examples/eval/btas/main.cpp) - target_include_directories(${example7} PUBLIC ${BTAS_SOURCE_DIR} ${Boost_INCLUDE_DIRS}) + target_include_directories(${example7} PUBLIC ${BTAS_SOURCE_DIR}) target_link_libraries(${example7} SeQuant) endif (BTAS_SOURCE_DIR) diff --git a/INSTALL.md b/INSTALL.md index d1149c886..0c7958a4d 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -11,7 +11,7 @@ prerequisites: * [Range-V3](https://github.com/ericniebler/range-v3.git), tag 0.12.0, *if not found, SeQuant will download and build Range-V3* * optional: * for building coupled-cluster evaluation tests: - * [TiledArray](https://github.com/ValeevGroup/tiledarray.git), tag 81bafdc39568d7d5f981d4453e4a2f49a9c0c428 + * [TiledArray](https://github.com/ValeevGroup/tiledarray.git), tag 954d861f553e938c3cfc4892fce9234bf4bf7193 * for building `stcc*` example programs * [Eigen](http://eigen.tuxfamily.org/), version 3 diff --git a/SeQuant/core/algorithm.hpp b/SeQuant/core/algorithm.hpp index cda949948..f162872c8 100644 --- a/SeQuant/core/algorithm.hpp +++ b/SeQuant/core/algorithm.hpp @@ -41,11 +41,11 @@ void bubble_sort(ForwardIter begin, Sentinel end, Compare comp) { static_assert(std::tuple_size_v == 2, "need to generalize comparer to handle tuples"); auto composite_compare = [](auto&& c0, auto&& c1) { - if (std::get<0>(c0) < std::get<0>(c1)) { // c0[0] < c1[1] + if (std::get<0>(c0) < std::get<0>(c1)) { // c0[0] < c1[0] return true; } else if (!(std::get<0>(c1) < std::get<0>(c0))) { // c0[0] == c1[0] return std::get<1>(c0) < std::get<1>(c1); - } else { // c0[0] > c1[0] + } else { // c0[0] > c1[0] return false; } }; diff --git a/SeQuant/core/hash.hpp b/SeQuant/core/hash.hpp index 7f7ca88d0..59851f2a9 100644 --- a/SeQuant/core/hash.hpp +++ b/SeQuant/core/hash.hpp @@ -6,9 +6,10 @@ #define SEQUANT_HASH_HPP #ifdef SEQUANT_USE_SYSTEM_BOOST_HASH +#include +#define SEQUANT_BOOST_VERSION BOOST_VERSION #include namespace sequant_boost = boost; -#define SEQUANT_BOOST_VERSION BOOST_VERSION #else #include #endif diff --git a/SeQuant/core/space.cpp b/SeQuant/core/space.cpp index d92dcd328..792510400 100644 --- a/SeQuant/core/space.cpp +++ b/SeQuant/core/space.cpp @@ -4,6 +4,8 @@ #include "space.hpp" +int32_t sequant::TypeAttr::used_bits = 0xffff; + sequant::container::map sequant::IndexSpace::attr2basekey_{}; sequant::container::map(bitset); } - constexpr int32_t to_int32() const { return bitset; } - constexpr TypeAttr intersection(TypeAttr other) const { + [[nodiscard]] constexpr int32_t to_int32() const { return bitset; } + [[nodiscard]] int32_t to_int32_used() const { return used_bits & bitset; } + [[nodiscard]] constexpr TypeAttr intersection(TypeAttr other) const { return TypeAttr(this->to_int32() & other.to_int32()); } - constexpr TypeAttr unIon(TypeAttr other) const { + [[nodiscard]] constexpr TypeAttr unIon(TypeAttr other) const { return TypeAttr(this->to_int32() | other.to_int32()); } - friend constexpr bool operator==(TypeAttr, TypeAttr); - friend constexpr bool operator!=(TypeAttr, TypeAttr); + [[nodiscard]] friend bool operator==(TypeAttr lhs, TypeAttr rhs) { + return lhs.to_int32_used() == rhs.to_int32_used(); + } + + [[nodiscard]] friend bool operator!=(TypeAttr lhs, TypeAttr rhs) { + return !(lhs == rhs); + } /// @return true if \c other is included in this object - constexpr bool includes(TypeAttr other) const { + [[nodiscard]] bool includes(TypeAttr other) const { return intersection(other) == other; } /// @return true if in canonical order this object preceeds \c other - constexpr bool operator<(TypeAttr other) const { - return this->to_int32() < other.to_int32(); + [[nodiscard]] bool operator<(TypeAttr other) const { + return this->to_int32_used() < other.to_int32_used(); } /// @return an invalid TypeAttr - static constexpr TypeAttr invalid() noexcept { return TypeAttr(0xffff); } + [[nodiscard]] static constexpr TypeAttr invalid() noexcept { + return TypeAttr(0xffff); + } }; -constexpr bool operator==(TypeAttr lhs, TypeAttr rhs) { - return lhs.to_int32() == rhs.to_int32(); -} - -constexpr bool operator!=(TypeAttr lhs, TypeAttr rhs) { return !(lhs == rhs); } - /// denotes other quantum numbers (particle type, spin, etc.) struct QuantumNumbersAttr { int32_t bitset = 0; @@ -75,8 +81,14 @@ struct QuantumNumbersAttr { return QuantumNumbersAttr(this->to_int32() | other.to_int32()); } - friend constexpr bool operator==(QuantumNumbersAttr, QuantumNumbersAttr); - friend constexpr bool operator!=(QuantumNumbersAttr, QuantumNumbersAttr); + friend constexpr bool operator==(QuantumNumbersAttr lhs, + QuantumNumbersAttr rhs) { + return lhs.to_int32() == rhs.to_int32(); + } + friend constexpr bool operator!=(QuantumNumbersAttr lhs, + QuantumNumbersAttr rhs) { + return !(lhs == rhs); + } /// @return true if \c other is included in this object constexpr bool includes(QuantumNumbersAttr other) const { @@ -93,14 +105,6 @@ struct QuantumNumbersAttr { } }; -constexpr bool operator==(QuantumNumbersAttr lhs, QuantumNumbersAttr rhs) { - return lhs.to_int32() == rhs.to_int32(); -} - -constexpr bool operator!=(QuantumNumbersAttr lhs, QuantumNumbersAttr rhs) { - return !(lhs == rhs); -} - /// @brief space of Index objects /// /// IndexSpace is a set of attributes associated 1-to-1 with keys @@ -154,10 +158,10 @@ class IndexSpace { this->qns().includes(other.qns()); } - bool operator==(Attr other) const { - return this->type() == other.type() && this->qns() == other.qns(); + friend bool operator==(Attr a, Attr b) { + return a.type() == b.type() && a.qns() == b.qns(); } - bool operator!=(Attr other) const { return !(*this == other); } + friend bool operator!=(Attr a, Attr b) { return !(a == b); } static Attr null() noexcept { return Attr{nulltype, nullqns}; } static Attr invalid() noexcept { diff --git a/bin/admin/clang-format.sh b/bin/admin/clang-format.sh new file mode 100755 index 000000000..3531dcc1b --- /dev/null +++ b/bin/admin/clang-format.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +# these are the versions of clang-format that are supported required +# should be ordered from oldest to newest to make sure the newest is picked +supported_clang_format_versions="16 17" +preferred_clang_format_version="" # prefer most recent supported clang-format version +for v in $supported_clang_format_versions; do + preferred_clang_format_version=$v +done + +# append common locations of clang-format to PATH +unameOut="$(uname -s)" +case "${unameOut}" in + Darwin*) + extra_path="" + # this prefers more recent versions + for v in $supported_clang_format_versions; do + extra_path=/opt/homebrew/opt/llvm@$v/bin:/opt/homebrew/opt/clang-format@$v/bin:$extra_path + done + # prepend paths + export PATH=$extra_path:$PATH:/opt/homebrew/bin + ;; +esac + +path_to_clang_format=`which clang-format` +have_supported_clang_format_version=0 +if [[ "X$path_to_clang_format" != "X" ]]; then + + # check clang-format version + clang_format_version=`clang-format --version | sed 's/.* version //' | awk -F'[.]' '{print $1}'` + + #echo "supported_clang_format_versions=\"$supported_clang_format_versions\" clang_format_version=$clang_format_version" + + # if found clang-format, but wrong version, check if docker is available + for v in $supported_clang_format_versions; do + if [[ $clang_format_version -eq $v ]]; then + have_supported_clang_format_version=1 + break + fi + done +fi + +if [[ $have_supported_clang_format_version -eq 0 ]]; then + echo "WARNING: found clang-format with unsupported version $clang_format_version (supported versions: $supported_clang_format_versions)" + + # look for docker + path_to_docker=`which docker` + if [[ "X$path_to_docker" = "X" ]]; then + echo "ERROR: docker is not found either, PATH=$PATH, install one of supported clang-format versions (any of these: $supported_clang_format_versions) or install docker" + exit 1 + fi + + # if docker up? + docker info >/dev/null 2>&1 + if [[ $? -ne 0 ]]; then + echo "ERROR: docker is found but not running, start it" + exit 1 + fi + + # use docker to run clang-format + mount_path=$(readlink -f "$HOME") + + # convert file names in the arguments to relative paths + args="" + for i in "$@"; do + # skip options + if [[ "$i" == -* ]]; then + args="$args $i" + continue + fi + abs_file_path=$(readlink -f "$i") + if [[ "X$abs_file_path" = "X" ]]; then + echo "ERROR: given file $i is not found" + exit 1 + fi + + dir=$(dirname $abs_file_path) + file_path_relative_to_project_root=$(basename $abs_file_path) + while [[ "$dir" != "$mount_path" && "$dir" != "/" ]]; do + file_path_relative_to_project_root="$(basename $dir)/$file_path_relative_to_project_root" + dir=$(dirname $dir) + #echo "dir=$dir file_path_relative_to_project_root=$file_path_relative_to_project_root" + done + if [[ "$dir" == "/" ]]; then + echo "ERROR: given file $i (absolute path $abs_file_path) is not under \$HOME=$mount_path, cannot use docker-based clang-format in this case" + exit 1 + fi + args="$args /hostHOME/$file_path_relative_to_project_root" + done + docker run --platform linux/x86_64 -v $mount_path:/hostHOME xianpengshen/clang-tools:$preferred_clang_format_version clang-format $args +else + #echo "found $path_to_clang_format with required version $clang_format_version" + clang-format $* +fi diff --git a/bin/admin/dependency-versions-update-hook.py b/bin/admin/dependency-versions-update-hook.py index f381ccc11..aecb3d41c 100755 --- a/bin/admin/dependency-versions-update-hook.py +++ b/bin/admin/dependency-versions-update-hook.py @@ -59,12 +59,7 @@ def replace_dep_id(topsrc, file_ext, dep_name, old_id, new_id, search_prefix = ' tokens = line.split() if len(tokens) < 3: continue - if tokens[1].find('TRACKED_BOOST') != -1: - if tokens[1].find('PREVIOUS') != -1: - boost_old_version = tokens[2] - else: - boost_new_version = tokens[2] - elif tokens[1].find('TRACKED_TILEDARRAY') != -1: + if tokens[1].find('TRACKED_TILEDARRAY') != -1: if tokens[1].find('PREVIOUS') != -1: ta_old_tag = tokens[2] else: @@ -77,9 +72,6 @@ def replace_dep_id(topsrc, file_ext, dep_name, old_id, new_id, search_prefix = ' any_files_changed = False -# Boost version in INSTALL.md -any_files_changed |= replace_dep_id(topsrc, 'md', 'Boost', boost_old_version, boost_new_version, ', version ', ' or higher (N.B.') - # replace TA tag in INSTALL.md any_files_changed |= replace_dep_id(topsrc, 'md', 'TiledArray', ta_old_tag, ta_new_tag, '', '') diff --git a/cmake/modules/FindOrFetchTiledArray.cmake b/cmake/modules/FindOrFetchTiledArray.cmake index 09b9cf9e4..a8b203462 100644 --- a/cmake/modules/FindOrFetchTiledArray.cmake +++ b/cmake/modules/FindOrFetchTiledArray.cmake @@ -26,7 +26,6 @@ else (TARGET tiledarray) SOURCE_DIR TILEDARRAY_SOURCE_DIR BINARY_DIR TILEDARRAY_BINARY_DIR ) - set_property(DIRECTORY ${TILEDARRAY_SOURCE_DIR} PROPERTY EXCLUDE_FROM_ALL TRUE) # TA includes dependencies that are built manually, not using FetchContent, hence make sure we build them before building any SeQuant-dependent code add_dependencies(tiledarray External-tiledarray) diff --git a/cmake/sequant-config.cmake.in b/cmake/sequant-config.cmake.in index e0b55f3ab..a201acaaa 100644 --- a/cmake/sequant-config.cmake.in +++ b/cmake/sequant-config.cmake.in @@ -16,38 +16,37 @@ set(SEQUANT_EXT_VERSION "@SEQUANT_EXT_VERSION@") @PACKAGE_INIT@ -if(NOT TARGET Boost::boost OR NOT TARGET Boost::regex) - set(Boost_USE_CONFIG @Boost_USE_CONFIG@) - if (Boost_USE_CONFIG) - set(Boost_CONFIG @Boost_CONFIG@) - if (NOT Boost_CONFIG OR NOT EXISTS ${Boost_CONFIG}) - message(FATAL_ERROR "Expected Boost config file at ${Boost_CONFIG}; directory moved since SeQuant configuration?") - endif() - get_filename_component(Boost_DIR ${Boost_CONFIG} DIRECTORY) - find_package(Boost CONFIG QUIET REQUIRED COMPONENTS regex PATHS ${Boost_DIR} NO_DEFAULT_PATH) - else (Boost_USE_CONFIG) - set(BOOST_INCLUDEDIR @Boost_INCLUDE_DIR@) - set(BOOST_LIBRARYDIR @Boost_LIBRARY_DIR_RELEASE@) - if (NOT BOOST_LIBRARYDIR OR NOT EXISTS ${BOOST_LIBRARYDIR}) - set(BOOST_LIBRARYDIR @Boost_LIBRARY_DIR_DEBUG@) - endif() - set(Boost_NO_SYSTEM_PATHS OFF) - if (BOOST_LIBRARYDIR AND BOOST_INCLUDEDIR) - if (EXISTS ${BOOST_LIBRARYDIR} AND EXISTS ${BOOST_INCLUDEDIR}) - set(Boost_NO_SYSTEM_PATHS ON) - endif() - endif() - find_package(Boost QUIET REQUIRED COMPONENTS regex) - endif (Boost_USE_CONFIG) +@Boost_CONFIG_FILE_CONTENTS@ + +set(SEQUANT_HAS_TILEDARRAY @SEQUANT_HAS_TILEDARRAY@) +if(SEQUANT_HAS_TILEDARRAY AND NOT TARGET tiledarray) + set(TiledArray_CONFIG @TiledArray_CONFIG@) + if (NOT TiledArray_CONFIG OR NOT EXISTS ${TiledArray_CONFIG}) + message(FATAL_ERROR "Expected TiledArray config file at ${TiledArray_CONFIG}; directory moved since SeQuant configuration?") + endif() + get_filename_component(TiledArray_DIR ${TiledArray_CONFIG} DIRECTORY) + find_dependency(TiledArray CONFIG QUIET REQUIRED COMPONENTS tiledarray PATHS ${TiledArray_DIR} NO_DEFAULT_PATH) +endif() + +set(SEQUANT_HAS_EIGEN @SEQUANT_HAS_EIGEN@) +if (NOT TARGET Eigen3::Eigen AND SEQUANT_HAS_EIGEN) + if (TARGET TiledArray_Eigen) + add_library(Eigen3::Eigen ALIAS TiledArray_Eigen) + else() + get_filename_component(Eigen3_DIR "@Eigen3_CONFIG@" DIRECTORY) + # re:NO_CMAKE_PACKAGE_REGISTRY: eigen3 registers its *build* tree with the user package registry ... + # to avoid issues with wiped build directory look for installed eigen + find_package(Eigen3 3.0 CONFIG REQUIRED NO_CMAKE_PACKAGE_REGISTRY HINTS "${Eigen3_DIR}") + endif() endif() if (NOT TARGET range-v3::range-v3) get_filename_component(range-v3_DIR "@range-v3_CONFIG@" DIRECTORY) - find_package(range-v3 QUIET REQUIRED HINTS "${range-v3_DIR}") + find_dependency(range-v3 QUIET REQUIRED HINTS "${range-v3_DIR}") endif(NOT TARGET range-v3::range-v3) if (NOT TARGET Threads::Threads) - find_package(Threads REQUIRED) + find_dependency(Threads REQUIRED) endif (NOT TARGET Threads::Threads) # Include library IMPORT targets diff --git a/external/boost.cmake b/external/boost.cmake new file mode 100644 index 000000000..4bde88973 --- /dev/null +++ b/external/boost.cmake @@ -0,0 +1,59 @@ +# -*- mode: cmake -*- + +# Boost can be discovered by every (sub)package but only the top package can *build* it ... +# in either case must declare the components used by SeQuant +set(required_components + headers + container + container_hash + core + fusion + locale + multiprecision + # numeric_conversion + # numeric_interval + accumulators # including numeric_* as targets is broken, instead include accumulators to ensure that numeric_{conversion,interval,ublas} are included + range + regex + spirit + variant +) +if (DEFINED Boost_REQUIRED_COMPONENTS) + list(APPEND Boost_REQUIRED_COMPONENTS + ${required_components}) + list(REMOVE_DUPLICATES Boost_REQUIRED_COMPONENTS) +else () + set(Boost_REQUIRED_COMPONENTS "${required_components}" CACHE STRING "Components of Boost to discovered or built") +endif () +set(optional_components) +if (DEFINED Boost_OPTIONAL_COMPONENTS) + list(APPEND Boost_OPTIONAL_COMPONENTS + ${optional_components} + ) + list(REMOVE_DUPLICATES Boost_OPTIONAL_COMPONENTS) +else () + set(Boost_OPTIONAL_COMPONENTS "${optional_components}" CACHE STRING "Optional components of Boost to discovered or built") +endif () + +if (NOT DEFINED Boost_FETCH_IF_MISSING) + set(Boost_FETCH_IF_MISSING 1) +endif () + +include(${vg_cmake_kit_SOURCE_DIR}/modules/FindOrFetchBoost.cmake) + +if (Boost_BUILT_FROM_SOURCE) + if ("${PROJECT_NAME}" STREQUAL "${CMAKE_PROJECT_NAME}") + add_custom_target(build-boost-in-SeQuant) + foreach(_target IN LISTS Boost_FOUND_TARGETS Boost_MODULAR_TARGETS_NOT_BUILT_BY_INSTALL) + add_dependencies(build-boost-in-SeQuant Boost::${_target}) + endforeach() + endif() +endif() + +# Boost.Move is broken in 1.77 and 1.78 unless using c++20 +# fixed in 1.79 via https://github.com/boostorg/move/commit/78f26da1f3a5a3831e9e70efe83f9c56eef94e8c +if (CMAKE_CXX_STANDARD LESS 20) + if (Boost_VERSION_MACRO GREATER_EQUAL 107700 AND Boost_VERSION_MACRO LESS 107900) + message(FATAL_ERROR "Found Boost 1.77 <= version < 1.79, but its Boost.Move is broken with pre-C++20: use a version older than 1.77 or newer than 1.78") + endif () +endif () diff --git a/external/versions.cmake b/external/versions.cmake index e3d4828e4..0558f79f6 100644 --- a/external/versions.cmake +++ b/external/versions.cmake @@ -1,13 +1,10 @@ # for each dependency track both current and previous id (the variable for the latter must contain PREVIOUS) # to be able to auto-update them -set(SEQUANT_TRACKED_VGCMAKEKIT_TAG d6746098e63deab4032309c4455bb084a17ff51a) - -set(SEQUANT_TRACKED_BOOST_VERSION 1.72) -set(SEQUANT_TRACKED_BOOST_PREVIOUS_VERSION 1.72) +set(SEQUANT_TRACKED_VGCMAKEKIT_TAG e0d04e91a84b7e71d9b87682c46c518e9966bd78) set(SEQUANT_TRACKED_RANGEV3_TAG 0.12.0) set(SEQUANT_TRACKED_RANGEV3_PREVIOUS_TAG d800a032132512a54c291ce55a2a43e0460591c7) -set(SEQUANT_TRACKED_TILEDARRAY_TAG 81bafdc39568d7d5f981d4453e4a2f49a9c0c428) -set(SEQUANT_TRACKED_TILEDARRAY_PREVIOUS_TAG d33511dac8e8baaaa28e295bffbd2503ef830c9d) +set(SEQUANT_TRACKED_TILEDARRAY_TAG 954d861f553e938c3cfc4892fce9234bf4bf7193) +set(SEQUANT_TRACKED_TILEDARRAY_PREVIOUS_TAG 98c6c3b2921589552a716acc2336aa2983e8b378) diff --git a/tests/unit/test_space.cpp b/tests/unit/test_space.cpp index 1a88eb776..b8735f711 100644 --- a/tests/unit/test_space.cpp +++ b/tests/unit/test_space.cpp @@ -57,6 +57,15 @@ TEST_CASE("IndexSpace", "[elements]") { REQUIRE(IndexSpace::instance(L"i") == IndexSpace::nullqns); REQUIRE(IndexSpace::nullqns == IndexSpace::instance(L"i").qns()); REQUIRE(IndexSpace::nullqns == IndexSpace::instance(L"i")); + + // use nondefault mask + TypeAttr::used_bits = 0b100; + REQUIRE(IndexSpace::active_occupied == IndexSpace::occupied); + REQUIRE(IndexSpace::active_occupied != IndexSpace::inactive_occupied); + REQUIRE(IndexSpace::active_occupied != IndexSpace::frozen_occupied); + REQUIRE(IndexSpace::active_occupied == IndexSpace::all); + REQUIRE(IndexSpace::active_occupied == IndexSpace::all_active); + TypeAttr::used_bits = 0xffff; } SECTION("ordering") { @@ -93,6 +102,15 @@ TEST_CASE("IndexSpace", "[elements]") { REQUIRE(i < iA); REQUIRE(i < iB); } + + // use nondefault mask + TypeAttr::used_bits = 0b100; + REQUIRE(!(IndexSpace::active_occupied < IndexSpace::occupied)); + REQUIRE(!(IndexSpace::inactive_occupied < IndexSpace::frozen_occupied)); + REQUIRE(IndexSpace::inactive_occupied < IndexSpace::active_occupied); + REQUIRE(!(IndexSpace::active_occupied < IndexSpace::all)); + REQUIRE(!(IndexSpace::active_occupied < IndexSpace::all_active)); + TypeAttr::used_bits = 0xffff; } SECTION("set operations") {