Menu

[94f52a]: / iterator_range.hpp  Maximize  Restore  History

Download this file

170 lines (137 with data), 5.4 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#ifndef CHILON_ITERATOR_RANGE_HPP
#define CHILON_ITERATOR_RANGE_HPP
#include <chilon/meta/return.hpp>
// allow boost to hash these ranges
#include <boost/functional/hash/hash.hpp>
#include <iostream>
#include <iterator>
#include <string>
namespace chilon {
template <class T>
static inline auto begin(T&& t) CHILON_RETURN(std::forward<T>(t).begin())
template <class T>
static inline auto end(T&& t) CHILON_RETURN(std::forward<T>(t).end())
static inline char const * const begin(char const *str) {
return str;
}
static inline char const * end(char const *str) {
while ('\0' != *str) ++str;
return str;
}
static inline char * end(char *str) {
while ('\0' != *str) ++str;
return str;
}
/**
* @brief This class represents an iterator_range much like boost::iterator_range.
* @detailed This iterator_range provides all of the functionality of boost::iterator_range
* but in addition allows easier modification of the range through
* references for begin/end in addition to .assign
* @tparam Iterator type for iterators to begin/end of range.
*/
template <class Iterator>
struct iterator_range {
typedef typename std::iterator_traits<Iterator>::value_type value_type;
typedef typename std::iterator_traits<Iterator>::reference reference;
typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
typedef typename std::iterator_traits<Iterator>::pointer pointer;
typedef typename std::iterator_traits<Iterator>::iterator_category iterator_category;
typedef Iterator iterator;
typedef Iterator const_iterator;
void assign(iterator const& begin, iterator const& end) {
begin_ = begin;
end_ = end;
}
std::size_t size() const { return end_ - begin_; }
bool empty() const { return begin_ >= end_; }
void advance() { ++begin_; }
void advance(int const size) { begin_ += size; }
bool same(char const * const ptr) const { return begin_ = ptr; }
bool end(iterator const candidate) const { return candidate == end_; }
iterator begin() const { return begin_; }
iterator end() const { return end_; }
iterator& begin() { return begin_; }
iterator& end() { return end_; }
reference front() const { return *begin_; }
reference back() const { return *(end_ - 1); }
template <class T>
friend std::ostream& operator<<(std::ostream &os, iterator_range<T> const& self);
template <class T>
bool operator==(T const& rhs) const {
return size() == rhs.size() && std::equal(begin_, end_, rhs.begin());
}
bool operator==(char const * const str) const {
return std::equal(begin_, end_, str) && str[end_ - begin_] == '\0';
}
bool operator==(std::string const &str) const {
return size() == str.size() && std::equal(begin_, end_, str.begin());
}
template <class T>
bool operator<(T const& rhs) const {
auto it = begin();
auto rhs_it = chilon::begin(rhs);
auto rhs_end = chilon::end(rhs);
for (;;) {
if (*it < *rhs_it) return true;
else if (*it != *rhs_it) return false;
else if (++rhs_it == rhs_end) return false;
else if (++it == end()) return true;
}
}
template <class T>
bool operator!=(T const& rhs) const {
return ! (*this == rhs);
}
template <class T>
void operator=(T const& rhs) {
begin_ = rhs.begin();
end_ = rhs.end();
}
reference operator[](difference_type const idx) const {
return begin_[idx];
}
// iterator_range can be converted into a string
operator std::string() const {
return std::string(begin_, end_);
}
iterator_range(iterator const& begin, iterator const& end) : begin_(begin), end_(end) {}
iterator_range(iterator const& end) : begin_(end), end_(end) {}
iterator_range(std::string const& str) : begin_(str.begin()), end_(str.end()) {}
// TODO: find default null type
iterator_range() : begin_(0), end_(0) {}
protected:
iterator begin_;
iterator end_;
};
template <class T>
std::ostream& operator<<(std::ostream &os, iterator_range<T> const& self) {
std::copy(self.begin_, self.end_,
std::ostream_iterator<typename iterator_range<T>::value_type>(os));
return os;
}
template <class T>
bool operator==(std::string const &str, iterator_range<T> const& self) {
return ! str.compare(0, str.size(), self.begin(), 0, self.size());
}
////////////////////////////////////////////////////////////////////////////////
typedef iterator_range<char const *> range;
typedef iterator_range<std::string::const_iterator> string_range;
typedef iterator_range<std::string::iterator> mutable_string_range;
static inline range to_range(char const * const str) {
return range(str, end(str));
return str;
}
template <class T>
std::size_t inline hash_value(chilon::iterator_range<T> const& arg) {
return boost::hash_range(arg.begin(), arg.end());
}
}
namespace std {
template <class T>
struct hash<chilon::iterator_range<T>> {
std::size_t operator()(chilon::iterator_range<T> const& arg) const {
return chilon::hash_value(arg);
}
};
}
#endif
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.