Skip to content

Instantly share code, notes, and snippets.

@FreeSlave
Created August 22, 2016 13:55
Show Gist options
  • Save FreeSlave/2e76fa18440441d68c21334e4c1a5a04 to your computer and use it in GitHub Desktop.
Save FreeSlave/2e76fa18440441d68c21334e4c1a5a04 to your computer and use it in GitHub Desktop.
Create range from single value
#include <iterator>
#include <string>
#include <cassert>
template<typename T>
struct Only
{
struct iterator : public std::iterator<std::forward_iterator_tag, T>
{
iterator(Only* only, bool isEnd = false) : _only(only), _isEnd(isEnd) {
}
T& operator*() {
return _only->_value;
}
const T& operator*() const {
return _only->_value;
}
T* operator->() {
return &_only->_value;
}
const T* operator->() const {
return &_only->_value;
}
iterator operator++() {
if (!_isEnd) {
_isEnd = true;
}
return *this;
}
iterator operator++(int) {
iterator toReturn = *this;
++(*this);
return toReturn;
}
bool operator==(const iterator& other) const {
return equal(other);
}
bool operator!=(const iterator& other) const {
return !equal(other);
}
private:
bool equal(const iterator& other) const {
return (_only == other._only) && ((_isEnd && other._isEnd) || (!_isEnd && !other._isEnd && _only->_value == other._only->_value));
}
Only* _only;
bool _isEnd;
};
Only(const T& value) : _value(value) {
}
iterator begin() {
return iterator(this);
}
iterator end() {
return iterator(this, true);
}
private:
T _value;
};
int main (int argc, char** argv) {
Only<std::string> only("Hello");
assert(only.begin() != only.end());
Only<std::string>::iterator first = only.begin();
assert(*first == "Hello");
assert(first->size() == 5);
Only<std::string>::iterator first2 = first++;
assert(first == only.end());
assert(first2 == only.begin());
first = ++first2;
assert(first == first2);
assert(first2 == only.end());
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment