Last active
May 15, 2017 20:12
-
-
Save willkill07/0c263b34ccfd4d8795b8e778fa833add to your computer and use it in GitHub Desktop.
tinymeta
This file contains hidden or 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
| 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; |
This file contains hidden or 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
| 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>(); | |
| }; |
This file contains hidden or 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
| #include <utility> | |
| template<typename T> | |
| struct logical_not : std::integral_constant<bool, !T::value> {}; |
This file contains hidden or 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
| #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 |
This file contains hidden or 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
| #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...>> {}; |
This file contains hidden or 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
| #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> {}; |
This file contains hidden or 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
| #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; |
This file contains hidden or 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
| 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; |
This file contains hidden or 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
| 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