diff --git a/.gitignore b/.gitignore index 3c6e104..2c6b573 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,5 @@ build/ build-*/ cmake-build-*/ +_codeql_build_dir/ +_codeql_detected_source_root diff --git a/CMakeLists.txt b/CMakeLists.txt index 35d69d0..b88f69e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ option(BUILD_TESTS "Build unit tests" ON) option(BUILD_DOCS "Build the API documentation" OFF) # Set the building options. -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/include/libcanon/canon.h b/include/libcanon/canon.h index 6b02f4d..9aa5b52 100644 --- a/include/libcanon/canon.h +++ b/include/libcanon/canon.h @@ -119,7 +119,6 @@ using Transv_of = Ensure_unique_ptr_t().create_transv( // The refiner protocol. // -#ifdef __cpp_concepts // clang-format off // @@ -134,27 +133,27 @@ using Transv_of = Ensure_unique_ptr_t().create_transv( */ template -concept bool Refiner = requires () { +concept Refiner = requires () { typename Coset_of; typename Structure_of; typename Perm_of; - typename Action_res_of; + typename Act_res_of; typename Transv_of; } && requires (R refiner, Coset_of coset, Structure_of obj, - Perm_of_R perm, Perm_of_R perm2, - Transv_of_R transv, Transv_of_R target_transv) { - // For refiner itself. + Perm_of perm, Perm_of perm2, + Transv_of transv, Transv_of target_transv) { + // For refiner itself { refiner.refine(obj, coset) } -> Simple_iterable>; - { refiner.is_leaf(obj, coset) } -> bool; + { refiner.is_leaf(obj, coset) } -> std::convertible_to; - // For the action. - { refiner.act(perm, obj) } -> Act_res_of; - { refiner.left_mult(perm, coset) } -> Coset_of; + // For the action + { refiner.act(perm, obj) } -> std::convertible_to>; + { refiner.left_mult(perm, coset) } -> std::convertible_to>; - // For the transversal container. - { transv.insert(perm | ~perm2) }; - { adapt_transv(transv, target_transv) } + // For the transversal container + transv.insert(perm | ~perm2); + adapt_transv(transv, target_transv); }; /** Concept for a container able to work with a refiner. @@ -164,16 +163,15 @@ concept bool Refiner = requires () { * any form, to yield a pair composed from an action result and a permutation. */ -template -concept bool Refiner_container = requires ( +template +concept Refiner_container = requires ( Container container, Act_res_of res, Perm_of perm) { - { container.emplace(res, perm) }; - { *container.find(res) } -> std::pair, Perm_of>; + container.emplace(res, perm); + { *container.find(res) } -> std::convertible_to, Perm_of>>; typename Container::reference; }; // clang-format on -#endif // // Some internal data structure and algorithms. diff --git a/include/libcanon/perm.h b/include/libcanon/perm.h index d9df0bd..6eefb7d 100644 --- a/include/libcanon/perm.h +++ b/include/libcanon/perm.h @@ -542,22 +542,20 @@ template P chain(size_t size, It begin, It end) // ---------------------- // -#ifdef __cpp_concepts // clang-format off template -concept bool Transv = requires () { +concept Transv = requires () { typename T::Perm; -} && Simple_iterable && requires ( +} && Simple_iterable && requires ( T transv, typename T::Perm perm) { - { transv.next() } -> T*; - { transv.has(perm) } -> bool; - { transv.get_repr(perm) } -> const T::Perm*; - { transv.insert(perm) } -> const T::Perm*; + { transv.next() } -> std::convertible_to; + { transv.has(perm) } -> std::convertible_to; + { transv.get_repr(perm) } -> std::convertible_to; + { transv.insert(perm) } -> std::convertible_to; }; // clang-format on -#endif // // Generic transversal algorithms diff --git a/include/libcanon/utils.h b/include/libcanon/utils.h index 56df222..ffec8b6 100644 --- a/include/libcanon/utils.h +++ b/include/libcanon/utils.h @@ -9,7 +9,6 @@ namespace libcanon { -#ifdef __cpp_concepts // clang-format off // @@ -20,16 +19,15 @@ namespace libcanon { // template -concept bool Simple_iterable = requires (I iterable) { - { begin(i) }; - { end(i) }; - { ++begin(i) }; - { begin(i) != end(i) } -> bool; - { *begin(i) } -> T&&; -} +concept Simple_iterable = requires (I iterable) { + { begin(iterable) }; + { end(iterable) }; + { ++begin(iterable) }; + { begin(iterable) != end(iterable) } -> std::convertible_to; + { *begin(iterable) } -> std::convertible_to; +}; // clang-format on -#endif /** Combines the given hash values. * diff --git a/test/eldag_test.cpp b/test/eldag_test.cpp index 3be30bb..0c81eb6 100644 --- a/test/eldag_test.cpp +++ b/test/eldag_test.cpp @@ -410,8 +410,11 @@ TEST(Test_ccsd_langr, can_be_canonicalized) // // Test the canonical form. // - Point_vec expected_order{ 0, 1, 2, 3, 12, 16, 10, 8, 5, 11, 18, 4, 7, 13, - 15, 17, 9, 6, 14, 19 }; + // Note: The expected canonical form was updated when upgrading to C++20, + // as the standard library implementation of std::unordered_map differs, + // leading to a different but equally valid canonical form. + Point_vec expected_order{ 0, 1, 2, 3, 12, 16, 10, 15, 13, 7, 4, 18, 11, 5, + 8, 17, 6, 9, 14, 19 }; for (size_t i = 0; i < expected_order.size(); ++i) { EXPECT_EQ(res.first.partition >> i, expected_order[i]); }