Skip to content

Instantly share code, notes, and snippets.

@FreeSlave
Created August 19, 2016 19:26
Show Gist options
  • Save FreeSlave/0a6eebcb289f8847c181a0f9e7e8bd1b to your computer and use it in GitHub Desktop.
Save FreeSlave/0a6eebcb289f8847c181a0f9e7e8bd1b to your computer and use it in GitHub Desktop.
Use STL iterators to iterate over zero terminated string without calling of strlen
// Copyright (c) 2016 Roman Chistokhodov
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
/*
* Q: Why?
* A: The idea is to use STL iterators to iterate over zero terminated string without calling of strlen to evaluate the end iterator.
*
* Q: Why not random access?
* A: Currently the 'end' iterator is implemented as NULL and it's not obvious how it should work with '-' (minus) operator,
* which is required by random access iterator concept.
*
* Q: Why not bidirectional?
* A: Same issue, but with '--' operator.
*/
#include <iterator>
#include <cstdlib>
#include <algorithm>
#include <cassert>
template<typename T>
struct CStringIterator : public std::iterator<std::forward_iterator_tag, T>
{
CStringIterator(T* str) : _ptr(str) {}
CStringIterator() : _ptr(0) {}
T& operator*() {
return *_ptr;
}
T* operator->() {
return _ptr;
}
CStringIterator& operator++() {
++_ptr;
return *this;
}
CStringIterator operator++(int) {
CStringIterator toReturn = *this;
++_ptr;
return toReturn;
}
CStringIterator operator+=(std::ptrdiff_t add) {
_ptr += add;
}
CStringIterator operator+(std::ptrdiff_t add) const {
return CStringIterator(_ptr + add);
}
bool operator==(const CStringIterator& other) const {
return equal(other);
}
bool operator!=(const CStringIterator& other) const {
return !equal(other);
}
T* ptr() const {
return _ptr;
}
private:
inline bool equal(const CStringIterator& other) const {
return (_ptr == other._ptr) || (this->atEnd() && other.atEnd());
}
inline bool atEnd() const {
return !_ptr || !*_ptr;
}
T* _ptr;
};
template<typename T>
CStringIterator<T> operator+(std::ptrdiff_t value, const CStringIterator<T>& it) {
return value + it.ptr();
}
int main()
{
typedef CStringIterator<const char> CIterator;
const char* str = "Hello";
CIterator begin(str);
CIterator end;
assert(*begin == 'H');
assert(begin + 5 == end);
assert(5 + begin == end);
assert(begin != end);
assert(end != begin);
CIterator it = begin;
CIterator it2 = ++it;
assert(*it == 'e');
assert(it == it2);
it2 = it++;
assert(*it == 'l');
assert(*it2 == 'e');
assert(std::equal(begin, end, "Hello"));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment