Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-30 08:46:18

0001 /*
0002     Copyright (c) 2005-2021 Intel Corporation
0003 
0004     Licensed under the Apache License, Version 2.0 (the "License");
0005     you may not use this file except in compliance with the License.
0006     You may obtain a copy of the License at
0007 
0008         http://www.apache.org/licenses/LICENSE-2.0
0009 
0010     Unless required by applicable law or agreed to in writing, software
0011     distributed under the License is distributed on an "AS IS" BASIS,
0012     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013     See the License for the specific language governing permissions and
0014     limitations under the License.
0015 */
0016 
0017 #ifndef __TBB_detail__range_common_H
0018 #define __TBB_detail__range_common_H
0019 
0020 #include "_config.h"
0021 #include "_utils.h"
0022 #if __TBB_CPP20_CONCEPTS_PRESENT
0023 #include <concepts>
0024 #endif
0025 #include <iterator>
0026 
0027 namespace tbb {
0028 namespace detail {
0029 inline namespace d0 {
0030 
0031 //! Dummy type that distinguishes splitting constructor from copy constructor.
0032 /**
0033  * See description of parallel_for and parallel_reduce for example usages.
0034  * @ingroup algorithms
0035  */
0036 class split {};
0037 
0038 //! Type enables transmission of splitting proportion from partitioners to range objects
0039 /**
0040  * In order to make use of such facility Range objects must implement
0041  * splitting constructor with this type passed.
0042  */
0043 class proportional_split : no_assign {
0044 public:
0045     proportional_split(size_t _left = 1, size_t _right = 1) : my_left(_left), my_right(_right) { }
0046 
0047     size_t left() const { return my_left; }
0048     size_t right() const { return my_right; }
0049 
0050     // used when range does not support proportional split
0051     explicit operator split() const { return split(); }
0052 
0053 private:
0054     size_t my_left, my_right;
0055 };
0056 
0057 template <typename Range, typename = void>
0058 struct range_split_object_provider {
0059     template <typename PartitionerSplitType>
0060     static split get( PartitionerSplitType& ) { return split(); }
0061 };
0062 
0063 template <typename Range>
0064 struct range_split_object_provider<Range,
0065                                    typename std::enable_if<std::is_constructible<Range, Range&, proportional_split&>::value>::type> {
0066     template <typename PartitionerSplitType>
0067     static PartitionerSplitType& get( PartitionerSplitType& split_obj ) { return split_obj; }
0068 };
0069 
0070 template <typename Range, typename PartitionerSplitType>
0071 auto get_range_split_object( PartitionerSplitType& split_obj )
0072 -> decltype(range_split_object_provider<Range>::get(split_obj)) {
0073     return range_split_object_provider<Range>::get(split_obj);
0074 }
0075 
0076 template <typename Range>
0077 using range_iterator_type = decltype(std::begin(std::declval<Range&>()));
0078 
0079 #if __TBB_CPP20_CONCEPTS_PRESENT
0080 template <typename Iterator>
0081 using iterator_reference_type = typename std::iterator_traits<Iterator>::reference;
0082 
0083 template <typename Range>
0084 using range_reference_type = iterator_reference_type<range_iterator_type<Range>>;
0085 
0086 template <typename Value>
0087 concept blocked_range_value = std::copyable<Value> &&
0088                               requires( const std::remove_reference_t<Value>& lhs, const std::remove_reference_t<Value>& rhs ) {
0089                                   { lhs < rhs } -> relaxed_convertible_to<bool>;
0090                                   { lhs - rhs } -> std::convertible_to<std::size_t>;
0091                                   { lhs + (rhs - lhs) } -> std::convertible_to<Value>;
0092                               };
0093 
0094 template <typename T>
0095 concept splittable = std::constructible_from<T, T&, tbb::detail::split>;
0096 
0097 template <typename Range>
0098 concept tbb_range = std::copy_constructible<Range> &&
0099                     splittable<Range> &&
0100                     requires( const std::remove_reference_t<Range>& range ) {
0101                         { range.empty() } -> relaxed_convertible_to<bool>;
0102                         { range.is_divisible() } -> relaxed_convertible_to<bool>;
0103                     };
0104 
0105 template <typename Iterator>
0106 constexpr bool iterator_concept_helper( std::input_iterator_tag ) {
0107     return std::input_iterator<Iterator>;
0108 }
0109 
0110 template <typename Iterator>
0111 constexpr bool iterator_concept_helper( std::random_access_iterator_tag ) {
0112     return std::random_access_iterator<Iterator>;
0113 }
0114 
0115 template <typename Iterator, typename IteratorTag>
0116 concept iterator_satisfies = requires (IteratorTag tag) {
0117     requires iterator_concept_helper<Iterator>(tag);
0118 };
0119 
0120 template <typename Sequence, typename IteratorTag>
0121 concept container_based_sequence = requires( Sequence& seq ) {
0122     { std::begin(seq) } -> iterator_satisfies<IteratorTag>;
0123     { std::end(seq) } -> iterator_satisfies<IteratorTag>;
0124 };
0125 #endif // __TBB_CPP20_CONCEPTS_PRESENT
0126 } // namespace d0
0127 } // namespace detail
0128 } // namespace tbb
0129 
0130 #endif // __TBB_detail__range_common_H