////////////////////////////////////////////////////////////////////////////// // // (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_FILL_N_HPP #define BOOST_CONTAINER_EXPERIMENTAL_SEGMENTED_FILL_N_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 FwdIt segmented_fill_n(FwdIt first, Size count, const T& value); namespace detail_algo { template BOOST_CONTAINER_FORCEINLINE segduo fill_n_scan ( OutIter first, OutIter last, Size count , const T& value, non_segmented_iterator_tag, const std::random_access_iterator_tag &) { Size range_sz = static_cast(last - first); //If the whole range is fixed at compile time (e.g. deque) //some compilers (e.g. MSVC 2026) can use SIMD more efficiently //than when using count. if (count >= range_sz) { count -= range_sz; BOOST_CONTAINER_SEGMENTED_UNROLL(4) for (Size cnt = 0; cnt != range_sz; ++first, ++cnt){ *first = value; } return segduo(first, count); } else { BOOST_CONTAINER_SEGMENTED_UNROLL(4) for (Size cnt = 0; cnt != count; ++first, ++cnt) *first = value; return segduo(first, Size(0)); } } template BOOST_CONTAINER_FORCEINLINE segduo fill_n_scan (OutIter first, OutIter last, Size count, const T& value, non_segmented_iterator_tag, const Cat &) { BOOST_CONTAINER_SEGMENTED_UNROLL(4) for (; count > 0 && first != last; ++first, --count) *first = value; return segduo(first, count); } template segduo fill_n_scan(SegIt first, SegIt last, Size count, const T& value, segmented_iterator_tag, const Cat &) { typedef segmented_iterator_traits traits; typedef typename traits::local_iterator local_iterator; typedef typename traits::segment_iterator segment_iterator; typedef typename segmented_iterator_traits::is_segmented_iterator is_local_seg_t; typedef typename iterator_traits::iterator_category local_cat_t; segment_iterator scur = traits::segment(first); segment_iterator const slast = traits::segment(last); if(scur == slast) { const local_iterator ll = traits::local(last); const segduo r = (fill_n_scan)(traits::local(first), ll, count, value, is_local_seg_t(), local_cat_t()); return segduo((r.first != ll) ? traits::compose(scur, r.first) : last, r.second); } else { segduo r = fill_n_scan(traits::local(first), traits::end(scur), count, value, is_local_seg_t(), local_cat_t()); count = r.second; if (!count) return segduo(traits::compose(scur, r.first), count); for (++scur; scur != slast; ++scur) { r = fill_n_scan(traits::begin(scur), traits::end(scur), count, value, is_local_seg_t(), local_cat_t()); count = r.second; if (!count) return segduo(traits::compose(scur, r.first), count); } const local_iterator ll = traits::local(last); r = fill_n_scan(traits::begin(slast), ll, count, value, is_local_seg_t(), local_cat_t()); return segduo((r.first != ll) ? traits::compose(scur, r.first) : last, r.second); } } template SegIter segmented_fill_n_ref (SegIter first, Size count, const T& value, segmented_iterator_tag) { typedef segmented_iterator_traits traits; typedef typename traits::local_iterator local_iterator; typedef typename traits::segment_iterator segment_iterator; typedef typename segmented_iterator_traits::is_segmented_iterator is_local_seg_t; typedef typename iterator_traits::iterator_category local_cat_t; segment_iterator scur = traits::segment(first); local_iterator lcur; { const segduo r = fill_n_scan(traits::local(first), traits::end(scur), count, value, is_local_seg_t(), local_cat_t()); lcur = r.first; count = r.second; } if (count) { ++scur; while (1) { const segduo r = fill_n_scan(traits::begin(scur), traits::end(scur), count, value, is_local_seg_t(), local_cat_t()); lcur = r.first; count = r.second; if (count == 0) break; ++scur; } } return traits::compose(scur, lcur); } template OutIt segmented_fill_n_ref (OutIt first, Size count, const T& value, non_segmented_iterator_tag) { BOOST_CONTAINER_SEGMENTED_UNROLL(4) for(; count > 0; ++first, --count) *first = value; return first; } } // namespace detail_algo //! Assigns \c value to the first \c count elements starting at \c first. //! Returns an iterator past the last filled element. //! Exploits segmentation when available. template BOOST_CONTAINER_FORCEINLINE FwdIt segmented_fill_n(FwdIt first, Size count, const T& value) { typedef segmented_iterator_traits traits; return detail_algo::segmented_fill_n_ref(first, count, value, typename traits::is_segmented_iterator()); } } // namespace container } // namespace boost #include #endif // BOOST_CONTAINER_EXPERIMENTAL_SEGMENTED_FILL_N_HPP