Add #pragma once to files, add utils
This commit is contained in:
parent
72ee630cd2
commit
7b5c08464d
4 changed files with 168 additions and 13 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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 {};
|
||||||
|
|
|
@ -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
133
include/utempl/utils.hpp
Normal 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>>());
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
Loading…
Reference in a new issue