refactor: finish constraint builder and its testbench
This commit is contained in:
		@ -34,32 +34,61 @@ namespace yycc::constraint::builder {
 | 
			
		||||
     * @brief Get constraint for enum values by enumerating all possible values.
 | 
			
		||||
     * @tparam T An enum type (except bool) of underlying stored value.
 | 
			
		||||
     * @param[in] il An initializer list storing all possible values.
 | 
			
		||||
     * @param[in] default_index The index of default value in given list.
 | 
			
		||||
     * @return The generated constraint instance which can be directly applied.
 | 
			
		||||
    */
 | 
			
		||||
    template<typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
 | 
			
		||||
    Constraint<T> enum_constraint(const std::initializer_list<T>& il) {
 | 
			
		||||
        std::set<T> data(il);
 | 
			
		||||
    Constraint<T> enum_constraint(const std::initializer_list<T>& il, size_t default_index = 0u) {
 | 
			
		||||
        if (default_index >= il.size())
 | 
			
		||||
            throw std::invalid_argument("the default index must be a valid index in given list");
 | 
			
		||||
 | 
			
		||||
        auto fn_check = [data](const T& val) -> bool { return data.find(val) != data.end(); };
 | 
			
		||||
        return Constraint<T>(std::move(fn_check), nullptr);
 | 
			
		||||
        T default_entry = il.begin()[default_index];
 | 
			
		||||
        std::set<T> entries(il);
 | 
			
		||||
 | 
			
		||||
        // TODO: modify it as `contain` once we finish patch namespace.
 | 
			
		||||
        auto fn_check = [entries](const T& val) -> bool {
 | 
			
		||||
            return entries.find(val) != entries.end();
 | 
			
		||||
        };
 | 
			
		||||
        auto fn_clamp = [entries, default_entry](const T& val) -> T {
 | 
			
		||||
            if (entries.find(val) != entries.end()) {
 | 
			
		||||
                return val;
 | 
			
		||||
            } else {
 | 
			
		||||
                return default_entry;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        return Constraint<T>(std::move(fn_check), fn_clamp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @brief Get constraint for string values by enumerating all possible values.
 | 
			
		||||
     * @param[in] il An initializer list storing all possible values.
 | 
			
		||||
     * @param[in] default_index The index of default value in given list.
 | 
			
		||||
     * @return The generated constraint instance which can be directly applied.
 | 
			
		||||
     * @remarks
 | 
			
		||||
     * Caller must make sure that the string view passed in initializer list is valid until this Constraint life time gone.
 | 
			
		||||
     * Becasue this generator will not copy your given string view into string.
 | 
			
		||||
    */
 | 
			
		||||
    inline Constraint<NS_YYCC_STRING::u8string> GetStringEnumerationConstraint(
 | 
			
		||||
        const std::initializer_list<NS_YYCC_STRING::u8string_view>& il) {
 | 
			
		||||
        std::set<NS_YYCC_STRING::u8string_view> data(il);
 | 
			
		||||
    inline Constraint<NS_YYCC_STRING::u8string> strenum_constraint(
 | 
			
		||||
        const std::initializer_list<NS_YYCC_STRING::u8string_view>& il, size_t default_index = 0u) {
 | 
			
		||||
        if (default_index >= il.size())
 | 
			
		||||
            throw std::invalid_argument("the default index must be a valid index in given list");
 | 
			
		||||
 | 
			
		||||
        auto fn_check = [data](const NS_YYCC_STRING::u8string& val) -> bool {
 | 
			
		||||
            return data.find(NS_YYCC_STRING::u8string_view(val)) != data.end();
 | 
			
		||||
        NS_YYCC_STRING::u8string default_entry = NS_YYCC_STRING::u8string(il.begin()[default_index]);
 | 
			
		||||
        std::set<NS_YYCC_STRING::u8string> entries;
 | 
			
		||||
        for (const auto& i : il) {
 | 
			
		||||
            entries.emplace(i);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // TODO: modify it as `contain` once we finish patch namespace.
 | 
			
		||||
        auto fn_check = [entries](const NS_YYCC_STRING::u8string& val) -> bool {
 | 
			
		||||
            return entries.find(val) != entries.end();
 | 
			
		||||
        };
 | 
			
		||||
        return Constraint<NS_YYCC_STRING::u8string>(std::move(fn_check), nullptr);
 | 
			
		||||
        auto fn_clamp = [entries, default_entry](
 | 
			
		||||
                            const NS_YYCC_STRING::u8string& val) -> NS_YYCC_STRING::u8string {
 | 
			
		||||
            if (entries.find(val) != entries.end()) {
 | 
			
		||||
                return val;
 | 
			
		||||
            } else {
 | 
			
		||||
                return default_entry;
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        return Constraint<NS_YYCC_STRING::u8string>(std::move(fn_check), fn_clamp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
} // namespace yycc::constraint::builder
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user