diff options
-rw-r--r-- | src/entity.hpp | 115 | ||||
-rw-r--r-- | test/entity.cpp | 21 |
2 files changed, 128 insertions, 8 deletions
diff --git a/src/entity.hpp b/src/entity.hpp index 6d24255b..3c32ea23 100644 --- a/src/entity.hpp +++ b/src/entity.hpp @@ -4,6 +4,7 @@ #include <compare> #include <type_traits> #include <utility> +#include <algorithm> #include <tuple> #include <Corrade/Containers/StringView.h> @@ -94,6 +95,33 @@ struct write_field<Obj, FieldType, FieldType Obj::*> { static constexpr void write(Obj& x, FieldType Obj::* w, move_qualified<FieldType> value) { x.*w = value; } }; +constexpr inline int memcmp_(const char* s1, const char* s2, std::size_t n) +{ +#ifdef __GNUC__ + return __builtin_memcmp(s1, s2, n); +#else + if (n != 0) { + do { + if (*s1++ != *s2++) + return (static_cast<unsigned char>(*--s1) - static_cast<unsigned char>(*--s2)); + } while (--n != 0); + } + return 0; +#endif +} + +constexpr inline std::size_t strlen_(const char* s) +{ +#ifdef __GNUC__ + return __builtin_strlen(s); +#else + const char* end; + for (end = s; *end; end++) + ; + return std::size_t(end - s); +#endif +} + } // namespace detail struct EntityBase {}; @@ -168,8 +196,8 @@ template<typename... Ts> struct parameter_pack; template<template<typename...> class F, typename Acc, typename T, typename... Fs> struct reduce0_; -template<template<typename...> class F, typename Acc, template<typename...> class T, typename... Fs> -struct reduce0_<F, Acc, T<>, Fs...> { +template<template<typename...> class F, typename Acc, template<typename...> class X, typename... Fs> +struct reduce0_<F, Acc, X<>, Fs...> { using type = Acc; }; @@ -178,6 +206,9 @@ struct reduce0_<F, Acc, X<T, Ts...>, Fs...> { using type = typename reduce0_< F, F<Acc, T>, parameter_pack<Ts...>, Fs... >::type; }; +template<template<typename...> class F, typename Acc, typename X, typename... Fs> +using reduce0 = typename reduce0_<F, Acc, X, Fs...>::type; + template<template<typename...> class F, typename X, typename... Fs> struct reduce_; @@ -211,6 +242,86 @@ struct map_<F, C, X<Ts...>, Us...> { template<template<typename...> class F, typename X, typename... Us> using map = typename map_<F, detail::parameter_pack, X, Us...>::type; +template<std::size_t N, typename T> +struct skip_; + +template<std::size_t N, template<typename...> class Tuple, typename T, typename... Ts> +struct skip_<N, Tuple<T, Ts...>> { + using type = typename skip_<N-1, parameter_pack<Ts...>>::type; +}; + +template<template<typename...> class Tuple, typename... Ts> +struct skip_<0, Tuple<Ts...>> { using type = parameter_pack<Ts...>; }; + +template<template<typename...> class Tuple, typename T, typename... Ts> +struct skip_<0, Tuple<T, Ts...>> { + using type = parameter_pack<T, Ts...>; +}; + +template<std::size_t N, typename T> +using skip = typename skip_<N, T>::type; + +template<std::size_t N, typename Acc, typename T> +struct take_; + +template<template<typename...> class Tuple, typename... Ts, typename... As> +struct take_<0, parameter_pack<As...>, Tuple<Ts...>> { + using type = parameter_pack<As...>; +}; + +template<typename... As, template<typename...> class Tuple, typename T1, typename... Ts> +struct take_<0, parameter_pack<As...>, Tuple<T1, Ts...>> { + using type = parameter_pack<As...>; +}; + +template<std::size_t N, typename... As, template<typename...> class Tuple, typename T1, typename... Ts> +struct take_<N, parameter_pack<As...>, Tuple<T1, Ts...>> { + using type = typename take_<N-1, parameter_pack<As..., T1>, parameter_pack<Ts...>>::type; +}; + +template<std::size_t N, typename T> +using take = typename take_<N, parameter_pack<>, T>::type; + +template<std::size_t N, typename T> +struct nth_; + +template<std::size_t N, template<typename...> class X, typename T, typename... Ts> +struct nth_<N, X<T, Ts...>> { + using type = typename nth_<N-1, parameter_pack<Ts...>>::type; +}; + +template<template<typename...> class X, typename T, typename... Ts> +struct nth_<0, X<T, Ts...>> { + using type = T; +}; + +template<std::size_t N, typename T> +using nth = typename nth_<N, T>::type; + +template<std::size_t N, typename Acc, typename T> +struct except_nth_; + +template<std::size_t N, template<typename...> class X, typename... As, typename T, typename... Ts> +struct except_nth_<N, parameter_pack<As...>, X<T, Ts...>> { + using type = typename except_nth_<N-1, parameter_pack<As..., T>, parameter_pack<Ts...>>::type; +}; + +template<typename... As, template<typename...> class X, typename T, typename... Ts> +struct except_nth_<0, parameter_pack<As...>, X<T, Ts...>> { + using type = parameter_pack<As..., Ts...>; +}; + +template<std::size_t N, typename T> +using except_nth = typename except_nth_<N, parameter_pack<>, T>::type; + +template<typename F, typename KeyT, typename Tuple> +struct sort_tuple_; + +template<typename F, typename KeyT, template<typename...> class Tuple, typename... Ts> +struct sort_tuple_<F, KeyT, Tuple<Ts...>> { + +}; + } // namespace detail template<typename F, typename Tuple> diff --git a/test/entity.cpp b/test/entity.cpp index 01d8a28c..838d18cd 100644 --- a/test/entity.cpp +++ b/test/entity.cpp @@ -75,13 +75,22 @@ namespace type_tests { using namespace floormat::entities::detail; template<typename T, typename U> using common_type2 = std::common_type_t<T, U>; -static_assert(std::is_same_v<long long, detail::reduce<common_type2, parameter_pack<char, unsigned short, short, long long>>>); -static_assert(std::is_same_v<detail::parameter_pack<unsigned char, unsigned short, unsigned int>, - detail::map<std::make_unsigned_t, detail::parameter_pack<char, short, int>>>); +static_assert(std::is_same_v<long long, reduce<common_type2, parameter_pack<char, unsigned short, short, long long>>>); +static_assert(std::is_same_v<parameter_pack<unsigned char, unsigned short, unsigned int>, + map<std::make_unsigned_t, parameter_pack<char, short, int>>>); + +static_assert(std::is_same_v<parameter_pack<unsigned char, unsigned short, unsigned, unsigned long>, + map<std::make_unsigned_t, parameter_pack<char, short, int, long>>>); +static_assert(std::is_same_v<std::tuple<int, short, char>, lift<parameter_pack<short, char>, std::tuple, int>>); +static_assert(std::is_same_v<parameter_pack<long, long long>, + skip<3, std::tuple<char, short, int, long, long long>>>); +static_assert(std::is_same_v<parameter_pack<char, short, int>, + take<3, std::tuple<char, short, int, float, double, long double>>>); +static_assert(std::is_same_v<int, nth<2, parameter_pack<char, short, int, long, long long>>>); + +static_assert(std::is_same_v<parameter_pack<char, short, long, float>, + except_nth<2, parameter_pack<char, short, int, long, float>>>); -static_assert(std::is_same_v<detail::parameter_pack<unsigned char, unsigned short, unsigned, unsigned long>, - detail::map<std::make_unsigned_t, detail::parameter_pack<char, short, int, long>>>); -static_assert(std::is_same_v<std::tuple<int, short, char>, detail::lift<detail::parameter_pack<short, char>, std::tuple, int>>); } // namespace type_tests } // namespace floormat |