Go to the documentation of this file.00001 #ifndef wali_nwa_query_details_ITERATORS_HPP
00002 #define wali_nwa_query_details_ITERATORS_HPP
00003
00004 #include "opennwa/Nwa.hpp"
00005
00006 #include <iterator>
00007 #include <utility>
00008 #include <algorithm>
00009
00010 #include <boost/iterator/iterator_facade.hpp>
00011 #include <boost/iterator/iterator_adaptor.hpp>
00012 #include <boost/shared_ptr.hpp>
00013
00014 namespace opennwa
00015 {
00016 namespace query
00017 {
00018 namespace details
00019 {
00020
00021 namespace iterators
00022 {
00023
00024
00025
00026 template<typename ValueType, typename ReferenceType = ValueType &>
00027 class iterator_base
00028 : public boost::iterator_facade<iterator_base<ValueType, ReferenceType>,
00029 ValueType,
00030 boost::forward_traversal_tag,
00031 ReferenceType>
00032 {
00033 friend class boost::iterator_core_access;
00034
00035 protected:
00036 virtual void increment() = 0;
00037 virtual ReferenceType dereference() const = 0;
00038
00039 public:
00040 virtual bool equal(iterator_base const & other) const = 0;
00041 virtual iterator_base* clone() const = 0;
00042 };
00043
00044
00045 template<typename CPlusPlusIterator>
00046 class cplusplus_iterator_adapter
00047 : public iterator_base<typename std::iterator_traits<CPlusPlusIterator>::value_type,
00048 typename std::iterator_traits<CPlusPlusIterator>::reference>
00049 {
00050 private:
00051 CPlusPlusIterator backing;
00052 typedef typename std::iterator_traits<CPlusPlusIterator>::value_type ValueType;
00053 typedef typename std::iterator_traits<CPlusPlusIterator>::reference Reference;
00054
00055 public:
00056 cplusplus_iterator_adapter()
00057 {}
00058
00059 cplusplus_iterator_adapter(cplusplus_iterator_adapter const & other)
00060 : backing(other.backing)
00061 {}
00062
00063 explicit cplusplus_iterator_adapter(CPlusPlusIterator iter)
00064 : backing(iter)
00065 {}
00066
00067
00068 virtual cplusplus_iterator_adapter* clone() const
00069 {
00070 return new cplusplus_iterator_adapter(*this);
00071 }
00072
00073 virtual void increment()
00074 {
00075 ++backing;
00076 }
00077
00078 virtual bool equal(iterator_base<ValueType, Reference> const & other) const
00079 {
00080 const cplusplus_iterator_adapter * p =
00081 dynamic_cast<cplusplus_iterator_adapter const*>(&other);
00082
00083 if (p) {
00084 return backing == p->backing;
00085 }
00086 else {
00087 return false;
00088 }
00089 }
00090
00091 Reference dereference() const
00092 {
00093 return *backing;
00094 }
00095 };
00096
00097
00098
00099 template<typename ValueType, typename ReferenceType = ValueType &>
00100 class iterator_base_wrapper
00101 : public boost::iterator_facade<iterator_base_wrapper<ValueType, ReferenceType>,
00102 ValueType,
00103 boost::forward_traversal_tag,
00104 ReferenceType>
00105 {
00106 private:
00107
00108
00109
00110 iterator_base<ValueType, ReferenceType> * backing;
00111
00112 public:
00113 iterator_base_wrapper()
00114 : backing(0)
00115 {}
00116
00117 iterator_base_wrapper(iterator_base_wrapper const & other)
00118 : backing(other.backing->clone())
00119 {}
00120
00121 template<typename V, typename R>
00122 explicit iterator_base_wrapper(iterator_base<V, R> const & base)
00123 : backing(base.clone())
00124 {}
00125
00126
00127
00128
00129 private:
00130 void swap(iterator_base_wrapper & other) const
00131 {
00132 std::swap(backing, other.backing);
00133 }
00134
00135 public:
00136 iterator_base_wrapper & operator=(iterator_base_wrapper const & other)
00137 {
00138
00139 iterator_base_wrapper copy(other);
00140 swap(copy);
00141 return *this;
00142 }
00143
00144 ~iterator_base_wrapper()
00145 {
00146 delete backing;
00147 }
00148
00149
00150 private:
00151 friend class boost::iterator_core_access;
00152
00153
00154
00155 virtual void increment()
00156 {
00157 ++(*backing);
00158 }
00159
00160 virtual bool equal(iterator_base_wrapper const & other) const
00161 {
00162 return backing->equal(*other.backing);
00163 }
00164
00165 ReferenceType dereference() const
00166 {
00167 return **backing;
00168 }
00169 };
00170
00171
00172 template <typename BackingIterator>
00173 class iterator_sequence
00174 : public boost::iterator_facade<iterator_sequence<BackingIterator>,
00175 typename std::iterator_traits<BackingIterator>::value_type,
00176 boost::forward_traversal_tag,
00177 typename std::iterator_traits<BackingIterator>::reference>
00178 {
00179 public:
00180 typedef std::pair<BackingIterator, BackingIterator> IteratorRange;
00181 typedef typename std::iterator_traits<BackingIterator>::value_type ValueType;
00182 typedef typename std::iterator_traits<BackingIterator>::reference Reference;
00183
00184 private:
00185 boost::shared_ptr<std::deque<IteratorRange> > ranges;
00186
00187 void dump_empty_ranges()
00188 {
00189 while (!ranges->empty() && ranges->front().first == ranges->front().second) {
00190 ranges->pop_front();
00191 }
00192 }
00193
00194 protected:
00195 friend class boost::iterator_core_access;
00196
00197 void increment()
00198 {
00199
00200 ++(ranges->front().first);
00201 dump_empty_ranges();
00202 }
00203
00204 Reference dereference() const
00205 {
00206 return *(ranges->front().first);
00207 }
00208
00209 bool equal(iterator_sequence const & other) const
00210 {
00211 if (ranges->empty() && other.ranges->empty()) {
00212 return true;
00213 }
00214 else if (ranges->empty() && other.ranges->empty()) {
00215 return false;
00216 }
00217 else {
00218 return ranges->front().first == other.ranges->front().first;
00219 }
00220 }
00221
00222 public:
00223 iterator_sequence()
00224 : ranges(new std::deque<IteratorRange>())
00225 {}
00226
00227 iterator_sequence(iterator_sequence const & other)
00228 : ranges(other.ranges)
00229 {}
00230
00231 void append_range(BackingIterator left, BackingIterator right)
00232 {
00233 if (left != right) {
00234 ranges->push_back(IteratorRange(left, right));
00235 }
00236 }
00237 };
00238
00239
00240
00241 }
00242 }
00243 }
00244 }
00245
00246
00247
00248
00249
00250
00251
00252 #endif