From 24e72091c0d31f69bd8ae0d4d3acfc3db0004eec Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sun, 13 Oct 2024 14:56:33 +0200 Subject: [PATCH] Ditch abseil, use Boost instead. --- CMakeLists.txt | 17 +- doc/install.rst | 3 +- include/obake/detail/abseil.hpp | 37 ---- include/obake/polynomials/polynomial.hpp | 253 +++++++++++------------ include/obake/series.hpp | 57 +---- obake-config.cmake.in | 1 - tools/conda_asan.sh | 2 +- tools/conda_coverage.sh | 2 +- tools/conda_docs.sh | 2 +- tools/conda_ubsan.sh | 2 +- 10 files changed, 135 insertions(+), 241 deletions(-) delete mode 100644 include/obake/detail/abseil.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index b5b2a5c99..bce8e828c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,12 +160,9 @@ if(${mp++_VERSION} VERSION_LESS ${_OBAKE_MIN_MPPP_VERSION}) message(FATAL_ERROR "The minimum mp++ version required by obake is ${_OBAKE_MIN_MPPP_VERSION}, but version ${mp++_VERSION} was found instead.") endif() -# abseil. -find_package(absl REQUIRED) - # Boost setup. -# NOTE: stacktrace available since 1.65.0. -set(_OBAKE_MIN_BOOST_VERSION "1.69") +# NOTE: need 1.81 for unordered_flat_set. +set(_OBAKE_MIN_BOOST_VERSION "1.81") # NOTE: we look for Boost in CONFIG mode first, as that has become the official supported way # of locating Boost in recent Boost/CMake versions. If we fail, we try again in # MODULE mode as last resort. @@ -307,7 +304,6 @@ if(YACMA_COMPILER_IS_MSVC) "${CMAKE_CURRENT_LIST_DIR}/include/obake/key/key_tex_stream_insert.hpp" "${CMAKE_CURRENT_LIST_DIR}/include/obake/key/key_trim.hpp" "${CMAKE_CURRENT_LIST_DIR}/include/obake/key/key_trim_identify.hpp" - "${CMAKE_CURRENT_LIST_DIR}/include/obake/detail/abseil.hpp" "${CMAKE_CURRENT_LIST_DIR}/include/obake/detail/atomic_flag_array.hpp" "${CMAKE_CURRENT_LIST_DIR}/include/obake/detail/atomic_lock_guard.hpp" "${CMAKE_CURRENT_LIST_DIR}/include/obake/detail/fcast.hpp" @@ -360,13 +356,6 @@ target_compile_options(obake PRIVATE target_compile_features(obake PUBLIC cxx_std_20) # Ensure vanilla C++ is being used. set_property(TARGET obake PROPERTY CXX_EXTENSIONS NO) -if(YACMA_COMPILER_IS_MSVC) - # NOTE: older abseil versions have a problem on MSVC - # when using C++20: - # https://github.com/abseil/abseil-cpp/issues/649 - # Hopefully we can eventually remove this. - target_compile_definitions(obake PUBLIC -D_HAS_DEPRECATED_RESULT_OF=1) -endif() if(YACMA_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "10") # GCC < 10 still needs the -fconcepts flag, even if C++20 is in use. message(STATUS "Activating the '-fconcepts' flag for GCC < 10.") @@ -383,8 +372,6 @@ target_include_directories(obake PUBLIC target_link_libraries(obake PUBLIC Threads::Threads mp++::mp++ - absl::flat_hash_map - absl::flat_hash_set Boost::boost Boost::serialization Boost::disable_autolinking diff --git a/doc/install.rst b/doc/install.rst index 5fb3ad90a..33c14a61a 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -11,8 +11,7 @@ Requirements Currently, obake has the following mandatory dependencies: * the `mp++ `_ multiprecision library (at least version 0.27), -* the `Boost `_ C++ libraries (at least version 1.65), -* the `Abseil `_ C++ libraries, +* the `Boost `_ C++ libraries (at least version 1.81), * the `Intel TBB `__ library, * the `{fmt} `__ library. diff --git a/include/obake/detail/abseil.hpp b/include/obake/detail/abseil.hpp deleted file mode 100644 index 09d3fa55d..000000000 --- a/include/obake/detail/abseil.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2019-2020 Francesco Biscani (bluescarni@gmail.com) -// -// This file is part of the obake library. -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef OBAKE_DETAIL_ABSEIL_HPP -#define OBAKE_DETAIL_ABSEIL_HPP - -// NOTE: on MSVC, some abseil headers give -// warnings in debug mode, which make -// obake's debug builds fail. Suppress -// those warnings. -#if defined(_MSC_VER) && !defined(__clang__) - -#pragma warning(push) -#pragma warning(disable : 4245) -#pragma warning(disable : 4127) -#pragma warning(disable : 4996) -#pragma warning(disable : 4324) - -#endif - -#include -#include -#include -#include - -#if defined(_MSC_VER) && !defined(__clang__) - -#pragma warning(pop) - -#endif - -#endif diff --git a/include/obake/polynomials/polynomial.hpp b/include/obake/polynomials/polynomial.hpp index 992cc7cc5..1a007f391 100644 --- a/include/obake/polynomials/polynomial.hpp +++ b/include/obake/polynomials/polynomial.hpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -41,7 +42,6 @@ #include #include -#include #include #include #include @@ -120,111 +120,111 @@ concept Polynomial = is_polynomial_v; namespace detail { - // Enabler for make_polynomials(): - // - need at least 1 Arg, - // - T must be a polynomial, - // - std::string can be constructed from each input Args, - // - poly key can be constructed from a const int * range, - // - poly cf can be constructed from an integral literal. - template - using make_polynomials_supported - = ::std::conjunction<::std::integral_constant 0u)>, is_polynomial, - ::std::is_constructible<::std::string, const Args &>..., - ::std::is_constructible, const int *, const int *>, - ::std::is_constructible, int>>; - - template - using make_polynomials_enabler = ::std::enable_if_t::value, int>; - - // Overload with a symbol set. - template = 0> - inline auto make_polynomials_impl(const symbol_set &ss, const Args &...names) - { - // Create a temp vector of ints which we will use to - // init the keys. - ::std::vector tmp(::obake::safe_cast<::std::vector::size_type>(ss.size())); - - // Create the fw version of the symbol set. - const detail::ss_fw ss_fw(ss); - - auto make_poly = [&ss_fw, &ss, &tmp](const auto &n) { - using str_t = remove_cvref_t; - - // Fetch a const reference to either the original - // std::string object n, or to a string temporary - // created from it. - const auto &s = [&n]() -> decltype(auto) { - if constexpr (::std::is_same_v) { - return n; - } else { - return ::std::string(n); - } - }(); +// Enabler for make_polynomials(): +// - need at least 1 Arg, +// - T must be a polynomial, +// - std::string can be constructed from each input Args, +// - poly key can be constructed from a const int * range, +// - poly cf can be constructed from an integral literal. +template +using make_polynomials_supported + = ::std::conjunction<::std::integral_constant 0u)>, is_polynomial, + ::std::is_constructible<::std::string, const Args &>..., + ::std::is_constructible, const int *, const int *>, + ::std::is_constructible, int>>; + +template +using make_polynomials_enabler = ::std::enable_if_t::value, int>; + +// Overload with a symbol set. +template = 0> +inline auto make_polynomials_impl(const symbol_set &ss, const Args &...names) +{ + // Create a temp vector of ints which we will use to + // init the keys. + ::std::vector tmp(::obake::safe_cast<::std::vector::size_type>(ss.size())); - // Init the retval, assign the symbol set. - T retval; - retval.set_symbol_set_fw(ss_fw); + // Create the fw version of the symbol set. + const detail::ss_fw ss_fw(ss); - // Try to locate s within the symbol set. - const auto it = ss.find(s); - if (obake_unlikely(it == ss.end() || *it != s)) { - obake_throw(::std::invalid_argument, "Cannot create a polynomial with symbol set " - + detail::to_string(ss) + " from the generator '" + s - + "': the generator is not in the symbol set"); + auto make_poly = [&ss_fw, &ss, &tmp](const auto &n) { + using str_t = remove_cvref_t; + + // Fetch a const reference to either the original + // std::string object n, or to a string temporary + // created from it. + const auto &s = [&n]() -> decltype(auto) { + if constexpr (::std::is_same_v) { + return n; + } else { + return ::std::string(n); } + }(); - // Set to 1 the exponent of the corresponding generator. - tmp[static_cast<::std::vector::size_type>(ss.index_of(it))] = 1; + // Init the retval, assign the symbol set. + T retval; + retval.set_symbol_set_fw(ss_fw); - // Create and add a new term. - // NOTE: at least for some monomial types (e.g., packed monomial), - // we will be computing the iterator difference when constructing from - // a range. Make sure we can safely represent the size of tmp via - // iterator difference. - ::obake::detail::it_diff_check(tmp.size()); - retval.add_term(series_key_t(::std::as_const(tmp).data(), ::std::as_const(tmp).data() + tmp.size()), 1); + // Try to locate s within the symbol set. + const auto it = ss.find(s); + if (obake_unlikely(it == ss.end() || *it != s)) { + obake_throw(::std::invalid_argument, "Cannot create a polynomial with symbol set " + detail::to_string(ss) + + " from the generator '" + s + + "': the generator is not in the symbol set"); + } - // Set back to zero the exponent that was previously set to 1. - tmp[static_cast<::std::vector::size_type>(ss.index_of(it))] = 0; + // Set to 1 the exponent of the corresponding generator. + tmp[static_cast<::std::vector::size_type>(ss.index_of(it))] = 1; - return retval; - }; + // Create and add a new term. + // NOTE: at least for some monomial types (e.g., packed monomial), + // we will be computing the iterator difference when constructing from + // a range. Make sure we can safely represent the size of tmp via + // iterator difference. + ::obake::detail::it_diff_check(tmp.size()); + retval.add_term(series_key_t(::std::as_const(tmp).data(), ::std::as_const(tmp).data() + tmp.size()), 1); - return detail::make_array(make_poly(names)...); - } + // Set back to zero the exponent that was previously set to 1. + tmp[static_cast<::std::vector::size_type>(ss.index_of(it))] = 0; - // Overload without a symbol set. - template = 0> - inline auto make_polynomials_impl(const Args &...names) - { - auto make_poly = [](const auto &n) { - using str_t = remove_cvref_t; + return retval; + }; - // Init the retval, assign a symbol set containing only n. - T retval; - if constexpr (::std::is_same_v) { - retval.set_symbol_set(symbol_set{n}); - } else { - retval.set_symbol_set(symbol_set{::std::string(n)}); - } + return detail::make_array(make_poly(names)...); +} + +// Overload without a symbol set. +template = 0> +inline auto make_polynomials_impl(const Args &...names) +{ + auto make_poly = [](const auto &n) { + using str_t = remove_cvref_t; + + // Init the retval, assign a symbol set containing only n. + T retval; + if constexpr (::std::is_same_v) { + retval.set_symbol_set(symbol_set{n}); + } else { + retval.set_symbol_set(symbol_set{::std::string(n)}); + } - static constexpr int arr[] = {1}; + static constexpr int arr[] = {1}; - // Create and add a new term. - retval.add_term(series_key_t(&arr[0], &arr[0] + 1), 1); + // Create and add a new term. + retval.add_term(series_key_t(&arr[0], &arr[0] + 1), 1); - return retval; - }; + return retval; + }; - return detail::make_array(make_poly(names)...); - } + return detail::make_array(make_poly(names)...); +} } // namespace detail // Polynomial creation functor. template -inline constexpr auto make_polynomials - = [](const auto &...args) OBAKE_SS_FORWARD_LAMBDA(detail::make_polynomials_impl(args...)); +inline constexpr auto make_polynomials = + [](const auto &...args) OBAKE_SS_FORWARD_LAMBDA(detail::make_polynomials_impl(args...)); namespace polynomials { @@ -666,8 +666,8 @@ inline auto poly_mul_estimate_product_size(const ::std::vector &x, const ::s // Init the hash set we will be using for the trials. // NOTE: use exactly the same hasher/comparer as in series.hpp, so that // we are sure we are being consistent wrt type requirements, etc. - using local_set = ::absl::flat_hash_set; + using local_set = ::boost::unordered_flat_set; local_set ls; ls.reserve(::obake::safe_cast(vidx1.size())); @@ -1361,15 +1361,8 @@ inline void poly_mul_impl_mt_hm(Ret &retval, const T &x, const U &y, const Args // coefficient. This is wasteful, it would be better to directly // construct the coefficient product only if the insertion actually // takes place (using a lazy multiplication approach). - // Unfortunately, abseil's hash map is not exception safe, - // and if the lazy multiplication throws, the table will be left - // in an inconsistent state. See: - // https://github.com/abseil/abseil-cpp/issues/388 - // See the commit - // 3e334f560d5844f5f2d8face05aa58be21649ff8 + // See the commit 3e334f560d5844f5f2d8face05aa58be21649ff8 // for an implementation of the lazy multiplication approach. - // If they fix the exception safety issue, we can re-enable the - // lazy approach. // NOTE: the coefficient concept demands default constructibility, // thus we can always emplace without arguments for the coefficient. const auto res = table.try_emplace(tmp_key); @@ -1401,11 +1394,10 @@ inline void poly_mul_impl_mt_hm(Ret &retval, const T &x, const U &y, const Args // in the current table. const auto it_f = table.end(); for (auto it = table.begin(); it != it_f;) { - // NOTE: abseil's flat_hash_map returns void on erase(), - // thus we need to increase 'it' before possibly erasing. - // erase() does not cause rehash and thus will not invalidate - // any other iterator apart from the one being erased. if (obake_unlikely(::obake::is_zero(::std::as_const(it->second)))) { + // NOTE: increase 'it' before erasing. + // erase() does not cause rehash and thus will not invalidate + // any other iterator apart from the one being erased. table.erase(it++); } else { ++it; @@ -1504,15 +1496,8 @@ inline void poly_mul_impl_mt_hm(Ret &retval, const T &x, const U &y, const Args // coefficient. This is wasteful, it would be better to directly // construct the coefficient product only if the insertion actually // takes place (using a lazy multiplication approach). - // Unfortunately, abseil's hash map is not exception safe, - // and if the lazy multiplication throws, the table will be left - // in an inconsistent state. See: - // https://github.com/abseil/abseil-cpp/issues/388 - // See the commit - // 3e334f560d5844f5f2d8face05aa58be21649ff8 + // See the commit 3e334f560d5844f5f2d8face05aa58be21649ff8 // for an implementation of the lazy multiplication approach. - // If they fix the exception safety issue, we can re-enable the - // lazy approach. // NOTE: the coefficient concept demands default constructibility, // thus we can always emplace without arguments for the coefficient. const auto res = table.try_emplace(tmp_key); @@ -1544,11 +1529,10 @@ inline void poly_mul_impl_mt_hm(Ret &retval, const T &x, const U &y, const Args // in the current table. const auto it_f = table.end(); for (auto it = table.begin(); it != it_f;) { - // NOTE: abseil's flat_hash_map returns void on erase(), - // thus we need to increase 'it' before possibly erasing. - // erase() does not cause rehash and thus will not invalidate - // any other iterator apart from the one being erased. if (obake_unlikely(::obake::is_zero(::std::as_const(it->second)))) { + // NOTE: increase 'it' before erasing. + // erase() does not cause rehash and thus will not invalidate + // any other iterator apart from the one being erased. table.erase(it++); } else { ++it; @@ -1867,11 +1851,10 @@ inline void poly_mul_impl_simple(Ret &retval, const T &x, const U &y, const Args // in the return value. const auto it_f = tab.end(); for (auto it = tab.begin(); it != it_f;) { - // NOTE: abseil's flat_hash_map returns void on erase(), - // thus we need to increase 'it' before possibly erasing. - // erase() does not cause rehash and thus will not invalidate - // any other iterator apart from the one being erased. if (obake_unlikely(::obake::is_zero(::std::as_const(it->second)))) { + // NOTE: increase 'it' before erasing. + // erase() does not cause rehash and thus will not invalidate + // any other iterator apart from the one being erased. tab.erase(it++); } else { ++it; @@ -2041,8 +2024,9 @@ inline auto poly_mul_impl_switch(const T &x, const U &y, const Args &...args) } // namespace detail template -requires(detail::poly_mul_algo, polynomial> != 0) inline detail::poly_mul_ret_t< - polynomial, polynomial> series_mul(const polynomial &x, const polynomial &y) + requires(detail::poly_mul_algo, polynomial> != 0) +inline detail::poly_mul_ret_t, polynomial> series_mul(const polynomial &x, + const polynomial &y) { return detail::poly_mul_impl_switch(x, y); } @@ -2127,18 +2111,17 @@ inline constexpr auto poly_mul_truncated_p_degree_algo // NOTE: do we need the type traits/concepts as well? // NOTE: should these be function objects? template -requires(detail::poly_mul_truncated_degree_algo, polynomial, V> != 0) inline detail:: - poly_mul_ret_t, polynomial> truncated_mul(const polynomial &x, - const polynomial &y, const V &max_degree) + requires(detail::poly_mul_truncated_degree_algo, polynomial, V> != 0) +inline detail::poly_mul_ret_t, polynomial> +truncated_mul(const polynomial &x, const polynomial &y, const V &max_degree) { return detail::poly_mul_impl_switch(x, y, max_degree); } template -requires(detail::poly_mul_truncated_p_degree_algo, polynomial, V> != 0) inline detail:: - poly_mul_ret_t, polynomial> truncated_mul(const polynomial &x, - const polynomial &y, const V &max_degree, - const symbol_set &s) + requires(detail::poly_mul_truncated_p_degree_algo, polynomial, V> != 0) +inline detail::poly_mul_ret_t, polynomial> +truncated_mul(const polynomial &x, const polynomial &y, const V &max_degree, const symbol_set &s) { return detail::poly_mul_impl_switch(x, y, max_degree, s); } @@ -2193,9 +2176,8 @@ inline auto pow_poly_impl(T &&x, U &&y) // Exponentiation. template -requires Polynomial> &&( - customisation::internal::series_default_pow_algo< - T &&, U &&> != 0) inline customisation::internal::series_default_pow_ret_t pow(T &&x, U &&y) + requires Polynomial> && (customisation::internal::series_default_pow_algo != 0) +inline customisation::internal::series_default_pow_ret_t pow(T &&x, U &&y) { return detail::pow_poly_impl(::std::forward(x), ::std::forward(y)); } @@ -2327,8 +2309,8 @@ inline auto poly_subs_impl(T &&x_, const symbol_map &sm) // Polynomial subs. template -requires Polynomial> &&( - detail::poly_subs_algo != 0) inline detail::poly_subs_ret_t subs(T &&x, const symbol_map &sm) + requires Polynomial> && (detail::poly_subs_algo != 0) +inline detail::poly_subs_ret_t subs(T &&x, const symbol_map &sm) { return detail::poly_subs_impl(::std::forward(x), sm); } @@ -2662,8 +2644,8 @@ inline auto poly_diff_impl(T &&x_, const ::std::string &s) } // namespace detail template -requires Polynomial> &&(detail::poly_diff_algo != 0) inline detail::poly_diff_ret_t diff( - T &&x, const ::std::string &s) + requires Polynomial> && (detail::poly_diff_algo != 0) +inline detail::poly_diff_ret_t diff(T &&x, const ::std::string &s) { return detail::poly_diff_impl(::std::forward(x), s); } @@ -2876,9 +2858,8 @@ inline auto poly_integrate_impl(T &&x_, const ::std::string &s) } // namespace detail template -requires Polynomial> &&( - detail::poly_integrate_algo != 0) inline detail::poly_integrate_ret_t integrate(T &&x, - const ::std::string &s) + requires Polynomial> && (detail::poly_integrate_algo != 0) +inline detail::poly_integrate_ret_t integrate(T &&x, const ::std::string &s) { return detail::poly_integrate_impl(::std::forward(x), s); } diff --git a/include/obake/series.hpp b/include/obake/series.hpp index f03737c90..6c3a890d8 100644 --- a/include/obake/series.hpp +++ b/include/obake/series.hpp @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -50,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -483,39 +483,12 @@ concept SeriesConvertible = is_series_convertible_v; namespace detail { -// A small hashing wrapper for keys. It accomplishes two tasks: -// - force the evaluation of a key through const reference, -// so that, in the Key requirements, we can request hashability -// through const lvalue ref; -// - provide additional mixing. +// Wrapper to force key hashing via const lvalue refs. struct series_key_hasher { - // NOTE: here we are duplicating a bit of internal - // abseil code for integral hash mixing, with the intent - // of avoiding the per-process seeding that abseil does. - // See here for the original code: - // https://github.com/abseil/abseil-cpp/blob/37dd2562ec830d547a1524bb306be313ac3f2556/absl/hash/internal/hash.h#L754 - // If/when abseil starts supporting DLL builds, we can - // remove this code and switch back to using abseil's - // own hash machinery for mixing. - static constexpr ::std::uint64_t kMul - = sizeof(::std::size_t) == 4u ? ::std::uint64_t{0xcc9e2d51ull} : ::std::uint64_t{0x9ddfea08eb382d69ull}; - ABSL_ATTRIBUTE_ALWAYS_INLINE static ::std::uint64_t Mix(::std::uint64_t state, ::std::uint64_t v) - { - using MultType = ::std::conditional_t; - // We do the addition in 64-bit space to make sure the 128-bit - // multiplication is fast. If we were to do it as MultType the compiler has - // to assume that the high word is non-zero and needs to perform 2 - // multiplications instead of one. - MultType m = state + v; - m *= kMul; - return static_cast<::std::uint64_t>(m ^ (m >> (sizeof(m) * 8 / 2))); - } template ::std::size_t operator()(const K &k) const noexcept(noexcept(::obake::hash(k))) { - // NOTE: mix with a compile-time seed. - return static_cast<::std::size_t>( - series_key_hasher::Mix(15124392053943080205ull, static_cast<::std::uint64_t>(::obake::hash(k)))); + return ::obake::hash(k); } }; @@ -661,7 +634,8 @@ class series public: // Define the table type, and the type holding the set of tables (i.e., the segmented table). - using table_type = ::absl::flat_hash_map; + using table_type + = ::boost::unordered::unordered_flat_map; using s_table_type = ::boost::container::small_vector; // Shortcut for the segmented table size type. @@ -1518,11 +1492,6 @@ class series // - the original table had no incompatible keys, // - the original table did not overflow the max size, // - the original table had only unique keys. - // Note that deserialisation of a series that was saved - // in a previous program execution will result in a term - // order different from the original one due to abseil's salting, - // but the number of terms in a specific table will be the same - // because the first level hash is not salted. // NOTE: this is essentially identical to a straight emplace_back() // on the table, just with some added assertions. detail::series_add_term_table) - (sizeof(k) + sizeof(c))); } - // Add the space occupied by the unused slots. - assert(tab.capacity() >= tab.size()); - ret += (tab.capacity() - tab.size()) * sizeof(series_term_t); - + // NOTE: here we are not accounting for the empty slots in the table. + // Hopefully we do not end up very far from the true memory utilisation. return ret; } template @@ -3346,8 +3313,7 @@ inline series_default_div_ret_t series_default_div_impl(T &&x, U &&y c /= ::std::as_const(y); if (obake_unlikely(::obake::is_zero(::std::as_const(c)))) { - // NOTE: abseil's flat_hash_map returns void on erase(), - // thus we need to increase 'it' before possibly erasing. + // NOTE: increase 'it' before erasing. // erase() does not cause rehash and thus will not invalidate // any other iterator apart from the one being erased. t.erase(it++); @@ -4288,13 +4254,12 @@ inline void filter_impl(series &s, const F &f) const auto it_f = table.end(); for (auto it = table.begin(); it != it_f;) { - // NOTE: abseil's flat_hash_map returns void on erase(), - // thus we need to increase 'it' before possibly erasing. - // erase() does not cause rehash and thus will not invalidate - // any other iterator apart from the one being erased. if (f(::std::as_const(*it))) { ++it; } else { + // NOTE: increase 'it' before erasing. + // erase() does not cause rehash and thus will not invalidate + // any other iterator apart from the one being erased. table.erase(it++); } } diff --git a/obake-config.cmake.in b/obake-config.cmake.in index e0917c0db..9e65db1b4 100644 --- a/obake-config.cmake.in +++ b/obake-config.cmake.in @@ -8,7 +8,6 @@ find_package(mp++ REQUIRED) if(${mp++_VERSION} VERSION_LESS @_OBAKE_MIN_MPPP_VERSION@) message(FATAL_ERROR "The minimum mp++ version required by obake is @_OBAKE_MIN_MPPP_VERSION@, but version ${mp++_VERSION} was found instead.") endif() -find_package(absl REQUIRED) # TBB. Try to find it first in config mode (supported # since version 2021 after the oneTBB rename), and, if this # fails, fall back to our own FindTBB.cmake. This is of course diff --git a/tools/conda_asan.sh b/tools/conda_asan.sh index 33ecbd1e5..d3381b512 100644 --- a/tools/conda_asan.sh +++ b/tools/conda_asan.sh @@ -11,7 +11,7 @@ export deps_dir=$HOME/local export PATH="$HOME/miniconda/bin:$PATH" bash miniconda.sh -b -p $HOME/miniconda conda create -y -p $deps_dir cmake c-compiler cxx-compiler fmt backtrace mppp \ - libboost-devel libabseil tbb-devel ninja + libboost-devel tbb-devel ninja source activate $deps_dir # Create the build dir and cd into it. diff --git a/tools/conda_coverage.sh b/tools/conda_coverage.sh index b26a45bd4..2b78759f8 100644 --- a/tools/conda_coverage.sh +++ b/tools/conda_coverage.sh @@ -15,7 +15,7 @@ bash miniconda.sh -b -p $HOME/miniconda export PATH="$HOME/miniconda/bin:$PATH" conda config --add channels conda-forge conda config --set channel_priority strict -conda_pkgs="cmake mppp boost-cpp tbb tbb-devel abseil-cpp backtrace fmt" +conda_pkgs="cmake mppp boost-cpp tbb tbb-devel backtrace fmt" conda create -q -p $deps_dir -y $conda_pkgs source activate $deps_dir diff --git a/tools/conda_docs.sh b/tools/conda_docs.sh index a77b8e2d0..67e624d19 100644 --- a/tools/conda_docs.sh +++ b/tools/conda_docs.sh @@ -15,7 +15,7 @@ bash miniconda.sh -b -p $HOME/miniconda export PATH="$HOME/miniconda/bin:$PATH" conda config --add channels conda-forge conda config --set channel_priority strict -conda_pkgs="cmake mppp boost-cpp tbb tbb-devel abseil-cpp fmt backtrace sphinx pip" +conda_pkgs="cmake mppp boost-cpp tbb tbb-devel fmt backtrace sphinx pip" conda create -q -p $deps_dir -y $conda_pkgs source activate $deps_dir diff --git a/tools/conda_ubsan.sh b/tools/conda_ubsan.sh index 417957dd7..329b56a13 100644 --- a/tools/conda_ubsan.sh +++ b/tools/conda_ubsan.sh @@ -15,7 +15,7 @@ bash miniconda.sh -b -p $HOME/miniconda export PATH="$HOME/miniconda/bin:$PATH" conda config --add channels conda-forge conda config --set channel_priority strict -conda_pkgs="cmake mppp boost-cpp tbb tbb-devel abseil-cpp fmt backtrace" +conda_pkgs="cmake mppp boost-cpp tbb tbb-devel fmt backtrace" conda create -q -p $deps_dir -y $conda_pkgs source activate $deps_dir