Add #pragma once to files, add utils

This commit is contained in:
sha512sum 2024-02-28 00:50:13 +00:00
parent 72ee630cd2
commit 7b5c08464d
4 changed files with 168 additions and 13 deletions

View file

@ -2,6 +2,7 @@
#include <utempl/optional.hpp> #include <utempl/optional.hpp>
#include <utempl/constexpr_string.hpp> #include <utempl/constexpr_string.hpp>
#include <utempl/tuple.hpp> #include <utempl/tuple.hpp>
#include <utempl/utils.hpp>
#include <iostream> #include <iostream>
#include <array> #include <array>
#include <fmt/format.h> #include <fmt/format.h>
@ -10,9 +11,6 @@
namespace utempl { namespace utempl {
template <auto>
struct Wrapper {};
constexpr std::size_t CountDigits(std::size_t num) { constexpr std::size_t CountDigits(std::size_t num) {
std::size_t count = 0; std::size_t count = 0;
do { do {

View file

@ -1,7 +1,10 @@
#pragma once
#include <utempl/type_list.hpp> #include <utempl/type_list.hpp>
namespace utempl { namespace utempl {
template <auto>
struct Wrapper;
namespace impl { namespace impl {
template <auto, typename T> template <auto, typename T>
@ -56,6 +59,11 @@ inline constexpr auto Get(Tuple<Ts...>&& tuple) -> auto&& requires (I < sizeof..
return std::move(static_cast<impl::TupleLeaf<I, Type>&&>(tuple).value); return std::move(static_cast<impl::TupleLeaf<I, Type>&&>(tuple).value);
}; };
template <std::size_t I, typename T>
inline constexpr auto Get(T&& arg) -> decltype(get<I>(std::forward<T>(arg))) {
return get<I>(std::forward<T>(arg));
};
template <typename... Ts> template <typename... Ts>
struct Tuple : public impl::TupleHelper<0, Ts...> { struct Tuple : public impl::TupleHelper<0, Ts...> {
template <typename... TTs> template <typename... TTs>
@ -70,21 +78,19 @@ struct Tuple : public impl::TupleHelper<0, Ts...> {
return {Get<Is>(*this)..., Get<IIs>(other)...}; return {Get<Is>(*this)..., Get<IIs>(other)...};
}(std::make_index_sequence<sizeof...(Ts)>(), std::make_index_sequence<sizeof...(TTs)>()); }(std::make_index_sequence<sizeof...(Ts)>(), std::make_index_sequence<sizeof...(TTs)>());
}; };
template <auto I>
inline constexpr auto operator[](Wrapper<I>) const -> const auto& {
return Get<I>(*this);
};
template <auto I>
inline constexpr auto operator[](Wrapper<I>) -> auto& {
return Get<I>(*this);
};
}; };
template <typename... Ts> template <typename... Ts>
Tuple(Ts&&...) -> Tuple<std::remove_cvref_t<Ts>...>; Tuple(Ts&&...) -> Tuple<std::remove_cvref_t<Ts>...>;
template <typename>
struct TupleSize {};
template <typename... Ts>
struct TupleSize<Tuple<Ts...>> {
static constexpr auto value = sizeof...(Ts);
};
template <typename Tuple>
inline constexpr auto kTupleSize = TupleSize<Tuple>::value;
template <typename... Ts> template <typename... Ts>
consteval auto ListFromTuple(Tuple<Ts...>) -> TypeList<Ts...> { consteval auto ListFromTuple(Tuple<Ts...>) -> TypeList<Ts...> {
return {}; return {};

View file

@ -1,3 +1,4 @@
#pragma once
#include <concepts> #include <concepts>
#include <utility> #include <utility>
#include <array> #include <array>
@ -16,6 +17,14 @@ struct Caster {
template <typename... Ts> template <typename... Ts>
struct TypeList { struct TypeList {
}; };
template <typename T>
inline constexpr auto kType = TypeList<T>{};
template <typename... Ts>
inline constexpr auto kTypeList = TypeList<Ts...>{};
template <typename... Ts, typename... TTs> template <typename... Ts, typename... TTs>
consteval auto operator==(const TypeList<Ts...>& first, const TypeList<TTs...>& second) -> bool { consteval auto operator==(const TypeList<Ts...>& first, const TypeList<TTs...>& second) -> bool {
return std::same_as<decltype(first), decltype(second)>; return std::same_as<decltype(first), decltype(second)>;
@ -32,4 +41,13 @@ consteval auto Find(TypeList<Ts...>) -> std::size_t {
return std::ranges::find(arr, true) - arr.begin(); return std::ranges::find(arr, true) - arr.begin();
}; };
template <typename... Ts>
consteval auto Reverse(TypeList<Ts...> list) {
return [&]<auto... Is>(std::index_sequence<Is...>) -> TypeList<decltype(Get<sizeof...(Ts) - Is - 1>(list))...> {
return {};
}(std::make_index_sequence<sizeof...(Ts)>());
};
} // namespace utempl } // namespace utempl

133
include/utempl/utils.hpp Normal file
View file

@ -0,0 +1,133 @@
#pragma once
#include <utempl/tuple.hpp>
#include <utempl/overloaded.hpp>
#include <utempl/constexpr_string.hpp>
#include <fmt/format.h>
namespace utempl {
template <auto Value>
struct Wrapper {
static constexpr auto kValue = Value;
inline constexpr auto operator==(auto&& arg) {
return arg == Value;
};
consteval operator decltype(Value)() {
return Value;
};
};
template <ConstexprString string, typename T = std::size_t>
consteval auto ParseNumber() -> T {
T response{};
for(const auto& c : string) {
if (c >= '0' && c <= '9') {
response = response * 10 + (c - '0');
};
};
return response;
};
namespace literals {
template <char... cs>
consteval auto operator"" _c() {
return Wrapper<ParseNumber<ConstexprString<sizeof...(cs)>({cs...})>()>{};
};
} // namespace literals
template <std::size_t I, typename... Ts>
inline constexpr auto Arg(Ts&&... args) requires (I < sizeof...(Ts)) {
return [&]<auto... Is>(std::index_sequence<Is...>){
return [](decltype(Caster(Is))..., auto&& response, ...){
return response;
}(std::forward<Ts>(args)...);
}(std::make_index_sequence<I>());
};
template <std::size_t Count>
inline constexpr auto Times(auto&& f) {
[&]<auto... Is>(std::index_sequence<Is...>){
(Arg<0>(f, Is)(), ...);
}(std::make_index_sequence<Count>());
};
template <typename T>
concept TupleLike = Overloaded(
[]<template <typename...> typename M, typename... Ts>(TypeList<M<Ts...>>) {return true;},
[](auto&&) {return false;}
)(kType<std::remove_cvref_t<T>>);
template <typename T>
concept IsTypeList = Overloaded(
[]<typename... Ts>(TypeList<TypeList<Ts...>>) {return true;},
[](auto&&) {return false;}
)(kType<std::remove_cvref_t<T>>);
template <TupleLike T>
inline constexpr std::size_t kTupleSize =
[]<template <typename...> typename M, typename... Ts>(TypeList<M<Ts...>>) {
return sizeof...(Ts);
}(TypeList<std::remove_cvref_t<T>>{});
template <TupleLike T = Tuple<>, typename... Args>
inline constexpr auto MakeTuple(Args&&... args) {
return [&]<template <typename...> typename M, typename... Ts>(TypeList<M<Ts...>>){
return M{std::forward<Args>(args)...};
}(kType<std::remove_cvref_t<T>>);
};
template <TupleLike Tuple>
inline constexpr auto Transform(Tuple&& container, auto&& f) {
return [&]<auto... Is>(std::index_sequence<Is...>){
return MakeTuple<Tuple>(f(Get<Is>(container))...);
}(std::make_index_sequence<kTupleSize<std::remove_cvref_t<Tuple>>>());
};
template <TupleLike Tuple>
inline constexpr auto Reverse(Tuple&& tuple) {
return [&]<auto... Is>(std::index_sequence<Is...>) {
return MakeTuple<Tuple>(Get<kTupleSize<Tuple> - Is - 1>(tuple)...);
}(std::make_index_sequence<kTupleSize<Tuple>>());
};
template <TupleLike Tuple, TupleLike Tuple2>
inline constexpr auto TupleCat(Tuple&& tuple, Tuple2&& tuple2) {
return [&]<auto... Is, auto... IIs>(std::index_sequence<Is...>, std::index_sequence<IIs...>){
return MakeTuple<Tuple>(Get<Is>(tuple)..., Get<IIs>(tuple2)...);
}(std::make_index_sequence<kTupleSize<Tuple>>(), std::make_index_sequence<kTupleSize<Tuple2>>());
};
namespace impl {
template <TupleLike Tuple>
struct TupleCater {
Tuple tuple;
template <TupleLike Other>
inline constexpr auto operator+(TupleCater<Other>&& other) {
using ResultType = decltype(TupleCat(std::move(this->tuple), other.tuple));
return TupleCater<ResultType>{TupleCat(std::move(this->tuple), std::move(other.tuple))};
};
};
} // namespace impl
template <TupleLike... Tuples>
inline constexpr auto TupleCat(Tuples&&... tuples) {
return (impl::TupleCater{std::forward<Tuples>(tuples)} + ...).tuple;
};
template <TupleLike Tuple>
inline constexpr auto Filter(Tuple&& tuple, auto&& f) {
return [&]<auto... Is>(std::index_sequence<Is...>){
return TupleCat([&]<auto I>(Wrapper<I>){
constexpr bool flag = decltype(f(Get<I>(tuple)))::kValue;
if constexpr(flag) {
return MakeTuple<Tuple>(Get<I>(tuple));
} else {
return MakeTuple<Tuple>();
};
}(Wrapper<Is>{})...);
}(std::make_index_sequence<kTupleSize<Tuple>>());
};
};