diff --git a/include/oneapi/tbb/detail/_config.h b/include/oneapi/tbb/detail/_config.h index 00f4aa4af4..1bcd75fe97 100644 --- a/include/oneapi/tbb/detail/_config.h +++ b/include/oneapi/tbb/detail/_config.h @@ -233,10 +233,8 @@ #if __INTEL_COMPILER && (!_MSC_VER || __INTEL_CXX11_MOVE__) #define __TBB_CPP14_VARIABLE_TEMPLATES_PRESENT (__TBB_LANG >= 201402L) #define __TBB_CPP17_DEDUCTION_GUIDES_PRESENT (__INTEL_COMPILER > 2021 && __TBB_LANG >= 201703L) - #define __TBB_CPP20_CONCEPTS_PRESENT 0 // TODO: add a mechanism for future addition #elif __clang__ #define __TBB_CPP14_VARIABLE_TEMPLATES_PRESENT (__has_feature(cxx_variable_templates)) - #define __TBB_CPP20_CONCEPTS_PRESENT 0 // TODO: add a mechanism for future addition #ifdef __cpp_deduction_guides #define __TBB_CPP17_DEDUCTION_GUIDES_PRESENT (__cpp_deduction_guides >= 201611L) #else @@ -245,15 +243,12 @@ #elif __GNUC__ #define __TBB_CPP14_VARIABLE_TEMPLATES_PRESENT (__TBB_LANG >= 201402L && __TBB_GCC_VERSION >= 50000) #define __TBB_CPP17_DEDUCTION_GUIDES_PRESENT (__cpp_deduction_guides >= 201606L) - #define __TBB_CPP20_CONCEPTS_PRESENT (__TBB_LANG >= 201709L && __TBB_GCC_VERSION >= 100201) #elif _MSC_VER #define __TBB_CPP14_VARIABLE_TEMPLATES_PRESENT (_MSC_FULL_VER >= 190023918 && (!__INTEL_COMPILER || __INTEL_COMPILER >= 1700)) #define __TBB_CPP17_DEDUCTION_GUIDES_PRESENT (_MSC_VER >= 1914 && __TBB_LANG >= 201703L && (!__INTEL_COMPILER || __INTEL_COMPILER > 2021)) - #define __TBB_CPP20_CONCEPTS_PRESENT (_MSC_VER >= 1923 && __TBB_LANG >= 202002L) // TODO: INTEL_COMPILER? #else #define __TBB_CPP14_VARIABLE_TEMPLATES_PRESENT (__TBB_LANG >= 201402L) #define __TBB_CPP17_DEDUCTION_GUIDES_PRESENT (__TBB_LANG >= 201703L) - #define __TBB_CPP20_CONCEPTS_PRESENT (__TBB_LANG >= 202002L) #endif // GCC4.8 on RHEL7 does not support std::get_new_handler @@ -268,6 +263,13 @@ #define __TBB_CPP17_ALLOCATOR_IS_ALWAYS_EQUAL_PRESENT (__TBB_LANG >= 201703L) #define __TBB_CPP17_IS_SWAPPABLE_PRESENT (__TBB_LANG >= 201703L) +// TODO: fix concepts on Clang or define the broken versions +#if !(__clang__) && defined(__cpp_concepts) && defined(__cpp_lib_concepts) + #define __TBB_CPP20_CONCEPTS_PRESENT ((__cpp_concepts >= 201907L) && (__cpp_lib_concepts >= 202002L)) +#else + #define __TBB_CPP20_CONCEPTS_PRESENT 0 +#endif + #if defined(__cpp_impl_three_way_comparison) && defined(__cpp_lib_three_way_comparison) #define __TBB_CPP20_COMPARISONS_PRESENT ((__cpp_impl_three_way_comparison >= 201907L) && (__cpp_lib_three_way_comparison >= 201907L)) #else diff --git a/include/oneapi/tbb/detail/_range_common.h b/include/oneapi/tbb/detail/_range_common.h index 1011f029df..ac219587d7 100644 --- a/include/oneapi/tbb/detail/_range_common.h +++ b/include/oneapi/tbb/detail/_range_common.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2021 Intel Corporation + Copyright (c) 2005-2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -102,20 +102,23 @@ concept tbb_range = std::copy_constructible && { range.is_divisible() } -> relaxed_convertible_to; }; +template +struct iterator_concept_helper; + +// New specializations should be added in case of using container_based_sequence with +// the new iterator tag types template -constexpr bool iterator_concept_helper( std::input_iterator_tag ) { - return std::input_iterator; -} +struct iterator_concept_helper { + static constexpr bool value = std::input_iterator; +}; template -constexpr bool iterator_concept_helper( std::random_access_iterator_tag ) { - return std::random_access_iterator; -} +struct iterator_concept_helper { + static constexpr bool value = std::random_access_iterator; +}; template -concept iterator_satisfies = requires (IteratorTag tag) { - requires iterator_concept_helper(tag); -}; +concept iterator_satisfies = iterator_concept_helper::value; template concept container_based_sequence = requires( Sequence& seq ) { diff --git a/include/oneapi/tbb/flow_graph.h b/include/oneapi/tbb/flow_graph.h index 5b438faabf..3ace331c09 100644 --- a/include/oneapi/tbb/flow_graph.h +++ b/include/oneapi/tbb/flow_graph.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2024 Intel Corporation + Copyright (c) 2005-2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -85,7 +85,7 @@ class continue_msg {}; } // namespace d2 #if __TBB_CPP20_CONCEPTS_PRESENT -namespace d0 { +inline namespace d0 { template concept node_body_return_type = std::same_as || @@ -127,7 +127,7 @@ template concept async_node_body = std::copy_constructible && std::invocable; -} // namespace d0 +} // inline namespace d0 #endif // __TBB_CPP20_CONCEPTS_PRESENT namespace d2 { diff --git a/include/oneapi/tbb/parallel_for_each.h b/include/oneapi/tbb/parallel_for_each.h index 85c0269196..b64eb233ec 100644 --- a/include/oneapi/tbb/parallel_for_each.h +++ b/include/oneapi/tbb/parallel_for_each.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2024 Intel Corporation + Copyright (c) 2005-2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -409,7 +409,7 @@ class parallel_for_body_wrapper { template using tag = typename std::iterator_traits::iterator_category; -#if __TBB_CPP20_PRESENT +#if __TBB_CPP20_CONCEPTS_PRESENT template struct move_iterator_dispatch_helper { using type = It; @@ -448,7 +448,7 @@ using iterator_tag_dispatch = typename std::input_iterator_tag >::type >::type; -#endif // __TBB_CPP20_PRESENT +#endif // __TBB_CPP20_CONCEPTS_PRESENT template using feeder_is_required = tbb::detail::void_t(), diff --git a/include/oneapi/tbb/parallel_scan.h b/include/oneapi/tbb/parallel_scan.h index d624f7ebdb..8ef0777baa 100644 --- a/include/oneapi/tbb/parallel_scan.h +++ b/include/oneapi/tbb/parallel_scan.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2024 Intel Corporation + Copyright (c) 2005-2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -52,7 +52,7 @@ struct sum_node; #if __TBB_CPP20_CONCEPTS_PRESENT } // namespace d1 -namespace d0 { +inline namespace d0 { template concept parallel_scan_body = splittable && diff --git a/test/common/concepts_common.h b/test/common/concepts_common.h index 19c1ec649f..dca9700d2d 100644 --- a/test/common/concepts_common.h +++ b/test/common/concepts_common.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2021 Intel Corporation + Copyright (c) 2021-2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -385,7 +385,7 @@ struct ParallelScanFunction { T operator()( Dummy, const T& a, bool ) const requires (EnableFunctionCallOperator == State::incorrect_first_input) { return a; } T operator()( const Range&, Dummy, bool ) const requires (EnableFunctionCallOperator == State::incorrect_second_input) { return T{}; } T operator()( const Range&, const T& a, Dummy ) const requires (EnableFunctionCallOperator == State::incorrect_third_input) { return a; } - Dummy operator()( const Range&, const T& a, bool ) const requires (EnableFunctionCallOperator == State::incorrect_return_type) { return Dummy{}; } + Dummy operator()( const Range&, const T&, bool ) const requires (EnableFunctionCallOperator == State::incorrect_return_type) { return Dummy{}; } }; template using Correct = ParallelScanFunction; diff --git a/test/tbb/test_parallel_for_each.cpp b/test/tbb/test_parallel_for_each.cpp index 3dfc107e91..67a8a048d0 100644 --- a/test/tbb/test_parallel_for_each.cpp +++ b/test/tbb/test_parallel_for_each.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2005-2023 Intel Corporation + Copyright (c) 2005-2025 Intel Corporation Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -22,7 +22,7 @@ //! \file test_parallel_for_each.cpp //! \brief Test for [algorithms.parallel_for_each] -#if __TBB_CPP20_PRESENT +#if __TBB_CPP20_CONCEPTS_PRESENT // Fancy iterator type that models the C++20 iterator type // that defines the real iterator category using iterator_concept type // and iterator_category is always std::input_iterator_type @@ -119,7 +119,7 @@ struct cpp20_iterator { private: T* my_ptr = nullptr; }; // class cpp20_iterator -#endif // __TBB_CPP20_PRESENT +#endif // __TBB_CPP20_CONCEPTS_PRESENT //! Test forward access iterator support //! \brief \ref error_guessing \ref interface @@ -270,10 +270,6 @@ TEST_CASE("parallel_for_each constraints") { test_pfor_each_body_constraints(); } -#endif // __TBB_CPP20_CONCEPTS_PRESENT - -#if __TBB_CPP20_PRESENT - struct no_copy_move { no_copy_move() = default; @@ -332,4 +328,4 @@ TEST_CASE("parallel_for_each with cpp20 iterator") { test_with_cpp20_iterator(); } -#endif // __TBB_CPP20_PRESENT +#endif // __TBB_CPP20_CONCEPTS_PRESENT