首次提交
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
#pragma once
|
||||
#include "fixed_string.hpp"
|
||||
#include <cmath>
|
||||
#include <concepts>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
namespace structive {
|
||||
struct Key_Category {};
|
||||
struct Access_Category {};
|
||||
struct Persistence_Category {};
|
||||
struct Unit_Category {};
|
||||
struct Sensitive_Category {};
|
||||
enum class External_Access {
|
||||
none,
|
||||
read,
|
||||
write,
|
||||
read_write
|
||||
};
|
||||
enum class Persistence_Access {
|
||||
none,
|
||||
load,
|
||||
store,
|
||||
load_store
|
||||
};
|
||||
template <Fixed_String Value>
|
||||
struct Key_Attribute {
|
||||
using attribute_category = Key_Category;
|
||||
static constexpr bool single_valued = true;
|
||||
static constexpr bool inheritable = false;
|
||||
static constexpr auto value = Value;
|
||||
};
|
||||
template <External_Access Value>
|
||||
struct External_Access_Attribute {
|
||||
using attribute_category = Access_Category;
|
||||
static constexpr bool single_valued = true;
|
||||
static constexpr bool inheritable = true;
|
||||
static constexpr auto value = Value;
|
||||
};
|
||||
template <Persistence_Access Value>
|
||||
struct Persistence_Access_Attribute {
|
||||
using attribute_category = Persistence_Category;
|
||||
static constexpr bool single_valued = true;
|
||||
static constexpr bool inheritable = true;
|
||||
static constexpr auto value = Value;
|
||||
};
|
||||
template <Fixed_String Value>
|
||||
struct Unit_Attribute {
|
||||
using attribute_category = Unit_Category;
|
||||
static constexpr bool single_valued = true;
|
||||
static constexpr bool inheritable = false;
|
||||
static constexpr auto value = Value;
|
||||
};
|
||||
template <bool Value>
|
||||
struct Sensitive_Attribute {
|
||||
using attribute_category = Sensitive_Category;
|
||||
static constexpr bool single_valued = true;
|
||||
static constexpr bool inheritable = true;
|
||||
static constexpr auto value = Value;
|
||||
};
|
||||
template <auto Value>
|
||||
struct Min_Constraint {
|
||||
using property_constraint_tag = void;
|
||||
static constexpr bool inheritable = false;
|
||||
static constexpr auto code = Fixed_String{"min_value"};
|
||||
template <class T>
|
||||
constexpr bool validate(const T& candidate) const requires requires { candidate >= Value; } {
|
||||
return candidate >= Value;
|
||||
}
|
||||
};
|
||||
template <auto Value>
|
||||
struct Max_Constraint {
|
||||
using property_constraint_tag = void;
|
||||
static constexpr bool inheritable = false;
|
||||
static constexpr auto code = Fixed_String{"max_value"};
|
||||
template <class T>
|
||||
constexpr bool validate(const T& candidate) const requires requires { candidate <= Value; } {
|
||||
return candidate <= Value;
|
||||
}
|
||||
};
|
||||
struct Finite_Constraint {
|
||||
using property_constraint_tag = void;
|
||||
static constexpr bool inheritable = false;
|
||||
static constexpr auto code = Fixed_String{"finite"};
|
||||
template <std::floating_point T>
|
||||
bool validate(T candidate) const {
|
||||
return std::isfinite(candidate);
|
||||
}
|
||||
};
|
||||
template <Fixed_String Code, class Function>
|
||||
struct Custom_Constraint {
|
||||
using property_constraint_tag = void;
|
||||
static constexpr bool inheritable = false;
|
||||
static constexpr auto code = Code;
|
||||
[[no_unique_address]] Function function;
|
||||
template <class T>
|
||||
constexpr bool validate(const T& candidate) const requires std::predicate<const Function&, const T&> {
|
||||
return static_cast<bool>(function(candidate));
|
||||
}
|
||||
};
|
||||
template <Fixed_String Value>
|
||||
inline constexpr Key_Attribute<Value> key{};
|
||||
template <External_Access Value>
|
||||
inline constexpr External_Access_Attribute<Value> external_access{};
|
||||
template <Persistence_Access Value>
|
||||
inline constexpr Persistence_Access_Attribute<Value> persistence_access{};
|
||||
template <Fixed_String Value>
|
||||
inline constexpr Unit_Attribute<Value> unit{};
|
||||
template <bool Value = true>
|
||||
inline constexpr Sensitive_Attribute<Value> sensitive{};
|
||||
template <auto Value>
|
||||
inline constexpr Min_Constraint<Value> min_value{};
|
||||
template <auto Value>
|
||||
inline constexpr Max_Constraint<Value> max_value{};
|
||||
inline constexpr Finite_Constraint finite{};
|
||||
template <Fixed_String Code, class Function>
|
||||
constexpr auto constraint(Function&& function) {
|
||||
return Custom_Constraint<Code, std::decay_t<Function>>{std::forward<Function>(function)};
|
||||
}
|
||||
template <class Attribute>
|
||||
concept Property_Constraint = requires {
|
||||
typename Attribute::property_constraint_tag;
|
||||
{ Attribute::code.view() } -> std::convertible_to<std::string_view>;
|
||||
};
|
||||
template <class Attribute, class Value>
|
||||
concept Property_Constraint_For = Property_Constraint<Attribute> && requires(const Attribute& attribute, const Value& value) {
|
||||
{ attribute.validate(value) } -> std::convertible_to<bool>;
|
||||
};
|
||||
template <class Attribute>
|
||||
concept Inheritable_Attribute = requires {
|
||||
{ Attribute::inheritable } -> std::convertible_to<bool>;
|
||||
} && Attribute::inheritable;
|
||||
}
|
||||
Reference in New Issue
Block a user