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 | ///////////////////////////////////////////////////////////////////////////////
|
---|
22 | namespace boost {
|
---|
23 | namespace wave {
|
---|
24 | namespace 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)
|
---|