1 //  Copyright (c) 2001-2011 Hartmut Kaiser
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef BOOST_SPIRIT_KARMA_DETAIL_INDIRECT_ITERATOR_HPP
7 #define BOOST_SPIRIT_KARMA_DETAIL_INDIRECT_ITERATOR_HPP
8 
9 #if defined(_MSC_VER)
10 #pragma once
11 #endif
12 
13 #include <boost/spirit/home/support/unused.hpp>
14 #include <boost/iterator/iterator_facade.hpp>
15 #include <iterator> // for std::iterator_traits
16 
17 ///////////////////////////////////////////////////////////////////////////////
18 namespace boost { namespace spirit { namespace karma { namespace detail
19 {
20     ///////////////////////////////////////////////////////////////////////
21     // This is a wrapper for any iterator allowing to pass a reference of it
22     // to the components of the sequence
23     template <typename Iterator>
24     class indirect_iterator
25       : public boost::iterator_facade<
26             indirect_iterator<Iterator>
27           , typename std::iterator_traits<Iterator>::value_type
28           , boost::forward_traversal_tag
29           , typename std::iterator_traits<Iterator>::reference>
30     {
31         typedef typename std::iterator_traits<Iterator>::value_type
32             base_value_type;
33         typedef typename std::iterator_traits<Iterator>::reference
34             base_reference_type;
35 
36         typedef boost::iterator_facade<
37             indirect_iterator<Iterator>, base_value_type
38           , boost::forward_traversal_tag, base_reference_type
39         > base_type;
40 
41     public:
indirect_iterator(Iterator & iter)42         indirect_iterator(Iterator& iter)
43           : iter_(&iter)
44         {}
indirect_iterator(indirect_iterator const & iter)45         indirect_iterator(indirect_iterator const& iter)
46           : iter_(iter.iter_)
47         {}
48 
49     private:
50         friend class boost::iterator_core_access;
51 
increment()52         void increment()
53         {
54             ++*iter_;
55         }
56 
equal(indirect_iterator const & other) const57         bool equal(indirect_iterator const& other) const
58         {
59             return *iter_ == *other.iter_;
60         }
61 
dereference() const62         base_reference_type dereference() const
63         {
64             return **iter_;
65         }
66 
67     private:
68         Iterator* iter_;
69     };
70 }}}}
71 
72 ///////////////////////////////////////////////////////////////////////////////
73 namespace boost { namespace spirit { namespace traits
74 {
75     template <typename Iterator>
76     struct make_indirect_iterator
77     {
78         typedef karma::detail::indirect_iterator<Iterator> type;
79     };
80 
81     template <typename Iterator>
82     struct make_indirect_iterator<karma::detail::indirect_iterator<Iterator> >
83     {
84         typedef karma::detail::indirect_iterator<Iterator> type;
85     };
86 
87     template <>
88     struct make_indirect_iterator<unused_type const*>
89     {
90         typedef unused_type const* type;
91     };
92 
93     template <typename Iterator>
94     struct make_indirect_iterator<Iterator const&>
95       : make_indirect_iterator<Iterator const>
96     {};
97 }}}
98 
99 #endif
100