Created
July 9, 2014 17:26
-
-
Save t-mat/436d68f0a486f2759a72 to your computer and use it in GitHub Desktop.
Range based for null terminated string
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <string> | |
template<class Char> | |
class ForEachNullTreminatedStringIterator { | |
using ThisClass = ForEachNullTreminatedStringIterator; | |
public: | |
ForEachNullTreminatedStringIterator() : p{} {} | |
ForEachNullTreminatedStringIterator(Char* p) : p{p} {} | |
Char& operator *() const { | |
return *p; | |
} | |
ThisClass& operator ++ () { | |
next(); | |
return *this; | |
} | |
bool operator == (const ThisClass& v) const { | |
if(good() || v.good()) { | |
return false; | |
} | |
return true; | |
} | |
bool operator != (const ThisClass& v) const { | |
return ! (*this == v); | |
} | |
protected: | |
bool good() const { | |
return p != nullptr; | |
} | |
void next() { | |
if(good()) { | |
++p; | |
if(0 == *p) { | |
p = nullptr; | |
} | |
} | |
} | |
Char* p; | |
}; | |
template<class Char> | |
class ForEachNullTreminatedString { | |
public: | |
using iterator = ForEachNullTreminatedStringIterator<Char>; | |
public: | |
explicit ForEachNullTreminatedString(iterator str) : itBegin { str } {} | |
iterator begin() const { return itBegin; } | |
iterator end() const { return iterator {}; } | |
private: | |
iterator itBegin; | |
}; | |
inline ForEachNullTreminatedString<char> foreach(char* str) { | |
return ForEachNullTreminatedString<char> {str}; | |
} | |
inline ForEachNullTreminatedString<char> foreach(std::string& str) { | |
return foreach(&str[0]); | |
} | |
inline ForEachNullTreminatedString<const char> foreach(const char* str) { | |
return ForEachNullTreminatedString<const char> {str}; | |
} | |
inline ForEachNullTreminatedString<const char> foreach(const std::string& str) { | |
return foreach(&str[0]); | |
} | |
int main() { | |
{ | |
const char str[] = "TEST STRING"; | |
for(const char& c : foreach(str)) { | |
std::cout << c; | |
} | |
std::cout << std::endl; | |
} | |
{ | |
char str[] = "TEST STRING"; | |
for(char& c : foreach(str)) { | |
if('T' == c) { | |
c = '+'; | |
} | |
} | |
std::cout << str << std::endl; | |
} | |
{ | |
const auto str = std::string("TEST STRING"); | |
for(const char& c : foreach(str)) { | |
std::cout << c; | |
} | |
std::cout << std::endl; | |
} | |
{ | |
auto str = std::string("TEST STRING"); | |
for(char& c : foreach(str)) { | |
if('T' == c) { | |
c = '+'; | |
} | |
} | |
std::cout << str << std::endl; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://ideone.com/YQcReL