Created
August 7, 2018 15:34
-
-
Save matovitch/11553ad74204fb426283b39fd073de05 to your computer and use it in GitHub Desktop.
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
// http://coliru.stacked-crooked.com/a/f49adfd932697df3 | |
#include <iostream> | |
#include <cstdint> | |
static const uint8_t BYTE_UNDERSCORE = static_cast<uint8_t>('_'); | |
static const uint8_t BYTE_ZERO = static_cast<uint8_t>('0'); | |
static const uint8_t BYTE_NINE = static_cast<uint8_t>('9'); | |
static const uint8_t BYTE_A_MIN = static_cast<uint8_t>('a'); | |
static const uint8_t BYTE_Z_MIN = static_cast<uint8_t>('z'); | |
static const uint8_t BYTE_A_MAJ = static_cast<uint8_t>('A'); | |
static const uint8_t BYTE_Z_MAJ = static_cast<uint8_t>('Z'); | |
template <uint8_t BYTE> | |
struct PredByte | |
{ | |
bool operator()(const uint8_t byte) const | |
{ | |
return byte == BYTE; | |
} | |
}; | |
template <uint8_t MIN, | |
uint8_t MAX> | |
struct PredInterval | |
{ | |
bool operator()(const uint8_t byte) const | |
{ | |
return byte >= MIN && byte <= MAX; | |
} | |
}; | |
template <class... Preds> | |
struct PredCombinatorOr; | |
template <class Pred> | |
struct PredCombinatorOr<Pred> | |
{ | |
bool operator()(const uint8_t byte) const | |
{ | |
return Pred{}(byte); | |
} | |
}; | |
template <class Pred, class... Preds> | |
struct PredCombinatorOr<Pred, Preds...> | |
{ | |
bool operator()(const uint8_t byte) const | |
{ | |
return Pred{}(byte) || PredCombinatorOr<Preds...>{}(byte); | |
} | |
}; | |
using PredIsUnderscore = PredByte<BYTE_UNDERSCORE>; | |
using PredIsNum = PredInterval<BYTE_ZERO, | |
BYTE_NINE>; | |
using PredIsAlphaMin = PredInterval<BYTE_A_MIN, | |
BYTE_Z_MIN>; | |
using PredIsAlphaMaj = PredInterval<BYTE_A_MAJ, | |
BYTE_Z_MAJ>; | |
using PredIsAlpha = PredCombinatorOr<PredIsAlphaMin, | |
PredIsAlphaMaj>; | |
using PredIsAlphaNum = PredCombinatorOr<PredIsAlpha, | |
PredIsNum>; | |
template <class Pred> | |
static const auto match = [](const uint8_t byte) { return Pred{}(byte); }; | |
class Reader | |
{ | |
public: | |
Reader(const std::string dataAsString) : | |
_dataAsString{dataAsString}, | |
_head{reinterpret_cast<const uint8_t*>(_dataAsString.data())}, | |
_tail{_head + _dataAsString.size()} | |
{} | |
operator bool() const | |
{ | |
return _head < _tail; | |
} | |
uint8_t operator*() const | |
{ | |
return *_head; | |
} | |
void operator++(int) | |
{ | |
_head++; | |
} | |
private: | |
std::string _dataAsString; | |
const uint8_t* _head; | |
const uint8_t* const _tail; | |
}; | |
template <class... Preds> | |
struct State; | |
template <> | |
struct State<> | |
{ | |
std::size_t operator()(const uint8_t byte) const | |
{ | |
return 0; | |
} | |
}; | |
template <class Pred, class... Preds> | |
struct State<Pred, Preds...> | |
{ | |
constexpr size() { return sizeof...(Preds) + 1; } | |
std::size_t operator()(const uint8_t byte) const | |
{ | |
return (Pred{}(byte)) ? size() : State<Preds...>{}(byte); | |
} | |
}; | |
template <class State> | |
struct StateWithMap | |
{ | |
std::array<abstract::State*, State::size()> | |
}; | |
int main() | |
{ | |
Reader reader{"pl9o_p"}; | |
State<PredIsNum, PredIsAlpha> state; | |
while (reader) | |
{ | |
std::cout << state(*reader) << std::endl; | |
reader++; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment