1 // Boost.Range library
2 //
3 //  Copyright Thorsten Ottosen, Neil Groves 2006 - 2008. Use, modification and
4 //  distribution is subject to the Boost Software License, Version
5 //  1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 //  http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // For more information, see http://www.boost.org/libs/range/
9 //
10 
11 #ifndef BOOST_RANGE_ADAPTOR_UNIQUED_IMPL_HPP
12 #define BOOST_RANGE_ADAPTOR_UNIQUED_IMPL_HPP
13 
14 #include <boost/range/adaptor/adjacent_filtered.hpp>
15 #include <boost/range/concepts.hpp>
16 
17 namespace boost
18 {
19 
20     namespace range_detail
21     {
22         struct unique_forwarder { };
23 
24         struct unique_not_equal_to
25         {
26             typedef bool result_type;
27 
28             template< class T >
operator ()boost::range_detail::unique_not_equal_to29             bool operator()( const T& l, const T& r ) const
30             {
31                 return !(l == r);
32             }
33         };
34 
35         template<class ForwardRng>
36         class uniqued_range : public adjacent_filtered_range<unique_not_equal_to, ForwardRng, true>
37         {
38             typedef adjacent_filtered_range<unique_not_equal_to, ForwardRng, true> base;
39         public:
uniqued_range(ForwardRng & rng)40             explicit uniqued_range(ForwardRng& rng)
41                 : base(unique_not_equal_to(), rng)
42             {
43             }
44         };
45 
46         template< class ForwardRng >
47         inline uniqued_range<ForwardRng>
operator |(ForwardRng & r,unique_forwarder)48         operator|( ForwardRng& r,
49                    unique_forwarder )
50         {
51             BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRng>));
52             return uniqued_range<ForwardRng>(r);
53         }
54 
55         template< class ForwardRng >
56         inline uniqued_range<const ForwardRng>
operator |(const ForwardRng & r,unique_forwarder)57         operator|( const ForwardRng& r,
58                    unique_forwarder )
59         {
60             BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<const ForwardRng>));
61             return uniqued_range<const ForwardRng>(r);
62         }
63 
64     } // 'range_detail'
65 
66     using range_detail::uniqued_range;
67 
68     namespace adaptors
69     {
70         namespace
71         {
72             const range_detail::unique_forwarder uniqued =
73                        range_detail::unique_forwarder();
74         }
75 
76         template<class ForwardRange>
77         inline uniqued_range<ForwardRange>
unique(ForwardRange & rng)78         unique(ForwardRange& rng)
79         {
80             BOOST_RANGE_CONCEPT_ASSERT((ForwardRangeConcept<ForwardRange>));
81             return uniqued_range<ForwardRange>(rng);
82         }
83 
84         template<class ForwardRange>
85         inline uniqued_range<const ForwardRange>
unique(const ForwardRange & rng)86         unique(const ForwardRange& rng)
87         {
88             BOOST_RANGE_CONCEPT_ASSERT((
89                 ForwardRangeConcept<const ForwardRange>));
90 
91             return uniqued_range<const ForwardRange>(rng);
92         }
93     } // 'adaptors'
94 
95 }
96 
97 #endif
98