////////////////////////////////////////////////////////////////////////////// // // (C) Copyright Ion Gaztanaga 2025-2026. Distributed under the Boost // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // // See http://www.boost.org/libs/container for documentation. // ////////////////////////////////////////////////////////////////////////////// #ifndef BOOST_CONTAINER_EXPERIMENTAL_SEGMENTED_REMOVE_COPY_HPP #define BOOST_CONTAINER_EXPERIMENTAL_SEGMENTED_REMOVE_COPY_HPP #ifndef BOOST_CONFIG_HPP # include #endif #if defined(BOOST_HAS_PRAGMA_ONCE) # pragma once #endif #include #include #include #include #include namespace boost { namespace container { template OutIter segmented_remove_copy(InIter first, Sent last, OutIter result, const T& value); namespace detail_algo { template BOOST_CONTAINER_FORCEINLINE typename algo_enable_if_c >::type segmented_remove_copy_dst_bounded (SrcIter first, Sent last, DstIter dst_first, DstSent dst_last, const T& value, DstTag, SrcCat) { BOOST_CONTAINER_SEGMENTED_UNROLL(4) for(; first != last; ++first) { if(!(*first == value)) { if(dst_first == dst_last) goto out_path; transfer_op::apply(*dst_first, *first); ++dst_first; } } out_path: return segduo(first, dst_first); } template segduo segmented_remove_copy_dst_bounded (SrcIter first, Sent last, SegDstIter dst_first, SegDstIter dst_last, const T& value, segmented_iterator_tag, SrcCat) { typedef segmented_iterator_traits dst_traits; typedef typename dst_traits::local_iterator dst_local_iterator; typedef typename dst_traits::segment_iterator dst_segment_iterator; typedef typename segmented_iterator_traits::is_segmented_iterator dst_is_local_seg_t; dst_segment_iterator sfirst = dst_traits::segment(dst_first); const dst_segment_iterator slast = dst_traits::segment(dst_last); if(sfirst == slast) { segduo r = (segmented_remove_copy_dst_bounded) (first, last, dst_traits::local(dst_first), dst_traits::local(dst_last), value, dst_is_local_seg_t(), SrcCat()); return segduo(r.first, dst_traits::compose(sfirst, r.second)); } else { segduo r = (segmented_remove_copy_dst_bounded) (first, last, dst_traits::local(dst_first), dst_traits::end(sfirst), value, dst_is_local_seg_t(), SrcCat()); first = r.first; if(first == last) return segduo(first, dst_traits::compose(sfirst, r.second)); for(++sfirst; sfirst != slast; ++sfirst) { r = (segmented_remove_copy_dst_bounded) (first, last, dst_traits::begin(sfirst), dst_traits::end(sfirst), value, dst_is_local_seg_t(), SrcCat()); first = r.first; if(first == last) return segduo(first, dst_traits::compose(sfirst, r.second)); } r = (segmented_remove_copy_dst_bounded) (first, last, dst_traits::begin(slast), dst_traits::local(dst_last), value, dst_is_local_seg_t(), SrcCat()); return segduo(r.first, dst_traits::compose(sfirst, r.second)); } } ////////////////////////////////////////////////////////////////////////////// // Destination dispatch ////////////////////////////////////////////////////////////////////////////// template BOOST_CONTAINER_FORCEINLINE DstIter segmented_remove_copy_dst_dispatch (SrcIter first, Sent last, DstIter result, const T& value, const non_segmented_iterator_tag &, Cat) { return (segmented_remove_copy_dst_bounded) (first, last, result, unreachable_sentinel_t(), value, non_segmented_iterator_tag(), Cat()).second; } template SegDstIter segmented_remove_copy_dst_dispatch (SrcIter first, const Sent last, SegDstIter result, const T& value, const segmented_iterator_tag &, Cat) { typedef segmented_iterator_traits dst_traits; typedef typename dst_traits::local_iterator dst_local_iterator; typedef typename dst_traits::segment_iterator dst_segment_iterator; typedef typename segmented_iterator_traits::is_segmented_iterator dst_is_local_seg_t; if(first == last) return result; dst_segment_iterator dst_seg = dst_traits::segment(result); dst_local_iterator dst_local = dst_traits::local(result); while(1) { const segduo r = (segmented_remove_copy_dst_bounded) (first, last, dst_local, dst_traits::end(dst_seg), value, dst_is_local_seg_t(), Cat()); if(r.first != last) { first = r.first; ++dst_seg; dst_local = dst_traits::begin(dst_seg); } else { dst_local = r.second; break; } } return dst_traits::compose(dst_seg, dst_local); } ////////////////////////////////////////////////////////////////////////////// // Source dispatch ////////////////////////////////////////////////////////////////////////////// template BOOST_CONTAINER_FORCEINLINE typename algo_enable_if_c< !Tag::value || is_sentinel::value, OutIter>::type segmented_remove_copy_dispatch (SrcIter first, Sent last, OutIter result, const T& value, Tag, Cat) { #if !defined(BOOST_CONTAINER_DISABLE_MULTI_SEGMENTED_ALGO) typedef segmented_iterator_traits dst_traits; return (segmented_remove_copy_dst_dispatch) (first, last, result, value, typename dst_traits::is_segmented_iterator(), Cat()); #else return (segmented_remove_copy_dst_dispatch) (first, last, result, value, non_segmented_iterator_tag(), Cat()); #endif } template OutIter segmented_remove_copy_dispatch (SegIter first, SegIter last, OutIter result, const T& value, segmented_iterator_tag, Cat) { typedef segmented_iterator_traits src_traits; typedef typename src_traits::local_iterator src_local_iterator; typedef typename src_traits::segment_iterator src_segment_iterator; typedef typename segmented_iterator_traits::is_segmented_iterator src_is_local_seg_t; typedef typename iterator_traits::iterator_category src_local_cat_t; src_segment_iterator sfirst = src_traits::segment(first); const src_segment_iterator slast = src_traits::segment(last); if(sfirst == slast) { return (segmented_remove_copy_dispatch) (src_traits::local(first), src_traits::local(last), result, value, src_is_local_seg_t(), src_local_cat_t()); } else { result = (segmented_remove_copy_dispatch) (src_traits::local(first), src_traits::end(sfirst), result, value, src_is_local_seg_t(), src_local_cat_t()); for(++sfirst; sfirst != slast; ++sfirst) result = (segmented_remove_copy_dispatch) (src_traits::begin(sfirst), src_traits::end(sfirst), result, value, src_is_local_seg_t(), src_local_cat_t()); return (segmented_remove_copy_dispatch) (src_traits::begin(slast), src_traits::local(last), result, value, src_is_local_seg_t(), src_local_cat_t()); } } } // namespace detail_algo //! Copies elements from [first, last) to the range beginning at \c result, //! skipping elements equal to \c value. Returns the output iterator past //! the last element written. template BOOST_CONTAINER_FORCEINLINE OutIter segmented_remove_copy(InIter first, Sent last, OutIter result, const T& value) { typedef segmented_iterator_traits traits; return detail_algo::segmented_remove_copy_dispatch (first, last, result, value, typename traits::is_segmented_iterator(), typename iterator_traits::iterator_category()); } } // namespace container } // namespace boost #include #endif // BOOST_CONTAINER_EXPERIMENTAL_SEGMENTED_REMOVE_COPY_HPP