source: NonGTP/Boost/boost/wave/util/transform_iterator.hpp @ 857

Revision 857, 5.7 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*=============================================================================
2    Boost.Wave: A Standard compliant C++ preprocessor library
3
4    http://www.boost.org/
5
6    Copyright (c) 2001-2005 Hartmut Kaiser. Distributed under the Boost
7    Software License, Version 1.0. (See accompanying file
8    LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9=============================================================================*/
10
11#if !defined(TRANSFORM_ITERATOR_HPP_D492C659_88C7_4258_8C42_192F9AE80EC0_INCLUDED)
12#define TRANSFORM_ITERATOR_HPP_D492C659_88C7_4258_8C42_192F9AE80EC0_INCLUDED
13
14#include <boost/iterator_adaptors.hpp>
15#if BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200
16#include <boost/iterator/transform_iterator.hpp>
17#endif // BOOST_ITERATOR_ADAPTORS_VERSION >= 0x0200
18
19#include <boost/assert.hpp>
20
21///////////////////////////////////////////////////////////////////////////////
22namespace boost {
23namespace wave {
24namespace impl {
25
26#if BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
27
28///////////////////////////////////////////////////////////////////////////////
29//
30//  Transform Iterator Adaptor
31//
32//  Upon deference, apply some unary function object and return the
33//  result by reference.
34//
35//  This class is adapted from the Boost.Iterator library, where a similar
36//  class exists, which returns the next item by value
37//
38///////////////////////////////////////////////////////////////////////////////
39    template <class AdaptableUnaryFunctionT>
40    struct ref_transform_iterator_policies
41    :   public boost::default_iterator_policies
42    {
43        ref_transform_iterator_policies()
44        {}
45        ref_transform_iterator_policies(const AdaptableUnaryFunctionT &f)
46        : m_f(f) {}
47
48        template <class IteratorAdaptorT>
49        typename IteratorAdaptorT::reference
50        dereference(const IteratorAdaptorT &iter) const
51        { return m_f(*iter.base()); }
52
53        AdaptableUnaryFunctionT m_f;
54    };
55
56    template <class AdaptableUnaryFunctionT, class IteratorT>
57    class ref_transform_iterator_generator
58    {
59        typedef typename AdaptableUnaryFunctionT::result_type value_type;
60       
61    public:
62        typedef boost::iterator_adaptor<
63                IteratorT,
64                ref_transform_iterator_policies<AdaptableUnaryFunctionT>,
65                value_type, value_type const &, value_type const *,
66                std::input_iterator_tag>
67            type;
68    };
69
70    template <class AdaptableUnaryFunctionT, class IteratorT>
71    inline
72    typename ref_transform_iterator_generator<
73        AdaptableUnaryFunctionT, IteratorT>::type
74    make_ref_transform_iterator(
75        IteratorT base,
76        const AdaptableUnaryFunctionT &f = AdaptableUnaryFunctionT())
77    {
78        typedef typename ref_transform_iterator_generator<
79                    AdaptableUnaryFunctionT, IteratorT>::type
80            result_t;
81        return result_t(base, f);
82    }
83
84    //  Retrieve the token value given a parse node
85    //  This is used in conjunction with the ref_transform_iterator above, to
86    //  get the token values while iterating directly over the parse tree.
87    template <typename TokenT, typename ParseTreeNodeT>
88    struct get_token_value {
89
90        typedef TokenT result_type;
91       
92        TokenT const &operator()(ParseTreeNodeT const &node) const
93        {
94            BOOST_ASSERT(1 == std::distance(node.value.begin(),
95                node.value.end()));
96            return *node.value.begin();
97        }
98    };
99
100#else // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
101
102///////////////////////////////////////////////////////////////////////////////
103//
104//  The new Boost.Iterator library already conatins a transform_iterator usable
105//  for our needs. The code below wraps this up.
106//
107///////////////////////////////////////////////////////////////////////////////
108    template <class AdaptableUnaryFunctionT, class IteratorT>
109    class ref_transform_iterator_generator
110    {
111        typedef typename AdaptableUnaryFunctionT::result_type   return_type;
112        typedef typename AdaptableUnaryFunctionT::argument_type argument_type;
113       
114    public:
115        typedef boost::transform_iterator<
116                return_type (*)(argument_type), IteratorT, return_type>
117            type;
118    };
119
120    template <class AdaptableUnaryFunctionT, class IteratorT>
121    inline
122    typename ref_transform_iterator_generator<
123        AdaptableUnaryFunctionT, IteratorT>::type
124    make_ref_transform_iterator(
125        IteratorT base, AdaptableUnaryFunctionT const &f)
126    {
127        typedef typename ref_transform_iterator_generator<
128                AdaptableUnaryFunctionT, IteratorT>::type
129            iterator_type;
130        return iterator_type(base, f.transform);
131    }
132
133    //  Retrieve the token value given a parse node
134    //  This is used in conjunction with the ref_transform_iterator above, to
135    //  get the token values while iterating directly over the parse tree.
136    template <typename TokenT, typename ParseTreeNodeT>
137    struct get_token_value {
138
139        typedef TokenT const &result_type;
140        typedef ParseTreeNodeT const &argument_type;
141       
142        static result_type
143        transform (argument_type node)
144        {
145            BOOST_ASSERT(1 == std::distance(node.value.begin(),
146                node.value.end()));
147            return *node.value.begin();
148        }
149    };
150
151#endif // BOOST_ITERATOR_ADAPTORS_VERSION < 0x0200
152   
153///////////////////////////////////////////////////////////////////////////////
154}   // namespace impl
155}   // namespace wave
156}   // namespace boost
157
158#endif // !defined(TRANSFORM_ITERATOR_HPP_D492C659_88C7_4258_8C42_192F9AE80EC0_INCLUDED)
Note: See TracBrowser for help on using the repository browser.