Skip to content

Instantly share code, notes, and snippets.

@willkill07
Last active May 15, 2017 20:12
Show Gist options
  • Select an option

  • Save willkill07/0c263b34ccfd4d8795b8e778fa833add to your computer and use it in GitHub Desktop.

Select an option

Save willkill07/0c263b34ccfd4d8795b8e778fa833add to your computer and use it in GitHub Desktop.
tinymeta
namespace impl {
template <template <class ...> class L, class = L<>, class = L<>, class ...>
struct concat_ {
using type = L<>;
};
template <template <class ...> class L,
template <class ...> class L1, class ... T1>
struct concat_<L, L1<T1...>> {
using type = L<T1...>;
};
template <template <class ...> class L,
template <class ...> class L1, template <class ...> class L2,
class ... T1, class ... T2, class ... Rest>
struct concat_<L, L1<T1...>, L2<T2...>, Rest...>
: concat_<L, L<T1..., T2...>, typename concat_<L, Rest...>::type> {
};
template <class ...> struct make_concat;
template <template <class...> class L, class ... Ts, class ... Rest>
struct make_concat<L<Ts...>,Rest...> {
using type = typename concat_<L, L<Ts...>,Rest...>::type;
};
} // end namespace impl
template <class ... Ts>
using concat = typename impl::make_concat<Ts...>::type;
struct cstr_view {
const char * data;
const unsigned int size;
};
constexpr bool operator== (const cstr_view s1, const cstr_view s2) {
if (s1.size != s2.size)
return false;
for (unsigned int i = 0; i < s1.size; ++i)
if (s1.data[i] != s2.data[i])
return false;
return true;
};
constexpr bool operator< (const cstr_view s1, const cstr_view s2) {
unsigned int limit = (s1.size < s2.size) ? s1.size : s2.size;
for (unsigned int i = 0; i < limit; ++i)
if (s1.data[i] < s2.data[i])
return true;
else if (s1.data[i] > s2.data[i])
return false;
return s1.size < s2.size;
};
template <typename T>
constexpr const cstr_view make_cstr_view() {
constexpr const auto fn = __PRETTY_FUNCTION__;
unsigned int len = 0;
for (const char * i = fn; i; ++i) {
if (*i == 0)
break;
++len;
}
return cstr_view{fn, len};
}
template <typename T>
struct cstr_of{
static constexpr auto value = make_cstr_view<T>();
};
#include <utility>
template<typename T>
struct logical_not : std::integral_constant<bool, !T::value> {};
#ifndef USING_GODBOLT
#include "occurrence_of.hpp"
#include "quick_sort.hpp"
#include "reverse.hpp"
#include "cstr_view.hpp"
#else
#include <type_traits>
#include <utility>
template<typename T>
struct logical_not : std::integral_constant<bool, !T::value> {};
namespace impl {
template <bool...> struct bool_list;
}
template <bool ... Vs> struct all_of : std::is_same<impl::bool_list<true, Vs...>, impl::bool_list<Vs..., true>> {};
template <bool ... Vs> struct none_of : std::is_same<impl::bool_list<false, Vs...>, impl::bool_list<Vs..., false>> {};
template <bool ... Vs> struct any_of : logical_not<none_of<Vs...>> {};
namespace impl {
template <template <class ...> class L, class = L<>, class = L<>, class ...>
struct concat_ {
using type = L<>;
};
template <template <class ...> class L,
template <class ...> class L1, class ... T1>
struct concat_<L, L1<T1...>> {
using type = L<T1...>;
};
template <template <class ...> class L,
template <class ...> class L1, template <class ...> class L2,
class ... T1, class ... T2, class ... Rest>
struct concat_<L, L1<T1...>, L2<T2...>, Rest...>
: concat_<L, L<T1..., T2...>, typename concat_<L, Rest...>::type> {
};
template <class ...> struct make_concat;
template <template <class...> class L, class ... Ts, class ... Rest>
struct make_concat<L<Ts...>,Rest...> {
using type = typename concat_<L, L<Ts...>,Rest...>::type;
};
}
template <class ... Ts>
using concat = typename impl::make_concat<Ts...>::type;
template <typename> struct unpack;
template <template <typename...> class Out, typename T, typename ... Rest>
struct unpack<Out<T,Rest...>> {
using empty = Out<>;
using first = T;
using rest = Out<Rest...>;
};
namespace impl{
template <
template <typename> class Proj,
typename Pivot, typename Frontier,
typename LT, typename EQ, typename GT>
struct partition_;
template <
template <typename> class Proj, template <typename ...> class L,
typename Pivot,
typename Curr, typename ... Rest,
typename ... LT, typename ... EQ, typename ... GT>
struct partition_<Proj, Pivot, L<Curr, Rest...>, L<LT...>, L<EQ...>, L<GT...>>
: std::conditional<
(Proj<Curr>::value == Proj<Pivot>::value),
partition_<Proj, Pivot, L<Rest...>, L<LT...>, L<EQ..., Curr>, L<GT...>>,
typename std::conditional<
(Proj<Curr>::value < Proj<Pivot>::value),
partition_<Proj, Pivot, L<Rest...>, L<LT..., Curr>, L<EQ...>, L<GT...>>,
partition_<Proj, Pivot, L<Rest...>, L<LT...>, L<EQ...>, L<GT..., Curr>>>::type>::type{};
template <
template <typename> class Proj, template <typename ...> class L,
typename Pivot,
typename ... LT, typename ... EQ, typename ... GT>
struct partition_<Proj, Pivot, L<>, L<LT...>, L<EQ...>, L<GT...>> {
using lt = L<LT...>;
using eq = L<Pivot, EQ...>;
using gt = L<GT...>;
};
}
template <template <typename> class Proj, typename L>
struct partition : public impl::partition_<
Proj,
typename unpack<L>::first,
typename unpack<L>::rest,
typename unpack<L>::empty,
typename unpack<L>::empty,
typename unpack<L>::empty> {};
namespace impl {
template <template <typename> class Proj, typename List>
struct quick_sort_ {
using part = partition<Proj, List>;
using type = concat<
typename quick_sort_<Proj, typename part::lt>::type,
typename part::eq,
typename quick_sort_<Proj, typename part::gt>::type
>;
};
template <template <typename> class Proj, template <typename...> class List>
struct quick_sort_<Proj,List<>> {
using type = List<>;
};
}
template <template <typename> class Proj, typename List>
using quick_sort = typename impl::quick_sort_<Proj, List>::type;
namespace impl {
template <typename In, typename Out> struct reverse_;
template <template <class...> class List, typename ... RestOut>
struct reverse_<List<>,List<RestOut...>> {
using type = List<RestOut...>;
};
template <template <class...> class List, typename Curr, typename ... RestIn, typename ... RestOut>
struct reverse_<List<Curr, RestIn...>, List<RestOut...>>
: reverse_<List<RestIn...>, List<Curr, RestOut...>> {};
template <template <class...> class List, typename C1, typename C2, typename C3, typename C4, typename ... RestIn, typename ... RestOut>
struct reverse_<List<C1, C2, C3, C4, RestIn...>, List<RestOut...>>
: reverse_<List<RestIn...>, List<C4, C3, C2, C1, RestOut...>> {};
template <class T> struct make_reverse;
template <template <class...> class L, class ... Ts>
struct make_reverse<L<Ts...>> : reverse_<L<Ts...>,L<>> {};
}
template <typename T>
using reverse = typename impl::make_reverse<T>::type;
struct cstr_view {
const char * data;
const unsigned int size;
};
constexpr bool operator== (const cstr_view s1, const cstr_view s2) {
if (s1.size != s2.size)
return false;
for (unsigned int i = 0; i < s1.size; ++i)
if (s1.data[i] != s2.data[i])
return false;
return true;
};
constexpr bool operator< (const cstr_view s1, const cstr_view s2) {
unsigned int limit = (s1.size < s2.size) ? s1.size : s2.size;
for (unsigned int i = 0; i < limit; ++i)
if (s1.data[i] < s2.data[i])
return true;
else if (s1.data[i] > s2.data[i])
return false;
return s1.size < s2.size;
};
template <typename T>
constexpr const cstr_view make_cstr_view() {
constexpr const auto fn = __PRETTY_FUNCTION__;
unsigned int len = 0;
for (const char * i = fn; i; ++i) {
if (*i == 0)
break;
++len;
}
return cstr_view{fn, len};
}
template <typename T>
struct cstr_of{
static constexpr auto value = make_cstr_view<T>();
};
#endif
#include <type_traits>
#ifndef USING_GODBOLT
# include "logical_not.hpp"
#endif
namespace impl {
template <bool...> struct bool_list;
} // end namespace impl
template <bool ... Vs> struct all_of : std::is_same<impl::bool_list<true, Vs...>, impl::bool_list<Vs..., true>> {};
template <bool ... Vs> struct none_of : std::is_same<impl::bool_list<false, Vs...>, impl::bool_list<Vs..., false>> {};
template <bool ... Vs> struct any_of : logical_not<none_of<Vs...>> {};
#include <type_traits>
#ifndef USING_GODBOLT
# include "concat.hpp"
# include "unpack.hpp"
#endif
namespace impl{
template <
template <typename> class Proj,
typename Pivot, typename Frontier,
typename LT, typename EQ, typename GT>
struct partition_;
template <
template <typename> class Proj, template <typename ...> class L,
typename Pivot,
typename Curr, typename ... Rest,
typename ... LT, typename ... EQ, typename ... GT>
struct partition_<Proj, Pivot, L<Curr, Rest...>, L<LT...>, L<EQ...>, L<GT...>>
: std::conditional<
(Proj<Curr>::value == Proj<Pivot>::value),
partition_<Proj, Pivot, L<Rest...>, L<LT...>, L<EQ..., Curr>, L<GT...>>,
typename std::conditional<
(Proj<Curr>::value < Proj<Pivot>::value),
partition_<Proj, Pivot, L<Rest...>, L<LT..., Curr>, L<EQ...>, L<GT...>>,
partition_<Proj, Pivot, L<Rest...>, L<LT...>, L<EQ...>, L<GT..., Curr>>>::type>::type{};
template <
template <typename> class Proj, template <typename ...> class L,
typename Pivot,
typename ... LT, typename ... EQ, typename ... GT>
struct partition_<Proj, Pivot, L<>, L<LT...>, L<EQ...>, L<GT...>> {
using lt = L<LT...>;
using eq = L<Pivot, EQ...>;
using gt = L<GT...>;
};
} // end namespace impl
template <template <typename> class Proj, typename L>
struct partition : public impl::partition_<
Proj,
typename unpack<L>::first,
typename unpack<L>::rest,
typename unpack<L>::empty,
typename unpack<L>::empty,
typename unpack<L>::empty> {};
#ifndef USING_GODBOLT
# include "partition.hpp"
#endif
namespace impl {
template <template <typename> class Proj, typename List>
struct quick_sort_ {
using part = partition<Proj, List>;
using type = concat<
typename quick_sort_<Proj, typename part::lt>::type,
typename part::eq,
typename quick_sort_<Proj, typename part::gt>::type
>;
};
template <template <typename> class Proj, template <typename...> class List>
struct quick_sort_<Proj,List<>> {
using type = List<>;
};
} // end namespace impl
template <template <typename> class Proj, typename List>
using quick_sort = typename impl::quick_sort_<Proj, List>::type;
namespace impl {
template <typename In, typename Out> struct reverse_;
template <template <class...> class List, typename ... RestOut>
struct reverse_<List<>,List<RestOut...>> {
using type = List<RestOut...>;
};
template <template <class...> class List, typename Curr, typename ... RestIn, typename ... RestOut>
struct reverse_<List<Curr, RestIn...>, List<RestOut...>>
: reverse_<List<RestIn...>, List<Curr, RestOut...>> {};
template <template <class...> class List, typename C1, typename C2, typename C3, typename C4, typename ... RestIn, typename ... RestOut>
struct reverse_<List<C1, C2, C3, C4, RestIn...>, List<RestOut...>>
: reverse_<List<RestIn...>, List<C4, C3, C2, C1, RestOut...>> {};
template <class T> struct make_reverse;
template <template <class...> class L, class ... Ts>
struct make_reverse<L<Ts...>> : reverse_<L<Ts...>,L<>> {};
} // end namespace impl
template <typename T>
using reverse = typename impl::make_reverse<T>::type;
template <typename> struct unpack;
template <template <typename...> class Out, typename T, typename ... Rest>
struct unpack<Out<T,Rest...>> {
using empty = Out<>;
using first = T;
using rest = Out<Rest...>;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment