Skip to content

Instantly share code, notes, and snippets.

@gatchamix
Last active August 28, 2017 23:18
Show Gist options
  • Save gatchamix/39bba179dcb23f47cbd4d5c44924e976 to your computer and use it in GitHub Desktop.
Save gatchamix/39bba179dcb23f47cbd4d5c44924e976 to your computer and use it in GitHub Desktop.
hard jump-list generator
#include <array>
#include <type_traits>
#include <utility>
//
template <auto... Vs>
struct auto_t
{ static auto constexpr size = sizeof...(Vs); };
template <auto... Vs>
auto constexpr auto_v = auto_t<Vs...>{};
template <auto... L, auto... R>
auto constexpr operator+(auto_t<L...>, auto_t<R...>)
{ return auto_t<L..., R...>{}; }
template <auto... Vs>
auto constexpr min(auto_t<Vs...>)
{
using type = std::common_type_t<decltype(Vs)...>;
auto val = std::numeric_limits<type>::max();
(((val > Vs) ? val = Vs : 0), ...);
return val;
}
template <auto... Vs>
auto constexpr max(auto_t<Vs...>)
{
using type = std::common_type_t<decltype(Vs)...>;
auto val = std::numeric_limits<type>::min();
(((val < Vs) ? val = Vs : 0), ...);
return val;
}
template <auto... Vs>
auto constexpr common_type(auto_t<Vs...>)
-> std::common_type_t<decltype(Vs)...>;
template <class T>
using common_type_t = decltype(common_type(T{}));
//
template <auto Val>
auto constexpr parse();
auto constexpr default_parse()
{ return 10; }
template <>
auto constexpr parse<'#'>()
{ return 1; }
template <>
auto constexpr parse<','>()
{ return 2; }
template <>
auto constexpr parse<':'>()
{ return 3; }
template <>
auto constexpr parse<'+'>()
{ return 4; }
template <>
auto constexpr parse<'-'>()
{ return 5; }
template <>
auto constexpr parse<'.'>()
{ return 6; }
template <>
auto constexpr parse<'!'>()
{ return 7; }
template <>
auto constexpr parse<'('>()
{ return 8; }
template <>
auto constexpr parse<')'>()
{ return 9; }
template <>
auto constexpr parse<'['>()
{ return 10; }
template <>
auto constexpr parse<']'>()
{ return 11; }
template <>
auto constexpr parse<'{'>()
{ return 12; }
template <>
auto constexpr parse<'}'>()
{ return 13; }
template <>
auto constexpr parse<'&'>()
{ return 14; }
template <>
auto constexpr parse<'<'>()
{ return 15; }
template <>
auto constexpr parse<'>'>()
{ return 16; }
template <>
auto constexpr parse<'='>()
{ return 17; }
template <>
auto constexpr parse<'|'>()
{ return 18; }
template <>
auto constexpr parse<'?'>()
{ return 19; }
template <>
auto constexpr parse<'^'>()
{ return 20; }
template <>
auto constexpr parse<'/'>()
{ return 21; }
template <>
auto constexpr parse<'*'>()
{ return 22; }
template <>
auto constexpr parse<'%'>()
{ return 23; }
template <>
auto constexpr parse<'~'>()
{ return 24; }
//
template <>
auto constexpr parse<1'000>()
{ return 1'000; }
template <>
auto constexpr parse<10'000>()
{ return 10'000; }
template <>
auto constexpr parse<100'000>()
{ return 100'000; }
template <>
auto constexpr parse<1'000'000>()
{ return 1'000'000; }
template <>
auto constexpr parse<10'000'000>()
{ return 10'000'000; }
template <>
auto constexpr parse<100'000'000>()
{ return 100'000'000; }
//
template <class Vals, class Funcs, auto Def = nullptr, auto Limit = 128>
struct jumplist
{
constexpr jumplist(Vals, Funcs, auto_t<Def> = {}, auto_t<Limit> = {})
{}
private:
using T = std::conditional_t<std::is_signed_v<common_type_t<Vals>>,
std::make_signed_t<size_t>, std::size_t>;
using func_t = common_type_t<Funcs>;
static auto constexpr MIN = min(Vals{});
static auto constexpr MAX = max(Vals{});
static auto constexpr BIG = MAX-MIN+1 > Limit;
static auto constexpr N = BIG ? Vals::size : MAX-MIN+1;
template <auto... Vs, auto... Is>
static auto constexpr get__(T v, auto_t<Vs...>, std::index_sequence<Is...>)
{
auto fun = Def;
(((v == Vs) ? fun = table_[Is] : 0) || ...);
return fun;
}
public:
auto constexpr operator[](T i) const
{
if (std::size_t(i-MIN) > MAX-MIN)
{ return static_cast<func_t>(Def); }
if constexpr (BIG)
{ return get__(i, Vals{}, std::make_index_sequence<N>{}); }
else
{ return table_[i - MIN]; }
}
template <class... Args>
auto constexpr operator()(T i, Args&&... args) const
{ return (this->operator[](i))(std::forward<Args>(args)...); }
private:
template <auto... Vs, auto... Fs>
static auto constexpr make_table__(auto_t<Vs...>, auto_t<Fs...>)
{
if constexpr (BIG)
{
return std::array<func_t, N>{ Fs... };
}
else
{
auto arr = std::array<func_t, N>{};
for (auto& f : arr) f = Def;
((arr[Vs - MIN] = Fs), ...);
return arr;
}
}
static auto constexpr table_ = make_table__(Vals{}, Funcs{});
};
//
template <auto... Vs>
auto constexpr make_funcs(auto_t<Vs...>)
{ return auto_v<&parse<Vs>...>; }
int main(int argc, char **argv)
{
auto constexpr core = auto_v
<
':', '+', '-', '.', '!', '(', ')', '[', ']', '{', '}', '#',
'&', '<', '>', '=', '|', '?', '^', '/', '*', '%', '~', ','
>;
#if 1
auto constexpr seq = core;
#else
auto constexpr seq = core + auto_v
<1'000, 10'000, 100'000, 1'000'000, 10'000'000, 100'000'000>;
#endif
auto constexpr test = auto_v<>;
auto constexpr fun = make_funcs(seq);
auto constexpr jl = jumplist{ seq, fun, auto_v<&default_parse> };
return jl(argv[0][0]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment