#include <iostream>
#include <type_traits>
#include <utility>
#include <string>
#include <algorithm>
#include <functional>
template<bool...> struct BoolSequence{}; //just here to hold bools
template<char...> struct CharSequence{}; //just here to hold chars
template<typename T, char C> struct Contains; //generic
template<char First, char... Cs, char Match> //not first specialization
struct Contains<CharSequence<First, Cs...>,Match> :
Contains<CharSequence<Cs...>, Match>{}; //strip first and increase index
template<char First, char... Cs> //is first specialization
struct Contains<CharSequence<First, Cs...>,First>: std::true_type {};
template<char Match> //not found specialization
struct Contains<CharSequence<>,Match>: std::false_type{};
template<int I, typename T, typename U>
struct MakeSequence; //generic
template<int I, bool... Bs, typename U>
struct MakeSequence<I,BoolSequence<Bs...>, U>: //not last
MakeSequence<I-1, BoolSequence<Contains<U,I-1>::value,Bs...>, U>{};
template<bool... Bs, typename U>
struct MakeSequence<0,BoolSequence<Bs...>,U>{ //last
using Type = BoolSequence<Bs...>;
};
template<typename T> struct BoolASCIITable;
template<bool... Bs> struct BoolASCIITable<BoolSequence<Bs...>>{
/* could be made constexpr but not yet supported by MSVC */
bool operator()(const char c) const{
static const bool table[256] = {Bs...};
return table[static_cast<int>(c)];
}
typedef char argument_type; //so that functional functors work
};
using Delims = CharSequence<'.',',',' ','-','\n'>; //list your custom delimiters here
using Table = BoolASCIITable<typename MakeSequence<256,BoolSequence<>,Delims>::Type>;
template<typename T_It>
std::pair<T_It,T_It> getNextToken(T_It begin,T_It end){
begin = std::find_if(begin,end,std::not1(Table{})); //find first non delim or end
auto second = std::find_if(begin,end,Table{}); //find first delim or end
return std::make_pair(begin,second);
}
int main() {
std::string s{"Some people, excluding those present, have been compile time constants - since puberty."};
auto it = std::begin(s);
auto end = std::end(s);
while(it != std::end(s)){
auto token = getNextToken(it,end);
std::cout << std::string(token.first,token.second) << std::endl;
it = token.second;
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CiNpbmNsdWRlIDx1dGlsaXR5PgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCnRlbXBsYXRlPGJvb2wuLi4+IHN0cnVjdCBCb29sU2VxdWVuY2V7fTsgCQkvL2p1c3QgaGVyZSB0byBob2xkIGJvb2xzCnRlbXBsYXRlPGNoYXIuLi4+IHN0cnVjdCBDaGFyU2VxdWVuY2V7fTsgCQkvL2p1c3QgaGVyZSB0byBob2xkIGNoYXJzCnRlbXBsYXRlPHR5cGVuYW1lIFQsIGNoYXIgQz4gc3RydWN0IENvbnRhaW5zOwkvL2dlbmVyaWMKdGVtcGxhdGU8Y2hhciBGaXJzdCwgY2hhci4uLiBDcywgY2hhciBNYXRjaD4gCS8vbm90IGZpcnN0IHNwZWNpYWxpemF0aW9uCnN0cnVjdCBDb250YWluczxDaGFyU2VxdWVuY2U8Rmlyc3QsIENzLi4uPixNYXRjaD4gOgoJQ29udGFpbnM8Q2hhclNlcXVlbmNlPENzLi4uPiwgTWF0Y2g+e307IAkvL3N0cmlwIGZpcnN0IGFuZCBpbmNyZWFzZSBpbmRleAp0ZW1wbGF0ZTxjaGFyIEZpcnN0LCBjaGFyLi4uIENzPiAJCQkJLy9pcyBmaXJzdCBzcGVjaWFsaXphdGlvbgpzdHJ1Y3QgQ29udGFpbnM8Q2hhclNlcXVlbmNlPEZpcnN0LCBDcy4uLj4sRmlyc3Q+OiBzdGQ6OnRydWVfdHlwZSB7fTsgCnRlbXBsYXRlPGNoYXIgTWF0Y2g+IAkJCQkJCQkvL25vdCBmb3VuZCBzcGVjaWFsaXphdGlvbgpzdHJ1Y3QgQ29udGFpbnM8Q2hhclNlcXVlbmNlPD4sTWF0Y2g+OiBzdGQ6OmZhbHNlX3R5cGV7fTsKCnRlbXBsYXRlPGludCBJLCB0eXBlbmFtZSBULCB0eXBlbmFtZSBVPiAKc3RydWN0IE1ha2VTZXF1ZW5jZTsJCQkJCQkJLy9nZW5lcmljCnRlbXBsYXRlPGludCBJLCBib29sLi4uIEJzLCB0eXBlbmFtZSBVPiAKc3RydWN0IE1ha2VTZXF1ZW5jZTxJLEJvb2xTZXF1ZW5jZTxCcy4uLj4sIFU+OgkvL25vdCBsYXN0CglNYWtlU2VxdWVuY2U8SS0xLCBCb29sU2VxdWVuY2U8Q29udGFpbnM8VSxJLTE+Ojp2YWx1ZSxCcy4uLj4sIFU+e307CnRlbXBsYXRlPGJvb2wuLi4gQnMsIHR5cGVuYW1lIFU+IApzdHJ1Y3QgTWFrZVNlcXVlbmNlPDAsQm9vbFNlcXVlbmNlPEJzLi4uPixVPnsJLy9sYXN0CQoJdXNpbmcgVHlwZSA9IEJvb2xTZXF1ZW5jZTxCcy4uLj47Cn07CnRlbXBsYXRlPHR5cGVuYW1lIFQ+IHN0cnVjdCBCb29sQVNDSUlUYWJsZTsKdGVtcGxhdGU8Ym9vbC4uLiBCcz4gc3RydWN0IEJvb2xBU0NJSVRhYmxlPEJvb2xTZXF1ZW5jZTxCcy4uLj4+ewoJLyogY291bGQgYmUgbWFkZSBjb25zdGV4cHIgYnV0IG5vdCB5ZXQgc3VwcG9ydGVkIGJ5IE1TVkMgKi8KCWJvb2wgb3BlcmF0b3IoKShjb25zdCBjaGFyIGMpIGNvbnN0ewoJCXN0YXRpYyBjb25zdCBib29sIHRhYmxlWzI1Nl0gPSB7QnMuLi59OwoJCXJldHVybiB0YWJsZVtzdGF0aWNfY2FzdDxpbnQ+KGMpXTsKCX0JCgl0eXBlZGVmIGNoYXIgYXJndW1lbnRfdHlwZTsgLy9zbyB0aGF0IGZ1bmN0aW9uYWwgZnVuY3RvcnMgd29yawp9Owp1c2luZyBEZWxpbXMgPSBDaGFyU2VxdWVuY2U8Jy4nLCcsJywnICcsJy0nLCdcbic+OyAgLy9saXN0IHlvdXIgY3VzdG9tIGRlbGltaXRlcnMgaGVyZQp1c2luZyBUYWJsZSA9IEJvb2xBU0NJSVRhYmxlPHR5cGVuYW1lIE1ha2VTZXF1ZW5jZTwyNTYsQm9vbFNlcXVlbmNlPD4sRGVsaW1zPjo6VHlwZT47Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUX0l0PgpzdGQ6OnBhaXI8VF9JdCxUX0l0PiBnZXROZXh0VG9rZW4oVF9JdCBiZWdpbixUX0l0IGVuZCl7CgliZWdpbiA9IHN0ZDo6ZmluZF9pZihiZWdpbixlbmQsc3RkOjpub3QxKFRhYmxle30pKTsgLy9maW5kIGZpcnN0IG5vbiBkZWxpbSBvciBlbmQKCWF1dG8gc2Vjb25kID0gc3RkOjpmaW5kX2lmKGJlZ2luLGVuZCxUYWJsZXt9KTsJCS8vZmluZCBmaXJzdCBkZWxpbSBvciBlbmQKCXJldHVybiBzdGQ6Om1ha2VfcGFpcihiZWdpbixzZWNvbmQpOwp9CgppbnQgbWFpbigpIHsKCXN0ZDo6c3RyaW5nIHN7IlNvbWUgcGVvcGxlLCBleGNsdWRpbmcgdGhvc2UgcHJlc2VudCwgaGF2ZSBiZWVuIGNvbXBpbGUgdGltZSBjb25zdGFudHMgLSBzaW5jZSBwdWJlcnR5LiJ9OwoJYXV0byBpdCA9IHN0ZDo6YmVnaW4ocyk7CglhdXRvIGVuZCA9IHN0ZDo6ZW5kKHMpOwoJd2hpbGUoaXQgIT0gc3RkOjplbmQocykpewoJCWF1dG8gdG9rZW4gPSBnZXROZXh0VG9rZW4oaXQsZW5kKTsKCQlzdGQ6OmNvdXQgPDwgc3RkOjpzdHJpbmcodG9rZW4uZmlyc3QsdG9rZW4uc2Vjb25kKSA8PCBzdGQ6OmVuZGw7CgkJaXQgPSB0b2tlbi5zZWNvbmQ7Cgl9CglyZXR1cm4gMDsKfQ==