首次提交
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
#include <concepts>
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
namespace structive {
|
||||
template <class... Types>
|
||||
struct Type_List {};
|
||||
template <class Type, class List>
|
||||
struct Type_List_Contains;
|
||||
template <class Type, class... Types>
|
||||
struct Type_List_Contains<Type, Type_List<Types...>> : std::bool_constant<(std::same_as<Type, Types> || ...)> {};
|
||||
template <class Type, class List>
|
||||
inline constexpr bool type_list_contains_v = Type_List_Contains<Type, List>::value;
|
||||
template <class List, class Type>
|
||||
struct Type_List_Push_Unique;
|
||||
template <class... Types, class Type>
|
||||
struct Type_List_Push_Unique<Type_List<Types...>, Type> {
|
||||
using type = std::conditional_t<(std::same_as<Type, Types> || ...), Type_List<Types...>, Type_List<Types..., Type>>;
|
||||
};
|
||||
template <class Input, class Output = Type_List<>>
|
||||
struct Type_List_Unique;
|
||||
template <class Output>
|
||||
struct Type_List_Unique<Type_List<>, Output> {
|
||||
using type = Output;
|
||||
};
|
||||
template <class Head, class... Tail, class Output>
|
||||
struct Type_List_Unique<Type_List<Head, Tail...>, Output> {
|
||||
using next = typename Type_List_Push_Unique<Output, Head>::type;
|
||||
using type = typename Type_List_Unique<Type_List<Tail...>, next>::type;
|
||||
};
|
||||
template <class Type, class List>
|
||||
struct Type_List_Index;
|
||||
template <class Type, class... Tail>
|
||||
struct Type_List_Index<Type, Type_List<Type, Tail...>> : std::integral_constant<std::size_t, 0> {};
|
||||
template <class Type, class Head, class... Tail>
|
||||
struct Type_List_Index<Type, Type_List<Head, Tail...>> : std::integral_constant<std::size_t, 1 + Type_List_Index<Type, Type_List<Tail...>>::value> {};
|
||||
template <class Type, class List>
|
||||
inline constexpr std::size_t type_list_index_v = Type_List_Index<Type, List>::value;
|
||||
template <class Attribute, class = void>
|
||||
struct Attribute_Category_Of {
|
||||
using type = void;
|
||||
};
|
||||
template <class Attribute>
|
||||
struct Attribute_Category_Of<Attribute, std::void_t<typename Attribute::attribute_category>> {
|
||||
using type = typename Attribute::attribute_category;
|
||||
};
|
||||
template <class Attribute>
|
||||
using attribute_category_of_t = typename Attribute_Category_Of<Attribute>::type;
|
||||
template <class Category, class... Attributes>
|
||||
struct Find_Attribute_By_Category;
|
||||
template <class Category>
|
||||
struct Find_Attribute_By_Category<Category> {
|
||||
using type = void;
|
||||
};
|
||||
template <class Category, class Head, class... Tail>
|
||||
struct Find_Attribute_By_Category<Category, Head, Tail...> {
|
||||
using type = std::conditional_t<std::same_as<Category, attribute_category_of_t<Head>>, Head, typename Find_Attribute_By_Category<Category, Tail...>::type>;
|
||||
};
|
||||
template <class Category, class List>
|
||||
struct Find_Attribute_In_List;
|
||||
template <class Category, class... Attributes>
|
||||
struct Find_Attribute_In_List<Category, Type_List<Attributes...>> {
|
||||
using type = typename Find_Attribute_By_Category<Category, Attributes...>::type;
|
||||
};
|
||||
template <class Category, class List>
|
||||
using find_attribute_in_list_t = typename Find_Attribute_In_List<Category, List>::type;
|
||||
template <class Category, class... Attributes>
|
||||
consteval std::size_t count_attribute_category() {
|
||||
return (std::size_t{0} + ... + (std::same_as<attribute_category_of_t<Attributes>, Category> ? 1u : 0u));
|
||||
}
|
||||
template <class Attribute, class... Attributes>
|
||||
consteval bool unique_single_value_category_for() {
|
||||
if constexpr (requires { Attribute::single_valued; }) {
|
||||
if constexpr (Attribute::single_valued && !std::same_as<attribute_category_of_t<Attribute>, void>) {
|
||||
return count_attribute_category<attribute_category_of_t<Attribute>, Attributes...>() == 1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
template <class... Attributes>
|
||||
consteval bool unique_single_value_categories() {
|
||||
return (unique_single_value_category_for<Attributes, Attributes...>() && ...);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user