Skip to content

Instantly share code, notes, and snippets.

@matovitch
Created August 7, 2018 15:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matovitch/11553ad74204fb426283b39fd073de05 to your computer and use it in GitHub Desktop.
Save matovitch/11553ad74204fb426283b39fd073de05 to your computer and use it in GitHub Desktop.
// 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