1 /// \file 2 // Range v3 library 3 // 4 // Copyright Eric Niebler 2013-present 5 // Copyright Gonzalo Brito Gadeschi 2014 6 // 7 // Use, modification and distribution is subject to the 8 // Boost Software License, Version 1.0. (See accompanying 9 // file LICENSE_1_0.txt or copy at 10 // http://www.boost.org/LICENSE_1_0.txt) 11 // 12 // Project home: https://github.com/ericniebler/range-v3 13 // 14 // Implementation based on the code in libc++ 15 // http://http://libcxx.llvm.org/ 16 17 #ifndef RANGES_V3_ALGORITHM_UNIQUE_HPP 18 #define RANGES_V3_ALGORITHM_UNIQUE_HPP 19 20 #include <range/v3/range_fwd.hpp> 21 22 #include <range/v3/algorithm/adjacent_find.hpp> 23 #include <range/v3/functional/comparisons.hpp> 24 #include <range/v3/functional/identity.hpp> 25 #include <range/v3/functional/invoke.hpp> 26 #include <range/v3/iterator/operations.hpp> 27 #include <range/v3/range/access.hpp> 28 #include <range/v3/range/concepts.hpp> 29 #include <range/v3/range/dangling.hpp> 30 #include <range/v3/range/traits.hpp> 31 #include <range/v3/utility/static_const.hpp> 32 33 #include <range/v3/detail/prologue.hpp> 34 35 namespace ranges 36 { 37 /// \addtogroup group-algorithms 38 /// @{ 39 RANGES_FUNC_BEGIN(unique) 40 41 /// \brief template function \c unique 42 /// 43 /// range-based version of the \c unique std algorithm 44 /// 45 /// \pre `Rng` is a model of the `forward_range` concept 46 /// \pre `I` is a model of the `forward_iterator` concept 47 /// \pre `S` is a model of the `sentinel_for` concept 48 /// \pre `C` is a model of the `relation` concept 49 /// 50 template(typename I, typename S, typename C = equal_to, typename P = identity)( 51 /// \pre 52 requires sortable<I, C, P> AND sentinel_for<S, I>) 53 I RANGES_FUNC(unique)(I first, S last, C pred = C{}, P proj = P{}) 54 { 55 first = adjacent_find(std::move(first), last, std::ref(pred), std::ref(proj)); 56 57 if(first != last) 58 { 59 for(I i = next(first); ++i != last;) 60 if(!invoke(pred, invoke(proj, *first), invoke(proj, *i))) 61 *++first = iter_move(i); 62 ++first; 63 } 64 return first; 65 } 66 67 /// \overload 68 template(typename Rng, typename C = equal_to, typename P = identity)( 69 /// \pre 70 requires sortable<iterator_t<Rng>, C, P> AND range<Rng>) 71 borrowed_iterator_t<Rng> // 72 RANGES_FUNC(unique)(Rng && rng, C pred = C{}, P proj = P{}) // 73 { 74 return (*this)(begin(rng), end(rng), std::move(pred), std::move(proj)); 75 } 76 77 RANGES_FUNC_END(unique) 78 79 namespace cpp20 80 { 81 using ranges::unique; 82 } 83 /// @} 84 } // namespace ranges 85 86 #include <range/v3/detail/epilogue.hpp> 87 88 #endif 89